blob: c8f6621f9753a5b187c8bff566636b0ccf8b69a1 [file] [log] [blame]
Scott Main50d7dc92014-03-18 05:13:12 -07001<!DOCTYPE html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92<html>
93<head>
94
95
96<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
97<meta name="viewport" content="width=device-width" />
98
99<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
100<title>Receiving Voice Input from a Notification | Android Developers</title>
101
102<!-- STYLESHEETS -->
103<link rel="stylesheet"
104href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
105<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
106
107
108
109<!-- JAVASCRIPT -->
110<script src="//www.google.com/jsapi" type="text/javascript"></script>
111<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
112<script type="text/javascript">
113 var toRoot = "/";
114 var metaTags = [];
115 var devsite = false;
116</script>
117<script src="/assets/js/docs.js" type="text/javascript"></script>
118
119<script type="text/javascript">
120 var _gaq = _gaq || [];
121 _gaq.push(['_setAccount', 'UA-5831155-1']);
122 _gaq.push(['_trackPageview']);
123
124 (function() {
125 var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
126 ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
127 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
128 })();
129</script>
130</head>
131
132<body class="gc-documentation
133 " itemscope itemtype="http://schema.org/Article">
134
135
136
137<a name="top"></a>
138
139 <!-- Header -->
140 <div id="header">
141 <div class="wrap" id="header-wrap">
142 <div class="col-3 logo-wear">
143 <a href="/wear/index.html">
144 <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
145 </a>
146 </div>
147
148
149 <div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
150 color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
151
152
153 <!-- New Search -->
154 <div class="menu-container">
155 <div class="moremenu">
156 <div id="more-btn"></div>
157 </div>
158 <div class="morehover" id="moremenu">
159 <div class="top"></div>
160 <div class="mid">
161 <div class="header">Links</div>
162 <ul>
163 <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
164 <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
165 <li><a href="/about/index.html">About Android</a></li>
166 </ul>
167 <div class="header">Android Sites</div>
168 <ul>
169 <li><a href="http://www.android.com">Android.com</a></li>
170 <li class="active"><a>Android Developers</a></li>
171 <li><a href="http://source.android.com">Android Open Source Project</a></li>
172 </ul>
173
174
175
176 <div class="header">Language</div>
177 <div id="language" class="locales">
178 <select name="language" onChange="changeLangPref(this.value, true)">
179 <option value="en">English</option>
180 <option value="es">Español</option>
181 <option value="ja">日本語</option>
182 <option value="ko">한국어</option>
183 <option value="ru">Русский</option>
184 <option value="zh-cn">中文 (中国)</option>
185 <option value="zh-tw">中文 (台灣)</option>
186 </select>
187 </div>
188 <script type="text/javascript">
189 <!--
190 loadLangPref();
191 //-->
192 </script>
193
194
195
196
197 <br class="clearfix" />
198 </div><!-- end mid -->
199 <div class="bottom"></div>
200 </div><!-- end morehover -->
201
202 <div class="search" id="search-container">
203 <div class="search-inner">
204 <div id="search-btn"></div>
205 <div class="left"></div>
206 <form onsubmit="return submit_search()">
207 <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
208onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
209onkeydown="return search_changed(event, true, '/')"
210onkeyup="return search_changed(event, false, '/')" />
211 </form>
212 <div class="right"></div>
213 <a class="close hide">close</a>
214 <div class="left"></div>
215 <div class="right"></div>
216 </div>
217 </div><!-- end search -->
218
219 <div class="search_filtered_wrapper reference">
220 <div class="suggest-card reference no-display">
221 <ul class="search_filtered">
222 </ul>
223 </div>
224 </div>
225
226 <div class="search_filtered_wrapper docs">
227 <div class="suggest-card dummy no-display">&nbsp;</div>
228 <div class="suggest-card develop no-display">
229 <ul class="search_filtered">
230 </ul>
231 <div class="child-card guides no-display">
232 </div>
233 <div class="child-card training no-display">
234 </div>
235 <div class="child-card samples no-display">
236 </div>
237 </div>
238 <div class="suggest-card design no-display">
239 <ul class="search_filtered">
240 </ul>
241 </div>
242 <div class="suggest-card distribute no-display">
243 <ul class="search_filtered">
244 </ul>
245 </div>
246 </div><!-- end search_filtered_wrapper -->
247
248 </div>
249 <!-- end menu_container -->
250
251
252 </div><!-- end header-wrap -->
253 </div>
254 <!-- /Header -->
255
256
257 <div id="searchResults" class="wrap" style="display:none;">
258 <h2 id="searchTitle">Results</h2>
259 <div id="leftSearchControl" class="search-control">Loading...</div>
260 </div>
261
262
263
264
265
266 <div class="wrap clearfix" id="body-content">
267 <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
268 <div id="devdoc-nav" class="scroll-pane">
269<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
270
271<ul id="nav">
272
273 <li class="nav-section">
274 <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
275 </a></div>
276 </li>
277
278 <li class="nav-section">
279 <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
280 </a></div>
281 </li>
282
283 <li class="nav-section">
284 <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
285 </a></div>
286 </li>
287
288 <li class="nav-section">
289 <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
290 </a></div>
291 </li>
292
293 <li class="nav-section">
294 <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
295 </a></div>
296 </li>
297
298 <li class="nav-section">
299 <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
300 </a></div>
301 </li>
302
303 <li class="nav-section">
304 <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
305 </a></div>
306 </li>
307
308 <li class="nav-section">
309 <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
310 <ul class="tree-list-children">
311<li class="nav-section">
312<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
313 <ul>
314<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
315 </ul>
316</li>
317
318<li class="nav-section">
319<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
320<ul>
321
322<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
323<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
324
325<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
326
327<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
328
329<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
330
331<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
332 </ul>
333 </li>
334</ul>
335</li>
336
337
338
339 <li class="nav-section">
340 <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
341 </li>
342
343
344</ul>
345
346
347
348 </div>
349 </div> <!-- end side-nav -->
350 <script>
351 $(document).ready(function() {
352 scrollIntoView("devdoc-nav");
353 });
354 </script>
355
356
357
358
359<div class="col-12" id="doc-col" >
360
361
362
363
364
365 <h1 itemprop="name" >Receiving Voice Input from a Notification</h1>
366
367
368
369
370
371
372 <div id="jd-content">
373
374
375 <div class="jd-descr" itemprop="articleBody">
Scott Maina32c4372014-03-19 11:51:05 -0700376 <img src="/wear/images/13_voicereply.png" height="200" width="169" style="float:right;margin:0 0 20px 40px" />
Scott Main50d7dc92014-03-18 05:13:12 -0700377
378<img src="/wear/images/03_actions.png" height="200" width="169" style="float:right;margin:0 0 20px 40px" />
379
380<p>If your notification includes an action to respond with text,
381 such as to reply to an email, it should normally launch an activity
Scott Maina32c4372014-03-19 11:51:05 -0700382 on the handheld device. However, when your notification appears on an Android wearable, you can
Scott Main50d7dc92014-03-18 05:13:12 -0700383 allow users to dictate a reply with voice input. You can also provide pre-defined text
Scott Maina32c4372014-03-19 11:51:05 -0700384 messages for the user to select.</p>
Scott Main50d7dc92014-03-18 05:13:12 -0700385
386<p>When the user replies with voice or selects one of the available
Scott Maina32c4372014-03-19 11:51:05 -0700387messages, the system sends the message to your app on the connected handheld device.
388The message is attached as an extra in the <code><a href="/reference/android/content/Intent.html">Intent</a></code> you specified
389to be used for the notification action.</p>
390
391<p class="note"><strong>Note:</strong> When developing with the Android emulator,
392you must type text replies into the voice input field, so be sure you have enabled
393<strong>Hardware keyboard present</strong> in the AVD settings.</p>
Scott Main50d7dc92014-03-18 05:13:12 -0700394
395
396<h2 id="RemoteInput">Define the Remote Input</h2>
397
398<p>To create an action that supports voice input, first create an instance of
399 <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">
400<code>RemoteInput</code></a> using the
401 <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html"><code>RemoteInput.Builder</code></a> APIs.
402 The
403 <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html"><code>RemoteInput.Builder</code></a> constructor takes a string that the system
Scott Maina32c4372014-03-19 11:51:05 -0700404 will use as a key for the <code><a href="/reference/android/content/Intent.html">Intent</a></code> extra that carries the reply message
Scott Main50d7dc92014-03-18 05:13:12 -0700405 to your app on the handheld.</p>
406
Scott Maina32c4372014-03-19 11:51:05 -0700407<p>For example, here's how to create a new
Scott Main50d7dc92014-03-18 05:13:12 -0700408 <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">
409<code>RemoteInput</code></a> object that provides a custom
410 label for the voice input prompt:</p>
411
412<pre class="prettyprint">
413// Key for the string that's delivered in the action's intent
414private static final String EXTRA_VOICE_REPLY = "extra_voice_reply";
415
416String replyLabel = getResources().getString(R.string.reply_label);
417
418RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
419 .setLabel(replyLabel)
420 .build();
421</pre>
422
423
424<h3>Add Pre-defined Text Responses</h3>
425
426<img src="/wear/images/12_voicereply.png" height="200" style="float:right;margin:0 0 20px 40px" />
427
428<p>In addition to allowing voice input, you can
Scott Maina32c4372014-03-19 11:51:05 -0700429 provide up to five text responses that the user can select for quick replies. Call
Scott Main50d7dc92014-03-18 05:13:12 -0700430 <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html#setChoices(java.lang.String[])"><code>setChoices()</code></a> and pass it a string array.</p>
431
432<p>For example, you may define some responses in a resource array:</p>
433
434<p class="code-caption">res/values/strings.xml</code>
435<pre class="prettyprint">
436&lt;?xml version="1.0" encoding="utf-8"?>
437&lt;resources>
438 &lt;string-array name="reply_choices">
439 &lt;item>Yes&lt;/item>
440 &lt;item>No&lt;/item>
441 &lt;item>Maybe&lt;/item>
442 &lt;/string-array>
443&lt;/resources>
444</pre>
445
446<p>Then, inflate the string array and add it to the
447 <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a>:</p>
448
449<pre>
450String replyLabel = getResources().getString(R.string.reply_label);
451String[] replyChoices = getResources().getStringArray(R.array.reply_choices);
452
453RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
454 .setLabel(replyLabel)
455 .setChoices(replyChoices)
456 .build();
457</pre>
458
459
460
461
462<h2 id="PrimaryAction">Receive Voice Input for the Primary Action</h2>
463
464<p>If "Reply" is your notification's primary action (defined by the <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html#setContentIntent(android.app.PendingIntent)">setContentIntent()</a></code>
465method), then you should attach the
466 <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> to the main action using
467 <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addRemoteInputForContentIntent(android.preview.support.wearable.notifications.RemoteInput)">
468<code>addRemoteInputForContentIntent()</code></a>. For example:</p>
469
470<pre>
471// Create intent for reply action
Scott Maina32c4372014-03-19 11:51:05 -0700472Intent replyIntent = new Intent(this, ReplyActivity.class);
Scott Main50d7dc92014-03-18 05:13:12 -0700473PendingIntent replyPendingIntent =
Scott Maina32c4372014-03-19 11:51:05 -0700474 PendingIntent.getActivity(this, 0, replyIntent, 0);
Scott Main50d7dc92014-03-18 05:13:12 -0700475
476// Build the notification
477NotificationCompat.Builder replyNotificationBuilder =
478 new NotificationCompat.Builder(this)
479 .setSmallIcon(R.drawable.ic_new_message)
480 .setContentTitle("Message from Travis")
481 .setContentText("I love key lime pie!")
482 .setContentIntent(replyPendingIntent);
483
484// Create the remote input
485RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
486 .setLabel(replyLabel)
487 .build();
488
489// Create wearable notification and add remote input
490Notification replyNotification =
491 new WearableNotifications.Builder(replyNotificationBuilder)
492 .addRemoteInputForContentIntent(replyAction)
493 .build();
494</pre>
495
496
497<p>By using
498 <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addRemoteInputForContentIntent(android.preview.support.wearable.notifications.RemoteInput)">
499<code>addRemoteInputForContentIntent()</code></a> to add the
500 <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> object to the notification's primary action,
501the button that normally appears as an "Open" action becomes the "Reply" action
502and starts the voice input UI when users select it on Android Wear.</p>
503
504
505
506<h2 id="NewAction">Receive Voice Input for a Secondary Action</h2>
507
508<p>If the "Reply" action is not your notification's primary action and you want to enable
509voice input for a secondary action, add the
510 <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> to a new action button defined by an
511 <a href="/reference/android/preview/support/wearable/notifications/Action.html">
512<code>Action</code></a> object.</p>
513
514<p>You should instantiate the
515 <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">
516<code>Action</code></a> with the
517 <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html"><code>Action.Builder()</code></a>
518constructor, which takes an icon and text label for the action button, plus the
519<code><a href="/reference/android/app/PendingIntent.html">PendingIntent</a></code>
520the system should use to invoke your app when the user selects the action. For example:</p>
521
522<pre>
523// Create the pending intent to fire when the user selects the action
524Intent replyIntent = new Intent(this, ReplyActivity.class);
525PendingIntent pendingReplyIntent =
526 PendingIntent.getActivity(this, 0, replyIntent, 0);
527
528// Create the remote input
529RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
530 .setLabel(replyLabel)
531 .build();
532
533// Create the notification action
534Action replyAction = new Action.Builder(R.drawable.ic_message,
535 "Reply", pendingIntent)
536 .addRemoteInput(remoteInput)
537 .build();
538</pre>
539
540
541<p>After you add the
542 <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> to the
543 <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">
544<code>Action</code></a>, add the
545 <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">
546<code>Action</code></a> to the
547 <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html"><code>WearableNotifications.Builder</code></a> using
548 <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addAction(Action)"><code>addAction()</code></a>.
549For example:</p>
550
551<pre>
552// Create basic notification builder
553NotificationCompat.Builder replyNotificationBuilder =
554 new NotificationCompat.Builder(this)
555 .setContentTitle("New message");
556
557// Create the notification action and add remote input
558Action replyAction = new Action.Builder(R.drawable.ic_message,
559 "Reply", pendingIntent)
560 .addRemoteInput(remoteInput)
561 .build();
562
563// Create wearable notification and add action
564Notification replyNotification =
565 new WearableNotifications.Builder(replyNotificationBuilder)
566 .addAction(replyAction)
567 .build();
568</pre>
569
Scott Maina32c4372014-03-19 11:51:05 -0700570<p>Now, when the user selects "Reply" from an Android wearable, the system prompts the user
571 for voice input (and shows the list of pre-defined replies, if provided).
Scott Main50d7dc92014-03-18 05:13:12 -0700572 Once the user completes a response, the system invokes
573 the <code><a href="/reference/android/content/Intent.html">Intent</a></code> attached to the action and adds the
574<code>EXTRA_VOICE_REPLY</code> extra (the string
575 you passed to the
576 <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html"><code>RemoteInput.Builder</code></a> constructor)
577 with the user's message as the string value.</p>
578
579
580
581
582</body>
583</html>
584
585 </div>
586
587 <div class="content-footer layout-content-row"
588 itemscope itemtype="http://schema.org/SiteNavigationElement">
589 <div class="layout-content-col col-9" style="padding-top:4px">
590
591 <div class="g-plusone" data-size="medium"></div>
592
593 </div>
594
595 <div class="paging-links layout-content-col col-4">
596
597 </div>
598
599 </div>
600
601
602
603
604 </div> <!-- end jd-content -->
605
606<div id="footer" class="wrap" >
607
608
609 <div id="copyright">
610
611 Except as noted, this content is
612 licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
613 Creative Commons Attribution 2.5</a>. For details and
614 restrictions, see the <a href="/license.html">Content
615 License</a>.
616 </div>
617
618
619 <div id="footerlinks">
620
621 <p>
622 <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
623 <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
624 <a href="/support.html">Support</a>
625 </p>
626 </div>
627
628</div> <!-- end footer -->
629</div><!-- end doc-content -->
630
631</div> <!-- end body-content -->
632
633
634
635
636
637
638<!-- Start of Tag -->
639<script type="text/javascript">
640var axel = Math.random() + "";
641var a = axel * 10000000000000;
642document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
643</script>
644<noscript>
645<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
646</noscript>
647<!-- End of Tag -->
648</body>
649</html>
650
651
652