Asystent Google i aplikacje do multimediów

Asystent Google pozwala używać poleceń głosowych do sterowania wieloma urządzeniami, takimi jak Google Home, telefon i inne urządzenia. Ma wbudowane funkcje rozumie polecenia multimedialne („odtwórz coś Beyoncé”) i obsługuje opcje sterowania multimediami (np. wstrzymywanie, pomijanie, przewijanie do przodu, kciuk w górę).

Asystent komunikuje się z aplikacjami do multimediów na Androida za pomocą multimediów . Może użyć funkcji zamiarów lub usług uruchom aplikację i rozpocznij odtwarzanie. Aby uzyskać najlepsze wyniki, aplikacja powinna implementować wszystkie funkcje opisane na tej stronie.

Korzystanie z sesji multimediów

Każda aplikacja audio i wideo musi zawierać sesja multimediów żeby Asystent mógł obsługiwać elementy sterujące transportem po rozpoczęciu odtwarzania.

Pamiętaj, że chociaż Asystent używa tylko działań wymienionych w tej sekcji, sprawdzoną metodą jest wdrożenie wszystkich interfejsów API przygotowywania i odtwarzania, zgodność z innymi aplikacjami. W przypadku działań, których nie wspierasz, wywołania zwrotne sesji multimediów mogą po prostu zwrócić błąd, wykorzystując funkcję ERROR_CODE_NOT_SUPPORTED

Włącz funkcje sterowania multimediami i transportem, ustawiając te flagi w aplikacji MediaSession obiekt:

Kotlin

session.setFlags(
        MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS or
        MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS
)

Java

session.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
    MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);

Sesja multimediów aplikacji musi zadeklarować obsługiwane działania i zaimplementować odpowiednie wywołania zwrotne sesji multimediów. Zadeklaruj obsługiwane działania w setActions()

Uniwersalny odtwarzacz muzyki na Androida Dobrym przykładem tego, jak skonfigurować sesję multimediów, jest przykładowy projekt.

Działania związane z odtwarzaniem

Aby rozpocząć odtwarzanie z usługi, sesja multimediów musi zawierać te działania PLAY wraz z wywołaniami zwrotnymi:

Działanie Oddzwanianie
ACTION_PLAY onPlay()
ACTION_PLAY_FROM_SEARCH onPlayFromSearch()
ACTION_PLAY_FROM_URI (*) onPlayFromUri()

Sesja powinna również implementować te działania PREPARE wraz z wywołaniami zwrotnymi:

Działanie Oddzwanianie
ACTION_PREPARE onPrepare()
ACTION_PREPARE_FROM_SEARCH onPrepareFromSearch()
ACTION_PREPARE_FROM_URI (*) onPrepareFromUri()

(*) Działania oparte na identyfikatorze URI Asystenta Google są dostępne tylko dla firm które dostarczają Google identyfikatory URI. Aby dowiedzieć się więcej o opisywaniu Google treści multimedialnych Więcej informacji: Działania związane z multimediami.

Dzięki wdrożeniu interfejsów API do przygotowywania treści opóźnienia odtwarzania po poleceniu głosowym można zmniejszyć. Aplikacje do multimediów, które chcą poprawić opóźnienie odtwarzania, mogą korzystać z funkcji więcej czasu na rozpoczęcie zapisywania treści w pamięci podręcznej i przygotowanie do odtwarzania multimediów.

Analizuj wyszukiwane hasła

Gdy użytkownik wyszukuje określony element multimedialny, na przykład „Włącz jazz na [nazwa aplikacji]” lub „Posłuchaj [tytuł utworu]”, onPrepareFromSearch() lub onPlayFromSearch(). metoda wywołania zwrotnego odbiera parametr zapytania i pakiet dodatków.

Aplikacja powinna przeanalizować zapytanie głosowe i rozpocząć odtwarzanie, postępując zgodnie z tymi instrukcjami kroki:

  1. Użyj pakietu dodatków i ciągu zapytania wyszukiwanego hasła zwróconego w wyniku wyszukiwania głosowego aby filtrować wyniki.
  2. Na podstawie tych wyników zbuduj kolejkę odtwarzania.
  3. Odtwórz najtrafniejszy element multimedialny z wyników.
