From a7f226b860455b26cc64f6db08f8c279be71117f Mon Sep 17 00:00:00 2001 From: Andrew Solovay Date: Wed, 12 Nov 2014 22:27:01 -0800 Subject: docs: (Preview) Building an Android Messaging App guide. See the first comment for doc staging location. Change-Id: Ibfa0f43abefbdd03c5468186b2ec0c76ed6c9ade --- docs/html/training/auto/messaging/index.jd | 533 +++++++++++++++++++++++++++++ docs/html/training/training_toc.cs | 5 + 2 files changed, 538 insertions(+) create mode 100644 docs/html/training/auto/messaging/index.jd 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 + +
+
+

Dependencies and Prerequisites

+
    +
  • Android 5.0 (API level 21) or higher
  • +
+ +

This class teaches you to:

+ + + +

Related Samples

+ + + +

See Also

+ + +
+
+ + +
+

Video

+

DevBytes: Android Auto Messaging

+
+
+ +

+ 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. +

+ +

+ 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. +

+ +

+ 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. +

+ + +

Provide Messaging Services

+ +

+ 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. +

+ +

To enable your app to provide messaging services for Auto devices:

+ + + + +

Configure Your Manifest

+ +

+ You configure your app manifest + 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. +

+ + +

Declare Auto messaging support

+ +

+ 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: +

+ +
+<application>
+    ...
+    <meta-data android:name="com.google.android.gms.car.application"
+        android:resource="@xml/automotive_app_desc" />
+    ...
+<application>
+
+ +

+ 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: +

+ +
+<automotiveApp>
+    <uses name="notification"/>
+</automotiveApp>
+
+ +

+ For more information about declaring capabilities for Auto devices, see Getting Started with Auto. +

+ + +

Define read and reply intent filters

+ +

+ 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. +

+ +

+ 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. +

+ +
+<application>
+    ...
+    <receiver android:name=".MyMessageReadReceiver">
+        <intent-filter>
+          <action android:name="com.myapp.messagingservice.ACTION_MESSAGE_HEARD"/>
+        </intent-filter>
+    </receiver>
+
+    <receiver android:name=".MyMessageReplyReceiver">
+        <intent-filter>
+          <action android:name="com.myapp.messagingservice.ACTION_MESSAGE_REPLY"/>
+        </intent-filter>
+    </receiver>
+    ...
+</application>
+
+ +

+ The definition of the {@code android.content.BroadcastReceiver} classes shown in this example + is discussed in Handle User Actions. +

+ + +

Import Support Library for Messaging

+ +

+ Building notifications for use with Auto devices requires classes from the + v4 support library. Use the + Android SDK Manager to update the + Extras > Android Support Repository to version 9 or higher and the + Extras > Android Support Library to version 21.1.0 or higher. +

+ +

+ After you have updated the support libraries, import them into your Android Studio development + project by adding this dependency to your + build.gradle file: +

+ +
+dependencies {
+    ...
+    compile 'com.android.support:support-v4:21.1.+'
+}
+
+ +

+ For information about importing the support library into development projects for other + development environments, see Support + Library Setup. +

+ + + +

Notify Users of Messages

+ +

+ A messaging app provides messages to a connected Auto dashboard using the notifications 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. +

+ +

+ The messaging user interface for Auto presents users with two levels of information about + messages. The first level of notification tells users what conversations 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. +

+ +

+ 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. +

+ +

+ This section describes how to notify Auto users that conversations are available and + provide the content of messages in those conversations. +

+ + +

Build message conversations

+ +

+ 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. +

+ +

+ Use the {@code UnreadConversation.Builder} class to create an unread conversation object, + as shown in the following example code: +

+ +
+// 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);
+
+ +

+ 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 Creating conversation read and + reply intents section. +

+ +

+ 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. +

+ + +

Associate messages with conversations

+ +

+ 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. +

+ +
+// 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);
+}
+
+ +

