Android Auto und Android Automotive OS (AAOS) rufen den Media Browser-Dienst Ihrer App auf, um herauszufinden, welche Inhalte verfügbar sind. Dazu implementieren Sie diese beiden Methoden in Ihrem Media Browser-Dienst.
onGetRoot implementieren
Die Methode onGetRoot Ihres Dienstes gibt Informationen zum Stammknoten
Ihrer Inhaltshierarchie zurück. Android Auto und AAOS verwenden diesen Stamm
knoten, um den Rest Ihrer Inhalte mit der onLoadChildren
Methode anzufordern. Dieser Code-Snippet zeigt eine Implementierung der Methode 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);
}
Ein detailliertes Beispiel für diese Methode finden Sie unter onGetRoot in der Universal
Android Music Player Beispiel-App auf GitHub.
Paketvalidierung hinzufügen
Wenn ein Aufruf an die Methode onGetRoot Ihres Dienstes erfolgt, übergibt das aufrufende
Paket Identifikationsinformationen an Ihren Dienst. Ihr Dienst kann anhand dieser Informationen entscheiden, ob dieses Paket auf Ihre Inhalte zugreifen darf.
Sie können beispielsweise den Zugriff auf die Inhalte Ihrer App auf eine Liste genehmigter Pakete beschränken:
- Vergleichen Sie
clientPackageNamemit Ihrer Zulassungsliste. - Prüfen Sie das Zertifikat, mit dem die APK für das Paket signiert wurde.
Wenn das Paket nicht verifiziert werden kann, geben Sie null zurück, um den Zugriff auf Ihre Inhalte zu verweigern.
Damit System-Apps wie Android Auto und AAOS auf Ihre Inhalte zugreifen können, muss Ihr Dienst ein BrowserRoot zurückgeben, das nicht null ist, wenn diese System-Apps die Methode onGetRoot aufrufen.
Die Signatur der AAOS-System-App variiert je nach Marke und Modell eines Autos. Achten Sie darauf, Verbindungen von allen System-Apps zuzulassen, um AAOS zu unterstützen.
Dieser Code-Snippet zeigt, wie Ihr Dienst prüfen kann, ob das aufrufende Paket eine System-App ist:
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
}
Dieser Code-Snippet ist ein Auszug aus der PackageValidator Klasse in der
Beispiel-App Universal Android Music Player auf GitHub. In dieser Klasse finden Sie ein detaillierteres Beispiel dafür, wie Sie die Paketvalidierung für die Methode onGetRoot Ihres Dienstes implementieren.
Neben System-Apps müssen Sie auch Google Assistant erlauben, eine Verbindung zu Ihrem MediaBrowserService herzustellen. Google Assistant verwendet unterschiedliche Paketnamen
für seine mobilen Apps und AAOS-Apps.
onLoadChildren implementieren
Nachdem Android Auto und AAOS Ihr Stammknotenobjekt erhalten haben,
erstellen sie ein Menü der obersten Ebene, indem sie onLoadChildren für das Stammknotenobjekt aufrufen,
um seine Nachfolger abzurufen. Client-Apps erstellen Untermenüs, indem sie dieselbe Methode mit Nachfolgerknotenobjekten aufrufen.
Jeder Knoten in Ihrer Inhaltshierarchie wird durch ein
MediaBrowserCompat.MediaItem-Objekt dargestellt. Jedes dieser MediaItems wird durch einen eindeutigen ID-String identifiziert. Client-Apps behandeln diese ID-Strings als undurchsichtige Tokens.
Wenn eine Client-App zu einem Untermenü wechseln oder ein MediaItem abspielen möchte, übergibt sie das Token. Ihre App ist dafür verantwortlich, das Token dem entsprechenden MediaItem zuzuordnen.
Dieser Code-Snippet zeigt eine Implementierung von 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);
}
Ein Beispiel für diese Methode finden Sie unter onLoadChildren in der
Beispiel-App Universal Android Music Player auf GitHub.
Struktur des Stammmenüs
Android Auto und Android Automotive OS haben bestimmte Einschränkungen hinsichtlich der Struktur des Stammmenüs. Diese werden dem MediaBrowserService über Stammhinweise mitgeteilt, die über das Bundle-Argument gelesen werden können, das an onGetRoot() übergeben wird. Wenn diese Hinweise befolgt werden, kann das System die Stamm-Inhalte als Navigationstabs anzeigen. Wenn Sie diese Hinweise nicht befolgen, werden einige Stamm-Inhalte möglicherweise vom System entfernt oder weniger auffindbar gemacht.

Abbildung 1 : Stamm-Inhalte, die als Navigationstabs angezeigt werden.
Wenn Sie diese Hinweise anwenden, zeigt das System die Stamm-Inhalte als Navigationstabs an. Wenn Sie diese Hinweise nicht anwenden, werden einige Stamm-Inhalte möglicherweise entfernt oder weniger auffindbar gemacht. Diese Hinweise werden übertragen:
Beschränkung der Anzahl der Stamm-Nachfolger: In den meisten Fällen ist diese Zahl vier. Das bedeutet, dass nur vier oder weniger Tabs angezeigt werden können.
Unterstützte Flags für die Stamm-Nachfolger: Dieser Wert sollte
MediaItem#FLAG_BROWSABLEsein. Das bedeutet, dass nur durchsuchbare Elemente (keine abspielbaren Elemente) als Tabs angezeigt werden können.Beschränkung der Anzahl der benutzerdefinierten Suchaktionen: Prüfen Sie, wie viele benutzerdefinierte Suchaktionen unterstützt werden.
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...
}
Sie können die Logik für die Struktur Ihrer Inhaltshierarchie basierend auf den Werten dieser Hinweise verzweigen, insbesondere wenn sich Ihre Hierarchie zwischen MediaBrowser-Integrationen außerhalb von Android Auto und AAOS unterscheidet.
Wenn Sie beispielsweise normalerweise ein abspielbares Stamm-Element anzeigen, sollten Sie es aufgrund des Werts des Hinweises zu den unterstützten Flags stattdessen unter einem durchsuchbaren Stamm-Element verschachteln.
Neben Stammhinweisen können Sie diese Richtlinien verwenden, um Tabs optimal zu rendern:
Monochrome (vorzugsweise weiße) Symbole für jedes Tab-Element
Kurze und aussagekräftige Labels für jedes Tab-Element (kurze Labels verringern die Wahrscheinlichkeit, dass Labels abgeschnitten werden)