.

onPlayFromSearch() pobiera parametr Extras z bardziej szczegółowymi informacjami . Ułatwiają one znajdowanie w aplikacji treści audio, które można odtworzyć. Jeśli wyniki wyszukiwania nie mogą dostarczyć tych danych, można za pomocą funkcji logicznej aby przeanalizować nieprzetworzone wyszukiwane hasło i odtworzyć odpowiednie ścieżki na podstawie zapytania.

W systemach operacyjnych Android Automotive i Android Auto obsługiwane są te dodatki:

Fragment kodu poniżej pokazuje, jak zastąpić parametr onPlayFromSearch() na koncie MediaSession.Callback implementacji umożliwiającej przeanalizowanie zapytania głosowego i rozpoczęcie odtwarzania:

Kotlin

override fun onPlayFromSearch(query: String?, extras: Bundle?) {
    if (query.isNullOrEmpty()) {
        // 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
        val mediaFocus: String? = extras?.getString(MediaStore.EXTRA_MEDIA_FOCUS)
        if (mediaFocus == MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) {
            isArtistFocus = true
            artist = extras.getString(MediaStore.EXTRA_MEDIA_ARTIST)
        } else if (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
    var result: String? = when {
        isArtistFocus -> artist?.also {
            searchMusicByArtist(it)
        }
        isAlbumFocus -> album?.also {
            searchMusicByAlbum(it)
        }
        else -> null
    }
    result = result ?: run {
        // No focus found, search by query for song title
        query?.also {
            searchMusicBySongTitle(it)
        }
    }

    if (result?.isNotEmpty() == true) {
        // 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
    }
}

Java

@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
    }
}

Bardziej szczegółowy przykład implementacji wyszukiwania głosowego w celu odtwarzania dźwięku treści w aplikacji, zobacz Uniwersalny odtwarzacz muzyki na Androida przykład.

Obsługa pustych zapytań

Jeśli onPrepare(), onPlay(), onPrepareFromSearch() lub onPlayFromSearch() są wywoływane bez zapytania, aplikacja do multimediów powinna odtworzyć „bieżący” multimediów. Jeśli nie ma dostępnych multimediów, aplikacja powinna spróbować coś odtworzyć, np. jako utwór z ostatniej playlisty lub losowej kolejki. Asystent używa: tych interfejsów API, gdy użytkownik poprosi o „Odtwarzaj muzykę w [nazwa aplikacji]” bez dodatkowe informacje.

gdy użytkownik mówi „Włącz muzykę w [nazwa aplikacji]”, w systemie operacyjnym Android Automotive lub Android Auto próbuje uruchomić Twoją aplikację i odtworzyć dźwięk, dzwoniąc pod jej numer onPlayFromSearch() . Użytkownik nie podał nazwy elementu multimedialnego, dlatego onPlayFromSearch() otrzymuje pusty parametr zapytania. W takich przypadkach aplikacja powinna zareagować, od razu włączając dźwięk, np. utwór z ostatniego utworu czy losową kolejkę.

Zadeklaruj starszą obsługę komend głosowych

W większości przypadków opisana powyżej obsługa odtwarzania sprawia, że aplikacja funkcje odtwarzania, których potrzebuje. Niektóre systemy wymagają jednak zawierają filtr intencji dla wyszukiwania. Musisz zadeklarować obsługę tej intencji w plikach manifestu aplikacji.

Umieść ten kod w pliku manifestu aplikacji na telefon:

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

Sterowanie transportem

Gdy sesja multimediów w aplikacji jest aktywna, Asystent może wydawać polecenia głosowe do sterowania odtwarzaniem i aktualizowania metadanych multimediów. Aby to działało, powinien włączać poniższe działania i implementować odpowiednie wywołania zwrotne:

