Asystent Google umożliwia sterowanie wieloma urządzeniami, takimi jak Google Home czy telefon, za pomocą poleceń głosowych. Ma wbudowaną funkcję rozumienia poleceń dotyczących multimediów („włącz coś Beyoncé”) i obsługuje sterowanie multimediami (np. wstrzymywanie, pomijanie, przewijanie do przodu, polubienie).
Asystent komunikuje się z aplikacjami multimedialnymi na Androida za pomocą sesji multimedialnej. Może używać intencji lub usług, aby uruchomić aplikację i rozpocząć odtwarzanie. Aby uzyskać najlepsze wyniki, aplikacja powinna implementować wszystkie funkcje opisane na tej stronie.
Korzystanie z sesji multimedialnej
Każda aplikacja audio i wideo musi implementować sesję multimedialną, aby Asystent mógł sterować odtwarzaniem po jego rozpoczęciu.
Pamiętaj, że Asystent używa tylko działań wymienionych w tej sekcji, ale najlepszym rozwiązaniem jest wdrożenie wszystkich interfejsów API przygotowania i odtwarzania, aby zapewnić zgodność z innymi aplikacjami. W przypadku działań, których nie obsługujesz, wywołania zwrotne sesji multimedialnej mogą po prostu zwracać błąd za pomocą ERROR_CODE_NOT_SUPPORTED.
Włącz sterowanie multimediami i transportem, ustawiając te flagi w obiekcie MediaSession aplikacji:
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 multimedialna aplikacji musi deklarować obsługiwane działania i implementować odpowiednie wywołania zwrotne sesji multimedialnej. Zadeklaruj obsługiwane działania w pliku setActions().
Przykładowy projekt Universal Android Music Player to dobry przykład konfiguracji sesji multimedialnej.
Działania związane z odtwarzaniem
Aby rozpocząć odtwarzanie z usługi, sesja multimedialna musi mieć te PLAY działania i ich wywołania zwrotne:
| Działanie | Oddzwanianie |
|---|---|
ACTION_PLAY |
onPlay() |
ACTION_PLAY_FROM_SEARCH |
onPlayFromSearch() |
ACTION_PLAY_FROM_URI (*) |
onPlayFromUri() |
Sesja powinna też implementować te działania PREPARE i ich wywołania zwrotne:
| Działanie | Oddzwanianie |
|---|---|
ACTION_PREPARE |
onPrepare() |
ACTION_PREPARE_FROM_SEARCH |
onPrepareFromSearch() |
ACTION_PREPARE_FROM_URI (*) |
onPrepareFromUri() |
(*) Akcje oparte na identyfikatorach URI Asystenta Google działają tylko w przypadku firm, które udostępniają Google identyfikatory URI. Więcej informacji o opisywaniu treści multimedialnych w Google znajdziesz w sekcji Media Actions.
Wdrażając interfejsy API przygotowania, możesz skrócić czas oczekiwania na odtwarzanie po wydaniu polecenia głosowego. Aplikacje multimedialne, które chcą skrócić czas oczekiwania na odtwarzanie, mogą wykorzystać dodatkowy czas na rozpoczęcie buforowania treści i przygotowanie odtwarzania multimediów.
Analizowanie zapytań
Gdy użytkownik wyszuka konkretny element multimedialny, np. „Odtwórz jazz w [nazwa aplikacji]” lub „Posłuchaj [tytuł utworu]”, metoda wywołania zwrotnego onPrepareFromSearch() lub onPlayFromSearch()
otrzymuje parametr zapytania i pakiet dodatków.
Aplikacja powinna przeanalizować zapytanie wyszukiwania głosowego i rozpocząć odtwarzanie, wykonując te czynności:
- Użyj pakietu dodatków i ciągu zapytania zwróconych przez wyszukiwanie głosowe, aby filtrować wyniki.
- Utwórz kolejkę odtwarzania na podstawie tych wyników.
- Odtwórz najbardziej odpowiedni element multimedialny z wyników.
Metoda onPlayFromSearch() przyjmuje parametr dodatkowy z bardziej szczegółowymi informacjami z wyszukiwania głosowego. Te dodatkowe funkcje pomagają znaleźć w aplikacji treści audio do odtworzenia.
Jeśli wyniki wyszukiwania nie mogą dostarczyć tych danych, możesz wdrożyć logikę, która będzie analizować nieprzetworzone zapytanie i odtwarzać odpowiednie utwory na jego podstawie.
W systemie operacyjnym Android Automotive i Androidzie Auto obsługiwane są te dodatki:
Poniższy fragment kodu pokazuje, jak zastąpić metodę onPlayFromSearch()
w implementacji MediaSession.Callback
w celu przeanalizowania zapytania wyszukiwania głosowego i rozpoczęcia 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 wdrażania wyszukiwania głosowego w celu odtwarzania treści audio w aplikacji znajdziesz w przykładowej aplikacji Universal Android Music Player.
Obsługa pustych zapytań
Jeśli wywołane zostaną funkcje onPrepare(), onPlay(), onPrepareFromSearch() lub onPlayFromSearch()
bez zapytania, aplikacja multimedialna powinna odtworzyć „bieżące”
multimedia. Jeśli nie ma aktualnie odtwarzanych multimediów, aplikacja powinna spróbować odtworzyć coś, np. utwór z ostatniej playlisty lub losowej kolejki. Asystent korzysta z tych interfejsów API, gdy użytkownik poprosi o „Odtwórz muzykę w [nazwa aplikacji]” bez podawania dodatkowych informacji.
Gdy użytkownik powie „Odtwórz muzykę w [nazwa aplikacji]”, system operacyjny Android Automotive lub Android Auto spróbuje uruchomić aplikację i odtwarzać dźwięk, wywołując metodę onPlayFromSearch() aplikacji. Ponieważ użytkownik nie podał nazwy elementu multimedialnego, metoda onPlayFromSearch()
otrzymuje pusty parametr zapytania. W takich przypadkach aplikacja powinna natychmiast odtworzyć dźwięk, np. utwór z najnowszej playlisty lub losowej kolejki.
Deklarowanie obsługi starszych wersji komend głosowych
W większości przypadków obsługa opisanych powyżej działań związanych z odtwarzaniem zapewnia aplikacji wszystkie potrzebne funkcje odtwarzania. Niektóre systemy wymagają jednak, aby aplikacja zawierała filtr intencji do wyszukiwania. W plikach manifestu aplikacji musisz zadeklarować obsługę tego filtra Intent.
Dodaj ten kod do 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>
Elementy sterujące odtwarzaniem
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, kod powinien umożliwiać te 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ę lub w dół. |
ACTION_SET_CAPTIONING_ENABLED |
onSetCaptioningEnabled(boolean) |
Włączanie i wyłączanie napisów. |
Uwaga:
- Aby polecenia wyszukiwania działały, aplikacja
PlaybackStatemusi być zaktualizowana do wersjistate, position, playback speed, and update time. Gdy stan się zmieni, aplikacja musi wywołać funkcjęsetPlaybackState(). - Aplikacja do multimediów musi też aktualizować metadane sesji multimedialnej. Dzięki temu możesz zadawać pytania takie jak „Jaki utwór jest odtwarzany?”. Aplikacja musi wywoływać funkcję
setMetadata(), gdy zmienią się odpowiednie pola (np. tytuł utworu, wykonawca i nazwa). MediaSession.setRatingType()musi być ustawiony, aby wskazywać typ oceny obsługiwany przez aplikację, a aplikacja musi implementowaćonSetRating(). Jeśli aplikacja nie obsługuje ocen, powinna ustawić typ oceny naRATING_NONE.
Obsługiwane działania głosowe będą się prawdopodobnie różnić w zależności od typu treści.
| Typ treści | Wymagane działania |
|---|---|
| Muzyka |
Musi obsługiwać: odtwarzanie, wstrzymywanie, zatrzymywanie, przechodzenie do następnego i przechodzenie do poprzedniego Zdecydowanie zalecamy obsługę: Seek To |
| Podcast |
Musi obsługiwać: odtwarzanie, wstrzymywanie, zatrzymywanie i przewijanie do Zalecane wsparcie: Przejdź do następnego i Przejdź do poprzedniego |
| Audiobook | Musi obsługiwać: odtwarzanie, wstrzymywanie, zatrzymywanie i przewijanie do |
| Radio | Musi obsługiwać: odtwarzanie, wstrzymywanie i zatrzymywanie |
| Wiadomości | Musi obsługiwać: odtwarzanie, wstrzymywanie, zatrzymywanie, przechodzenie do następnego i przechodzenie do poprzedniego |
| Wideo |
Musi obsługiwać: odtwarzanie, wstrzymywanie, zatrzymywanie, przewijanie do, przewijanie do tyłu i przewijanie do przodu. Zdecydowanie zalecane: Przejdź do następnego i Przejdź do poprzedniego |
Musisz obsługiwać jak najwięcej działań wymienionych powyżej, na ile pozwalają Twoje oferty produktów, ale nadal musisz odpowiednio reagować na inne działania. Jeśli na przykład tylko użytkownicy wersji premium mogą wrócić do poprzedniego elementu, możesz zgłosić błąd, gdy użytkownik wersji bezpłatnej 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 przykładowe zapytania, których możesz użyć podczas testowania wdrożenia:
| Wywołanie zwrotne MediaSession | Fraza „OK Google” do użycia | |
|---|---|---|
onPlay() |
„Odtwórz”. „Wznów”. |
|
onPlayFromSearch()
onPlayFromUri() |
Muzyka |
„Odtwórz muzykę lub utwory w (nazwa aplikacji)”. To puste zapytanie. „Odtwórz (utwór | wykonawcę | album | gatunek | playlistę) w (nazwa aplikacji)”. |
| Radio | „Włącz (częstotliwość | stacja) w (nazwa aplikacji)”. | |
| Audiobook |
„Odtwórz mój audiobook w (nazwa aplikacji)”. „Przeczytaj (audiobook) w (nazwa aplikacji)”. |
|
| Podcasty | „Odtwórz (podcast) w (nazwa aplikacji)”. | |
onPause() |
„Wstrzymaj”. | |
onStop() |
„Zatrzymaj”. | |
onSkipToNext() |
„Następny (utwór | odcinek | ścieżka)”. | |
onSkipToPrevious() |
„Poprzedni (utwór | odcinek | ścieżka)”. | |
onSeekTo() |
„Uruchom ponownie”. „Przewiń do przodu o ## sekund”. „Cofnij o ## minut”. |
|
Nie dotyczy (dbaj o MediaMetadata
aktualność) |
„Co jest odtwarzane?” | |
Błędy
Asystent obsługuje błędy sesji multimedialnej, gdy wystąpią, i informuje o nich użytkowników. Upewnij się, że sesja multimedialna prawidłowo aktualizuje stan transportu i kod błędu w swoim PlaybackState, zgodnie z opisem w artykule Praca z sesją multimedialną. Asystent rozpoznaje wszystkie kody błędów zwracane przez getErrorCode().
Często źle rozpatrywane przypadki
Oto kilka przykładów błędów, które musisz prawidłowo obsługiwać:
- Użytkownik musi się zalogować
- Ustaw kod błędu
PlaybackStatenaERROR_CODE_AUTHENTICATION_EXPIRED. - Ustaw komunikat o błędzie
PlaybackState. - Jeśli jest to wymagane do odtwarzania, ustaw stan
PlaybackStatenaSTATE_ERROR. W przeciwnym razie zachowaj pozostałe wartościPlaybackState.
- Ustaw kod błędu
- Użytkownik prosi o wykonanie niedostępnej czynności.
- Ustaw odpowiedni kod błędu
PlaybackState. Na przykład ustaw wartośćPlaybackStatenaERROR_CODE_NOT_SUPPORTED, jeśli działanie jest nieobsługiwane, lubERROR_CODE_PREMIUM_ACCOUNT_REQUIRED, jeśli działanie jest chronione logowaniem. - Ustaw komunikat o błędzie
PlaybackState. - Pozostałe znaki
PlaybackStatepozostaw bez zmian.
- Ustaw odpowiedni kod błędu
- Prośby użytkowników o treści niedostępne w aplikacji
- Ustaw odpowiedni kod błędu
PlaybackState. Na przykład użyj elementuERROR_CODE_NOT_AVAILABLE_IN_REGION. - Ustaw komunikat o błędzie
PlaybackState. - Ustaw stan
PlaybackSatenaSTATE_ERROR, aby przerwać odtwarzanie. W przeciwnym razie zachowaj pozostałą częśćPlaybackStatebez zmian.
- Ustaw odpowiedni kod błędu
- Użytkownik prosi o treści, dla których nie ma dokładnego dopasowania. Na przykład użytkownik korzystający z bezpłatnej wersji usługi prosi o treści dostępne tylko dla użytkowników wersji premium.
- Zalecamy, aby nie zwracać błędu, tylko priorytetowo traktować wyszukiwanie podobnych treści do odtworzenia. Asystent odczyta najbardziej odpowiednią odpowiedź głosową przed rozpoczęciem odtwarzania.
Odtwarzanie z określonym zamiarem
Asystent może uruchomić aplikację audio lub wideo i rozpocząć odtwarzanie, wysyłając intencję z precyzyjnym linkiem.
Intencja i jej link bezpośredni mogą pochodzić z różnych źródeł:
- Gdy Asystent uruchamia aplikację mobilną, może używać wyszukiwarki Google do pobierania oznaczonych treści, które zawierają działanie „Oglądaj” z linkiem.
- Gdy Asystent uruchamia aplikację TV, powinna ona zawierać dostawcę wyszukiwania w telewizji, aby udostępniać identyfikatory URI treści multimedialnych. Asystent wysyła zapytanie do dostawcy treści, który powinien zwrócić intencję zawierającą identyfikator URI precyzyjnego linku i opcjonalne działanie.
Jeśli zapytanie zwróci działanie w intencji, Asystent wyśle to działanie i identyfikator URI z powrotem do Twojej aplikacji. Jeśli dostawca nie określił działania, Asystent doda do intencji wartość
ACTION_VIEW.
Asystent dodaje dodatkowy parametr EXTRA_START_PLAYBACK z wartością true
do intencji wysyłanej do aplikacji. Aplikacja powinna rozpocząć odtwarzanie, gdy otrzyma intencję z parametrem EXTRA_START_PLAYBACK.
Obsługa intencji podczas aktywności
Użytkownicy mogą poprosić Asystenta o włączenie czegoś, gdy aplikacja nadal odtwarza treści z poprzedniego żądania. Oznacza to, że aplikacja może otrzymywać nowe intencje rozpoczęcia odtwarzania, gdy jej działanie odtwarzania jest już uruchomione i aktywne.
Aktywności, które obsługują intencje z precyzyjnymi linkami, powinny zastępować
onNewIntent()
obsługę nowych żądań.
Podczas rozpoczynania odtwarzania Asystent może dodać do intencji wysyłanej do aplikacji dodatkowe flagi. W szczególności może dodać flagę FLAG_ACTIVITY_CLEAR_TOP lub FLAG_ACTIVITY_NEW_TASK albo obie te flagi. Chociaż Twój kod nie musi obsługiwać tych flag, system Android na nie reaguje.
Może to wpłynąć na działanie aplikacji, gdy podczas odtwarzania poprzedniego identyfikatora URI nadejdzie drugie żądanie odtwarzania z nowym identyfikatorem URI. Warto sprawdzić, jak aplikacja zachowuje się w takiej sytuacji. Aby zasymulować tę sytuację, możesz użyć narzędzia wiersza poleceń adb (stała 0x14000000 to bitowa operacja OR na 2 flagach):
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
umożliwiający połączenia z Asystentem, Asystent może uruchomić aplikację, komunikując się z media sessionusługi.
Usługa przeglądarki multimediów nigdy nie powinna uruchamiać aktywności.
Asystent uruchomi Twoją aktywność na podstawie PendingIntent, którą określisz za pomocą funkcji setSessionActivity().
Pamiętaj, aby ustawić MediaSession.Token podczas inicjowania usługi przeglądarki multimediów. Pamiętaj, aby zawsze ustawiać obsługiwane działania odtwarzania, w tym podczas inicjowania. Asystent oczekuje, że aplikacja multimedialna ustawi działania związane z odtwarzaniem, zanim Asystent wyśle pierwsze polecenie odtwarzania.
Aby rozpocząć od usługi, Asystent implementuje interfejsy API klienta przeglądarki multimediów. Wykonuje wywołania TransportControls, które wywołują zwrotne wywołania PLAY w sesji multimedialnej aplikacji.
Poniższy diagram przedstawia kolejność wywołań generowanych przez Asystenta i odpowiednich wywołań zwrotnych sesji multimedialnej. (Wywołania zwrotne prepare są wysyłane tylko wtedy, gdy aplikacja je obsługuje). Wszystkie wywołania są asynchroniczne. Asystent nie czeka na odpowiedź z aplikacji.

