Android Auto i system operacyjny Android Automotive (AAOS) wywołują usługę przeglądarki multimediów aplikacji, aby sprawdzić, jakie treści są dostępne. Aby to umożliwić, zaimplementuj w usłudze przeglądarki multimediów te 2 metody.
Implementowanie metody onGetRoot
Metoda onGetRoot usługi zwraca informacje o węźle głównym
hierarchii treści. Android Auto i AAOS używają tego węzła głównego do żądania pozostałych treści za pomocą metody.onLoadChildren Ten fragment kodu pokazuje implementację metody onGetRoot:
Kotlin
override fun onGetRoot(
clientPackageName: String,
clientUid: Int,
rootHints: Bundle?
): BrowserRoot? =
// Verify that the specified package is allowed to access your
// content. You'll need to write your own logic to do this.
if (!isValid(clientPackageName, clientUid)) {
// If the request comes from an untrusted package, return null.
// No further calls will be made to other media browsing methods.
null
} else MediaBrowserServiceCompat.BrowserRoot(MY_MEDIA_ROOT_ID, null)
Java
@Override
public BrowserRoot onGetRoot(String clientPackageName, int clientUid,
Bundle rootHints) {
// Verify that the specified package is allowed to access your
// content. You'll need to write your own logic to do this.
if (!isValid(clientPackageName, clientUid)) {
// If the request comes from an untrusted package, return null.
// No further calls will be made to other media browsing methods.
return null;
}
return new MediaBrowserServiceCompat.BrowserRoot(MY_MEDIA_ROOT_ID, null);
}
Szczegółowy przykład użycia tej metody znajdziesz w metodzie onGetRoot w przykładowej aplikacji Universal
Android Music Player na GitHubie.
Dodawanie weryfikacji pakietu
Gdy wywoływana jest metoda onGetRoot usługi, wywołujący pakiet przekazuje do usługi informacje umożliwiające identyfikację. Usługa może użyć tych informacji, aby określić, czy dany pakiet może uzyskać dostęp do treści.
Możesz na przykład ograniczyć dostęp do treści aplikacji do listy zatwierdzonych pakietów:
- Porównaj
clientPackageNamez listą dozwolonych. - Sprawdź certyfikat użyty do podpisania pliku APK pakietu.
Jeśli nie można zweryfikować pakietu, zwróć wartość null, aby odmówić dostępu do treści.
Aby zapewnić aplikacjom systemowym, takim jak Android Auto i AAOS, dostęp do treści, usługa musi zwracać wartość inną niż null BrowserRoot, gdy te aplikacje systemowe wywołują metodę onGetRoot.
Podpis aplikacji systemowej AAOS różni się w zależności od marki i modelu samochodu. Aby obsługiwać AAOS, zezwól na połączenia ze wszystkich aplikacji systemowych.
Ten fragment kodu pokazuje, jak usługa może sprawdzić, czy wywołujący pakiet jest aplikacją systemową:
fun isKnownCaller(
callingPackage: String,
callingUid: Int
): Boolean {
...
val isCallerKnown = when {
// If the system is making the call, allow it.
callingUid == Process.SYSTEM_UID -> true
// If the app was signed by the same certificate as the platform
// itself, also allow it.
callerSignature == platformSignature -> true
// ... more cases
}
return isCallerKnown
}
Ten fragment kodu jest fragmentem klasy PackageValidator w
przykładowej aplikacji Universal Android Music Player na GitHubie. Więcej informacji o tym, jak zaimplementować weryfikację pakietu w metodzie onGetRoot usługi, znajdziesz w tej klasie.
Oprócz zezwolenia na dostęp aplikacjom systemowym musisz też zezwolić Gemini lub Asystentowi Google na łączenie się z usługą MediaBrowserService. Asystent Google używa
różnych nazw pakietów w przypadku aplikacji mobilnych i aplikacji AAOS.
Implementowanie metody onLoadChildren
Po otrzymaniu obiektu węzła głównego Android Auto i AAOS
tworzą menu najwyższego poziomu, wywołując metodę onLoadChildren w obiekcie węzła głównego
aby uzyskać jego elementy podrzędne. Aplikacje klienckie tworzą podmenu, wywołując tę samą metodę za pomocą obiektów węzłów podrzędnych.
Każdy węzeł w hierarchii treści jest reprezentowany przez
MediaBrowserCompat.MediaItem obiekt. Każdy z tych elementów multimedialnych jest identyfikowany przez unikalny ciąg znaków ID. Aplikacje klienckie traktują te ciągi znaków ID jako nieprzezroczyste tokeny.
Gdy aplikacja kliencka chce przejść do podmenu lub odtworzyć element multimedialny, przekazuje token. Twoja aplikacja jest odpowiedzialna za powiązanie tokena z odpowiednim elementem multimedialnym.
Ten fragment kodu pokazuje implementację metody onLoadChildren:
Kotlin
override fun onLoadChildren(
parentMediaId: String,
result: Result<List<MediaBrowserCompat.MediaItem>>
) {
// Assume for example that the music catalog is already loaded/cached.
val mediaItems: MutableList<MediaBrowserCompat.MediaItem> = mutableListOf()
// Check if this is the root menu:
if (MY_MEDIA_ROOT_ID == parentMediaId) {
// Build the MediaItem objects for the top level
// and put them in the mediaItems list.
} else {
// Examine the passed parentMediaId to see which submenu we're at
// and put the descendants of that menu in the mediaItems list.
}
result.sendResult(mediaItems)
}
Java
@Override
public void onLoadChildren(final String parentMediaId,
final Result<List<MediaBrowserCompat.MediaItem>> result) {
// Assume for example that the music catalog is already loaded/cached.
List<MediaBrowserCompat.MediaItem> mediaItems = new ArrayList<>();
// Check if this is the root menu:
if (MY_MEDIA_ROOT_ID.equals(parentMediaId)) {
// Build the MediaItem objects for the top level
// and put them in the mediaItems list.
} else {
// Examine the passed parentMediaId to see which submenu we're at
// and put the descendants of that menu in the mediaItems list.
}
result.sendResult(mediaItems);
}
Przykład użycia tej metody znajdziesz w metodzie onLoadChildren w
przykładowej aplikacji Universal Android Music Player na GitHubie.
Struktura menu głównego
Android Auto i system operacyjny Android Automotive mają określone ograniczenia dotyczące struktury menu głównego. Są one przekazywane do usługi MediaBrowserService za pomocą wskazówek dotyczących węzła głównego, które można odczytać za pomocą argumentu Bundle przekazanego do metody onGetRoot(). Jeśli będziesz się ich trzymać, system będzie wyświetlać treści główne jako karty nawigacyjne. Jeśli nie będziesz się ich trzymać, niektóre treści główne mogą zostać pominięte lub trudniej dostępne dla systemu.

