blob: c8f6621f9753a5b187c8bff566636b0ccf8b69a1 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width" />
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
<title>Receiving Voice Input from a Notification | Android Developers</title>
<!-- STYLESHEETS -->
<link rel="stylesheet"
href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
<!-- JAVASCRIPT -->
<script src="//www.google.com/jsapi" type="text/javascript"></script>
<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
<script type="text/javascript">
var toRoot = "/";
var metaTags = [];
var devsite = false;
</script>
<script src="/assets/js/docs.js" type="text/javascript"></script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-5831155-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body class="gc-documentation
" itemscope itemtype="http://schema.org/Article">
<a name="top"></a>
<!-- Header -->
<div id="header">
<div class="wrap" id="header-wrap">
<div class="col-3 logo-wear">
<a href="/wear/index.html">
<img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
</a>
</div>
<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
<!-- New Search -->
<div class="menu-container">
<div class="moremenu">
<div id="more-btn"></div>
</div>
<div class="morehover" id="moremenu">
<div class="top"></div>
<div class="mid">
<div class="header">Links</div>
<ul>
<li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
<li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
<li><a href="/about/index.html">About Android</a></li>
</ul>
<div class="header">Android Sites</div>
<ul>
<li><a href="http://www.android.com">Android.com</a></li>
<li class="active"><a>Android Developers</a></li>
<li><a href="http://source.android.com">Android Open Source Project</a></li>
</ul>
<div class="header">Language</div>
<div id="language" class="locales">
<select name="language" onChange="changeLangPref(this.value, true)">
<option value="en">English</option>
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文 (中国)</option>
<option value="zh-tw">中文 (台灣)</option>
</select>
</div>
<script type="text/javascript">
<!--
loadLangPref();
//-->
</script>
<br class="clearfix" />
</div><!-- end mid -->
<div class="bottom"></div>
</div><!-- end morehover -->
<div class="search" id="search-container">
<div class="search-inner">
<div id="search-btn"></div>
<div class="left"></div>
<form onsubmit="return submit_search()">
<input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
onkeydown="return search_changed(event, true, '/')"
onkeyup="return search_changed(event, false, '/')" />
</form>
<div class="right"></div>
<a class="close hide">close</a>
<div class="left"></div>
<div class="right"></div>
</div>
</div><!-- end search -->
<div class="search_filtered_wrapper reference">
<div class="suggest-card reference no-display">
<ul class="search_filtered">
</ul>
</div>
</div>
<div class="search_filtered_wrapper docs">
<div class="suggest-card dummy no-display">&nbsp;</div>
<div class="suggest-card develop no-display">
<ul class="search_filtered">
</ul>
<div class="child-card guides no-display">
</div>
<div class="child-card training no-display">
</div>
<div class="child-card samples no-display">
</div>
</div>
<div class="suggest-card design no-display">
<ul class="search_filtered">
</ul>
</div>
<div class="suggest-card distribute no-display">
<ul class="search_filtered">
</ul>
</div>
</div><!-- end search_filtered_wrapper -->
</div>
<!-- end menu_container -->
</div><!-- end header-wrap -->
</div>
<!-- /Header -->
<div id="searchResults" class="wrap" style="display:none;">
<h2 id="searchTitle">Results</h2>
<div id="leftSearchControl" class="search-control">Loading...</div>
</div>
<div class="wrap clearfix" id="body-content">
<div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav" class="scroll-pane">
<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
<ul id="nav">
<li class="nav-section">
<div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
</a></div>
</li>
<li class="nav-section">
<div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
</a></div>
</li>
<li class="nav-section">
<div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
</a></div>
</li>
<li class="nav-section">
<div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
</a></div>
</li>
<li class="nav-section">
<div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
</a></div>
</li>
<li class="nav-section">
<div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
</a></div>
</li>
<li class="nav-section">
<div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
</a></div>
</li>
<li class="nav-section">
<div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
<ul class="tree-list-children">
<li class="nav-section">
<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>
<ul>
<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
</ul>
</li>
<li class="nav-section">
<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>
<ul>
<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
</ul>
</li>
</ul>
</li>
<li class="nav-section">
<div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
</li>
</ul>
</div>
</div> <!-- end side-nav -->
<script>
$(document).ready(function() {
scrollIntoView("devdoc-nav");
});
</script>
<div class="col-12" id="doc-col" >
<h1 itemprop="name" >Receiving Voice Input from a Notification</h1>
<div id="jd-content">
<div class="jd-descr" itemprop="articleBody">
<img src="/wear/images/13_voicereply.png" height="200" width="169" style="float:right;margin:0 0 20px 40px" />
<img src="/wear/images/03_actions.png" height="200" width="169" style="float:right;margin:0 0 20px 40px" />
<p>If your notification includes an action to respond with text,
such as to reply to an email, it should normally launch an activity
on the handheld device. However, when your notification appears on an Android wearable, you can
allow users to dictate a reply with voice input. You can also provide pre-defined text
messages for the user to select.</p>
<p>When the user replies with voice or selects one of the available
messages, the system sends the message to your app on the connected handheld device.
The message is attached as an extra in the <code><a href="/reference/android/content/Intent.html">Intent</a></code> you specified
to be used for the notification action.</p>
<p class="note"><strong>Note:</strong> When developing with the Android emulator,
you must type text replies into the voice input field, so be sure you have enabled
<strong>Hardware keyboard present</strong> in the AVD settings.</p>
<h2 id="RemoteInput">Define the Remote Input</h2>
<p>To create an action that supports voice input, first create an instance of
<a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">
<code>RemoteInput</code></a> using the
<a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html"><code>RemoteInput.Builder</code></a> APIs.
The
<a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html"><code>RemoteInput.Builder</code></a> constructor takes a string that the system
will use as a key for the <code><a href="/reference/android/content/Intent.html">Intent</a></code> extra that carries the reply message
to your app on the handheld.</p>
<p>For example, here's how to create a new
<a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">
<code>RemoteInput</code></a> object that provides a custom
label for the voice input prompt:</p>
<pre class="prettyprint">
// Key for the string that's delivered in the action's intent
private static final String EXTRA_VOICE_REPLY = "extra_voice_reply";
String replyLabel = getResources().getString(R.string.reply_label);
RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
.setLabel(replyLabel)
.build();
</pre>
<h3>Add Pre-defined Text Responses</h3>
<img src="/wear/images/12_voicereply.png" height="200" style="float:right;margin:0 0 20px 40px" />
<p>In addition to allowing voice input, you can
provide up to five text responses that the user can select for quick replies. Call
<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>
<p>For example, you may define some responses in a resource array:</p>
<p class="code-caption">res/values/strings.xml</code>
<pre class="prettyprint">
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;resources>
&lt;string-array name="reply_choices">
&lt;item>Yes&lt;/item>
&lt;item>No&lt;/item>
&lt;item>Maybe&lt;/item>
&lt;/string-array>
&lt;/resources>
</pre>
<p>Then, inflate the string array and add it to the
<a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a>:</p>
<pre>
String replyLabel = getResources().getString(R.string.reply_label);
String[] replyChoices = getResources().getStringArray(R.array.reply_choices);
RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
.setLabel(replyLabel)
.setChoices(replyChoices)
.build();
</pre>
<h2 id="PrimaryAction">Receive Voice Input for the Primary Action</h2>
<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>
method), then you should attach the
<a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> to the main action using
<a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addRemoteInputForContentIntent(android.preview.support.wearable.notifications.RemoteInput)">
<code>addRemoteInputForContentIntent()</code></a>. For example:</p>
<pre>
// Create intent for reply action
Intent replyIntent = new Intent(this, ReplyActivity.class);
PendingIntent replyPendingIntent =
PendingIntent.getActivity(this, 0, replyIntent, 0);
// Build the notification
NotificationCompat.Builder replyNotificationBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_new_message)
.setContentTitle("Message from Travis")
.setContentText("I love key lime pie!")
.setContentIntent(replyPendingIntent);
// Create the remote input
RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
.setLabel(replyLabel)
.build();
// Create wearable notification and add remote input
Notification replyNotification =
new WearableNotifications.Builder(replyNotificationBuilder)
.addRemoteInputForContentIntent(replyAction)
.build();
</pre>
<p>By using
<a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addRemoteInputForContentIntent(android.preview.support.wearable.notifications.RemoteInput)">
<code>addRemoteInputForContentIntent()</code></a> to add the
<a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> object to the notification's primary action,
the button that normally appears as an "Open" action becomes the "Reply" action
and starts the voice input UI when users select it on Android Wear.</p>
<h2 id="NewAction">Receive Voice Input for a Secondary Action</h2>
<p>If the "Reply" action is not your notification's primary action and you want to enable
voice input for a secondary action, add the
<a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> to a new action button defined by an
<a href="/reference/android/preview/support/wearable/notifications/Action.html">
<code>Action</code></a> object.</p>
<p>You should instantiate the
<a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">
<code>Action</code></a> with the
<a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html"><code>Action.Builder()</code></a>
constructor, which takes an icon and text label for the action button, plus the
<code><a href="/reference/android/app/PendingIntent.html">PendingIntent</a></code>
the system should use to invoke your app when the user selects the action. For example:</p>
<pre>
// Create the pending intent to fire when the user selects the action
Intent replyIntent = new Intent(this, ReplyActivity.class);
PendingIntent pendingReplyIntent =
PendingIntent.getActivity(this, 0, replyIntent, 0);
// Create the remote input
RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
.setLabel(replyLabel)
.build();
// Create the notification action
Action replyAction = new Action.Builder(R.drawable.ic_message,
"Reply", pendingIntent)
.addRemoteInput(remoteInput)
.build();
</pre>
<p>After you add the
<a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> to the
<a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">
<code>Action</code></a>, add the
<a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">
<code>Action</code></a> to the
<a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html"><code>WearableNotifications.Builder</code></a> using
<a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addAction(Action)"><code>addAction()</code></a>.
For example:</p>
<pre>
// Create basic notification builder
NotificationCompat.Builder replyNotificationBuilder =
new NotificationCompat.Builder(this)
.setContentTitle("New message");
// Create the notification action and add remote input
Action replyAction = new Action.Builder(R.drawable.ic_message,
"Reply", pendingIntent)
.addRemoteInput(remoteInput)
.build();
// Create wearable notification and add action
Notification replyNotification =
new WearableNotifications.Builder(replyNotificationBuilder)
.addAction(replyAction)
.build();
</pre>
<p>Now, when the user selects "Reply" from an Android wearable, the system prompts the user
for voice input (and shows the list of pre-defined replies, if provided).
Once the user completes a response, the system invokes
the <code><a href="/reference/android/content/Intent.html">Intent</a></code> attached to the action and adds the
<code>EXTRA_VOICE_REPLY</code> extra (the string
you passed to the
<a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html"><code>RemoteInput.Builder</code></a> constructor)
with the user's message as the string value.</p>
</body>
</html>
</div>
<div class="content-footer layout-content-row"
itemscope itemtype="http://schema.org/SiteNavigationElement">
<div class="layout-content-col col-9" style="padding-top:4px">
<div class="g-plusone" data-size="medium"></div>
</div>
<div class="paging-links layout-content-col col-4">
</div>
</div>
</div> <!-- end jd-content -->
<div id="footer" class="wrap" >
<div id="copyright">
Except as noted, this content is
licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
Creative Commons Attribution 2.5</a>. For details and
restrictions, see the <a href="/license.html">Content
License</a>.
</div>
<div id="footerlinks">
<p>
<a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
<a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
<a href="/support.html">Support</a>
</p>
</div>
</div> <!-- end footer -->
</div><!-- end doc-content -->
</div> <!-- end body-content -->
<!-- Start of Tag -->
<script type="text/javascript">
var axel = Math.random() + "";
var a = axel * 10000000000000;
document.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>');
</script>
<noscript>
<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>
</noscript>
<!-- End of Tag -->
</body>
</html>