Działanie Oddzwanianie Opis
ACTION_SKIP_TO_NEXT onSkipToNext() Następny film
ACTION_SKIP_TO_PREVIOUS onSkipToPrevious() Poprzedni utwór
ACTION_PAUSE, ACTION_PLAY_PAUSE onPause() Wstrzymaj
ACTION_STOP onStop() Zatrzymaj
ACTION_PLAY onPlay() Wznów
ACTION_SEEK_TO onSeekTo() Przewiń do tyłu o 30 sekund.
ACTION_SET_RATING onSetRating(android.support.v4.media.RatingCompat) Kciuk w górę/w dół.
ACTION_SET_CAPTIONING_ENABLED onSetCaptioningEnabled(boolean) Włącz/wyłącz napisy.

Pamiętaj:

  • Aby polecenia przewijania działały, PlaybackState musi być aktualny w wersji state, position, playback speed, and update time. Po zmianie stanu aplikacja musi wywołać metodę setPlaybackState().
  • Aplikacja do multimediów musi też aktualizować metadane sesji multimediów. Pozwala to uzyskać odpowiedzi na pytania takie jak „Jaki jest odtwarzany utwór?” Aplikacja musi wywołać metodę setMetadata(), gdy zmienią się odpowiednie pola (takie jak tytuł utworu, wykonawca i nazwa).
  • Wartość MediaSession.setRatingType() musi być ustawiona, aby wskazać typ oceny, którą obsługuje aplikacja, a aplikacja musi mieć zaimplementowany element onSetRating(). Jeśli aplikacja nie obsługuje oceny, ustaw typ oceny na RATING_NONE.

Dostępne komendy głosowe będą się prawdopodobnie różnić w zależności od typu treści.

Typ treści Wymagane działania
Muzyka

Wymagana obsługa: Odtwórz, Wstrzymaj, Zatrzymaj, Przejdź do następnego i Przejdź do poprzedniego

Zdecydowanie zalecam pomoc dotyczącą: Seek To

Podcast

Wymagana obsługa: Odtwórz, Wstrzymaj, Zatrzymaj i Przewiń do

Zalecane wsparcie dla: przejdź do następnego i poprzedniego

Audiobook Wymagana obsługa: Odtwórz, Wstrzymaj, Zatrzymaj i Przewiń do
Radio Wymagana obsługa: Odtwórz, Wstrzymaj i Zatrzymaj
Wiadomości Wymagana obsługa: Odtwórz, Wstrzymaj, Zatrzymaj, Przejdź do następnego i Przejdź do poprzedniego
Wideo

Wymagana obsługa: Odtwórz, Wstrzymaj, Zatrzymaj, Przewiń do, Przewiń do tyłu i Przewiń do przodu

Zdecydowanie zalecam wsparcie dotyczące: przejdź do następnego i poprzedniego

Musisz obsługiwać tyle działań wymienionych powyżej, ile jest w Twojej ofercie produktów pozwalać użytkownikom na ich wykorzystywanie, ale wciąż z góry odpowiadać na wszelkie inne działania. Na przykład, jeśli użytkownicy premium mają możliwość powrotu do poprzedniej pozycji, pojawi się błąd, gdy użytkownik poziomu bezpłatnego poprosi Asystenta o powrót do poprzedniego elementu. Więcej wskazówek znajdziesz w sekcji dotyczącej obsługi błędów.

Przykładowe zapytania głosowe do wypróbowania

W tabeli poniżej znajdziesz kilka przykładowych zapytań, których możesz użyć Sprawdź implementację:

Wywołanie zwrotne MediaSession Wyrażenie „OK Google” do użycia
onPlay()

„Odtwórz”.

„Wznów”.

onPlayFromSearch()
onPlayFromUri()
Muzyka

„Włącz muzykę lub utwory w aplikacji (nazwa aplikacji)”. To zapytanie jest puste.

„Włącz (utwór | wykonawca | album | gatunek | playlista) na urządzeniu (nazwa aplikacji)”.

Radio „Włącz (częstotliwość | stacja) na urządzeniu (nazwa aplikacji)”.
Audiobook

„Przeczytaj mojego audiobooka na stronie (nazwa aplikacji)”.