Gdy użytkownik wyda polecenie głosowe dotyczące odtwarzania, Asystent odpowie krótkim komunikatem. Gdy komunikat się zakończy, Asystent wyda polecenie PLAY. Nie czeka na żaden konkretny stan odtwarzania.
Jeśli Twoja aplikacja obsługuje ACTION_PREPARE_*, Asystent wywołuje działanie PREPARE przed rozpoczęciem ogłoszenia.
Łączenie się z usługą MediaBrowserService
Aby usługa mogła uruchomić aplikację, Asystent musi mieć możliwość połączenia się z usługą MediaBrowserService aplikacji i pobrania jej tokena MediaSession. Żądania połączenia są obsługiwane w metodzie usługi
onGetRoot(). Żądania można obsługiwać na 2 sposoby:
- Akceptowanie wszystkich próśb o połączenie
- Akceptowanie próśb o połączenie tylko z aplikacji Asystent
Akceptowanie wszystkich próśb o połączenie
Aby umożliwić Asystentowi wysyłanie poleceń do sesji multimedialnej, musisz zwrócić BrowserRoot. Najprostszym sposobem jest zezwolenie wszystkim aplikacjom MediaBrowser na łączenie się z usługą MediaBrowserService. Musisz zwrócić wartość BrowserRoot inną niż null. Oto odpowiedni kod z uniwersalnego odtwarzacza muzyki:
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, sprawdzając nazwę pakietu i podpis. Aplikacja otrzyma nazwę pakietu w metodzie onGetRoot usługi MediaBrowserService. Aby umożliwić Asystentowi wysyłanie poleceń do sesji multimedialnej, musisz zwrócić BrowserRoot. Przykładowa aplikacja Universal Music Player zawiera listę znanych nazw pakietów i sygnatur. Poniżej znajdziesz nazwy pakietów i sygnatury 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>