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 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 metodo onLoadChildren
. 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, 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)
;
}
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 servizio, il pacchetto chiamante
trasmette le informazioni identificative al 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
clientPackageName
con la tua lista consentita. - Verifica il certificato utilizzato per firmare l'APK per il pacchetto.
Se il pacchetto non può essere verificato, premi 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 valore non nullo
BrowserRoot
quando queste app di sistema chiamano il metodo onGetRoot
.
La firma dell'app di sistema AAOS varia a seconda della marca e del 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 dei pacchetti per il metodo onGetRoot
del tuo servizio.
Oltre a consentire le app di sistema, devi consentire all'Assistente Google di connettersi al tuo MediaBrowserService
. L'Assistente Google utilizza nomi di pacchetti separati
per lo smartphone, che include Android Auto Android AAOS.
Implementare onLoadChildren
Dopo aver ricevuto l'oggetto nodo radice, Android Auto e AAOS
creano un menu di primo livello chiamando onLoadChildren
sull'oggetto nodo radice
per ottenere i relativi discendenti. Le app client creano i sottomenu chiamando questo stesso metodo
utilizzando gli oggetti nodo discendenti.
Ogni nodo della gerarchia dei contenuti è rappresentato da un oggetto
MediaBrowserCompat.MediaItem
. Ciascuno 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 della radice, che possono essere letti tramite l'argomento Bundle passato a
onGetRoot()
. Se seguiti, questi suggerimenti consentono al sistema di visualizzare i contenuti
principali come schede di navigazione. Se non segui questi suggerimenti, alcuni contenuti
principali potrebbero essere eliminati o resi meno rilevabili dal sistema.
Figura 1. Contenuti di primo livello visualizzati come schede di navigazione.
Se applichi questi suggerimenti, il sistema visualizza i contenuti principali come schede di navigazione. Se non applichi questi suggerimenti, alcuni contenuti principali potrebbero essere eliminati o resi meno rilevabili. Questi suggerimenti vengono trasmessi:
Limite al numero di elementi secondari principali: nella maggior parte dei casi, questo numero è quattro, il che significa che possono essere visualizzate solo quattro schede (o meno).
Flag supportati per i figli della radice: prevedi che questo valore sia
MediaItem#FLAG_BROWSABLE
, il che significa che solo gli elementi sfogliabili (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 di solito mostri un elemento riproducibile principale, potresti volerlo nidificare in un elemento principale sfogliabile a causa del valore del suggerimento dei flag supportati.
Oltre ai suggerimenti per la 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 vengano troncate)