Home | History | Annotate | Download | only in messaging
      1 page.title=Providing Messaging for Auto
      2 page.tags="auto", "car", "automotive", "messaging"
      3 page.article=true
      4 
      5 page.metaDescription=Learn how to extend your messaging app for use in Android Auto devices.
      6 page.image=auto/images/assets/icons/messaging_app_notifications.png
      7 
      8 @jd:body
      9 
     10 <div id="tb-wrapper">
     11 <div id="tb">
     12   <h2>Dependencies and Prerequisites</h2>
     13   <ul>
     14     <li>Android 5.0 (API level 21) or higher</li>
     15   </ul>
     16 
     17     <h2>This class teaches you to:</h2>
     18 
     19     <ul>
     20       <li><a href="#overview">Provide Messaging Services</a></li>
     21       <li><a href="#manifest">Configure Your Manifest</a></li>
     22       <li><a href="#support-lib">Import Support Library for Messaging</a></li>
     23       <li><a href="#messaging">Notify Users of Messages</a></li>
     24       <li><a href="#handle_actions">Handle User Actions</a></li>
     25     </ul>
     26 
     27     <h2>Related Samples</h2>
     28 
     29     <ul>
     30       <li><a href="{@docRoot}samples/MessagingService/index.html">
     31         MessagingService</a></li>
     32     </ul>
     33 
     34     <h2>See Also</h2>
     35 
     36     <ul>
     37       <li><a href="{@docRoot}shareables/auto/AndroidAuto-messaging-apps.pdf">
     38         User Experience Guidelines: Messaging Apps</a></li>
     39       <li><a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">
     40         Notifications</a></li>
     41     </ul>
     42 </div>
     43 </div>
     44 
     45 <a class="notice-developers-video wide"
     46     href="https://www.youtube.com/watch?v=gSVLuaOTIPk">
     47 <div>
     48     <h3>Video</h3>
     49     <p>DevBytes: Android Auto Messaging</p>
     50 </div>
     51 </a>
     52 
     53 <p>
     54   Staying connected through messages is important to many drivers. Chat apps can let users
     55   know if a child need to be picked up, or if a dinner location has been changed.
     56   The Android framework enables messaging apps to extend their
     57   services into car dashboards using a standard user interface that lets drivers keep their eyes
     58   on the road.
     59 </p>
     60 
     61 <p>
     62   Apps that support messaging can be extended to pass messaging notifications to Auto
     63   dashboard systems, alerting them to new messages and allowing them to respond. You can configure
     64   your messaging app to provide these services when an Android mobile device with your app
     65   installed is connected to an Auto dashboard. Once connected, your app can provide text
     66   information to users and allow them to respond. The Auto dashboard system handles displaying the
     67   notification and the interface for replies.
     68 </p>
     69 
     70 <p>
     71   This lesson assumes that you have built an app that displays messages to the user and receive the
     72   user's replies, such as a chat app. It shows you how to extend your app to hand those messages
     73   off to an Auto device for display and replies.
     74 </p>
     75 
     76 
     77 <h2 id="overview">Provide Messaging Services</h2>
     78 
     79 <p>
     80   Messaging apps do not run directly on the Android dashboard hardware. They are installed on
     81   a separate Android mobile device. When the mobile device is plugged into a dashboard,
     82   the installed messaging apps can offer services for viewing and responding to messages
     83   through the Auto user interface.
     84 </p>
     85 
     86 <p>To enable your app to provide messaging services for Auto devices:</p>
     87 
     88 <ul>
     89   <li>Configure your app manifest to indicate that your app provides messaging services which are
     90   compatible with Android Auto dashboard devices.
     91   </li>
     92   <li>Build and send a specific type of <a href=
     93   "{@docRoot}guide/topics/ui/notifiers/notifications.html">notification</a> for display on Auto
     94   devices.
     95   </li>
     96   <li>Configure your app to receive {@link android.content.Intent} objects that indicate a user
     97     has read or replied to a message.
     98 </ul>
     99 
    100 <h3 id="concepts">Concepts and objects</h3>
    101 
    102 <p>Before you start designing your app, it's helpful to understand how Auto
    103 handles messaging.</p>
    104 
    105 <p>Each individual chunk of communication is a <em>message</em>. A message is a
    106 short length of text, suitable for the Auto device to read aloud. In a chat app,
    107 this might be a single message from one person to another: <code>"Fitzy -- Jane
    108 can't come to the ball, her youngest has the croup. :-( --Liz"</code>.</p>
    109 
    110 <p>A <em>conversation</em> is a group of messages that are all grouped together
    111 in some way. Auto uses the conversation information to group the messages
    112 together when presenting them to the user. In a chat app, a conversation might
    113 be all the messages between the user and another person (for example, all
    114 the messages back and forth between Darcy and Elizabeth). Every message
    115 belongs to a conversation, even if it's the only message in that conversation.
    116 Each conversation has a <em>conversation name</em>.
    117 The conversation name is used by Android Auto to
    118 present the messages; it's up to your app to choose an appropriate conversation
    119 name. In a chat app, the conversation name is usually the person your user is
    120 talking to.</p>
    121 
    122 <p>The v4 support library defines an {@link
    123 android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation
    124 UnreadConversation} object. This object holds all messages in a conversation
    125 which have not yet been heard by the user. To give those messages to the user,
    126 you attach that {@link
    127 android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation
    128 UnreadConversation} to a notification. However, you do not attach messages to
    129 the {@link
    130 android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation
    131 UnreadConversation} directly. Instead, you must first set up an {@link
    132 android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder
    133 UnreadConversation.Builder} object for the conversation. The messages are added to the builder,
    134 then when you are ready to send the messages, you use the builder to create the
    135 actual {@link
    136 android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation
    137 UnreadConversation} and attach the {@link
    138 android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation
    139 UnreadConversation} to the notification.</p>
    140 
    141 <p class="note"><strong>Note:</strong> When Auto presents messages to the
    142 user, it uses the notification <em>tag</em> and <em>ID</em> to determine which conversation the
    143 messages belong to. It is important to use the same tag and ID for all messages in
    144 a conversation, and to not use that tag for other conversations.</p>
    145 
    146 <h3 id="workflow">Workflow</h3>
    147 
    148 <p>This section describes how the mobile device interacts with Auto to present
    149 messages to the user.</p>
    150 
    151 <ol>
    152 
    153 <li>The app receives a message that it wants to pass on to the user. The app
    154 attaches the message to an {@link
    155 android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder
    156 UnreadConversation.Builder} object, then uses the {@link
    157 android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder
    158 UnreadConversation.Builder} to generate an {@link
    159 android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation
    160 UnreadConversation}. The app attaches that {@link
    161 android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation
    162 UnreadConversation} to a notification. That notification
    163 is associated with a {@link
    164 android.support.v4.app.NotificationCompat.CarExtender CarExtender} object, which
    165 indicates that the notification can be handled by Android Auto.</li>
    166 
    167 <li>The app posts the notification. The Android notification framework passes the
    168 message to Auto. Auto uses the notification tag and ID to determine which conversation
    169 the message belongs to, and presents the message to the user in an appropriate
    170 way.</li>
    171 
    172 <li>When the user listens to the message, Auto triggers the app's message heard
    173 pending intent. The app should discard the {@link
    174 android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation
    175 UnreadConversation} object and its builder at this time, since the messages
    176 contained in those objects have been heard by the user.</li>
    177 
    178 <li>If the user sends a reply, Auto triggers the app's "message reply" intent and
    179 attaches a transcript of the user's response.  The app can take appropriate
    180 action, based on the app's logic. For example, a chat app might interpret the
    181 reply as a message to go to the other conversation participants.</li>
    182 
    183 </ol>
    184 
    185 <h2 id="manifest">Configure Your Manifest</h2>
    186 
    187 <p>
    188   You configure your app <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">manifest</a>
    189   to indicate that it supports messaging services for Auto devices and handle message actions. This
    190   section describes what changes to make to your manifest to support messaging for Auto devices.
    191 </p>
    192 
    193 <h3 id="manifest-messaging">Declare Auto messaging support</h3>
    194 
    195 <p>
    196   When a user connects a Android mobile device to a dashboard running Android, the dashboard
    197   device looks for apps that declare support for vehicle services, such as messaging. You indicate
    198   that your app supports cars capabilities using the following manifest entry:
    199 </p>
    200 
    201 <pre>
    202 &lt;application&gt;
    203     ...
    204     &lt;meta-data android:name="com.google.android.gms.car.application"
    205         android:resource="@xml/automotive_app_desc" /&gt;
    206     ...
    207 &lt;application&gt;
    208 </pre>
    209 
    210 <p>
    211   This manifest entry refers to a secondary xml file, where you declare what Auto capabilities your
    212   app supports. For an app that supports messaging for Auto devices, add an xml file to the {@code
    213   res/xml/} your app's development project directory as {@code automotive_app_desc.xml}, with the
    214   following content:
    215 </p>
    216 
    217 <pre>
    218 &lt;automotiveApp&gt;
    219     &lt;uses name="notification"/&gt;
    220 &lt;/automotiveApp&gt;
    221 </pre>
    222 
    223 <p>
    224   For more information about declaring capabilities for Auto devices, see <a href=
    225   "{@docRoot}training/auto/start/index.html#auto-metadata">Getting Started with Auto</a>.
    226 </p>
    227 
    228 
    229 <h3 id="manifest-intent">Define read and reply intent filters</h3>
    230 
    231 <p>
    232   Auto devices use {@link android.content.Intent} objects that indicate a user has read or replied
    233   to a message provided by your app. Your app defines intent types for reading and replying to
    234   messages and adds this information to messaging notifications for Auto devices, so that the
    235   dashboard system can notify your app when a user takes one of these actions.
    236 </p>
    237 
    238 <p>
    239   You define the read action and reply action intents types for your app and the {@link
    240   android.content.BroadcastReceiver} classes that handle them in the manifest. The following code
    241   example demonstrates how to declare these intents and their associated receivers.
    242 </p>
    243 
    244 <pre>
    245 &lt;application&gt;
    246     ...
    247     &lt;receiver android:name=".MyMessageHeardReceiver"&gt;
    248         &lt;intent-filter&gt;
    249           &lt;action android:name="com.myapp.messagingservice.MY_ACTION_MESSAGE_HEARD"/&gt;
    250         &lt;/intent-filter&gt;
    251     &lt;/receiver&gt;
    252 
    253     &lt;receiver android:name=".MyMessageReplyReceiver"&gt;
    254         &lt;intent-filter&gt;
    255           &lt;action android:name="com.myapp.messagingservice.MY_ACTION_MESSAGE_REPLY"/&gt;
    256         &lt;/intent-filter&gt;
    257     &lt;/receiver&gt;
    258     ...
    259 &lt;/application&gt;
    260 </pre>
    261 
    262 <p>   In this example, <code>"MyMessageReadReceiver"</code> and
    263 <code>"MyMessageReplyReceiver"</code> are the names of the {@link
    264 android.content.BroadcastReceiver} subclasses you define to handle the
    265 intents. You can choose whatever you like   as the action names, but it's best
    266 to prepend your package name to ensure that   the action names are unique. For
    267 more information about handling actions, see <a href="#handle_actions">Handle
    268 User Actions</a>. </p>
    269 
    270 <h2 id="support-lib">Import Support Library for Messaging</h3>
    271 
    272 <p>
    273   Building notifications for use with Auto devices requires classes from the
    274   <a href="{@docRoot}tools/support-library/features.html#v4">v4 support library</a>. Use the
    275   <a href="{@docRoot}tools/help/sdk-manager.html">Android SDK Manager</a> to update the
    276   <em>Extras > Android Support Repository</em> to version 9 or higher and the
    277   <em>Extras > Android Support Library</em> to version 21.0.2 or higher.
    278 </p>
    279 
    280 <p>
    281   After you have updated the support libraries, import them into your Android Studio development
    282   project by adding this dependency to your
    283   <a href="{@docRoot}studio/build/index.html#configBuild">build.gradle</a> file:
    284 </p>
    285 
    286 <pre>
    287 dependencies {
    288     ...
    289     compile 'com.android.support:support-v4:21.0.2'
    290 }
    291 </pre>
    292 
    293 <p>
    294   For information about importing the support library into development projects for other
    295   development environments, see <a href="{@docRoot}tools/support-library/setup.html">Support
    296   Library Setup</a>.
    297 </p>
    298 
    299 
    300 
    301 <h2 id="messaging">Notify Users of Messages</h2>
    302 
    303 <p>
    304   A messaging app provides messages to a connected Auto dashboard using the <a href=
    305   "{@docRoot}guide/topics/ui/notifiers/notifications.html">notifications</a> framework. When your
    306   messaging app has a message for a user, you build a specially configured notification that is
    307   received by the dashboard system and presented to the user. The Auto device manages the
    308   presentation on the dashboard screen and may play the message via text-to-speech. The dashboard
    309   system also handles voice interaction if the user replies to a message using verbal input.
    310 </p>
    311 
    312 <p>
    313   The messaging user interface for Auto presents users with two levels of information about
    314   messages. The first level of notification tells users what <em>conversations</em> are
    315   available, and who they are with, but not the content of the messages. Typically, a
    316   conversation is one or more messages from another user to the Auto user.
    317 </p>
    318 
    319 <p>
    320   The second level of the notification is the actual content of messages in the conversation. If a
    321   user indicates they want to hear the messages in a conversation, the Auto user interface plays
    322   the messages using text-to-speech.
    323 </p>
    324 
    325 <p>
    326   This section describes how to notify Auto users that conversations are available and
    327   provide the content of messages in those conversations.
    328 </p>
    329 
    330 <h4 id="conversation-intents">Create conversation read and reply intents</h4>
    331 
    332 <p>
    333   Unread conversation objects contain intents for reading and replying to a conversation. You
    334   create a {@link android.app.PendingIntent} object for each of these actions, so the Auto device
    335   can notify your app of action taken by the Auto user on a particular conversation.
    336 </p>
    337 
    338 <p>
    339   The following example code demonstrates how to define a {@link android.app.PendingIntent} to let
    340   your app know if a conversation was read to the Auto user:
    341 </p>
    342 
    343 <pre>
    344 Intent msgHeardIntent = new Intent()
    345     .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
    346     .setAction("com.myapp.messagingservice.MY_ACTION_MESSAGE_HEARD")
    347     .putExtra("conversation_id", thisConversationId);
    348 
    349 PendingIntent msgHeardPendingIntent =
    350     PendingIntent.getBroadcast(getApplicationContext(),
    351         thisConversationId,
    352         msgHeardIntent,
    353         PendingIntent.FLAG_UPDATE_CURRENT);
    354 </pre>
    355 
    356 <p>In this example, {@code thisConversationId} is an integer that identifies the
    357 current conversation.   The value of {@link android.content.Intent#setAction
    358 Intent.setAction()} is the intent filter identifier for heard messages which you
    359 defined in your app manifest, as shown in <a href="#manifest-intent">Define read
    360 and reply intent filters</a>. </p>
    361 
    362 <p>
    363   If your app supports replying to conversations, you also create a {@link
    364   android.app.PendingIntent} for each conversation to notify your app that the user has replied.
    365   The following code example shows you how to build this intent for use with a particular
    366   conversation:
    367 </p>
    368 
    369 <pre>
    370 Intent msgReplyIntent = new Intent()
    371     .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
    372     .setAction("com.myapp.messagingservice.MY_ACTION_MESSAGE_REPLY")
    373     .putExtra("conversation_id", thisConversationId);
    374 
    375 PendingIntent msgReplyPendingIntent = PendingIntent.getBroadcast(
    376     getApplicationContext(),
    377     thisConversationId,
    378     msgReplyIntent,
    379     PendingIntent.FLAG_UPDATE_CURRENT);
    380 </pre>
    381 
    382 <p>   Once again, {@code thisConversationId} is an integer that uniquely identifies
    383 this conversation, and    the value you pass to {@link
    384 android.content.Intent#setAction Intent.setAction()} is the intent filter
    385 identifier you defined for replies in your   app manifest. </p>
    386 
    387 <h3 id="build_conversation">Set up the conversation builder</h4>
    388 
    389 <p>
    390   Messaging notifications for Auto organize messages into conversations using the {@link
    391   android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation} class,
    392   that represents an unread or new
    393   portion of a conversation from a particular sender. It contains a list of messages from the
    394   sender.
    395 </p>
    396 
    397 <p>
    398   You generally do not configure the {@link
    399   android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation UnreadConversation}
    400   directly. Instead, you configure an
    401   {@link android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder
    402   UnreadConversation.Builder} with the information about the conversation,
    403   as shown in the following example code.
    404 </p>
    405 
    406 <pre>
    407 // Build a RemoteInput for receiving voice input in a Car Notification
    408 RemoteInput remoteInput = new RemoteInput.Builder(MY_VOICE_REPLY_KEY)
    409         .setLabel(getApplicationContext().getString(R.string.notification_reply))
    410         .build();
    411 
    412 // Create an unread conversation object to organize a group of messages
    413 // from a particular sender.
    414 UnreadConversation.Builder unreadConvBuilder =
    415     new UnreadConversation.Builder(conversationName)
    416         .setReadPendingIntent(msgHeardPendingIntent)
    417         .setReplyAction(msgReplyPendingIntent, remoteInput);
    418 </pre>
    419 
    420 <p class="note">
    421   <strong>Note:</strong> You won't actually create the {@link
    422   android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation
    423   UnreadConversation} until you are almost ready to send the message.
    424 </p>
    425 
    426 <p>
    427   This conversation object includes a {@link android.app.PendingIntent}, which allows the Auto
    428   device to signal your app that the conversation has been read by the Auto user. The construction
    429   of this intent is discussed in the <a href="#conversation-intents">Creating conversation read and
    430   reply intents</a> section.
    431 </p>
    432 
    433 <p>
    434   If your app supports replying to a conversation, you must call the
    435   {@link android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder#setReplyAction
    436   UnreadConversation.Builder.setReplyAction()}
    437   method and provide a pending intent to pass that user action back to your app. The
    438   {@link android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation
    439   UnreadConversation}
    440   object you create must also include a {@link
    441   android.support.v4.app.RemoteInput} object. When the Auto user
    442   receiving this conversation speaks a reply, the remote input objects lets your app get a text
    443   version of the voice reply.
    444 </p>
    445 
    446 <h3 id="sending_messages">Sending Messages</h4>
    447 
    448 <p>
    449   When a message arrives for a conversation, you take the following steps to dispatch it as a
    450   notification to Auto.
    451 </p>
    452 
    453 <p>First, add the message to the {@link
    454 android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder
    455 UnreadConversation.Builder} for this conversation, and update its timestamp:</p>
    456 
    457 <pre>
    458 unreadConvBuilder.addMessage(messageString)
    459     .setLatestTimestamp(currentTimestamp);
    460 </pre>
    461 
    462 <p class="note"><strong>Note:</strong> If you are sending several messages at
    463 once, add them to the {@link
    464 android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder
    465 UnreadConversation.Builder} in order, from oldest to newest.</p>
    466 
    467 <p>Then create the {@link android.support.v4.app.NotificationCompat.Builder
    468 NotificationCompat.Builder}
    469 object that builds the actual notification. You need to use the
    470 pending intents you created in the previous step.</p>
    471 
    472 <pre>
    473 NotificationCompat.Builder notificationBuilder =
    474     new NotificationCompat.Builder(getApplicationContext())
    475         .setSmallIcon(smallIconResourceID)
    476         .setLargeIcon(largeIconBitmap);
    477 </pre>
    478 
    479 <dl>
    480   <dt><code>smallIconResourceID</code></dt>
    481   <dd>The resource ID of a small icon to use for the conversation. This is
    482     typically a generic icon for the messaging app.</dd>
    483 
    484   <dt><code>largeIconBitmap</code></dt>
    485   <dd>A {@link android.graphics.Bitmap} of a large version of the icon. This
    486     is typically a conversation-specific graphic. For example, if this is a
    487     chat app, the large icon would be a picture of the person the user is
    488     chatting with.</dd>
    489 
    490   <dt><code>messageString</code></dt>
    491   <dd>The text of the message you want to send. (If you are sending several
    492     messages at once, concatenate them into a single string, with the oldest
    493     message first.)</dd>
    494 
    495   <dt><code>currentTimestamp</code></dt>
    496   <dd>The message timestamp. (If you are sending several messages at once,
    497     use the timestamp of the most recent message.)</dd>
    498 
    499   <dt><code>conversationName</code></dt>
    500 
    501   <dd>The name you chose for this conversation (for example, the name of the
    502     person the user is chatting with). This should be the same conversation
    503     name you used when you created the {@link
    504 android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder
    505     UnreadConversation.Builder}.</dd>
    506 
    507   <dt><code>msgHeardPendingIntent</code></dt>
    508   <dd>The pending intent object you created in
    509     <a href="#conversation-intents">Create conversation read and reply
    510       intents</a>.</dd>
    511 </dl>
    512 
    513 
    514 <p>You'll also need to extend the  {@link
    515 android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder} with the {@link
    516 android.support.v4.app.NotificationCompat.CarExtender CarExtender}. This is where you
    517 actually create the
    518 {@link android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation
    519 UnreadConversation} object using the builder you
    520 just created, and attach it to the {@link
    521 android.support.v4.app.NotificationCompat.CarExtender CarExtender}:</p>
    522 
    523 <pre>
    524 notificationBuilder.extend(new CarExtender()
    525     .setUnreadConversation(unreadConvBuilder.build());
    526 </pre>
    527 
    528 <p class="note"><strong>Note:</strong> If you wish, you can set an override icon
    529 or color for the {@link android.support.v4.app.NotificationCompat.CarExtender
    530 CarExtender} by calling {@link
    531 android.support.v4.app.NotificationCompat.CarExtender#setLargeIcon
    532 setLargeIcon()} or {@link
    533 android.support.v4.app.NotificationCompat.CarExtender#setColor setColor()}. The
    534 override icon or color is used when the notification is handled by a car, and
    535 has no effect if the notification is handled on the Android device. This is
    536 useful if the notification's default icon or color are not suitable for the
    537 car's display.</p>
    538 
    539 <p>Once you've done all this, you use your app's {@link
    540 android.support.v4.app.NotificationManagerCompat} to send the notification:</p>
    541 
    542 <pre>
    543 NotificationManagerCompat msgNotificationManager =
    544     NotificationManagerCompat.from(context);
    545 msgNotificationManager.notify(notificationTag,
    546     notificationId, notificationBuilder.build());
    547 </pre>
    548 
    549 <h2 id="handle_actions">Handle User Actions</h2>
    550 
    551 <p>
    552   When your create and dispatch a notification for messaging, you specify intents to be triggered
    553   when the Auto user hears the message and when the user dictates a reply. Your app indicates to
    554   the Android framework that it handles these intends by registering them through its manifest, as
    555   discussed in <a href="#manifest-intent">Define read and reply intent filters</a>.
    556 </p>
    557 
    558 <p>
    559   In addition to registering these intent filters, your app must provide code to handle these
    560   actions. Your app can do this by providing a service or {@link android.content.BroadcastReceiver}
    561   objects that handle these intents.</p>
    562 
    563 <p>
    564   For more information about intents, see <a href=
    565   "{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>.
    566 </p>
    567 
    568 
    569 <h3 id="handling_msg_heard">Handling a message heard action</h3>
    570 
    571 <p>
    572   When a user listens to a messaging conversation through the Auto user interface, the dashboard
    573   device sends a read intent based on how your app defined the messaging notification. Your app
    574   catches that intent and invokes the broadcast receiver class associated with it, or the service
    575   method set up to handle that action.
    576 </p>
    577 
    578 <p>
    579   The following code example shows how to define a {@link android.content.BroadcastReceiver} class
    580   to handle a received message heard intent:
    581 </p>
    582 
    583 <pre>
    584 public class MyMessageHeardReceiver extends BroadcastReceiver {
    585 
    586     &#64;Override
    587     public void onReceive(Context context, Intent intent) {
    588 
    589         // If you set up the intent as described in
    590         // "Create conversation read and reply intents",
    591         // you can get the conversation ID by calling:
    592         int thisConversationId = intent.getIntExtra("conversation_id", -1);
    593 
    594         // Remove the notification to indicate it has been read
    595         // and update the list of unread conversations in your app.
    596     }
    597 }
    598 </pre>
    599 
    600 <p>
    601   Once a notification is read, your app can remove it by calling
    602   {@link android.support.v4.app.NotificationManagerCompat#cancel
    603   NotificationManagerCompat.cancel()} with the notification ID.
    604   Within your app, you should mark the messages provided in the notification as read.
    605 </p>
    606 
    607 
    608 <p class="note">
    609   <strong>Note:</strong> An alternative to this implementation is to use a service in a
    610   {@link android.app.PendingIntent}.
    611 </p>
    612 
    613 
    614 <h3 id="handling_reply">Handling a reply action</h3>
    615 
    616 <p>
    617   When a user replies to a messaging conversation through the Auto user interface, the dashboard
    618   system sends a reply intent based on how your app defined the messaging notification. Your app
    619   catches that intent and invokes the broadcast receiver class associated with it, or the service
    620   method set up to handle that action.
    621 </p>
    622 
    623 <p>
    624   The following code example shows how to define a {@link android.content.BroadcastReceiver} class
    625   to handle a received message reply intent:
    626 </p>
    627 
    628 <pre>
    629   public class MyMessageReplyReceiver extends BroadcastReceiver {
    630 
    631 
    632     &#64;Override
    633     public void onReceive(Context context, Intent intent) {
    634         // If you set up the intent as described in
    635         // "Create conversation read and reply intents",
    636         // you can get the conversation ID by calling:
    637         int thisConversationId = intent.getIntExtra("conversation_id", -1).
    638 
    639     }
    640 
    641     /**
    642      * Get the message text from the intent.
    643      * Note that you should call
    644      * RemoteInput.getResultsFromIntent() to process
    645      * the RemoteInput.
    646      */
    647     private CharSequence getMessageText(Intent intent) {
    648         Bundle remoteInput =
    649             RemoteInput.getResultsFromIntent(intent);
    650         if (remoteInput != null) {
    651             return remoteInput.getCharSequence(MY_VOICE_REPLY_KEY);
    652         }
    653         return null;
    654     }
    655 
    656 }</pre>
    657