Rysunek 1. Treści główne wyświetlane jako karty nawigacyjne.
Jeśli zastosujesz te wskazówki, system będzie wyświetlać treści główne jako karty nawigacyjne. Jeśli nie zastosujesz tych wskazówek, niektóre treści główne mogą zostać pominięte lub trudniej dostępne. Te wskazówki są przesyłane:
Limit liczby elementów podrzędnych węzła głównego: w większości przypadków ta liczba wynosi 4, co oznacza, że można wyświetlić tylko 4 karty (lub mniej).
Obsługiwane flagi elementów podrzędnych węzła głównego: ta wartość powinna być równa
MediaItem#FLAG_BROWSABLE, co oznacza, że jako karty można wyświetlać tylko elementy, które można przeglądać (a nie odtwarzać).Limit liczby niestandardowych działań przeglądania: sprawdź, ile niestandardowych działań przeglądania jest obsługiwanych.
Kotlin
import androidx.media.utils.MediaConstants
override fun onGetRoot(
clientPackageName: String,
clientUid: Int,
rootHints: Bundle
): BrowserRoot {
val maximumRootChildLimit = rootHints.getInt(
MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_LIMIT,
/* defaultValue= */ 4)
val supportedRootChildFlags = rootHints.getInt(
MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_SUPPORTED_FLAGS,
/* defaultValue= */ MediaItem.FLAG_BROWSABLE)
// Rest of method...
}
Java
import androidx.media.utils.MediaConstants;
// Later, in your MediaBrowserServiceCompat.
@Override
public BrowserRoot onGetRoot(
String clientPackageName, int clientUid, Bundle rootHints) {
int maximumRootChildLimit = rootHints.getInt(
MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_LIMIT,
/* defaultValue= */ 4);
int supportedRootChildFlags = rootHints.getInt(
MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_SUPPORTED_FLAGS,
/* defaultValue= */ MediaItem.FLAG_BROWSABLE);
// Rest of method...
}
Możesz rozgałęzić logikę struktury hierarchii treści na podstawie wartości tych wskazówek, zwłaszcza jeśli hierarchia różni się w zależności od integracji MediaBrowser poza Androidem Auto i AAOS.
Jeśli na przykład zwykle wyświetlasz element główny, który można odtworzyć, możesz go zagnieździć pod elementem głównym, który można przeglądać, ze względu na wartość wskazówki dotyczącej obsługiwanych flag.
Oprócz wskazówek dotyczących węzła głównego stosuj te wytyczne, aby optymalnie renderować karty:
Ikony monochromatyczne (najlepiej białe) dla każdego elementu karty.
Krótkie i znaczące etykiety dla każdego elementu karty (krótkie etykiety zmniejszają prawdopodobieństwo, że zostaną obcięte).