„Czytaj (audiobook) w aplikacji (nazwa aplikacji)”.

Podcasty „Włącz (podcast) w aplikacji (nazwa aplikacji)”.
onPause() „Wstrzymaj”.
onStop() „Zatrzymaj”.
onSkipToNext() „Następny (utwór | odcinek | utwór)”.
onSkipToPrevious() „Poprzedni (utwór | odcinek | utwór)”.
onSeekTo()

„Uruchom ponownie”.

„Przeskocz o ## s do przodu”.

„Cofnij się o ## min”.

Nie dotyczy (Zachowaj MediaMetadata zaktualizowano) „Co teraz leci?”

Błędy

Asystent wykrywa błędy z sesji multimediów, kiedy tylko występują, i raportuje ich użytkownikom. Upewnij się, że sesja multimediów aktualizuje stan transportu PlaybackState zawiera kod błędu, tak jak to opisano w sekcji Korzystanie z biblioteki sesja multimediów. Asystent rozpoznaje wszystkie kody błędów zwracane przez funkcję getErrorCode()

Typowe problemy

Oto kilka przykładów błędów, o które warto zadbać, prawidłowo:

  • Użytkownik musi się zalogować
    • Ustaw kod błędu PlaybackState na ERROR_CODE_AUTHENTICATION_EXPIRED.
    • Ustaw komunikat o błędzie PlaybackState.
    • Jeśli jest to wymagane do odtwarzania, ustaw stan PlaybackState na STATE_ERROR, w przeciwnym razie pozostaw resztę PlaybackState w niezmienionej formie.
  • Użytkownik prosi o niedostępne działanie
    • Ustaw prawidłowo kod błędu PlaybackState. Na przykład ustaw parametr Od PlaybackState do ERROR_CODE_NOT_SUPPORTED jeśli działanie nie jest obsługiwane, lub ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED jeśli czynność jest zabezpieczona logowaniem.
    • Ustaw komunikat o błędzie PlaybackState.
    • Pozostałe PlaybackState zachowaj bez zmian.
  • Użytkownik prosi o dostęp do treści niedostępnych w aplikacji
    • Ustaw prawidłowo kod błędu PlaybackState. Na przykład użyj wartości ERROR_CODE_NOT_AVAILABLE_IN_REGION
    • Ustaw komunikat o błędzie PlaybackState.
    • Aby przerwać odtwarzanie, ustaw stan PlaybackSate na STATE_ERROR. w przeciwnym razie pozostaw resztę PlaybackState bez zmian.
  • Użytkownik wysyła żądanie treści, gdy dopasowanie ścisłe jest niedostępne. Na przykład plik użytkownika wersji bezpłatnej, prosząc o udostępnienie treści tylko dla użytkowników wersji Premium.
    • Zalecamy, aby nie zwracać błędów. Zamiast tego potraktuj priorytetowo znalezienie czegoś podobnego do zagrania. Asystent będzie mówić najwięcej odpowiednią odpowiedź głosową przed rozpoczęciem odtwarzania.

Odtwarzanie zgodne z oczekiwaniami

Asystent może uruchomić aplikację audio lub wideo i rozpocząć odtwarzanie, wysyłając wiadomość intencję za pomocą precyzyjnego linku.

Intencja i jej precyzyjny link mogą pochodzić z różnych źródeł:

  • Gdy Asystent jest: uruchamiający aplikację mobilną, może skorzystać z wyszukiwarki Google, aby pobrać przesyła działanie dotyczące zegarka z linkiem.
  • Gdy Asystent uruchamia aplikację na telewizorze, powinna ona zawierać Dostawca wyszukiwania telewizyjnego w celu ujawniania identyfikatorów URI treści multimedialnych. Asystent wysyła zapytanie do: dostawcy treści, który powinien zwrócić intencję zawierającą identyfikator URI precyzyjnego linku oraz jest to czynność opcjonalna. Jeśli zapytanie zwróci działanie w intencji, Asystent wysyła to działanie wraz z identyfikatorem URI z powrotem do aplikacji. Jeśli usługodawca nie podał działanie, Asystent doda do intencji ACTION_VIEW.

