Android Auto i Android Automotive OS (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, nu
ll)
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 nawiązywane z metodą onGetRoot
usługi, pakiet wywołujący przekazuje do usługi informacje identyfikacyjne. Usługa może wykorzystać te informacje, aby określić, czy dany pakiet ma 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
clientPackageName
z listą dozwolonych. - Sprawdź certyfikat użyty do podpisania pliku APK pakietu.
Jeśli nie można zweryfikować pakietu, 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 osobnych nazw pakietów
na telefonie, w tym w Androidzie Auto i Androidzie AAOS.
Implementowanie funkcji 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 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 na GitHubie.
Struktura menu głównego
Android Auto i Android Automotive OS mają określone ograniczenia dotyczące struktury menu głównego. Są one przekazywane do MediaBrowserService
za 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, system może pominąć niektóre treści główne lub sprawić, że będą trudniej dostępne.
Rysunek 1. Treści główne wyświetlane jako karty nawigacyjne.
Po 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ę mniej widoczne. 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 w katalogu głównym: oczekuj, że ta wartość będzie wynosić
MediaItem#FLAG_BROWSABLE
, co oznacza, że jako karty można wyświetlać tylko elementy, które można przeglądać (nie można ich 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 MediaBrowser
integracji 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 dla każdego elementu karty (krótkie etykiety zmniejszają prawdopodobieństwo, że zostaną one obcięte);