+ 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. +

+ + +

Create conversation read and reply intents

+ +

+ 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. +

+ +

+ 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: +

+ +
+Intent msgHeardIntent = new Intent()
+    .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
+    .setAction(com.myapp.messagingservice.ACTION_MESSAGE_HEARD)
+    .putExtra("conversation_id", conversationId);
+
+PendingIntent msgHeardPendingIntent =
+    PendingIntent.getBroadcast(getApplicationContext(),
+        conversationId,
+        msgHeardIntent,
+        PendingIntent.FLAG_UPDATE_CURRENT);
+
+ +

+ 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 Define read and reply intent + filters. +

+ +

+ 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: +

+ +
+Intent msgReplyIntent = new Intent()
+    .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
+    .setAction(com.myapp.messagingservice.ACTION_MESSAGE_REPLY)
+    .putExtra("conversation_id", conversationId);
+
+PendingIntent msgReplyPendingIntent = PendingIntent.getBroadcast(
+    getApplicationContext(),
+    conversationId,
+    msgReplyIntent,
+    PendingIntent.FLAG_UPDATE_CURRENT);
+
+ +

+ 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 Define read and reply intent filters. +

+ + +

Sending Messages

+ +

+ When a message arrives for a conversation, you take the following steps to dispatch it as a + notification to Auto. +

+ +

First, add the message to the UnreadConversation.Builder for +this conversation, and update its timestamp:

+ +
+unreadConvBuilder.addMessage(messageString)
+    .setLatestTimestamp(currentTimestamp);
+
+ +

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.

+ +
+NotificationCompat.Builder notificationBuilder =
+    new NotificationCompat.Builder(getApplicationContext())
+        .setSmallIcon(R.drawable.notification_icon)
+        .setLargeIcon(icon_bitmap)
+        .setContentText(messageString)
+        .setWhen(currentTimestamp)
+        .setContentTitle(participant_name)
+        .setContentIntent(msgHeardPendingIntent);
+
+
+ +

You'll also need to extend the {@link +android.support.v4.app.NotificationCompat.Builder} with the +CarExtender. This is where you actually create the +UnreadConversation object using the builder you just +created, and attach it to the CarExtender:

+ +
+notificationBuilder.extend(new CarExtender()
+    .setUnreadConversation(unreadConvBuilder.build());
+
+ +

Once you've done all this, you use your app's {@link +android.support.v4.app.NotificationManagerCompat} to send the notification:

+ +
+mNotificationManager = NotificationManagerCompat.from(context);
+mNotificationManager.notify(notificationId, notificationBuilder.build());
+
+ +

In this example, msgNotificationManager is a +{@link android.support.v4.app.NotificationManagerCompat} you created for your app.

+ + +

Handle User Actions

+ +

+ 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 Define read and reply intent filters. +

+ +

+ 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.

+ +

+ For more information about intents, see Intents and Intent Filters. +

+ + +

Handling a message heard action

+ +

+ 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. +

+ +

+ The following code example shows how to define a {@link android.content.BroadcastReceiver} class + to handle a received message heard intent: +

+ +
+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.
+    }
+}
+
+ +

+ 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. +

+ + +

+ Note: An alternative to this implementation is to use a service in a + {@link android.app.PendingIntent}. +

+ + +

Handling a reply action

+ +

+ 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. +

+ +

+ The following code example shows how to define a {@link android.content.BroadcastReceiver} class + to handle a received message reply intent: +

+ +
+  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;
+    }
+
+}
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs index 791aef6..61a5e3c 100644 --- a/docs/html/training/training_toc.cs +++ b/docs/html/training/training_toc.cs @@ -959,6 +959,11 @@ include the action bar on devices running Android 2.1 or higher." description="How to extend audio apps to play content on Auto devices."> Playing Audio for Auto +
  • + + Messaging for Auto +
  • -- cgit v1.1