Asystent dodaje EXTRA_START_PLAYBACK z wartością true do intencji wysyłanej do aplikacji. Aplikacja powinna rozpocząć odtwarzanie, gdy odbiera intencję z funkcją EXTRA_START_PLAYBACK.

Obsługa intencji, gdy jest aktywna

Użytkownicy mogą poprosić Asystenta o włączenie czegoś podczas odtwarzania aplikacji treści z poprzedniego żądania. Oznacza to, że aplikacja może otrzymywać nowe intencje rozpocząć odtwarzanie, gdy jest ono już uruchomione i aktywne.

Działania obsługujące intencje z użyciem precyzyjnych linków powinny zastąpić onNewIntent() obsługi nowych żądań.

Gdy rozpoczniesz odtwarzanie, Asystent może dodać dodatkowe flagi do intencji wysyłanej do aplikacji. W szczególności można dodać FLAG_ACTIVITY_CLEAR_TOP lub FLAG_ACTIVITY_NEW_TASK lub oba. Chociaż Twój kod nie musi obsługiwać tych flag, system Android na nie reaguje. Może to wpływać na działanie aplikacji po otrzymaniu drugiego żądania odtwarzania z nowym identyfikatorem URI podczas odtwarzania poprzedniego identyfikatora URI. W takim przypadku warto sprawdzić, jak aplikacja reaguje. Możesz użyć polecenia adb narzędziem do symulowania sytuacji (stała 0x14000000 to wartość logiczna LUB tych dwóch flag):

adb shell 'am start -a android.intent.action.VIEW --ez android.intent.extra.START_PLAYBACK true -d "<first_uri>"' -f 0x14000000
adb shell 'am start -a android.intent.action.VIEW --ez android.intent.extra.START_PLAYBACK true -d "<second_uri>"' -f 0x14000000

Odtwarzanie z usługi

Jeśli Twoja aplikacja ma media browser service który zezwala na połączenia z Asystentem, Asystent może uruchomić aplikację, komunikując się z usługą media session Usługa przeglądarki multimediów nie powinna nigdy uruchamiać aktywności. Asystent będzie uruchamiać Twoją aktywność na podstawie zdefiniowanej przez Ciebie PendingIntent za pomocą funkcji setSessionActivity().

Pamiętaj, aby ustawić MediaSession.Token podczas zainicjować usługę przeglądarki multimediów. Pamiętaj, aby ustawić obsługiwane działania związane z odtwarzaniem przez cały czas, również podczas inicjowania. Asystent oczekuje Twoich multimediów aby ustawić działania związane z odtwarzaniem, zanim Asystent wyśle pierwsze odtworzenie .

Aby rozpocząć od usługi, Asystent implementuje interfejsy API klienta przeglądarki multimediów. Wykonuje wywołania TransportControls, które wywołują wywołania zwrotne czynności PLAY na w trakcie sesji multimediów w aplikacji.

Na diagramie poniżej widać kolejność połączeń wygenerowanych przez Asystenta odpowiednie wywołania zwrotne sesji multimediów. (Wywołania zwrotne przygotowywane są wysyłane tylko jeśli aplikacja je obsługuje). Wszystkie wywołania są asynchroniczne. Asystent nie na odpowiedź aplikacji.

Rozpoczynanie odtwarzania z sesją multimediów

Gdy użytkownik wydaje polecenie głosowe, aby zagrać, Asystent odpowiada, wydając krótkie ogłoszenie. Po zakończeniu ogłoszenia Asystent wykona działanie ODTWÓRZ. Nie oczekuje na określony stan odtwarzania.

Jeśli Twoja aplikacja obsługuje działania ACTION_PREPARE_*, Asystent wywołuje działanie PREPARE przed rozpoczęciem ogłoszenia.

Łączenie z usługą Media BrowserService

Aby użyć usługi do uruchamiania aplikacji, Asystent musi mieć możliwość połączenia się z usługą MediabrowserService oraz i pobiera obiekt MediaSession.Token. Żądania połączenia są obsługiwane w usłudze onGetRoot() . Istnieją 2 sposoby obsługi próśb:

  • Akceptuj wszystkie prośby o połączenie
  • Akceptuj prośby o połączenie tylko z aplikacji Asystent
