summaryrefslogtreecommitdiffstats
path: root/docs/html/training
diff options
context:
space:
mode:
Diffstat (limited to 'docs/html/training')
-rw-r--r--docs/html/training/auto/audio/index.jd208
-rw-r--r--docs/html/training/auto/messaging/index.jd23
-rw-r--r--docs/html/training/index.jd25
-rw-r--r--docs/html/training/run-background-service/create-service.jd4
-rw-r--r--docs/html/training/training_toc.cs15
5 files changed, 231 insertions, 44 deletions
diff --git a/docs/html/training/auto/audio/index.jd b/docs/html/training/auto/audio/index.jd
index 56ec90a..f5a797c 100644
--- a/docs/html/training/auto/audio/index.jd
+++ b/docs/html/training/auto/audio/index.jd
@@ -21,6 +21,7 @@ page.image=auto/images/assets/icons/media_app_playback.png
<li><a href="#config_manifest">Configure Your Manifest</a></li>
<li><a href="#implement_browser">Build a Browser Service</a></li>
<li><a href="#implement_callback">Implement Play Controls</a></li>
+ <li><a href="#support_voice">Support Voice Actions</a></li>
</ol>
<h2>Related Samples</h2>
@@ -28,6 +29,8 @@ page.image=auto/images/assets/icons/media_app_playback.png
<ul>
<li><a href="{@docRoot}samples/MediaBrowserService/index.html">
MediaBrowserService</a></li>
+ <li><a href="//github.com/googlesamples/android-UniversalMusicPlayer">Universal Media
+ Player</a></li>
</ul>
<h2>See Also</h2>
@@ -58,7 +61,7 @@ href="https://www.youtube.com/watch?v=Q96Sw6v4ULg">
Drivers want to access their music and other audio content on the road. Audio books, podcasts,
sports commentary, and recorded talks can make a long trip educational, inspirational, and
enjoyable. The Android framework allows you to extend your audio app so users can listen to their
- favorite tunes and audio content using a simpler, safer user interface.
+ favorite tunes and audio content using a simple, yet customizable user interface.
</p>
<p>
@@ -280,7 +283,7 @@ token with the appropriate menu node or content item.</p>
<p class="note"><strong>Note:</strong> You should consider providing different content
hierarchies depending on what client is making the query. In particular, Auto
applications have strict limits on how large a menu they can display. This is
-intended to prevent distracting the driver, and to make it easy for the driver
+intended to minimize distracting the driver, and to make it easy for the driver
to operate the app via voice commands. For more information on the Auto user
experience restrictions, see the <a href="{@docRoot}shareables/auto/AndroidAuto-audio-apps.pdf">
Auto Audio Apps</a> guidelines.</p>
@@ -383,7 +386,7 @@ the token with your browser service:</p>
<pre>
public void onCreate() {
- super.onCreate();
+ super.onCreate();
...
// Start a new MediaSession
@@ -426,6 +429,12 @@ app should play its default content. If playback was paused with
{@link android.media.session.MediaSession.Callback#onPause onPause()}, your
app should resume playback.</dd>
+<p class="note">
+ <strong>Note:</strong> Google Play requires your app not to play music immediately when it
+ launches. For more information on this and other requirements, see
+<a href="{@docRoot}distribute/essentials/quality/auto.html">Auto App Quality</a>.
+</p>
+
<dt>{@link android.media.session.MediaSession.Callback#onPlayFromMediaId
onPlayFromMediaId()}</dt>
<dd>Invoked when the user chooses to play a specific item. The method is passed
@@ -470,3 +479,196 @@ to be played over the car's speakers.</p>
<a href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a>,
<a href="{@docRoot}training/managing-audio/index.html">Managing Audio Playback</a>, and
<a href="{@docRoot}guide/topics/media/exoplayer.html">ExoPlayer</a>.</p>
+
+
+<h2 id="support_voice">Support Voice Actions</h2>
+
+<p>To reduce driver distractions, you can add voice actions in your audio playback app. With voice
+action support, users can launch your app and play audio by providing voice input on Auto screens.
+If your audio playback app is already active and the user says
+<i>“Play a song”</i>, the system starts playing music without requiring the user to look at or touch
+the screen.</p>
+
+<h3 id="enable_playback">Enable your app to handle audio playback requests</h3>
+
+<p>Enable your audio app to launch with a voice command such as <i>"Play [search query] on
+[your app name]"</i> by adding the following entry in your manifest:</p>
+
+<pre>
+&lt;activity>
+ &lt;intent-filter>
+ &lt;action android:name=
+ "android.media.action.MEDIA_PLAY_FROM_SEARCH" />
+ &lt;category android:name=
+ "android.intent.category.DEFAULT" />
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p>When the user says <i>“Play music on [your app name]”</i> on an Auto screen, Auto
+attempts to launch your app and play audio by calling your app’s
+<a href="{@docRoot}reference/android/media/session/MediaSession.Callback.html#onPlayFromSearch(java.lang.String, android.os.Bundle)"><code>MediaSession.Callback.onPlayFromSearch()</code></a>
+method. If the user has not specified criteria such as a track name or music genre, the
+<a href="{@docRoot}reference/android/media/session/MediaSession.Callback.html#onPlayFromSearch(java.lang.String, android.os.Bundle)"><code>MediaSession.Callback.onPlayFromSearch()</code></a>
+method receives an empty query parameter. Your app should respond by immediately playing audio, such
+as a song from a random queue or the most recent playlist.
+</p>
+
+<h3 id="parse_voice">Parse the voice query to build the playback queue</h3>
+
+<p>When a user searches for a specific criteria, such as <i>“Play jazz on [your app name]”</i>
+or <i>“Listen to [song title]”</i>, the
+<a href="{@docRoot}reference/android/media/session/MediaSession.Callback.html#onPlayFromSearch(java.lang.String, android.os.Bundle)"><code>onPlayFromSearch()</code></a>
+callback method receives the voice search results in the query parameter and an extras bundle. For
+more information on how to handle search queries to play audio content, see
+<a href="https://developer.android.com/guide/components/intents-common.html#PlaySearch">Play music
+based on a search query</a>.
+</p>
+
+<p>To parse the voice search query to play back audio content in your app, follow these steps:</p>
+
+<ol>
+ <li>Use the extras bundle and search query string returned from the voice search to filter
+ results.</li>
+ <li>Build the audio content queue based on these results.</li>
+ <li>Play the audio content.</li>
+</ol>
+
+<p>The
+<a href="{@docRoot}reference/android/media/session/MediaSession.Callback.html#onPlayFromSearch(java.lang.String, android.os.Bundle)"><code>onPlayFromSearch()</code></a>
+method takes an extras parameter with more detailed information from the voice search.
+These extras help you find the audio content in your app for playback. If the search results are
+unable to provide this data, you can implement logic to parse the raw search query and play the
+appropriate tracks based on the query.
+</p>
+
+<p>The following extras are supported in Android Auto:</p>
+
+<ul>
+ <li><a href="{@docRoot}reference/android/provider/MediaStore.html#EXTRA_MEDIA_ALBUM"><code>android.intent.extra.album</code></a></li>
+ <li><a href="{@docRoot}reference/android/provider/MediaStore.html#EXTRA_MEDIA_ARTIST"><code>android.intent.extra.artist</code></a></li>
+ <li><a href="{@docRoot}reference/android/provider/MediaStore.html#EXTRA_MEDIA_GENRE"><code>android.intent.extra.genre</code></a></li>
+ <li><a href="{@docRoot}reference/android/provider/MediaStore.html#EXTRA_MEDIA_PLAYLIST"><code>android.intent.extra.playlist</code></a></li>
+ <li><a href="{@docRoot}reference/android/provider/MediaStore.html#EXTRA_MEDIA_TITLE"><code>android.intent.extra.title</code></a></li>
+</ul>
+
+<p>The following snippet shows how to override the
+<a href="{@docRoot}reference/android/media/session/MediaSession.Callback.html#onPlayFromSearch(java.lang.String, android.os.Bundle)"><code>onPlayFromSearch()</code></a>
+method in your
+<a href="{@docRoot}reference/android/media/session/MediaSession.Callback.html"><code>MediaSession.Callback</code></a>
+implementation to handle the search query and extras for playing audio content in your app:
+</p>
+
+<pre>
+&#64;Override
+public void onPlayFromSearch(String query, Bundle extras) {
+ if (TextUtils.isEmpty(query)) {
+ // The user provided generic string e.g. 'Play music'
+ // Build appropriate playlist queue
+ } else {
+ // Build a queue based on songs that match "query" or "extras" param
+ String mediaFocus = extras.getString(MediaStore.EXTRA_MEDIA_FOCUS);
+ if (TextUtils.equals(mediaFocus,
+ MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE)) {
+ isArtistFocus = true;
+ artist = extras.getString(MediaStore.EXTRA_MEDIA_ARTIST);
+ } else if (TextUtils.equals(mediaFocus,
+ MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE)) {
+ isAlbumFocus = true;
+ album = extras.getString(MediaStore.EXTRA_MEDIA_ALBUM);
+ }
+
+ // Implement additional "extras" param filtering
+ }
+
+ // Implement your logic to retrieve the queue
+ if (isArtistFocus) {
+ result = searchMusicByArtist(artist);
+ } else if (isAlbumFocus) {
+ result = searchMusicByAlbum(album);
+ }
+
+ if (result == null) {
+ // No focus found, search by query for song title
+ result = searchMusicBySongTitle(query);
+ }
+
+ if (result != null && !result.isEmpty()) {
+ // Immediately start playing from the beginning of the search results
+ // Implement your logic to start playing music
+ playMusic(result);
+ } else {
+ // Handle no queue found. Stop playing if the app
+ // is currently playing a song
+ }
+}
+</pre>
+
+<p class="note">
+ <strong>Note:</strong> To minimize driver distractions, immediately initiate audio content
+ playback in the
+ <a href="{@docRoot}reference/android/media/session/MediaSession.Callback.html#onPlayFromSearch(java.lang.String, android.os.Bundle)"><code>onPlayFromSearch()</code></a>
+ method when you have generated the audio content queue based on the user's request.
+</p>
+
+<p>For a more detailed example on how to implement voice search to play audio content in your app,
+see the
+<a href="//github.com/googlesamples/android-UniversalMusicPlayer/">Universal Media Player</a>
+sample.
+</p>
+
+<h3 id="implement_playback_controls">Implement playback control actions</h3>
+
+<p>To provide a hands-free experience while users drive and listen to audio content in Android Auto,
+your app should allow users to control audio content playback with voice actions. When users speak
+commands such as <i>“Next song”</i>, <i>“Pause music”</i>, or <i>“Resume music”</i>, the system
+triggers the corresponding callback method where you implement the playback control action.
+</p>
+
+<p>To provide voice-enabled playback controls, first enable the hardware controls by setting these
+flags in your app’s
+<a href="{@docRoot}reference/android/media/session/MediaSession.html"><code>MediaSession</code></a>
+object:
+</p>
+
+<pre>
+mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS |
+ MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
+</pre>
+
+<p>Then, implement the callback methods with the playback controls that you support in your app.
+Here’s a list of voice-enabled playback controls supported by Android Auto:
+</p>
+
+<table>
+ <tr>
+ <th>Example phrase</th>
+ <th>Callback method</th>
+ </tr>
+ <tr>
+ <td><i>"Next song"</i></td>
+ <td><a href="{@docRoot}reference/android/media/session/MediaSession.Callback.html#onSkipToNext()"><code>onSkipToNext()</code></a></td>
+ </tr>
+ <tr>
+ <td><i>"Previous song"</i></td>
+ <td><a href="{@docRoot}reference/android/media/session/MediaSession.Callback.html#onSkipToPrevious()"><code>onSkipToPrevious()</code></a></td>
+ </tr>
+ <tr>
+ <td><i>"Pause music"</i></td>
+ <td><a href="{@docRoot}reference/android/media/session/MediaSession.Callback.html#onPause()"><code>onPause()</code></a></td>
+ </tr>
+ <tr>
+ <td><i>"Stop music"</i></td>
+ <td><a href="{@docRoot}reference/android/media/session/MediaSession.Callback.html#onStop()"><code>onStop()</code></a></td>
+ </tr>
+ <tr>
+ <td><i>"Resume music"</i></td>
+ <td><a href="{@docRoot}reference/android/media/session/MediaSession.Callback.html#onPlay()"><code>onPlay()</code></a></td>
+ </tr>
+</table>
+
+<p>For a more detailed example on how to implement voice-enabled playback actions in your app, see
+the
+<a href="//github.com/googlesamples/android-UniversalMusicPlayer/">Universal Media Player</a>
+sample.
+</p> \ No newline at end of file
diff --git a/docs/html/training/auto/messaging/index.jd b/docs/html/training/auto/messaging/index.jd
index 7540a3f..0177c84 100644
--- a/docs/html/training/auto/messaging/index.jd
+++ b/docs/html/training/auto/messaging/index.jd
@@ -52,9 +52,8 @@ page.image=auto/images/assets/icons/messaging_app_notifications.png
<p>
Staying connected through 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
+ know if a child need to be picked up, or if a dinner location has been changed.
+ 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>
@@ -79,7 +78,7 @@ page.image=auto/images/assets/icons/messaging_app_notifications.png
<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,
+ a 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>
@@ -98,7 +97,7 @@ page.image=auto/images/assets/icons/messaging_app_notifications.png
has read or replied to a message.
</ul>
-<h3 id="#concepts">Concepts and Objects</h3>
+<h3 id="concepts">Concepts and objects</h3>
<p>Before you start designing your app, it's helpful to understand how Auto
handles messaging.</p>
@@ -106,23 +105,19 @@ handles messaging.</p>
<p>Each individual chunk of communication is a <em>message</em>. A message is a
short length of text, suitable for the Auto device to read aloud. In a chat app,
this might be a single message from one person to another: <code>"Fitzy -- Jane
-can't come to the ball, her youngest has the croup. :-( --Liz"</code> In a
-sports app, a message might be a single bit of news about a game: <code>"Granger
-scores for Harpies at 7 minutes in."</code></p>
+can't come to the ball, her youngest has the croup. :-( --Liz"</code>.</p>
<p>A <em>conversation</em> is a group of messages that are all grouped together
in some way. Auto uses the conversation information to group the messages
together when presenting them to the user. In a chat app, a conversation might
be all the messages between the user and another person (for example, all
-the messages back and forth between Darcy and Elizabeth). In a sports app, a
-conversation might be all the messages about a particular game. Every message
+the messages back and forth between Darcy and Elizabeth). Every message
belongs to a conversation, even if it's the only message in that conversation.
Each conversation has a <em>conversation name</em>.
The conversation name is used by Android Auto to
present the messages; it's up to your app to choose an appropriate conversation
name. In a chat app, the conversation name is usually the person your user is
-talking to.
-In a sports app, this might be the name of the teams playing in the game.</p>
+talking to.</p>
<p>The v4 support library defines an {@link
android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation
@@ -177,9 +172,7 @@ contained in those objects have been heard by the user.</li>
<li>If the user sends a reply, Auto triggers the app's "message reply" intent and
attaches a transcript of the user's response. The app can take appropriate
action, based on the app's logic. For example, a chat app might interpret the
-reply as a message to go to the other conversation participants, while a sports
-app might try to interpret the "reply" as a request for other information
-("What's the score in the Sharks game?").</li>
+reply as a message to go to the other conversation participants.</li>
</ol>
diff --git a/docs/html/training/index.jd b/docs/html/training/index.jd
index 44b6747..3e0d593 100644
--- a/docs/html/training/index.jd
+++ b/docs/html/training/index.jd
@@ -12,18 +12,19 @@ Classes are organized into several groups you can see at the top-level of the le
essentials for Android app development. If you're a new Android app developer, you should
complete each of these classes in order.</p>
-<div>
-<div style="float:left; width:40%; margin-right:30px">
-
- <p>If you prefer to learn through interactive video training,
- check out this trailer for a course about the fundamentals of Android development.</p>
- <p><a href="https://www.udacity.com/course/ud853" class="button">
- Start the video course</a></p>
-</div>
-
-<div style="float:left; margin-bottom:20px">
- <iframe width="300" height="169" src="//www.youtube.com/embed/LfVBFFoy9Y0?utm_source=dac&utm_medium=video&utm_content=andfuntrain&utm_campaign=udacint?rel=0&amp;hd=1" frameborder="0" allowfullscreen></iframe>
-</div>
+<div class="wrap">
+ <div class="cols">
+ <div class="col-1of2">
+ <p>If you prefer to learn through interactive video training,
+ check out this trailer for a course about the fundamentals of Android development.</p>
+ <p><a href="https://www.udacity.com/course/ud853" class="button">
+ Start the video course</a>
+ </p>
+ </div>
+ <div class="col-1of2">
+ <iframe width="300" height="169" src="//www.youtube.com/embed/LfVBFFoy9Y0?utm_source=dac&utm_medium=video&utm_content=andfuntrain&utm_campaign=udacint?rel=0&amp;hd=1" frameborder="0" allowfullscreen></iframe>
+ </div>
+ </div>
</div>
<div style="clear:left"></div>
diff --git a/docs/html/training/run-background-service/create-service.jd b/docs/html/training/run-background-service/create-service.jd
index 5f4799c..9b9fcd2 100644
--- a/docs/html/training/run-background-service/create-service.jd
+++ b/docs/html/training/run-background-service/create-service.jd
@@ -55,8 +55,8 @@ trainingnavtop=true
</li>
</ul>
<p>
- However, in most cases an {@link android.app.IntentService} is the preferred way to simple
- background operations.
+ However, in most cases an {@link android.app.IntentService} is the preferred way to perform
+ simple background operations.
</p>
<p>
This lesson shows you how to create your own subclass of {@link android.app.IntentService}.
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index cefff81..535a87e 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -1654,20 +1654,11 @@ results."
</ul>
</li> <!-- end of Background Jobs -->
- <li class="nav-section">
- <div class="nav-section-header">
- <a href="<?cs var:toroot ?>training/best-performance.html">
- <span class="small">Best Practices for</span><br/>
- Performance
- </a>
- </div>
- <ul>
-
<li>
<a href="<?cs var:toroot ?>training/articles/memory.html"
- description=
- "How to keep your app's memory footprint small in order to improve performance
- on a variety of mobile devices."
+ description=
+ "How to keep your app's memory footprint small in order to improve performance
+ on a variety of mobile devices."
>Managing Your App's Memory</a>
</li>