Android Auto e Android Automotive OS (AAOS) chiamano il servizio di esplorazione dei contenuti multimediali della tua app per scoprire quali contenuti sono disponibili. Per supportare questa funzionalità, implementa questi due metodi nel servizio di esplorazione dei contenuti multimediali.
Implementare onGetRoot
Il metodo onGetRoot del tuo servizio restituisce informazioni sul nodo radice
della gerarchia dei contenuti. Android Auto e AAOS utilizzano questo nodo radice
per richiedere il resto dei contenuti utilizzando il onLoadChildren
metodo. Questo snippet di codice mostra un'implementazione del metodo 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);
}
Per un esempio dettagliato di questo metodo, consulta onGetRoot nell'app di esempio Universal
Android Music Player su GitHub.
Aggiungere la convalida del pacchetto
Quando viene effettuata una chiamata al metodo onGetRoot del tuo servizio, il pacchetto chiamante passa le informazioni identitarie al tuo servizio. Il tuo servizio può utilizzare queste informazioni per decidere se il pacchetto può accedere ai tuoi contenuti.
Ad esempio, puoi limitare l'accesso ai contenuti della tua app a un elenco di pacchetti approvati:
- Confronta
clientPackageNamecon la tua lista consentita. - Verifica il certificato utilizzato per firmare l'APK del pacchetto.
Se non è possibile verificare il pacchetto, restituisci null per negare l'accesso ai tuoi contenuti.
Per fornire alle app di sistema, come Android Auto e AAOS, l'accesso ai tuoi contenuti, il tuo servizio deve restituire un BrowserRoot non nullo quando queste app di sistema chiamano il metodo onGetRoot.
La firma dell'app di sistema AAOS varia in base alla marca e al modello di un'auto. Assicurati di consentire le connessioni da tutte le app di sistema per supportare AAOS.
Questo snippet di codice mostra come il tuo servizio può verificare che il pacchetto chiamante sia un'app di sistema:
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
}
Questo snippet di codice è un estratto della classe PackageValidator nell'app di esempio
Universal Android Music Player su GitHub. Consulta questa classe per un esempio più dettagliato di come implementare la convalida del pacchetto per il metodo onGetRoot del tuo servizio.
Oltre a consentire le app di sistema, devi consentire a Google Assistant di connettersi al tuo MediaBrowserService. Google Assistant utilizza nomi di pacchetti diversi
per le sue app per dispositivi mobili e AAOS.
Implementare onLoadChildren
Dopo aver ricevuto l'oggetto del nodo radice, Android Auto e AAOS
creano un menu di primo livello chiamando onLoadChildren sull'oggetto del nodo radice
per ottenere i relativi discendenti. Le app client creano sottomenu chiamando lo stesso metodo utilizzando gli oggetti dei nodi discendenti.
Ogni nodo della gerarchia dei contenuti è rappresentato da un
MediaBrowserCompat.MediaItem oggetto. Ognuno di questi elementi multimediali è identificato da una stringa ID univoca. Le app client trattano queste stringhe ID come token opachi.
Quando un'app client vuole passare a un sottomenu o riprodurre un elemento multimediale, passa il token. La tua app è responsabile dell'associazione del token all'elemento multimediale appropriato.
Questo snippet di codice mostra un'implementazione di 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);
}
Per visualizzare un esempio di questo metodo, consulta onLoadChildren nell'
app di esempio Universal Android Music Player su GitHub.
Strutturare il menu principale
Android Auto e Android Automotive OS hanno vincoli specifici sulla struttura del menu principale. Questi vengono comunicati a MediaBrowserService tramite suggerimenti radice, che possono essere letti tramite l'argomento Bundle passato a onGetRoot(). Se seguiti questi suggerimenti, il sistema visualizza i contenuti radice come schede di navigazione. Se non segui questi suggerimenti, alcuni contenuti radice potrebbero essere eliminati o resi meno rilevabili dal sistema.

Figura 1. Contenuti radice visualizzati come schede di navigazione.
Applicando questi suggerimenti, il sistema visualizza i contenuti radice come schede di navigazione. Se non applichi questi suggerimenti, alcuni contenuti radice potrebbero essere eliminati o resi meno rilevabili. Questi suggerimenti vengono trasmessi:
Limite al numero di figli radice: nella maggior parte dei casi, questo numero è quattro, il che significa che possono essere visualizzate solo quattro (o meno) schede.
Flag supportati sui figli radice: questo valore dovrebbe essere
MediaItem#FLAG_BROWSABLE, il che significa che solo gli elementi navigabili (non riproducibili) possono essere visualizzati come schede.Limite al numero di azioni di navigazione personalizzate: controlla quante azioni di navigazione personalizzate sono supportate.
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...
}
Puoi scegliere di ramificare la logica per la struttura della gerarchia dei contenuti in base ai valori di questi suggerimenti, in particolare se la gerarchia varia tra le integrazioni MediaBrowser al di fuori di Android Auto e AAOS.
Ad esempio, se in genere mostri un elemento riproducibile radice, potresti volerlo nidificare sotto un elemento navigabile radice a causa del valore del suggerimento dei flag supportati.
Oltre ai suggerimenti radice, utilizza queste linee guida per eseguire il rendering ottimale delle schede:
Icone monocromatiche (preferibilmente bianche) per ogni elemento della scheda
Etichette brevi e significative per ogni elemento della scheda (le etichette brevi riducono le probabilità che le etichette vengano troncate)