.

Akceptuj wszystkie prośby o połączenie

Aby zezwolić Asystentowi na wysyłanie poleceń do sesji multimediów, musisz zwrócić plik BrowserRoot. Najłatwiejszym sposobem jest zezwolenie wszystkim aplikacjom MediaFirefox na łączenie się z usługą Media BrowserService. Musisz zwrócić wartość BrowserRoot inną niż zero. Oto odpowiedni kod z Universal Music Player:

Kotlin

override fun onGetRoot(
        clientPackageName: String,
        clientUid: Int,
        rootHints: Bundle?
): BrowserRoot? {

    // To ensure you are not allowing any arbitrary app to browse your app's contents, you
    // need to check the origin:
    if (!packageValidator.isCallerAllowed(this, clientPackageName, clientUid)) {
        // If the request comes from an untrusted package, return an empty browser root.
        // If you return null, then the media browser will not be able to connect and
        // no further calls will be made to other media browsing methods.
        Log.i(TAG, "OnGetRoot: Browsing NOT ALLOWED for unknown caller. Returning empty "
                + "browser root so all apps can use MediaController. $clientPackageName")
        return MediaBrowserServiceCompat.BrowserRoot(MEDIA_ID_EMPTY_ROOT, null)
    }

    // Return browser roots for browsing...
}

Java

@Override
public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid,
                             Bundle rootHints) {

    // To ensure you are not allowing any arbitrary app to browse your app's contents, you
    // need to check the origin:
    if (!packageValidator.isCallerAllowed(this, clientPackageName, clientUid)) {
        // If the request comes from an untrusted package, return an empty browser root.
        // If you return null, then the media browser will not be able to connect and
        // no further calls will be made to other media browsing methods.
        LogHelper.i(TAG, "OnGetRoot: Browsing NOT ALLOWED for unknown caller. "
                + "Returning empty browser root so all apps can use MediaController."
                + clientPackageName);
        return new MediaBrowserServiceCompat.BrowserRoot(MEDIA_ID_EMPTY_ROOT, null);
    }

    // Return browser roots for browsing...
}

Zaakceptuj pakiet aplikacji Asystent i podpis

Możesz wyraźnie zezwolić Asystentowi na łączenie się z usługą przeglądarki multimediów. Aby to zrobić, sprawdź nazwę pakietu i podpis. Twoja aplikacja otrzyma nazwę pakietu w metodzie onGetRoot obiektu Media BrowserService. Aby zezwolić Asystentowi na wysyłanie poleceń do sesji multimediów, musisz zwrócić plik BrowserRoot. Uniwersalny odtwarzacz muzyki Przykład zawiera listę znanych nazw pakietów i podpisów. Poniżej znajdują się nazwy pakietów i podpisy używane przez Asystenta Google.

<signature name="Google" package="com.google.android.googlequicksearchbox">
    <key release="false">19:75:b2:f1:71:77:bc:89:a5:df:f3:1f:9e:64:a6:ca:e2:81:a5:3d:c1:d1:d5:9b:1d:14:7f:e1:c8:2a:fa:00</key>
    <key release="true">f0:fd:6c:5b:41:0f:25:cb:25:c3:b5:33:46:c8:97:2f:ae:30:f8:ee:74:11:df:91:04:80:ad:6b:2d:60:db:83</key>
</signature>

<signature name="Google Assistant on Android Automotive OS" package="com.google.android.carassistant">
    <key release="false">17:E2:81:11:06:2F:97:A8:60:79:7A:83:70:5B:F8:2C:7C:C0:29:35:56:6D:46:22:BC:4E:CF:EE:1B:EB:F8:15</key>
    <key release="true">74:B6:FB:F7:10:E8:D9:0D:44:D3:40:12:58:89:B4:23:06:A6:2C:43:79:D0:E5:A6:62:20:E3:A6:8A:BF:90:E2</key>
</signature>