diff options
author | Andrew Solovay <asolovay@google.com> | 2014-11-18 10:22:54 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-11-18 10:22:54 +0000 |
commit | b2d73807a93495e132e6b12e5612cbaaeea06fd9 (patch) | |
tree | 93a7059d1e24e592963135391e50ca7d8b9dcb5a /docs/html/training/auto/messaging/index.jd | |
parent | 7ca874e71c014718e2107e2f50e095bcc2c474fc (diff) | |
parent | e4662f7e4b73a78074bd1f6b5c9fc17509759d45 (diff) | |
download | frameworks_base-b2d73807a93495e132e6b12e5612cbaaeea06fd9.zip frameworks_base-b2d73807a93495e132e6b12e5612cbaaeea06fd9.tar.gz frameworks_base-b2d73807a93495e132e6b12e5612cbaaeea06fd9.tar.bz2 |
am e4662f7e: am a7f226b8: docs: (Preview) Building an Android Messaging App guide.
* commit 'e4662f7e4b73a78074bd1f6b5c9fc17509759d45':
docs: (Preview) Building an Android Messaging App guide.
Diffstat (limited to 'docs/html/training/auto/messaging/index.jd')
-rw-r--r-- | docs/html/training/auto/messaging/index.jd | 533 |
1 files changed, 533 insertions, 0 deletions
diff --git a/docs/html/training/auto/messaging/index.jd b/docs/html/training/auto/messaging/index.jd new file mode 100644 index 0000000..c51ad7e --- /dev/null +++ b/docs/html/training/auto/messaging/index.jd @@ -0,0 +1,533 @@ +page.title=Providing Messaging for Auto +page.tags="auto", "car", "automotive", "messaging" +page.article=true + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + <h2>Dependencies and Prerequisites</h2> + <ul> + <li>Android 5.0 (API level 21) or higher</li> + </ul> + + <h2>This class teaches you to:</h2> + + <ul> + <li><a href="#overview">Provide Messaging Services</a></li> + <li><a href="#manifest">Configure Your Manifest</a></li> + <li><a href="#support-lib">Import Support Library for Messaging</a></li> + <li><a href="#messaging">Notify Users of Messages</a></li> + <li><a href="#handle_actions">Handle User Actions</a></li> + </ul> + + <h2>Related Samples</h2> + + <ul> + <li><a href="{@docRoot}samples/MessagingService/index.html"> + MessagingService</a></li> + </ul> + + <h2>See Also</h2> + + <ul> + <li><a href="{@docRoot}shareables/auto/AndroidAuto-messaging-apps.pdf"> + User Experience Guidelines: Messaging Apps</a></li> + <li><a href="{@docRoot}guide/topics/ui/notifiers/notifications.html"> + Notifications</a></li> + </ul> +</div> +</div> + +<a class="notice-developers-video wide" + href="https://www.youtube.com/watch?v=gSVLuaOTIPk"> +<div> + <h3>Video</h3> + <p>DevBytes: Android Auto Messaging</p> +</div> +</a> + +<p> + Staying connected through text messages is important to many drivers. Chat apps can let users + know if a child need to be picked up, or if a dinner location has been changed. Apps that provide + sports information might tell the user who just won the big game, and let the user ask questions + about other games being played. The Android framework enables messaging apps to extend their + services into car dashboards using a standard user interface that lets drivers keep their eyes + on the road. +</p> + +<p> + Apps that support messaging can be extended to pass messaging notifications to Auto + dashboard systems, alerting them to new messages and allowing them to respond. You can configure + your messaging app to provide these services when an Android mobile device with your app + installed is connected to an Auto dashboard. Once connected, your app can provide text + information to users and allow them to respond. The Auto dashboard system handles displaying the + notification and the interface for replies. +</p> + +<p> + This lesson assumes that you have built an app that displays messages to the user and receive the + user's replies, such as a chat app. It shows you how to extend your app to hand those messages + off to an Auto device for display and replies. +</p> + + +<h2 id="overview">Provide Messaging Services</h2> + +<p> + Messaging apps do not run directly on the Android dashboard hardware. They are installed on + separate, Android mobile device. When the mobile device is plugged into a dashboard, + the installed messaging apps can offer services for viewing and responding to messages + through the Auto user interface. +</p> + +<p>To enable your app to provide messaging services for Auto devices:</p> + +<ul> + <li>Configure your app manifest to indicate that your app provides messaging services which are + compatible with Android Auto dashboard devices. + </li> + <li>Build and send a specific type of <a href= + "{@docRoot}guide/topics/ui/notifiers/notifications.html">notification</a> for display on Auto + devices. + </li> + <li>Configure your app to receive {@link android.content.Intent} objects that indicate a user + has read or replied to a message. +</ul> + + +<h2 id="#manifest">Configure Your Manifest</h2> + +<p> + You configure your app <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">manifest</a> + to indicate that it supports messaging services for Auto devices and handle message actions. This + section describes what changes to make to your manifest to support messaging for Auto devices. +</p> + + +<h3 id="manifest-messaging">Declare Auto messaging support</h3> + +<p> + When a user connects a Android mobile device to a dashboard running Android, the dashboard + device looks for apps that declare support for vehicle services, such as messaging. You indicate + that your app supports cars capabilities using the following manifest entry: +</p> + +<pre> +<application> + ... + <meta-data android:name="com.google.android.gms.car.application" + android:resource="@xml/automotive_app_desc" /> + ... +<application> +</pre> + +<p> + This manifest entry refers to a secondary xml file, where you declare what Auto capabilities your + app supports. For an app that supports messaging for Auto devices, add an xml file to the {@code + res/xml/} your app's development project directory as {@code automotive_app_desc.xml}, with the + following content: +</p> + +<pre> +<automotiveApp> + <uses name="notification"/> +</automotiveApp> +</pre> + +<p> + For more information about declaring capabilities for Auto devices, see <a href= + "{@docRoot}training/auto/start/index.html#auto-metadata">Getting Started with Auto</a>. +</p> + + +<h3 id="manifest-intent">Define read and reply intent filters</h3> + +<p> + Auto devices use {@link android.content.Intent} objects that indicate a user has read or replied + to a message provided by your app. Your app defines intent types for reading and replying to + messages and adds this information to messaging notifications for Auto devices, so that the + dashboard system can notify your app when a user takes one of these actions. +</p> + +<p> + You define the read action and reply action intents types for your app and the {@code + android.content.BroadcastReceiver} classes that handle them in the manifest. The following code + example demonstrates how to declare these intents and thier associated receivers. +</p> + +<pre> +<application> + ... + <receiver android:name="<em>.MyMessageReadReceiver</em>"> + <intent-filter> + <action android:name="<em>com.myapp.messagingservice.ACTION_MESSAGE_HEARD</em>"/> + </intent-filter> + </receiver> + + <receiver android:name="<em>.MyMessageReplyReceiver</em>"> + <intent-filter> + <action android:name="<em>com.myapp.messagingservice.ACTION_MESSAGE_REPLY</em>"/> + </intent-filter> + </receiver> + ... +</application> +</pre> + +<p> + The definition of the {@code android.content.BroadcastReceiver} classes shown in this example + is discussed in <a href="#handle_actions">Handle User Actions</a>. +</p> + + +<h2 id="support-lib">Import Support Library for Messaging</h3> + +<p> + Building notifications for use with Auto devices requires classes from the + <a href="{@docRoot}tools/support-library/features.html#v4">v4 support library</a>. Use the + <a href="{@docRoot}tools/help/sdk-manager.html">Android SDK Manager</a> to update the + <em>Extras > Android Support Repository</em> to version 9 or higher and the + <em>Extras > Android Support Library</em> to version 21.1.0 or higher. +</p> + +<p> + After you have updated the support libraries, import them into your Android Studio development + project by adding this dependency to your + <a href="{@docRoot}sdk/installing/studio-build.html#configBuild">build.gradle</a> file: +</p> + +<pre> +dependencies { + ... + compile 'com.android.support:support-v4:21.1.+' +} +</pre> + +<p> + For information about importing the support library into development projects for other + development environments, see <a href="{@docRoot}tools/support-library/setup.html">Support + Library Setup</a>. +</p> + + + +<h2 id="messaging">Notify Users of Messages</h2> + +<p> + A messaging app provides messages to a connected Auto dashboard using the <a href= + "{@docRoot}guide/topics/ui/notifiers/notifications.html">notifications</a> framework. When your + messaging app has a message for a user, you build a specially configured notification that is + received by the dashboard system and presented to the user. The Auto device manages the + presentation on the dashboard screen and may play the message via text-to-speech. The dashboard + system also handles voice interaction if the user replies to a message using verbal input. +</p> + +<p> + The messaging user interface for Auto presents users with two levels of information about + messages. The first level of notification tells users what <em>conversations</em> are + available, and who they are with, but not the content of the messages. Typically, a + conversation is one or more messages from another user to the Auto user. +</p> + +<p> + The second level of the notification is the actual content of messages in the conversation. If a + user indicates they want to hear the messages in a conversation, the Auto user interface plays + the messages using text-to-speech. +</p> + +<p> + This section describes how to notify Auto users that conversations are available and + provide the content of messages in those conversations. +</p> + + +<h3 id="build_conversation">Build message conversations</h4> + +<p> + Messaging notifications for Auto organize messages into conversations using the {@code + NotificationCompat.CarExtender.UnreadConversation} class, that represents an unread or new + portion of a conversation from a particular sender. It contains a list of messages from the + sender. +</p> + +<p> + Use the {@code UnreadConversation.Builder} class to create an unread conversation object, + as shown in the following example code: +</p> + +<pre> +// Build a RemoteInput for receiving voice input in a Car Notification +RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY) + .setLabel(getApplicationContext().getString(R.string.notification_reply)) + .build(); + +// Create an unread conversation object to organize a group of messages +// from a particular sender. +UnreadConversation.Builder unreadConvBuilder = + new UnreadConversation.Builder(participantName) + .setReadPendingIntent(msgHeardPendingIntent) + .setReplyAction(replyPendingIntent, remoteInput); +</pre> + +<p> + This conversation object includes a {@link android.app.PendingIntent}, which allows the Auto + device to signal your app that the conversation has been read by the Auto user. The construction + of this intent is discussed in the <a href="#conversation-intents">Creating conversation read and + reply intents</a> section. +</p> + +<p> + If your app supports replying to a conversation, you must call the {@code setReplyAction()} + method and provide a pending intent to pass that user action back to your app. The {@code + UnreadConversation} object you create must also include a {@link + android.support.v4.app.RemoteInput} object. This object is required because the Auto user + receiving this conversation speaks a reply, a the remote input objects lets your app get a text + version of the voice reply. +</p> + + +<h4 id="conversation-messages">Associate messages with conversations</h4> + +<p> + Messages provided for Auto must be associated with a conversation using the {@code + NotificationCompat.CarExtender.UnreadConversation} class. The following code example shows how + to associate individual messages with a conversation object. +</p> + +<pre> +// Note: Add messages from oldest to newest to the UnreadConversation.Builder +for (Iterator<String> messages = conversation.getMessages().iterator(); + messages.hasNext(); ) { + String message = messages.next(); + unreadConvBuilder.addMessage(message); +} +</pre> + +<p> + When a new message arrives in a particular conversation, your app should check if there is + already a conversation object for that particular conversation. If there is, associate the new + message with the existing conversation instead of building a new one. +</p> + + +<h4 id="conversation-intents">Create conversation read and reply intents</h4> + +<p> + Unread conversation objects contain intents for reading and replying to a conversation. You + create a {@link android.app.PendingIntent} object for each of these actions, so the Auto device + can notify your app of action taken by the Auto user on a particular conversation. +</p> + +<p> + The following example code demonstrates how to define a {@link android.app.PendingIntent} to let + your app know if a conversation was listened to by the Auto user: +</p> + +<pre> +Intent msgHeardIntent = new Intent() + .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) + .setAction(<em>com.myapp.messagingservice.ACTION_MESSAGE_HEARD</em>) + .putExtra("conversation_id", conversationId); + +PendingIntent msgHeardPendingIntent = + PendingIntent.getBroadcast(getApplicationContext(), + conversationId, + msgHeardIntent, + PendingIntent.FLAG_UPDATE_CURRENT); +</pre> + +<p> + In this example, {@code conversationId} is an integer that identifies the current conversation. + The value of {@code setAction()} is an intent filter identifier for heard messages which is + defined in your app manifest, as shown in <a href="#manifest-intent">Define read and reply intent + filters</a>. +</p> + +<p> + If your app supports replying to conversations, you also create a {@link + android.app.PendingIntent} for each conversation to notify your app that the user has replied. + The following code example shows you how to build this intent for use with a particular + conversation: +</p> + +<pre> +Intent msgReplyIntent = new Intent() + .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) + .setAction(<em>com.myapp.messagingservice.ACTION_MESSAGE_REPLY</em>) + .putExtra("conversation_id", <em>conversationId</em>); + +PendingIntent msgReplyPendingIntent = PendingIntent.getBroadcast( + getApplicationContext(), + <em>conversationId</em>, + msgReplyIntent, + PendingIntent.FLAG_UPDATE_CURRENT); +</pre> + +<p> + Once again, {@code conversationId} is an integer that uniquely identifies this conversation. The + value of {@code setAction()} is an intent filter identifier for replies which is defined in your + app manifest, as shown in <a href="#manifest-intent">Define read and reply intent filters</a>. +</p> + + +<h3 id="sending_messages">Sending Messages</h4> + +<p> + When a message arrives for a conversation, you take the following steps to dispatch it as a + notification to Auto. +</p> + +<p>First, add the message to the <code>UnreadConversation.Builder</code> for +this conversation, and update its timestamp:</p> + +<pre> +unreadConvBuilder.addMessage(<em>messageString</em>) + .setLatestTimestamp(<em>currentTimestamp</em>); +</pre> + +<p>Then create a {@link android.support.v4.app.NotificationCompat.Builder} +object that you'll use to build the actual notification. You'll need to use the +pending intents you created in the previous step.</p> + +<pre> +NotificationCompat.Builder notificationBuilder = + new NotificationCompat.Builder(getApplicationContext()) + .setSmallIcon(R.drawable.<em>notification_icon</em>) + .setLargeIcon(<em>icon_bitmap</em>) + .setContentText(<em>messageString</em>) + .setWhen(<em>currentTimestamp</em>) + .setContentTitle(<em>participant_name</em>) + .setContentIntent(msgHeardPendingIntent); + +</pre> + +<p>You'll also need to extend the {@link +android.support.v4.app.NotificationCompat.Builder} with the +<code>CarExtender</code>. This is where you actually create the +<code>UnreadConversation</code> object using the builder you just +created, and attach it to the <code>CarExtender</code>:</p> + +<pre> +notificationBuilder.extend(new CarExtender() + .setUnreadConversation(unreadConvBuilder.build()); +</pre> + +<p>Once you've done all this, you use your app's {@link +android.support.v4.app.NotificationManagerCompat} to send the notification:</p> + +<pre> +mNotificationManager = NotificationManagerCompat.from(context); +mNotificationManager.notify(<em>notificationId</em>, notificationBuilder.build()); +</pre> + +<p>In this example, <em>msgNotificationManager</em> is a +{@link android.support.v4.app.NotificationManagerCompat} you created for your app.</p> + + +<h2 id="handle_actions">Handle User Actions</h2> + +<p> + When your create and dispatch a notification for messaging, you specify intents to be triggered + when the Auto user hears the message and when the user dictates a reply. Your app indicates to + the Android framework that it handles these intends by registering them through it's manifest, as + discussed in <a href="#manifest-intent">Define read and reply intent filters</a>. +</p> + +<p> + In addition to registering these intent filters, your app must provide code to handle these + actions. Your app can do this by providing a service or {@link android.content.BroadcastReceiver} + objects that handle these intents.</p> + +<p> + For more information about intents, see <a href= + "{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>. +</p> + + +<h3 id="handling_msg_heard">Handling a message heard action</h3> + +<p> + When a user listens to a messaging conversation through the Auto user interface, the dashboard + device sends a read intent based on how your app defined the messaging notification. Your app + catches that intent and invokes the broadcast receiver class associated with it, or the service + method set up to handle that action. +</p> + +<p> + The following code example shows how to define a {@link android.content.BroadcastReceiver} class + to handle a received message heard intent: +</p> + +<pre> +public class MessageHeardReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + + // If you set up the intent as described in + // "Create conversation read and reply intents", + // you can get the conversation ID by calling: + int conversationId = intent.getIntExtra("conversation_id", -1); + + // Remove the notification to indicate it has been read + // and update the list of unread conversations in your app. + } +} +</pre> + +<p> + Once a notification is read, your app can remove it by calling + {@link android.support.v4.app.NotificationManagerCompat#cancel} with the notification ID. + Within your app, you should mark the messages provided in the notification as read. +</p> + + +<p class="note"> + <strong>Note:</strong> An alternative to this implementation is to use a service in a + {@link android.app.PendingIntent}. +</p> + + +<h3 id="handling_reply">Handling a reply action</h3> + +<p> + When a user replies to a messaging conversation through the Auto user interface, the dashboard + system sends a reply intent based on how your app defined the messaging notification. Your app + catches that intent and invokes the broadcast receiver class associated with it, or the service + method set up to handle that action. +</p> + +<p> + The following code example shows how to define a {@link android.content.BroadcastReceiver} class + to handle a received message reply intent: +</p> + +<pre> + public class MessageReplyReceiver extends BroadcastReceiver { + + + @Override + public void onReceive(Context context, Intent intent) { + // If you set up the intent as described in + // "Create conversation read and reply intents", + // you can get the conversation ID by calling: + int conversationId = intent.getIntExtra("conversation_id", -1). + + } + + /** + * Get the message text from the intent. + * Note that you should call + * RemoteInput.getResultsFromIntent() to process + * the RemoteInput. + */ + private CharSequence getMessageText(Intent intent) { + Bundle remoteInput = + RemoteInput.getResultsFromIntent(intent); + if (remoteInput != null) { + return remoteInput.getCharSequence("extra_voice_reply"); + } + return null; + } + +}</pre> |