Android Auto i system operacyjny Android Automotive (AAOS) wywołują usługę przeglądarki multimediów w Twojej aplikacji, aby sprawdzić, jakie treści są dostępne. Aby to umożliwić, w usłudze przeglądarki multimediów musisz zaimplementować te 2 metody.
Implementacja 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 wysyłania żądań dotyczących 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 tej metody znajdziesz w onGetRoot w przykładowej aplikacji Universal Android Music Player na GitHubie.
Dodawanie weryfikacji pakietu
Gdy połączenie jest wykonywane do metody onGetRoot usługi, pakiet wywołujący przekazuje do usługi informacje umożliwiające identyfikację. Usługa może wykorzystać te informacje, aby określić, czy dany pakiet może uzyskać dostęp do Twoich treści.
Możesz na przykład ograniczyć dostęp do treści w aplikacji do listy zatwierdzonych pakietów:
- Porównaj
clientPackageNamez listą dozwolonych. - Sprawdź certyfikat użyty do podpisania pliku APK pakietu.
Jeśli nie możesz zweryfikować przesyłki, kliknij null, aby odmówić dostępu do treści.
Aby zapewnić aplikacjom systemowym, takim jak Android Auto i AAOS, dostęp do Twoich 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 pakiet wywołujący 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 pochodzi z klasy PackageValidator w przykładowej aplikacji Universal Android Music Player na GitHubie. Więcej szczegółowych informacji o tym, jak wdrożyć weryfikację pakietu w przypadku metody onGetRoot usługi, znajdziesz w tej klasie.
Oprócz zezwolenia na korzystanie z aplikacji systemowych musisz zezwolić Asystentowi Google na łączenie się z Twoim MediaBrowserService. Asystent Google używa różnych nazw pakietów w przypadku aplikacji mobilnych i aplikacji na AAOS.
Implementowanie funkcji onLoadChildren
Po otrzymaniu obiektu węzła głównego Android Auto i AAOS tworzą menu najwyższego poziomu, wywołując 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 obiekt MediaBrowserCompat.MediaItem. Każdy z tych elementów multimedialnych jest identyfikowany za pomocą unikalnego ciągu znaków. Aplikacje klienckie traktują te ciągi identyfikatorów jako nieprzezroczyste tokeny.
Gdy aplikacja kliencka chce przejść do podmenu lub odtworzyć element multimedialny, przekazuje token. Aplikacja jest odpowiedzialna za powiązanie tokena z odpowiednim elementem multimedialnym.
Ten fragment kodu pokazuje implementację 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 tej metody znajdziesz w onLoadChildren w przykładowej aplikacji Universal Android Music Player w 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 MediaBrowserServiceza pomocą wskazówek dotyczących katalogu głównego, które można odczytać za pomocą argumentu Bundle przekazanego do onGetRoot(). Jeśli zastosujesz się do tych wskazówek, system wyświetli treści główne jako karty nawigacyjne. Jeśli nie będziesz przestrzegać tych wskazówek, niektóre treści główne mogą zostać pominięte lub system może utrudnić ich wykrywanie.

Rysunek 1. Treści główne wyświetlane jako karty nawigacyjne.
Dzięki zastosowaniu tych wskazówek system 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 stać się trudniejsze do znalezienia. Wskazówki te są przesyłane:
Limit liczby elementów podrzędnych najwyższego poziomu: 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 w przypadku elementów podrzędnych głównego węzła: oczekuj, że ta wartość będzie wynosić
MediaItem#FLAG_BROWSABLE, co oznacza, że jako karty mogą być wyświetlane tylko elementy, które można przeglądać (a nie odtwarzać).Limit liczby niestandardowych działań związanych z przeglądaniem: sprawdź, ile niestandardowych działań związanych z przeglądaniem 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 przypadku MediaBrowserintegracji poza Androidem Auto i AAOS.
Jeśli na przykład zwykle wyświetlasz element grywalny najwyższego poziomu, możesz zechcieć zagnieździć go pod elementem przeglądanym najwyższego poziomu ze względu na wartość wskazówki dotyczącej obsługiwanych flag.
Oprócz wskazówek dotyczących domeny głównej stosuj te wytyczne, aby optymalnie renderować karty:
Monochromatyczne (najlepiej białe) ikony każdego elementu karty
Krótkie i zrozumiałe etykiety poszczególnych elementów karty (krótkie etykiety zmniejszają prawdopodobieństwo obcięcia etykiet).