diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index f69cad096d38e..457afcc8023ea 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -109,14 +109,18 @@ public final class MediaStore { * An intent to perform a search for music media and automatically play content from the * result when possible. This can be fired, for example, by the result of a voice recognition * command to listen to music. - *

- * Contains the {@link android.app.SearchManager#QUERY} extra, which is a string - * that can contain any type of unstructured music search, like the name of an artist, - * an album, a song, a genre, or any combination of these. - *

- * Because this intent includes an open-ended unstructured search string, it makes the most - * sense for apps that can support large-scale search of music, such as services connected - * to an online database of music which can be streamed and played on the device. + *

This intent always includes the {@link android.provider.MediaStore#EXTRA_MEDIA_FOCUS} + * and {@link android.app.SearchManager#QUERY} extras. The + * {@link android.provider.MediaStore#EXTRA_MEDIA_FOCUS} extra determines the search mode, and + * the value of the {@link android.app.SearchManager#QUERY} extra depends on the search mode. + * For more information about the search modes for this intent, see + * Play music based + * on a search query in Common + * Intents.

+ * + *

This intent makes the most sense for apps that can support large-scale search of music, + * such as services connected to an online database of music which can be streamed and played + * on the device.

*/ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH = diff --git a/docs/html/guide/components/intents-common.jd b/docs/html/guide/components/intents-common.jd index 826dcfff54364..a0f7ce159e931 100644 --- a/docs/html/guide/components/intents-common.jd +++ b/docs/html/guide/components/intents-common.jd @@ -56,6 +56,7 @@ page.tags="IntentFilter"
  • Music or Video
    1. Play a media file
    2. +
    3. Play music based on a search query
  • Phone @@ -1287,9 +1288,251 @@ public void playMedia(Uri file) { +

    Play music based on a search query

    + +

    To play music based on a search query, use the +{@link android.provider.MediaStore#INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH} intent. An app may fire +this intent in response to the user's voice command to play music. The receiving app for this +intent performs a search within its inventory to match existing content to the given query and +starts playing that content.

    + +

    This intent should include the {@link android.provider.MediaStore#EXTRA_MEDIA_FOCUS} string +extra, which specifies the inteded search mode. For example, the search mode can specify whether +the search is for an artist name or song name.

    + +
    +
    Action
    +
    {@link android.provider.MediaStore#INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH}
    + +
    Data URI Scheme
    +
    None
    + +
    MIME Type
    +
    None
    + +
    Extras
    +
    +
    +
    {@link android.provider.MediaStore#EXTRA_MEDIA_FOCUS MediaStore.EXTRA_MEDIA_FOCUS} (required)
    +
    +

    Indicates the search mode (whether the user is looking for a particular artist, album, song, +playlist, or radio channel). Most search modes take additional extras. For example, if the user +is interested in listening to a particular song, the intent might have three additional extras: +the song title, the artist, and the album. This intent supports the following search modes for +each value of {@link android.provider.MediaStore#EXTRA_MEDIA_FOCUS}:

    +
    +

    Any - "vnd.android.cursor.item/*"

    +
    +

    Play any music. The receiving app should play some music based on a smart choice, such +as the last playlist the user listened to.

    +

    Additional extras:

    +
      +
    • {@link android.app.SearchManager#QUERY} (required) - An empty string. This extra is always + provided for backward compatibility: existing apps that do not know about search modes can + process this intent as an unstructured search.
    • +
    +
    +

    Unstructured - "vnd.android.cursor.item/*"

    +
    +

    Play a particular song, album or genre from an unstructured search query. Apps may generate +an intent with this search mode when they can't identify the type of content the user wants to +listen to. Apps should use more specific search modes when possible.

    +

    Additional extras:

    +
      +
    • {@link android.app.SearchManager#QUERY} (required) - A string that contains any combination + of: the artist, the album, the song name, or the genre.
    • +
    +
    +

    Genre - +{@link android.provider.MediaStore.Audio.Genres#ENTRY_CONTENT_TYPE Audio.Genres.ENTRY_CONTENT_TYPE}

    +
    +

    Play music of a particular genre.

    +

    Additional extras:

    +
      +
    • "android.intent.extra.genre" (required) - The genre.
    • +
    • {@link android.app.SearchManager#QUERY} (required) - The genre. This extra is always provided + for backward compatibility: existing apps that do not know about search modes can process + this intent as an unstructured search.
    • +
    +
    +

    Artist - +{@link android.provider.MediaStore.Audio.Artists#ENTRY_CONTENT_TYPE Audio.Artists.ENTRY_CONTENT_TYPE}

    +
    +

    Play music from a particular artist.

    +

    Additional extras:

    +
      +
    • {@link android.provider.MediaStore#EXTRA_MEDIA_ARTIST} (required) - The artist.
    • +
    • "android.intent.extra.genre" - The genre.
    • +
    • {@link android.app.SearchManager#QUERY} (required) - A string that contains any combination of + the artist or the genre. This extra is always provided for backward compatibility: + existing apps that do not know about search modes can process this intent as an unstructured + search.
    • +
    +
    +

    Album - +{@link android.provider.MediaStore.Audio.Albums#ENTRY_CONTENT_TYPE Audio.Albums.ENTRY_CONTENT_TYPE}

    +
    +

    Play music from a particular album.

    +

    Additional extras:

    +
      +
    • {@link android.provider.MediaStore#EXTRA_MEDIA_ALBUM} (required) - The album.
    • +
    • {@link android.provider.MediaStore#EXTRA_MEDIA_ARTIST} - The artist.
    • +
    • "android.intent.extra.genre" - The genre.
    • +
    • {@link android.app.SearchManager#QUERY} (required) - A string that contains any combination of + the album or the artist. This extra is always provided for backward + compatibility: existing apps that do not know about search modes can process this intent as an + unstructured search.
    • +
    +
    +

    Song - "vnd.android.cursor.item/audio"

    +
    +

    Play a particular song.

    +

    Additional extras:

    +
      +
    • {@link android.provider.MediaStore#EXTRA_MEDIA_ALBUM} - The album.
    • +
    • {@link android.provider.MediaStore#EXTRA_MEDIA_ARTIST} - The artist.
    • +
    • "android.intent.extra.genre" - The genre.
    • +
    • {@link android.provider.MediaStore#EXTRA_MEDIA_TITLE} (required) - The song name.
    • +
    • {@link android.app.SearchManager#QUERY} (required) - A string that contains any combination of: + the album, the artist, the genre, or the title. This extra is always provided for + backward compatibility: existing apps that do not know about search modes can process this + intent as an unstructured search.
    • +
    +
    +

    Radio channel - "vnd.android.cursor.item/radio"

    +
    +

    Play a particular radio channel or a radio channel that matches some criteria specified +by additional extras.

    +

    Additional extras:

    +
      +
    • {@link android.provider.MediaStore#EXTRA_MEDIA_ALBUM} - The album.
    • +
    • {@link android.provider.MediaStore#EXTRA_MEDIA_ARTIST} - The artist.
    • +
    • "android.intent.extra.genre" - The genre.
    • +
    • "android.intent.extra.radio_channel" - The radio channel.
    • +
    • {@link android.provider.MediaStore#EXTRA_MEDIA_TITLE} - The song name that the radio + channel is based on.
    • +
    • {@link android.app.SearchManager#QUERY} (required) - A string that contains any combination + of: the album, the artist, the genre, the radio channel, or the title. This extra is + always provided for backward compatibility: existing apps that do not know about search + modes can process this intent as an unstructured search.
    • +
    +
    +

    Playlist - {@link android.provider.MediaStore.Audio.Playlists#ENTRY_CONTENT_TYPE Audio.Playlists.ENTRY_CONTENT_TYPE}

    +
    +

    Play a particular playlist or a playlist that matches some criteria specified +by additional extras.

    +

    Additional extras:

    +
      +
    • {@link android.provider.MediaStore#EXTRA_MEDIA_ALBUM} - The album.
    • +
    • {@link android.provider.MediaStore#EXTRA_MEDIA_ARTIST} - The artist.
    • +
    • "android.intent.extra.genre" - The genre.
    • +
    • "android.intent.extra.playlist" - The playlist.
    • +
    • {@link android.provider.MediaStore#EXTRA_MEDIA_TITLE} - The song name that the playlist is + based on.
    • +
    • {@link android.app.SearchManager#QUERY} (required) - A string that contains any combination + of: the album, the artist, the genre, the playlist, or the title. This extra is always + provided for backward compatibility: existing apps that do not know about search modes can + process this intent as an unstructured search.
    • +
    +
    +
    +
    +
    +
    +
    +

    Example intent:

    +

    If the user wants to listen to a radio station that plays songs from a particular artist, +a search app may generate the following intent:

    +
    +public void playSearchRadioByArtist(String artist) {
    +    Intent intent = new Intent(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH);
    +    intent.putExtra(MediaStore.EXTRA_MEDIA_FOCUS,
    +                    "vnd.android.cursor.item/radio");
    +    intent.putExtra(MediaStore.EXTRA_MEDIA_ARTIST, artist);
    +    intent.putExtra(SearchManager.QUERY, artist);
    +    if (intent.resolveActivity(getPackageManager()) != null) {
    +        startActivity(intent);
    +    }
    +}
    +
    + +

    Example intent filter:

    +
    +<activity ...>
    +    <intent-filter>
    +        <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
    +        <category android:name="android.intent.category.DEFAULT" />
    +    </intent-filter>
    +</activity>
    +
    +

    When handling this intent, your activity should check the value of the +{@link android.provider.MediaStore#EXTRA_MEDIA_FOCUS} extra in the incoming +{@link android.content.Intent} to determine the search mode. Once your activity has identified +the search mode, it should read the values of the additional extras for that particular search mode. +With this information your app can then perform the search within its inventory to play the +content that matches the search query. For example:

    +
    +protected void onCreate(Bundle savedInstanceState) {
    +    ...
    +    Intent intent = this.getIntent();
    +    if (intent.getAction().compareTo(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) == 0) {
    +
    +        String mediaFocus = intent.getStringExtra(MediaStore.EXTRA_MEDIA_FOCUS);
    +        String query = intent.getStringExtra(SearchManager.QUERY);
    +
    +        // Some of these extras may not be available depending on the search mode
    +        String album = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ALBUM);
    +        String artist = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ARTIST);
    +        String genre = intent.getStringExtra("android.intent.extra.genre");
    +        String playlist = intent.getStringExtra("android.intent.extra.playlist");
    +        String rchannel = intent.getStringExtra("android.intent.extra.radio_channel");
    +        String title = intent.getStringExtra(MediaStore.EXTRA_MEDIA_TITLE);
    +
    +        // Determine the search mode and use the corresponding extras
    +        if (mediaFocus == null) {
    +            // 'Unstructured' search mode (backward compatible)
    +            playUnstructuredSearch(query);
    +
    +        } else if (mediaFocus.compareTo("vnd.android.cursor.item/*") == 0) {
    +            if (query.isEmpty()) {
    +                // 'Any' search mode
    +                playResumeLastPlaylist();
    +            } else {
    +                // 'Unstructured' search mode
    +                playUnstructuredSearch(query);
    +            }
    +
    +        } else if (mediaFocus.compareTo(MediaStore.Audio.Genres.ENTRY_CONTENT_TYPE) == 0) {
    +            // 'Genre' search mode
    +            playGenre(genre);
    +
    +        } else if (mediaFocus.compareTo(MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) == 0) {
    +            // 'Artist' search mode
    +            playArtist(artist, genre);
    +
    +        } else if (mediaFocus.compareTo(MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE) == 0) {
    +            // 'Album' search mode
    +            playAlbum(album, artist);
    +
    +        } else if (mediaFocus.compareTo("vnd.android.cursor.item/audio") == 0) {
    +            // 'Song' search mode
    +            playSong(album, artist, genre, title);
    +
    +        } else if (mediaFocus.compareTo("vnd.android.cursor.item/radio") == 0) {
    +            // 'Radio channel' search mode
    +            playRadioChannel(album, artist, genre, rchannel, title);
    +
    +        } else if (mediaFocus.compareTo(MediaStore.Audio.Playlists.ENTRY_CONTENT_TYPE) == 0) {
    +            // 'Playlist' search mode
    +            playPlaylist(album, artist, genre, playlist, title);
    +        }
    +    }
    +}
    +
    +