Mit Android Auto und Android Automotive OS kannst du die Inhalte deiner Medien-App in ihrem Auto nutzen. Eine Medien-App für Autos muss einen Medienbrowserdienst bieten damit Android Auto und Android Automotive OS oder eine andere App Ihre Inhalte finden und anzeigen kann.
In diesem Leitfaden wird davon ausgegangen, dass Sie bereits eine Medien-App haben, die Audioinhalte auf einem und dass Ihre Medien-App der Medien-App von Android entspricht Architektur.
In diesem Leitfaden werden die erforderlichen Komponenten eines MediaBrowserService
und
MediaSession
, die deine App für Android Auto oder Android benötigt
Automotive OS Nachdem Sie die Kernmedieninfrastruktur fertiggestellt haben,
Unterstützung für Android Auto und Unterstützung für
Android Automotive OS zu Ihren Medien
Hinweis
- Lesen Sie die Dokumentation zur Android Media API.
- Lesen Sie den Hilfeartikel Medien-Apps erstellen. für Designberatung.
- Sehen Sie sich die in diesem Abschnitt aufgeführten wichtigsten Begriffe und Konzepte noch einmal an.
Wichtige Begriffe und Konzepte
- Medienbrowserdienst
- Ein Android-Dienst, der von Ihrer Medien-App implementiert und den
MediaBrowserServiceCompat
der API erstellen. Deine App verwendet diesen Dienst, um seine Inhalte verfügbar zu machen. - Medienbrowser
- Eine API, die von Medien-Apps verwendet wird, um Medienbrowserdienste zu erkennen und für ihre Inhalte. Android Auto und Android Automotive OS nutzen einen Medienbrowser, um den Medienbrowser Ihrer App zu finden.
- Medienelement
Der Medienbrowser organisiert seinen Inhalt in einer Baumstruktur von
MediaItem
. Objekte. Ein Medienelement kann eines oder beide der folgenden Flags haben:FLAG_PLAYABLE
: Gibt an, dass das Element ein Blatt im Inhaltsbaum ist. Das Element steht für einen einzelnen Soundstream, z. B. einen Titel auf einem Album, in einem Hörbuch oder in einer Folge eines Podcasts.FLAG_BROWSABLE
: Gibt an, dass das Element ein Knoten im Inhaltsbaum ist und hat Kinder. Das Element steht beispielsweise für ein Album und die untergeordneten Elemente sind die Songs auf dem Album.
Ein Medienelement, das sowohl blätterbar als auch abspielbar ist, agiert wie eine Playlist. Sie können wählen Sie das Element selbst aus, um alle seine untergeordneten Elemente wiederzugeben, oder suchen Sie in den Kinder.
- Fahrzeugoptimiert
Eine Aktivität für eine Android Automotive OS-App, die die Android Automotive OS-Designrichtlinien Die Oberfläche für diese Aktivitäten wird nicht von Android Automotive OS gezeichnet. müssen Sie sicherstellen, dass Ihre App den Designrichtlinien entspricht. In der Regel bietet größere Tippziele und Schriftgrößen, Unterstützung für Tag- und Nachtmodi sowie höhere Kontrastverhältnisse.
Fahrzeugoptimierte Benutzeroberflächen dürfen nur angezeigt werden, wenn Einschränkungen für die Nutzerfreundlichkeit sind nicht in Kraft, weil diese Benutzeroberflächen erfordern möglicherweise besondere Aufmerksamkeit oder Interaktion der Nutzenden. CUXR sind nicht aktiv, wenn das Fahrzeug steht oder geparkt ist, aber immer aktiv sind. wenn das Auto in Bewegung ist.
Sie müssen keine Aktivitäten für Android Auto entwerfen, und erstellt mithilfe der Informationen aus der Medienbrowserdienst.
Manifestdateien Ihrer App konfigurieren
Bevor Sie den Medienbrowserdienst erstellen können, müssen Sie Ihren den Manifestdateien der App.
Medienbrowserdienst deklarieren
Sowohl Android Auto als auch Android Automotive OS stellen über Ihr Medienbrowserdienst zum Durchsuchen von Medieninhalten. Medien deklarieren Browserdienst in deinem Manifest, um Android Auto und Android Automotive OS um den Dienst zu finden und eine Verbindung zu Ihrer App herzustellen.
Das folgende Code-Snippet zeigt, wie Sie Ihren Medienbrowserdienst in in deinem Manifest. Fügen Sie diesen Code in die Manifestdatei für Ihr Das Android Automotive OS-Modul und in der Manifestdatei für Ihre Smartphone-App
<application>
...
<service android:name=".MyMediaBrowserService"
android:exported="true">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
...
</application>
App-Symbole festlegen
Du musst App-Symbole festlegen, die Android Auto und Android Automotive OS nutzen können zur Darstellung Ihrer App in der System-UI. Es sind zwei Symboltypen erforderlich:
- Launcher-Symbol
- Attributionssymbol
Launcher-Symbol
Das Launcher-Symbol repräsentiert Ihre App auf der System-Benutzeroberfläche, z. B. im Launcher und in der Leiste mit Symbolen. Sie können angeben, dass Sie das Symbol aus Ihre mobile App, um Ihre Auto-Medien-App mithilfe des folgenden Manifests darzustellen Erklärung:
<application
...
android:icon="@mipmap/ic_launcher"
...
/>
Wenn Sie ein anderes Symbol als das Ihrer mobilen App verwenden möchten, legen Sie die Property android:icon
fest.
im <service>
-Element des Medienbrowserdienstes im Manifest:
<application>
...
<service
...
android:icon="@mipmap/auto_launcher"
...
/>
</application>
Attributionssymbol
![](https://developer.android.google.cn/static/images/training/cars/attribution-icon.png?authuser=7&hl=de)
Abbildung 1: Attributionssymbol auf der Medienkarte.
Das Symbol für die Namensnennung wird an Stellen verwendet, an denen Medieninhalte Vorrang haben, zum Beispiel auf Medienkarten. Vielleicht solltest du das kleine Symbol für Benachrichtigungen wiederverwenden. Dieses Symbol muss einfarbig sein. Sie können ein Symbol angeben, das für mit der folgenden Manifest-Deklaration:
<application>
...
<meta-data
android:name="androidx.car.app.TintableAttributionIcon"
android:resource="@drawable/ic_status_icon" />
...
</application>
Medienbrowserdienst erstellen
Sie erstellen einen Medienbrowserdienst, indem Sie die MediaBrowserServiceCompat
erweitern
. Sowohl Android Auto als auch Android Automotive OS können deinen Dienst dann verwenden
um Folgendes zu tun:
- Durchsuchen Sie die Contenthierarchie Ihrer App, um dem Nutzer ein Menü anzuzeigen.
- Token für
MediaSessionCompat
Ihrer App abrufen Objekt zur Steuerung der Audiowiedergabe.
Sie können Ihren Medienbrowser auch nutzen, um anderen Clients über deine App auf Medieninhalte zuzugreifen. Diese Medienclients können andere Apps auf einem oder ein anderer Remote-Client.
Workflow für Medienbrowser-Dienste
In diesem Abschnitt wird beschrieben, wie Android Automotive OS und Android Sie können in einem typischen Nutzerworkflow automatisch mit dem Medienbrowserdienst interagieren.
- Der Nutzer startet deine App unter Android Automotive OS oder Android Auto.
- Android Automotive OS oder Android Auto kontaktiert den Medienbrowser deiner App
Dienst mithilfe der
onCreate()
. Bei der Implementierung desonCreate()
müssen Sie eineMediaSessionCompat
erstellen und registrieren. und das zugehörige Callback-Objekt enthält. - Android Automotive OS oder Android Auto ruft die
onGetRoot()
deines Dienstes auf , um das Stammmedienelement in der Contenthierarchie abzurufen. Das Stammmedienelement wird nicht angezeigt. Stattdessen werden sie verwendet, um mehr Inhalte aus Ihrer App abzurufen. - Android Automotive OS oder Android Auto ruft die
onLoadChildren()
, um die untergeordneten Elemente des Stammmedienelements abzurufen. Android Automotive OS und In Android Auto werden diese Medienelemente als oberste Ebene der Inhalte angezeigt. Weitere Informationen finden Sie unter Strukturieren Sie das Stammverzeichnis auf dieser Seite, um weitere Informationen zu erhalten. was das System auf dieser Ebene erwartet. - Wenn der Nutzer ein durchsuchbares Medienelement auswählt, wird der
onLoadChildren()
wird erneut aufgerufen, um die untergeordneten Elemente des ausgewählten Menüelements abzurufen. - Wenn der Nutzer ein abspielbares Medienelement, Android Automotive OS oder Android auswählt, Die entsprechende Callback-Methode für Mediensitzungen wird automatisch aufgerufen, um diese Aktion auszuführen.
- Sofern Ihre App dies unterstützt, können Nutzer auch in Ihren Inhalten suchen. In dieser
Android Automotive OS oder Android Auto den
onSearch()
.
Contenthierarchie erstellen
Android Auto und Android Automotive OS rufen den Medienbrowserdienst Ihrer App auf,
um herauszufinden, welche Inhalte verfügbar sind. Sie müssen zwei Methoden in Ihrem
Medienbrowserdienst onGetRoot()
und
onLoadChildren()
onGetRoot implementieren
onGetRoot()
Ihres Dienstes
werden Informationen zum Stammknoten der Contenthierarchie zurückgegeben.
Android Auto und Android Automotive OS verwenden
diesen Root-Knoten, um den Rest des
Ihre Inhalte mithilfe der
onLoadChildren()
.
Das folgende Code-Snippet zeigt eine einfache Implementierung des
onGetRoot()
-Methode:
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 ausführlicheres Beispiel für diese Methode finden Sie in der onGetRoot()
.
in der Beispiel-App "Universal Android Music Player" auf GitHub.
Paketvalidierung für onGetRoot() hinzufügen
Bei einem Aufruf der onGetRoot()
Ihres Dienstes
übergibt das aufrufende Paket identifizierende Informationen an Ihren Dienst. Ihr
kann anhand dieser Informationen entscheiden, ob das Paket auf Ihre
Inhalte. Beispielsweise können Sie den Zugriff auf App-Inhalte auf eine Liste mit
genehmigte Pakete, indem Sie die clientPackageName
mit Ihrer Zulassungsliste vergleichen und
Prüfen des Zertifikats, mit dem das APK des Pakets signiert wurde. Wenn das Paket nicht
bestätigt werden, geben Sie null
zurück, um den Zugriff auf Ihre Inhalte zu verweigern.
Um System-Apps wie Android Auto und Android Automotive OS zur Verfügung zu stellen,
mit Zugriff auf Ihre Inhalte verwendet, muss Ihr Dienst immer einen Wert ungleich null zurückgeben.
BrowserRoot
, wenn diese System-Apps die onGetRoot()
aufrufen
. Die Signatur der Android Automotive OS-System-App kann je nach
nach der Marke und dem Modell des Autos, sodass Sie Verbindungen von allen
System-Apps, um Android Automotive OS zuverlässig zu unterstützen.
Das folgende Code-Snippet zeigt, wie Ihr Dienst überprüfen kann, ob das Das aufrufende Paket ist eine System-App:
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
}
Dieses Code-Snippet ist ein Auszug aus dem PackageValidator
-
in der Beispiel-App "Universal Android Music Player" auf GitHub. Kurs ansehen
ein ausführlicheres Beispiel zur Implementierung der Paketvalidierung für Ihre
onGetRoot()
des Dienstes
.
Sie müssen nicht nur System-Apps, sondern auch Google Assistant
eine Verbindung zu deinem MediaBrowserService
herstellen. Beachte, dass Google Assistant
separate Paketnamen
für das Smartphone (einschließlich Android Auto) und für Android Automotive OS.
onLoadChildren() implementieren
Nach Erhalt des Root-Knotenobjekts werden Android Auto und Android Automotive OS
Erstellen eines übergeordneten Menüs durch Aufrufen von onLoadChildren()
für das Root-Knotenobjekt,
um dessen untergeordnete Elemente abzurufen. Client-Apps erstellen Untermenüs von
und rufen diese Methode unter Verwendung von
untergeordneten Knotenobjekten auf.
Jeder Knoten in Ihrer Contenthierarchie wird durch ein MediaBrowserCompat.MediaItem
dargestellt.
-Objekt enthält. Jedes dieser Medienelemente wird durch einen eindeutigen ID-String identifiziert. Kunde
Apps behandeln diese ID-Strings als intransparente Tokens. Wenn eine Client-App Daten durchsuchen möchte
an ein Untermenü senden oder ein Medienelement abspielen,
gibt es das Token weiter. Ihre App ist verantwortlich
zum Verknüpfen des Tokens mit dem entsprechenden Medienelement.
Das folgende Code-Snippet zeigt eine einfache 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 whether 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 children 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 whether 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 children of that menu in the mediaItems list. } result.sendResult(mediaItems); }
Ein vollständiges Beispiel für diese Methode finden Sie in der
onLoadChildren()
in der Beispiel-App "Universal Android Music Player" auf GitHub.
Stammmenü strukturieren
![](https://developer.android.google.cn/static/images/training/cars/browse_home_tabs.png?authuser=7&hl=de)
Abbildung 2: Stamminhalt wird als Navigationstab angezeigt.
Android Auto und Android Automotive OS haben spezifische Einschränkungen
Struktur des Stammmenüs. Diese Informationen werden MediaBrowserService
mitgeteilt
über Stammhinweise, die durch das Argument Bundle
gelesen werden können, das an
onGetRoot()
Wenn Sie diese Hinweise beachten, kann das System den Stamminhalt optimal anzeigen.
als Navigationstabs. Wenn Sie diese Hinweise nicht beachten,
entfernt oder vom System weniger gut sichtbar sind. Zwei Hinweise werden gesendet:
- Ein Limit für die Anzahl untergeordneter Stammelemente: In den meisten Fällen sind es vier. Das bedeutet, dass mehr als vier Registerkarten können nicht angezeigt werden.
- Unterstützte Flags für die untergeordneten Root-Zertifikate:
können Sie davon ausgehen, dass dieser Wert
MediaItem#FLAG_BROWSABLE
Das bedeutet, dass nur durchsuchbare Elemente, keine spielbaren Elemente, als Tabs angezeigt werden können.
Verwenden Sie den folgenden Code, um die relevanten Stammhinweise zu lesen:
Kotlin
import androidx.media.utils.MediaConstants // Later, in your MediaBrowserServiceCompat. 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 Contenthierarchie verzweigen.
dieser Hinweise berücksichtigt werden, insbesondere wenn Ihre Hierarchie zwischen
MediaBrowser
-Integrationen außerhalb von Android Auto und Android Automotive OS.
Wenn Sie normalerweise ein abspielbares Root-Element anzeigen, sollten Sie es verschachteln.
unter einem durchsuchbaren Stammelement
aufgrund des Werts der unterstützten Flags
Tipp:
Neben den Root-Hinweisen sind noch ein paar weitere Richtlinien zu beachten, um sicherzustellen, dass Tabs optimal gerendert werden:
- Stellen Sie für jedes Tabelement monochrome, vorzugsweise weiße Symbole bereit.
- Geben Sie kurze, aber aussagekräftige Labels für jedes Tabelement an. Labels kurz halten verringert die Wahrscheinlichkeit, dass Strings abgeschnitten werden.
Media-Artwork anzeigen
Artwork für Medienelemente muss als lokaler URI übergeben werden mit einer der folgenden Methoden:
ContentResolver.SCHEME_CONTENT
oder ContentResolver.SCHEME_ANDROID_RESOURCE
.
Dieser lokale URI muss entweder in eine Bitmap oder ein Vektor-Drawable im
Anwendungsressourcen. Für MediaDescriptionCompat
-Objekte, die Elemente darstellen in
in der Contenthierarchie übergeben Sie den URI über setIconUri()
.
Übergeben Sie für MediaMetadataCompat
-Objekte, die das gerade wiedergegebene Element darstellen, den
URI über putString()
,
mit einem der folgenden Schlüssel:
MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI
MediaMetadataCompat.METADATA_KEY_ART_URI
MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI
In den folgenden Schritten wird beschrieben, wie Sie Artwork aus einem Web-URI herunterladen und bereitstellen können.
über einen lokalen URI. Ein vollständigeres Beispiel finden Sie in der
Implementierung
openFile()
und die umliegenden Methoden in Universal Android Music
Beispiel-App für Player.
Erstellen Sie einen
content://
-URI, der dem Web-URI entspricht. Der Medienbrowser Dienst- und Mediensitzung übergeben diesen Inhalts-URI an Android Auto und Android Automotive OSKotlin
fun Uri.asAlbumArtContentURI(): Uri { return Uri.Builder() .scheme(ContentResolver.SCHEME_CONTENT) .authority(CONTENT_PROVIDER_AUTHORITY) .appendPath(this.getPath()) // Make sure you trust the URI .build() }
Java
public static Uri asAlbumArtContentURI(Uri webUri) { return new Uri.Builder() .scheme(ContentResolver.SCHEME_CONTENT) .authority(CONTENT_PROVIDER_AUTHORITY) .appendPath(webUri.getPath()) // Make sure you trust the URI! .build(); }
Prüfen Sie bei der Implementierung von
ContentProvider.openFile()
, ob eine Datei für den entsprechenden URI vorhanden ist. Ist dies nicht der Fall, laden Sie die Bilddatei herunter und speichern Sie sie im Cache. Die Im folgenden Code-Snippet wird Glide verwendet.Kotlin
override fun openFile(uri: Uri, mode: String): ParcelFileDescriptor? { val context = this.context ?: return null val file = File(context.cacheDir, uri.path) if (!file.exists()) { val remoteUri = Uri.Builder() .scheme("https") .authority("my-image-site") .appendPath(uri.path) .build() val cacheFile = Glide.with(context) .asFile() .load(remoteUri) .submit() .get(DOWNLOAD_TIMEOUT_SECONDS, TimeUnit.SECONDS) cacheFile.renameTo(file) file = cacheFile } return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY) }
Java
@Nullable @Override public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode) throws FileNotFoundException { Context context = this.getContext(); File file = new File(context.getCacheDir(), uri.getPath()); if (!file.exists()) { Uri remoteUri = new Uri.Builder() .scheme("https") .authority("my-image-site") .appendPath(uri.getPath()) .build(); File cacheFile = Glide.with(context) .asFile() .load(remoteUri) .submit() .get(DOWNLOAD_TIMEOUT_SECONDS, TimeUnit.SECONDS); cacheFile.renameTo(file); file = cacheFile; } return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); }
Weitere Informationen zu Contentanbietern finden Sie unter Erstellen von Inhalten Dienstanbieter.
Inhaltsstile anwenden
Nachdem Sie Ihre Contenthierarchie mit durchsuchbaren oder abspielbaren Elementen erstellt haben, können Inhaltsstile anwenden, die bestimmen, wie diese Elemente im Auto angezeigt werden.
Sie können die folgenden Inhaltsstile verwenden:
- Listenelemente
-
Bei diesem Inhaltsstil haben Titel und Metadaten Vorrang vor Bildern.
- Rasterelemente
-
Bei diesem Inhaltsstil werden Bilder gegenüber Titeln und Metadaten priorisiert.
Standardstile für Inhalte festlegen
Sie können globale Standardeinstellungen für die Anzeige Ihrer Medienelemente festlegen, indem Sie
bestimmte Konstanten im Extra-Bundle BrowserRoot
Ihres Dienstes
onGetRoot()
. Android Auto und Android Automotive OS lesen dieses Paket und suchen nach
um den passenden Stil zu bestimmen.
Die folgenden Extras können als Schlüssel im Bundle verwendet werden:
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE
: zeigt einen Präsentationshinweis für alle durchsuchbaren Elemente innerhalb des Suchbaums an.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE
: zeigt einen Präsentationshinweis für alle abspielbaren Elemente im Suchbaum an.
Die Schlüssel können den folgenden ganzzahligen konstanten Werten zugeordnet werden, um die Präsentation dieser Elemente:
DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM
: werden die entsprechenden Elemente als Listenelemente dargestellt.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM
: werden die entsprechenden Elemente als Rasterelemente dargestellt.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM
: werden die entsprechenden Elemente als „Kategorie“ Listeneinträgen. Dies sind entsprechen den gewöhnlichen Listenelementen, mit dem Unterschied, dass Ränder um der Elemente da die Symbole auf kleinen Bildschirmen besser aussehen. Die Symbole müssen tönbare Vektor-Drawables sein. Dieser Hinweis wird nur angegeben, für durchsuchbare Elemente.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_GRID_ITEM
: werden die entsprechenden Elemente als „Kategorie“ Rasterelemente. Dies sind wie gewöhnliche Rasterelemente, mit dem Unterschied, dass Ränder um der Elemente da die Symbole auf kleinen Bildschirmen besser aussehen. Die Symbole müssen tönbare Vektor-Drawables sein. Dieser Hinweis wird nur angegeben, für durchsuchbare Elemente.
Im folgenden Code-Snippet sehen Sie, wie der Standardinhaltsstil durchsuchbare Elemente zu Rastern und abspielbare Elemente zu Listen:
Kotlin
import androidx.media.utils.MediaConstants @Nullable override fun onGetRoot( @NonNull clientPackageName: String, clientUid: Int, @Nullable rootHints: Bundle ): BrowserRoot { val extras = Bundle() extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM) extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM) return BrowserRoot(ROOT_ID, extras) }
Java
import androidx.media.utils.MediaConstants; @Nullable @Override public BrowserRoot onGetRoot( @NonNull String clientPackageName, int clientUid, @Nullable Bundle rootHints) { Bundle extras = new Bundle(); extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM); extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM); return new BrowserRoot(ROOT_ID, extras); }
Inhaltsstile pro Element festlegen
Mit der Content Style API können Sie den Standardinhaltsstil für beliebige die untergeordneten Elemente des durchsuchbaren Medienelements sowie jedes Medienelement selbst.
Um die Standardeinstellung für die untergeordneten Elemente eines durchsuchbaren Medienelements zu überschreiben, erstellen Sie ein
Extras-Set in der MediaDescription
des Medienelements und fügen Sie dasselbe hinzu.
die zuvor genannten Hinweise. DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE
gilt für alle spielbaren untergeordneten Elemente dieses Elements, während
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE
gilt für dieses Element
durchsuchbaren Kindern.
Um den Standardwert für ein bestimmtes Medienelement selbst zu überschreiben, nicht für dessen
Kinder, erstelle ein Extras-Set unter MediaDescription
des Medienelements
und füge einen Hinweis mit dem Schlüssel
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM
Verwenden Sie die zuvor beschriebenen Werte, um die Darstellung dieses Elements anzugeben.
Das folgende Code-Snippet zeigt, wie Sie ein durchsuchbares MediaItem
-Element erstellen,
überschreibt den Standardinhaltsstil sowohl für sich selbst als auch für die untergeordneten Elemente. Stile erstellen
sich selbst als Kategorielistenelement, seine durchsuchbaren untergeordneten Elemente als Listenelemente und seine
spielbare untergeordnete Elemente als Rasterelemente:
Kotlin
import androidx.media.utils.MediaConstants private fun createBrowsableMediaItem( mediaId: String, folderName: String, iconUri: Uri ): MediaBrowser.MediaItem { val mediaDescriptionBuilder = MediaDescription.Builder() mediaDescriptionBuilder.setMediaId(mediaId) mediaDescriptionBuilder.setTitle(folderName) mediaDescriptionBuilder.setIconUri(iconUri) val extras = Bundle() extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM) extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM) extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM) mediaDescriptionBuilder.setExtras(extras) return MediaBrowser.MediaItem( mediaDescriptionBuilder.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE) }
Java
import androidx.media.utils.MediaConstants; private MediaBrowser.MediaItem createBrowsableMediaItem( String mediaId, String folderName, Uri iconUri) { MediaDescription.Builder mediaDescriptionBuilder = new MediaDescription.Builder(); mediaDescriptionBuilder.setMediaId(mediaId); mediaDescriptionBuilder.setTitle(folderName); mediaDescriptionBuilder.setIconUri(iconUri); Bundle extras = new Bundle(); extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM); extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM); extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM); mediaDescriptionBuilder.setExtras(extras); return new MediaBrowser.MediaItem( mediaDescriptionBuilder.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE); }
Elemente mithilfe von Titelhinweisen gruppieren
Um ähnliche Medienelemente zu gruppieren, verwenden Sie einen Hinweis pro Element. Jedes Medienelement
in einer Gruppe ein Extras-Set in der MediaDescription
deklarieren, die
enthält eine Zuordnung mit dem Schlüssel
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE
und einen identischen Stringwert. Lokalisieren Sie diesen String, der als
Titel der Gruppe.
Im folgenden Code-Snippet sehen Sie, wie ein MediaItem
mit einer Untergruppe erstellt wird
Überschrift von "Songs"
:
Kotlin
import androidx.media.utils.MediaConstants private fun createMediaItem( mediaId: String, folderName: String, iconUri: Uri ): MediaBrowser.MediaItem { val mediaDescriptionBuilder = MediaDescription.Builder() mediaDescriptionBuilder.setMediaId(mediaId) mediaDescriptionBuilder.setTitle(folderName) mediaDescriptionBuilder.setIconUri(iconUri) val extras = Bundle() extras.putString( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs") mediaDescriptionBuilder.setExtras(extras) return MediaBrowser.MediaItem( mediaDescriptionBuilder.build(), /* playable or browsable flag*/) }
Java
import androidx.media.utils.MediaConstants; private MediaBrowser.MediaItem createMediaItem(String mediaId, String folderName, Uri iconUri) { MediaDescription.Builder mediaDescriptionBuilder = new MediaDescription.Builder(); mediaDescriptionBuilder.setMediaId(mediaId); mediaDescriptionBuilder.setTitle(folderName); mediaDescriptionBuilder.setIconUri(iconUri); Bundle extras = new Bundle(); extras.putString( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs"); mediaDescriptionBuilder.setExtras(extras); return new MediaBrowser.MediaItem( mediaDescriptionBuilder.build(), /* playable or browsable flag*/); }
Ihre App muss alle Medienelemente übergeben, die Sie als zusammenhängender Block. Angenommen, Sie möchten zwei Gruppen anzeigen, von Medienelementen, "Titel" und "Alben", in dieser Reihenfolge und Ihre App fünf Medienelemente in der folgenden Reihenfolge:
- Medienelement A mit
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Medienelement B mit
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
- Medienelement C mit
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Medienelement D mit
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Medienelement E mit
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
Da die Medienelemente für die "Songs" Gruppe und "Alben" Gruppe werden nicht beibehalten in zusammenhängenden Blöcken zusammen, Android Auto und Android Automotive OS interpretiert dies als die folgenden vier Gruppen:
- Gruppe 1 namens „Songs“ mit Medienelement A
- Gruppe 2 namens „Alben“ mit Medienelement B
- Gruppe 3 namens „Songs“ mit den Medienelementen C und D
- Gruppe 4 namens „Alben“ mit Medienelement E
Um diese Elemente in zwei Gruppen anzuzeigen, muss Ihre App die Medienelemente in der in folgender Reihenfolge:
- Medienelement A mit
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Medienelement C mit
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Medienelement D mit
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Medienelement B mit
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
- Medienelement E mit
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
Zusätzliche Metadatenindikatoren anzeigen
Sie können zusätzliche Indikatoren für Metadaten einfügen, um einen schnellen Überblick zu erhalten. Informationen für Inhalte in der Baumstruktur des Mediabrowsers und während der Wiedergabe Im Baum durchsuchen, Android Auto und Android Automotive OS lesen die zugehörigen Extras mit einem Element und suchen Sie nach bestimmten Konstanten, um zu bestimmen, welche Indikatoren Display. Während der Medienwiedergabe lesen Android Auto und Android Automotive OS die Metadaten für die Mediensitzung und achten Sie auf bestimmte Konstanten, angezeigt werden sollen.
![](https://developer.android.google.cn/static/images/training/cars/metadata_indicators.png?authuser=7&hl=de)
Abbildung 3: Wiedergabeansicht mit Metadaten zur Identifizierung des Songs und Interpret sowie ein Symbol für anstößige Inhalte.
![](https://developer.android.google.cn/static/images/training/cars/progress_indicators.png?authuser=7&hl=de)
Abbildung 4: Suchansicht mit einem Punkt für nicht wiedergegebene Inhalte auf das erste Element und eine Fortschrittsanzeige für teilweise abgespielte Inhalte auf der Seite zweiten Element.
Die folgenden Konstanten können beide MediaItem
-Beschreibungsextras und
MediaMetadata
Extras:
EXTRA_DOWNLOAD_STATUS
: zeigt den Download-Status eines Elements an. Verwenden Sie diese Konstante als Schlüssel; sind folgende lange Konstanten mögliche Werte: <ph type="x-smartling-placeholder">- </ph>
STATUS_DOWNLOADED
: der Download abgeschlossen ist.STATUS_DOWNLOADING
: das Element wird heruntergeladen.STATUS_NOT_DOWNLOADED
: wird das Element nicht heruntergeladen.
METADATA_KEY_IS_EXPLICIT
: gibt an, ob das Element explizite Inhalte enthält. Um anzugeben, dass ein Element explizit ist, verwenden Sie diese Konstante als Schlüssel und langenMETADATA_VALUE_ATTRIBUTE_PRESENT
als Wert ein.
Die folgenden Konstanten können nur in MediaItem
-Beschreibungsextras verwendet werden:
DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS
: den Status der Fertigstellung von langen Inhalten wie Podcastfolgen oder Hörbücher. Verwenden Sie diese Konstante als Schlüssel; die folgende Ganzzahl Konstanten sind die möglichen Werte: <ph type="x-smartling-placeholder">- </ph>
DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_NOT_PLAYED
: das Element nicht abgespielt wurde.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED
: Das Element wurde teilweise abgespielt und die aktuelle Position ist irgendwo anders in der Mitte.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_FULLY_PLAYED
: abgeschlossen ist.
DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
: gibt an, wie weit der Fortschritt von Videos im Langformat im Doppelwert ist. zwischen 0,0 und 1,0 (einschließlich) liegt. Dieses Extra bietet weitere Informationen zumPARTIALLY_PLAYING
, damit Android Auto oder Android Automotive OS zeigt eine aussagekräftigere Fortschrittsanzeige an, z. B. Fortschrittsanzeige. Wenn Sie diese Zusatzinformationen verwenden, lesen Sie den Abschnitt zur Aktualisierung der Fortschrittsanzeige in der Übersicht, während Inhalte abgespielt werden in diesem Leitfaden, um zu erfahren, wie Sie diesen Indikator nach ersten Eindruck machen.
Anzeigen, die angezeigt werden, während der Nutzer im Medienstöber surft
erstellen, erstellen Sie ein Extras-Set, das eine oder mehrere dieser Konstanten und
übergeben Sie dieses Bundle an die Methode MediaDescription.Builder.setExtras()
.
Das folgende Code-Snippet zeigt, wie Indikatoren für explizite Medien Element, das zu 70% abgeschlossen ist:
Kotlin
import androidx.media.utils.MediaConstants val extras = Bundle() extras.putLong( MediaConstants.METADATA_KEY_IS_EXPLICIT, MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT) extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS, MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED) extras.putDouble( MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.7) val description = MediaDescriptionCompat.Builder() .setMediaId(/*...*/) .setTitle(resources.getString(/*...*/)) .setExtras(extras) .build() return MediaBrowserCompat.MediaItem(description, /* flags */)
Java
import androidx.media.utils.MediaConstants; Bundle extras = new Bundle(); extras.putLong( MediaConstants.METADATA_KEY_IS_EXPLICIT, MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT); extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS, MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED); extras.putDouble( MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.7); MediaDescriptionCompat description = new MediaDescriptionCompat.Builder() .setMediaId(/*...*/) .setTitle(resources.getString(/*...*/)) .setExtras(extras) .build(); return new MediaBrowserCompat.MediaItem(description, /* flags */);
Um Hinweise für ein Medienelement anzuzeigen, das gerade abgespielt wird, hast du folgende Möglichkeiten:
Deklarieren Sie Long
-Werte für METADATA_KEY_IS_EXPLICIT
oder EXTRA_DOWNLOAD_STATUS
in: MediaMetadataCompat
von mediaSession
. Sie können den
DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS
oder
DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
in der Wiedergabeansicht.
Das folgende Code-Snippet zeigt, wie angegeben wird, dass der aktuelle Titel im Wiedergabeansicht ist explizit und wird heruntergeladen:
Kotlin
import androidx.media.utils.MediaConstants mediaSession.setMetadata( MediaMetadataCompat.Builder() .putString( MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "Song Name") .putString( MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, "Artist name") .putString( MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, albumArtUri.toString()) .putLong( MediaConstants.METADATA_KEY_IS_EXPLICIT, MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT) .putLong( MediaDescriptionCompat.EXTRA_DOWNLOAD_STATUS, MediaDescriptionCompat.STATUS_DOWNLOADED) .build())
Java
import androidx.media.utils.MediaConstants; mediaSession.setMetadata( new MediaMetadataCompat.Builder() .putString( MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "Song Name") .putString( MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, "Artist name") .putString( MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, albumArtUri.toString()) .putLong( MediaConstants.METADATA_KEY_IS_EXPLICIT, MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT) .putLong( MediaDescriptionCompat.EXTRA_DOWNLOAD_STATUS, MediaDescriptionCompat.STATUS_DOWNLOADED) .build());
Aktualisiere die Fortschrittsanzeige in der Übersicht, während Inhalte abgespielt werden
Wie bereits erwähnt, können Sie
DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
um eine Fortschrittsanzeige für teilweise abgespielte Inhalte im
Suchansicht. Spielt ein Nutzer den teilweise abgespielten Inhalt jedoch
Android Auto oder Android Automotive OS verwendet,
mit der Zeit ungenau sind.
Für Android Auto und Android Automotive OS
Damit die Fortschrittsanzeige immer auf dem neuesten Stand ist, können Sie im
MediaMetadataCompat
und PlaybackStateCompat
, mit denen aktuelle Inhalte verknüpft werden sollen
Medienelemente in der Ansicht zum Durchsuchen angezeigt. Die folgenden Anforderungen müssen für den
Medienelement eine automatisch aktualisierte Fortschrittsanzeige zu erhalten:
- Nach der Erstellung muss der
MediaItem
DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
in seinen Extras mit einem Wert zwischen 0,0 und einschließlich 1,0. - Der
MediaMetadataCompat
mussMETADATA_KEY_MEDIA_ID
mit einem Stringwert gleich dem Medien-ID anMediaItem
übergeben. PlaybackStateCompat
muss ein Extra mit dem Schlüssel enthaltenPLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID
die einem Stringwert entspricht, der dem Medien-ID anMediaItem
übergeben.
Im folgenden Code-Snippet sehen Sie, wie angegeben wird, dass das aktuell abgespielte Element ist mit einem Element in der Übersicht verknüpft:
Kotlin
import androidx.media.utils.MediaConstants // When the MediaItem is constructed to show in the browse view. // Suppose the item was 25% complete when the user launched the browse view. val mediaItemExtras = Bundle() mediaItemExtras.putDouble( MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.25) val description = MediaDescriptionCompat.Builder() .setMediaId("my-media-id") .setExtras(mediaItemExtras) // ...and any other setters. .build() return MediaBrowserCompat.MediaItem(description, /* flags */) // Elsewhere, when the user has selected MediaItem for playback. mediaSession.setMetadata( MediaMetadataCompat.Builder() .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, "my-media-id") // ...and any other setters. .build()) val playbackStateExtras = Bundle() playbackStateExtras.putString( MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID, "my-media-id") mediaSession.setPlaybackState( PlaybackStateCompat.Builder() .setExtras(playbackStateExtras) // ...and any other setters. .build())
Java
import androidx.media.utils.MediaConstants; // When the MediaItem is constructed to show in the browse view. // Suppose the item was 25% complete when the user launched the browse view. Bundle mediaItemExtras = new Bundle(); mediaItemExtras.putDouble( MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.25); MediaDescriptionCompat description = new MediaDescriptionCompat.Builder() .setMediaId("my-media-id") .setExtras(mediaItemExtras) // ...and any other setters. .build(); return MediaBrowserCompat.MediaItem(description, /* flags */); // Elsewhere, when the user has selected MediaItem for playback. mediaSession.setMetadata( new MediaMetadataCompat.Builder() .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, "my-media-id") // ...and any other setters. .build()); Bundle playbackStateExtras = new Bundle(); playbackStateExtras.putString( MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID, "my-media-id"); mediaSession.setPlaybackState( new PlaybackStateCompat.Builder() .setExtras(playbackStateExtras) // ...and any other setters. .build());
Durchsuchbare Suchergebnisse anzeigen
![](https://developer.android.google.cn/static/images/training/cars/search_results.png?authuser=7&hl=de)
Abbildung 5: Wiedergabeansicht mit der Option „Suchergebnisse“ für Anzeigen von Medieninhalten, die sich auf die Sprachsuche des Nutzers beziehen
Ihre App kann kontextbezogene Suchergebnisse bereitstellen, die Nutzern angezeigt werden, wenn wird eine Suchanfrage gestartet. Android Auto und Android Automotive OS-Sendung diese Ergebnisse über Benutzeroberflächen für Suchanfragen oder Angebote, die neu ausgerichtet sind, in früheren Sitzungen. Weitere Informationen finden Sie in der Unterstützung der Sprachbedienung in diesem Leitfaden.
Um durchsuchbare Suchergebnisse anzuzeigen, schließen Sie den Konstantenschlüssel ein
BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED
im Extras-Paket des onGetRoot()
-Objekts Ihres Dienstes
-Methode zur Zuordnung zum booleschen Wert true
.
Das folgende Code-Snippet zeigt, wie die Unterstützung im onGetRoot()
aktiviert wird
:
Kotlin
import androidx.media.utils.MediaConstants @Nullable fun onGetRoot( @NonNull clientPackageName: String, clientUid: Int, @Nullable rootHints: Bundle ): BrowserRoot { val extras = Bundle() extras.putBoolean( MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED, true) return BrowserRoot(ROOT_ID, extras) }
Java
import androidx.media.utils.MediaConstants; @Nullable @Override public BrowserRoot onGetRoot( @NonNull String clientPackageName, int clientUid, @Nullable Bundle rootHints) { Bundle extras = new Bundle(); extras.putBoolean( MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED, true); return new BrowserRoot(ROOT_ID, extras); }
Wenn du Suchergebnisse bereitstellen möchtest, musst du den onSearch()
überschreiben
in Ihrem Medienbrowserdienst auf. Android Auto und Android Automotive OS
die Suchbegriffe des Nutzers an diese Methode weiterleiten, wenn ein Nutzer eine Suche aufruft
die Abfrageoberfläche oder
die Option „Suchergebnisse“.
Sie können die Suche
Ergebnisse aus der onSearch()
-Methode Ihres Dienstes mithilfe von title items
damit sie leichter durchsuchbar sind. Wenn Ihre App beispielsweise Musik wiedergibt,
Die Suchergebnisse lassen sich nach Album, Künstler und Songs sortieren.
Das folgende Code-Snippet zeigt eine einfache Implementierung der onSearch()
:
Kotlin
fun onSearch(query: String, extras: Bundle) { // Detach from results to unblock the caller (if a search is expensive). result.detach() object:AsyncTask() { internal var searchResponse:ArrayList internal var succeeded = false protected fun doInBackground(vararg params:Void):Void { searchResponse = ArrayList() if (doSearch(query, extras, searchResponse)) { succeeded = true } return null } protected fun onPostExecute(param:Void) { if (succeeded) { // Sending an empty List informs the caller that there were no results. result.sendResult(searchResponse) } else { // This invokes onError() on the search callback. result.sendResult(null) } return null } }.execute() } // Populates resultsToFill with search results. Returns true on success or false on error. private fun doSearch( query: String, extras: Bundle, resultsToFill: ArrayList ): Boolean { // Implement this method. }
Java
@Override public void onSearch(final String query, final Bundle extras, Result<List<MediaItem>> result) { // Detach from results to unblock the caller (if a search is expensive). result.detach(); new AsyncTask<Void, Void, Void>() { List<MediaItem> searchResponse; boolean succeeded = false; @Override protected Void doInBackground(Void... params) { searchResponse = new ArrayList<MediaItem>(); if (doSearch(query, extras, searchResponse)) { succeeded = true; } return null; } @Override protected void onPostExecute(Void param) { if (succeeded) { // Sending an empty List informs the caller that there were no results. result.sendResult(searchResponse); } else { // This invokes onError() on the search callback. result.sendResult(null); } } }.execute() } /** Populates resultsToFill with search results. Returns true on success or false on error. */ private boolean doSearch(String query, Bundle extras, ArrayList<MediaItem> resultsToFill) { // Implement this method. }
Benutzerdefinierte Suchaktionen
![Eine einzelne benutzerdefinierte Suchaktion.](https://developer.android.google.cn/static/images/training/cars/custom_browse_action_single.png?authuser=7&hl=de)
Abbildung 6: Einzelne benutzerdefinierte Suchaktion
Mit benutzerdefinierten Suchaktionen kannst du benutzerdefinierte Symbole und Labels zu den
MediaItem
-Objekten in der Medien-App des Autos und verarbeiten Nutzerinteraktionen mit
diese Aktionen durchführen. Damit können Sie die Funktionalität der Medien-App um eine
zum Beispiel „Herunterladen“, „Zur Wiedergabeliste hinzufügen“, „Radio abspielen“
„Favorit“ oder „Entfernen“ Aktionen.
![Ein Dreipunkt-Menü für benutzerdefinierte Suchaktionen.](https://developer.android.google.cn/static/images/training/cars/custom_browse_action_overflow.png?authuser=7&hl=de)
Abbildung 7: Überlauf der benutzerdefinierten Suchaktion
Wenn es mehr benutzerdefinierte Aktionen gibt, als der OEM zulässt, wird eine Dreipunkt-Menü angezeigt.
So funktioniert es:
Jede benutzerdefinierte Suchaktion wird wie folgt definiert:
- Eine Aktions-ID (ein eindeutiger String-Identifikator)
- Ein Aktionslabel (der Text, der dem Nutzer angezeigt wird)
- URI für ein Aktionssymbol (ein Vektor-Drawable, das gefärbt werden kann)
Sie definieren eine globale Liste von benutzerdefinierten Suchaktionen im Rahmen Ihres
BrowseRoot
Dann können Sie eine Teilmenge dieser Aktionen einzelnen
MediaItem.
Wenn ein Nutzer mit einer benutzerdefinierten Suchaktion interagiert, erhält Ihre App einen Callback.
in „onCustomAction()
“. Sie können dann die Aktion ausführen und die Liste der
Aktionen für MediaItem
, falls erforderlich. Dies ist nützlich für zustandsorientierte Aktionen
z. B. „Favorit“ und „Herunterladen“. Für Aktionen, die nicht aktualisiert werden müssen, z. B. „Wiedergabe“
Radio“ verwenden, müssen Sie die Liste der Aktionen nicht aktualisieren.
![Benutzerdefinierte Suchaktionen im Stamm eines Suchknotens.](https://developer.android.google.cn/static/images/training/cars/custom_browse_action_toolbar.png?authuser=7&hl=de)
Abbildung 8: Symbolleiste für benutzerdefinierte Suchaktionen
Sie können auch benutzerdefinierte Suchaktionen an den Stamm des Suchknotens anhängen. Diese Aktionen werden in einer sekundären Symbolleiste unterhalb der Hauptsymbolleiste angezeigt.
So implementieren Sie benutzerdefinierte Suchaktionen
So fügen Sie Ihrem Projekt benutzerdefinierte Suchaktionen hinzu:
- Zwei Methoden in Ihrem
MediaBrowserServiceCompat
Implementierung: <ph type="x-smartling-placeholder"> - Parsen Sie die Aktionslimits während der Laufzeit:
<ph type="x-smartling-placeholder">
- </ph>
- Holen Sie sich in
onGetRoot()
die maximal zulässige Anzahl von Aktionen für jedeMediaItem
mit dem SchlüsselBROWSER_ROOT_HINTS_KEY_CUSTOM_BROWSER_ACTION_LIMIT
inrootHints
Bundle
. Eine Grenze von 0 bedeutet, dass das Element nicht vom System unterstützt.
- Holen Sie sich in
- Erstellen Sie die globale Liste benutzerdefinierter Suchaktionen:
<ph type="x-smartling-placeholder">
- </ph>
- Erstellen Sie für jede Aktion ein
Bundle
-Objekt mit den folgenden Schlüsseln: *EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID
: Die Aktions-ID *EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL
: Das Aktionslabel *EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI
: Der URI des Aktionssymbols * Fügen Sie alleBundle
-Aktionsobjekte einer Liste hinzu.
- Erstellen Sie für jede Aktion ein
- Fügen Sie die globale Liste zu
BrowseRoot
hinzu: <ph type="x-smartling-placeholder">- </ph>
- Füge die Liste der Aktionen in den
BrowseRoot
ExtrasBundle
hinzu alsParcelable
Arraylist
mit dem SchlüsselBROWSER_SERVICE_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ROOT_LIST
- Füge die Liste der Aktionen in den
- Fügen Sie Ihren
MediaItem
-Objekten Aktionen hinzu: <ph type="x-smartling-placeholder">- </ph>
- Sie können einzelnen
MediaItem
-Objekten Aktionen hinzufügen, indem Sie den Parameter Liste der Aktions-IDs in denMediaDescriptionCompat
-Extras mit dem SchlüsselDESCRIPTION_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID_LIST
Diese Liste muss eine Teilmenge der globalen Liste der Aktionen sein, die Sie inBrowseRoot
.
- Sie können einzelnen
- Aktionen verarbeiten und Fortschritt oder Ergebnisse zurückgeben:
<ph type="x-smartling-placeholder">
- </ph>
- Verarbeiten Sie in
onCustomAction
die Aktion basierend auf der Aktions-ID und allen andere Daten, die Sie benötigen. Sie können die ID desMediaItem
abrufen, hat die Aktion von den Extras mit der TasteEXTRAS_KEY_CUSTOM_BROWSER_ACTION_MEDIA_ITEM_ID
: - Sie können die Liste der Aktionen für ein
MediaItem
aktualisieren, indem Sie den TasteEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
im Fortschritt oder im Ergebnisset.
- Verarbeiten Sie in
Hier sind einige Änderungen, die du in deinem BrowserServiceCompat
vornehmen kannst, um loszulegen
mit benutzerdefinierten Suchaktionen.
BrowserServiceCompat überschreiben
Sie müssen die folgenden Methoden in MediaBrowserServiceCompat
überschreiben.
public void onLoadItem(String itemId, @NonNull Result<MediaBrowserCompat.MediaItem> result)
public void onCustomAction(@NonNull String action, Bundle extras, @NonNull Result<Bundle> result)
Limit für Parse-Aktionen
Überprüfe, wie viele benutzerdefinierte Suchaktionen unterstützt werden.
public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, Bundle rootHints) { rootHints.getInt( MediaConstants.BROWSER_ROOT_HINTS_KEY_CUSTOM_BROWSER_ACTION_LIMIT, 0) }
Benutzerdefinierte Suchaktion erstellen
Jede Aktion muss in einer separaten Bundle
zusammengefasst werden.
- Aktions-ID
bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID, "<ACTION_ID>")
- Aktionslabel
bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL, "<ACTION_LABEL>")
- URI für Aktionssymbol
bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI, "<ACTION_ICON_URI>")
Benutzerdefinierte Suchaktionen zu Parceable
ArrayList
hinzufügen
Fügen Sie alle Bundle
-Objekte der benutzerdefinierten Suchaktion zu einem ArrayList
hinzu.
private ArrayList<Bundle> createCustomActionsList( CustomBrowseAction browseActions) { ArrayList<Bundle> browseActionsBundle = new ArrayList<>(); for (CustomBrowseAction browseAction : browseActions) { Bundle action = new Bundle(); action.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID, browseAction.mId); action.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL, getString(browseAction.mLabelResId)); action.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI, browseAction.mIcon); browseActionsBundle.add(action); } return browseActionsBundle; }
Liste der benutzerdefinierten Suchaktionen zum Suchstamm hinzufügen
public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, Bundle rootHints) { Bundle browserRootExtras = new Bundle(); browserRootExtras.putParcelableArrayList( BROWSER_SERVICE_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ROOT_LIST, createCustomActionsList())); mRoot = new BrowserRoot(ROOT_ID, browserRootExtras); return mRoot; }
Einem MediaItem
Aktionen hinzufügen
MediaDescriptionCompat buildDescription (long id, String title, String subtitle, String description, Uri iconUri, Uri mediaUri, ArrayList<String> browseActionIds) { MediaDescriptionCompat.Builder bob = new MediaDescriptionCompat.Builder(); bob.setMediaId(id); bob.setTitle(title); bob.setSubtitle(subtitle); bob.setDescription(description); bob.setIconUri(iconUri); bob.setMediaUri(mediaUri); Bundle extras = new Bundle(); extras.putStringArrayList( DESCRIPTION_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID_LIST, browseActionIds); bob.setExtras(extras); return bob.build(); } MediaItem mediaItem = new MediaItem(buildDescription(...), flags);
onCustomAction
-Build-Ergebnis
- Analysieren Sie die mediaId aus
Bundle extras
:@Override public void onCustomAction( @NonNull String action, Bundle extras, @NonNull Result<Bundle> result){ String mediaId = extras.getString(MediaConstans.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_MEDIA_ITEM_ID); }
- Für asynchrone Ergebnisse trennen Sie das Ergebnis.
result.detach()
- Build-Ergebnis-Bundle
<ph type="x-smartling-placeholder">
- </ph>
- Nachricht an Nutzer
mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE, mContext.getString(stringRes))
- Artikel aktualisieren(um Aktionen in einem Artikel zu aktualisieren)
mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM, mediaId);
- Wiedergabeansicht öffnen
//Shows user the PBV without changing the playback state mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_SHOW_PLAYING_ITEM, null);
- Suchknoten aktualisieren
//Change current browse node to mediaId mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_BROWSE_NODE, mediaId);
- Nachricht an Nutzer
- Wenn ein Fehler auftritt, rufen Sie
result.sendError(resultBundle).
auf. - Wenn ein Fortschritt angezeigt wird, rufe
result.sendProgressUpdate(resultBundle)
auf. - Rufe zum Abschluss
result.sendResult(resultBundle)
auf.
Aktionsstatus aktualisieren
Wenn Sie die Methode result.sendProgressUpdate(resultBundle)
mit dem Parameter
EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
können Sie MediaItem
aktualisieren, um den neuen Status der Aktion widerzuspiegeln. Dieses
können Sie den Nutzenden in Echtzeit Feedback zum Fortschritt geben
Ergebnis ihrer Handlung.
Beispiel: Download-Aktion
Hier ist ein Beispiel, wie Sie mit dieser Funktion eine Downloadaktion implementieren können. mit drei Status:
- Herunterladen: Dies ist der anfängliche Status der Aktion. Wenn der Nutzer
können Sie stattdessen „Wird heruntergeladen“ verwenden, und rufen Sie
sendProgressUpdate
, um die UI zu aktualisieren. - Downloading: Dieser Status zeigt an, dass der Download läuft. Sie können Verwenden Sie diesen Status, um dem Nutzer eine Fortschrittsanzeige oder einen anderen Indikator anzuzeigen.
- Heruntergeladen: Dieser Status zeigt an, dass der Download abgeschlossen ist. Wenn der Parameter
wird der Download beendet, mit „Heruntergeladen“ und rufen Sie
sendResult
mit demEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
um anzugeben, dass das Element aktualisiert werden soll. Außerdem können Sie dieEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE
um dem Nutzer eine Erfolgsmeldung anzuzeigen.
Auf diese Weise können Sie den Nutzenden klares Feedback zum Download geben. Prozess und seinen aktuellen Status. Mit Symbolen können Sie noch mehr Details hinzufügen, Downloadstatus von 25%, 50%, 75 %.
Beispiel: Lieblingsaktion
Ein weiteres Beispiel ist eine Lieblingsaktion mit zwei Status:
- Favorit: Diese Aktion wird für Elemente angezeigt, die nicht im
Favoritenliste des Nutzers. Wenn der Nutzer diese Aktion auswählt, kannst du sie austauschen.
mit „Zu Favoriten hinzugefügt“ und rufe
sendResult
mit derEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
um die Benutzeroberfläche zu aktualisieren. - In Favoriten: Diese Aktion wird für Elemente angezeigt, die sich in der
Favoritenliste. Wenn der Nutzer diese Aktion auswählt, kannst du sie austauschen durch
„Favorit“ und rufe
sendResult
mit derEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
um die Benutzeroberfläche zu aktualisieren.
Dieser Ansatz bietet Nutzern eine klare und einheitliche Möglichkeit, Favoriten hinzufügen.
Diese Beispiele veranschaulichen die Flexibilität von benutzerdefinierten Suchaktionen verschiedene Funktionen mit Echtzeit-Feedback für für eine verbesserte Nutzererfahrung in der Medien-App des Autos.
Ein vollständiges Beispiel für die Implementierung dieser Funktion finden Sie in der
TestMediaApp
Wiedergabesteuerung aktivieren
Android Auto und Android Automotive OS senden Befehle zur Wiedergabesteuerung
MediaSessionCompat
Ihres Dienstes.
Sie müssen eine Sitzung registrieren und die zugehörigen Callback-Methoden implementieren.
Mediensitzung registrieren
Im onCreate()
des Medienbrowserdienstes
eine MediaSessionCompat
-Datei erstellen,
Registrieren Sie dann die Mediensitzung durch Aufrufen von setSessionToken()
.
Das folgende Code-Snippet zeigt, wie eine Mediensitzung erstellt und registriert wird:
Kotlin
override fun onCreate() { super.onCreate() ... // Start a new MediaSession. val session = MediaSessionCompat(this, "session tag").apply { // Set a callback object that implements MediaSession.Callback // to handle play control requests. setCallback(MyMediaSessionCallback()) } sessionToken = session.sessionToken ... }
Java
public void onCreate() { super.onCreate(); ... // Start a new MediaSession. MediaSessionCompat session = new MediaSessionCompat(this, "session tag"); setSessionToken(session.getSessionToken()); // Set a callback object that implements MediaSession.Callback // to handle play control requests. session.setCallback(new MyMediaSessionCallback()); ... }
Beim Erstellen des Mediensitzungsobjekts legen Sie ein Callback-Objekt fest, das verwendet wird.
für Anfragen zur Wiedergabesteuerung. Sie erstellen dieses Callback-Objekt, indem Sie
Bereitstellung der MediaSessionCompat.Callback
-Klasse für Ihre App. Im nächsten Abschnitt wird die Implementierung dieses Objekts erläutert.
Wiedergabebefehle implementieren
Wenn ein Nutzer die Wiedergabe eines Medienelements aus deiner App anfordert, wird Android Automotive
Betriebssystem und Android Auto verwenden den MediaSessionCompat.Callback
Kurs aus dem MediaSessionCompat
Ihrer App
-Objekt, das sie vom Medienbrowserdienst Ihrer App erhalten haben. Wenn ein Nutzer
möchte die Wiedergabe von Inhalten steuern, indem sie z. B. die Wiedergabe anhalten oder zur
beim nächsten Track, Android Auto und Android Automotive OS einen der Callbacks aufrufen,
Methoden des Objekts.
Damit die Wiedergabe von Inhalten verarbeitet werden kann, muss deine App die abstrakte MediaSessionCompat.Callback
-Funktion erweitern
und implementiere die von deiner App unterstützten Methoden.
Implementieren Sie alle folgenden Callback-Methoden, die für die Art der Inhalte, die Ihre App bietet:
onPrepare()
- Wird aufgerufen, wenn die Mediaquelle geändert wird. Android Automotive OS ruft außerdem diese Methode sofort nach dem Booten. Deine Medien-App muss dies implementieren .
onPlay()
- Wird aufgerufen, wenn der Nutzer „Spielen“ auswählt, ohne ein bestimmtes Element auszuwählen. Ihr
müssen die Standardinhalte der App wiedergeben. Wenn die Wiedergabe pausiert wurde,
onPause()
, dein setzt die Wiedergabe fort.Hinweis:Ihre App sollte nicht automatisch mit der Wiedergabe von Musik beginnen. wenn Android Automotive OS oder Android Auto eine Verbindung zu Ihrem Medienbrowser herstellen . Weitere Informationen finden Sie im Abschnitt über Festlegen des anfänglichen Wiedergabestatus
onPlayFromMediaId()
- Wird aufgerufen, wenn der Nutzer entscheidet, ein bestimmtes Element abzuspielen. Die Methode wurde übergeben. Die ID, die Ihr Medienbrowserdienst zugewiesen hat zum Medienelement in Ihrer Contenthierarchie hinzugefügt.
onPlayFromSearch()
- Wird aufgerufen, wenn der Nutzer sich für eine Suchanfrage entscheidet. Die App muss treffen Sie auf Grundlage der übergebenen Suchzeichenfolge eine geeignete Entscheidung.
onPause()
- Wird aufgerufen, wenn der Nutzer die Wiedergabe pausiert.
onSkipToNext()
- Wird aufgerufen, wenn der Nutzer entscheidet, zum nächsten Element zu springen.
onSkipToPrevious()
- Wird aufgerufen, wenn der Nutzer entscheidet, zum vorherigen Element zu springen.
onStop()
- Wird aufgerufen, wenn der Nutzer die Wiedergabe beendet.
Überschreiben Sie diese Methoden in Ihrer App, um die gewünschten Funktionen bereitzustellen. Ich
Sie müssen keine Methode implementieren, wenn ihre Funktionalität nicht von Ihrer App unterstützt wird. Für
Spielt Ihre App beispielsweise einen Livestream ab, etwa eine Sportübertragung,
die Methode onSkipToNext()
nicht implementieren. Sie können die Standardeinstellung
Implementierung von onSkipToNext()
.
Ihre App benötigt keine spezielle Logik, um Inhalte über die Lautsprechern. Wenn deine App eine Anfrage zur Wiedergabe von Inhalten erhält, kann sie Audio abspielen wie Inhalte über eine die über die Lautsprecher oder Kopfhörer des Smartphones ausgeliefert werden. Android Auto und Android Automotive OS automatisch an das System des Autos zur Wiedergabe über den die Lautsprecher des Autos.
Weitere Informationen zum Abspielen von Audioinhalten finden Sie unter MediaPlayer – Übersicht Übersicht über die Audio-App, und die ExoPlayer-Übersicht.
Standardmäßige Wiedergabeaktionen festlegen
Die Wiedergabesteuerung von Android Auto und Android Automotive OS
Aktionen, die in der PlaybackStateCompat
aktiviert sind
-Objekt enthält.
Standardmäßig muss Ihre App die folgenden Aktionen unterstützen:
Deine App kann außerdem die folgenden Aktionen unterstützen, wenn sie relevant für Inhalte der App:
Darüber hinaus haben Sie die Möglichkeit, eine Warteschlange für die Wiedergabe zu erstellen, die für alle Nutzer
nicht unbedingt erforderlich. Rufen Sie dazu die Methode setQueue()
auf.
und setQueueTitle()
die ACTION_SKIP_TO_QUEUE_ITEM
zu aktivieren.
Aktion und definiere den Callback onSkipToQueueItem()
.
Sie können auch das Symbol Läuft gerade unterstützen, das anzeigt, was
das gerade läuft. Rufen Sie dazu die Methode setActiveQueueItemId()
auf.
und übergeben Sie die ID des aktuell in der Warteschlange wiedergegebenen Elements. Erforderliche Schritte
setActiveQueueItemId()
bei jeder Änderung der Warteschlange aktualisieren.
Android Auto- und Android Automotive OS-Schaltflächen auf dem Display für jede aktivierte Aktion
und der Wiedergabeliste. Wenn die Tasten
klickt, ruft das System den entsprechenden Callback von
MediaSessionCompat.Callback
Ungenutzte Flächen reservieren
Android Auto und Android Automotive OS reservieren in der Benutzeroberfläche
Aktionen „ACTION_SKIP_TO_PREVIOUS
“ und „ACTION_SKIP_TO_NEXT
“. Wenn Ihre App
keine dieser Funktionen unterstützt, verwenden Android Auto und Android Automotive OS
Bereich zum Anzeigen von benutzerdefinierten Aktionen, die Sie erstellen.
Wenn Sie diese Bereiche nicht mit benutzerdefinierten Aktionen füllen möchten, können Sie
damit Android Auto und Android Automotive OS
wenn deine App die entsprechende Funktion nicht unterstützt. Rufen Sie dazu
setExtras()
mit einem Extra-Bundle, das Konstanten enthält, die dem
reservierten Funktionen.
SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_NEXT
entspricht ACTION_SKIP_TO_NEXT
und
SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_PREV
entspricht ACTION_SKIP_TO_PREVIOUS
. Verwenden Sie diese Konstanten als Schlüssel in der
Bündeln und verwenden Sie den booleschen Wert true
für die zugehörigen Werte.
Anfänglichen Wiedergabestatus festlegen
Wenn Android Auto und Android Automotive OS mit deinem Medienbrowser kommunizieren
übermittelt, sendet Ihre Mediensitzung den Status der Inhaltswiedergabe mithilfe von
PlaybackStateCompat
.
Deine App sollte nicht automatisch mit der Wiedergabe von Musik beginnen, wenn Android Automotive OS
oder Android Auto eine Verbindung
zu Ihrem Medienbrowser herstellen. Verwenden Sie stattdessen Android
und Android Automotive OS, um die Wiedergabe je nach
Status oder Nutzeraktionen.
Legen Sie dazu den anfänglichen PlaybackStateCompat
fest.
Ihrer Mediensitzung zu
STATE_STOPPED
,
STATE_PAUSED
,
STATE_NONE
oder STATE_ERROR
.
Mediensitzungen in Android Auto und Android Automotive OS dauern nur
Dauer der Fahrt, sodass die Nutzer diese Sitzungen häufig starten und beenden. Bis
nahtlose Fahrt zwischen den Fahrten fördern,
sodass die Medien-App
um die Anfrage fortzusetzen, kann der Nutzer automatisch dort weitermachen, wo er aufgehört hat.
deaktiviert, z. B. das zuletzt wiedergegebene Medienelement, PlaybackStateCompat
,
und der Warteschlange.
Benutzerdefinierte Wiedergabeaktionen hinzufügen
Du kannst benutzerdefinierte Wiedergabeaktionen hinzufügen, um zusätzliche Aktionen anzuzeigen, die deine
Medien-App unterstützt. Wenn der Platz ausreicht (und nicht reserviert ist), fügt Android den
benutzerdefinierte Aktionen an die Transportsteuerungen an. Andernfalls werden die benutzerdefinierten Aktionen
im Dreipunkt-Menü angezeigt. Benutzerdefinierte Aktionen werden in der Reihenfolge angezeigt
werden sie PlaybackStateCompat
hinzugefügt.
Benutzerdefinierte Aktionen verwenden, um ein Verhalten zu ermöglichen, das sich vom Standardverhalten unterscheidet Aktionen. Verwenden Sie sie nicht als Ersatz oder Duplizierung von Standard- Aktionen.
Mit dem addCustomAction()
können Sie benutzerdefinierte Aktionen hinzufügen.
in der PlaybackStateCompat.Builder
-Datei
.
Das folgende Code-Snippet zeigt, wie Sie ein benutzerdefiniertes Aktion:
Kotlin
stateBuilder.addCustomAction( PlaybackStateCompat.CustomAction.Builder( CUSTOM_ACTION_START_RADIO_FROM_MEDIA, resources.getString(R.string.start_radio_from_media), startRadioFromMediaIcon ).run { setExtras(customActionExtras) build() } )
Java
stateBuilder.addCustomAction( new PlaybackStateCompat.CustomAction.Builder( CUSTOM_ACTION_START_RADIO_FROM_MEDIA, resources.getString(R.string.start_radio_from_media), startRadioFromMediaIcon) .setExtras(customActionExtras) .build());
Ein ausführlicheres Beispiel für diese Methode finden Sie in der setCustomAction()
.
in der Beispiel-App "Universal Android Music Player" auf GitHub.
Nachdem Sie die benutzerdefinierte Aktion erstellt haben, kann Ihre Mediensitzung auf die Aktion reagieren
durch Überschreiben des onCustomAction()
.
Das folgende Code-Snippet zeigt, wie Ihre App auf eine Aktion „Radiokanal starten“:
Kotlin
override fun onCustomAction(action: String, extras: Bundle?) { when(action) { CUSTOM_ACTION_START_RADIO_FROM_MEDIA -> { ... } } }
Java
@Override public void onCustomAction(@NonNull String action, Bundle extras) { if (CUSTOM_ACTION_START_RADIO_FROM_MEDIA.equals(action)) { ... } }
Ein ausführlicheres Beispiel für diese Methode finden Sie in der onCustomAction
.
in der Beispiel-App "Universal Android Music Player" auf GitHub.
Symbole für benutzerdefinierte Aktionen
Für jede benutzerdefinierte Aktion, die Sie erstellen, ist eine Symbolressource erforderlich. Apps in Autos können die auf vielen verschiedenen Bildschirmgrößen und -dichten ausgeführt werden. müssen Vektor-Drawables sein. A Mit Vector Drawable kannst du Assets skalieren, ohne Details zu verlieren. Ein Vektor Drawable vereinfacht auch das Ausrichten der Kanten und Ecken an Pixelgrenzen bei kleinere Auflösungen.
Wenn eine benutzerdefinierte Aktion zustandsorientiert ist, z. B. wenn sie eine Wiedergabeeinstellung ein- oder ausschaltet, deaktiviert. Bieten Sie unterschiedliche Symbole für die verschiedenen Stadien an, damit Nutzende eine Änderung sehen, wenn sie die Aktion auswählen.
Alternative Symbolstile für deaktivierte Aktionen angeben
Wenn eine benutzerdefinierte Aktion für den aktuellen Kontext nicht verfügbar ist, tauschen Sie das benutzerdefinierte Aktionssymbol mit einem alternativen Symbol, das anzeigt, dass die Aktion deaktiviert ist.
Audioformat angeben
Um anzugeben, dass für die aktuelle Wiedergabe von Medien ein spezielles Audioformat verwendet wird,
kannst du Symbole angeben, die in Autos gerendert werden, die diese Funktion unterstützen. Ich
kann das
KEY_CONTENT_FORMAT_TINTABLE_LARGE_ICON_URI
und die
KEY_CONTENT_FORMAT_TINTABLE_SMALL_ICON_URI
im Extras-Paket des aktuell wiedergegebenen Medienelements (übergeben an
MediaSession.setMetadata()
. Legen Sie beides fest:
dieser Extras für unterschiedliche Layouts.
Außerdem können Sie den zusätzlichen Wert für KEY_IMMERSIVE_AUDIO
festlegen.
Autohersteller zu informieren, dass es sich um immersiven Audio handelt. Diese sollten vorsichtig sein,
wenn ihr entscheidet, ob ihr Audioeffekte anwendet, die die
immersive Inhalte zu erstellen.
Links von gerade wiedergegebenem Element hinzufügen
Sie können das aktuell wiedergegebene Medienelement so konfigurieren, dass Untertitel, Beschreibung oder beide sind Links zu anderen Medienelementen. So können Nutzende schnell zu verwandte Artikel; z. B. zu anderen Songs desselben Künstlers, andere Folgen dieses Podcasts usw. unterstützt. Wenn das Auto diese Funktion unterstützt, können Nutzer können Sie auf den Link tippen, um zu diesen Inhalten zu gelangen.
Um Links hinzuzufügen, konfigurieren Sie die
KEY_SUBTITLE_LINK_MEDIA_ID
-Metadaten
(um aus der Untertitel zu verlinken) oder
KEY_DESCRIPTION_LINK_MEDIA_ID
(für Verknüpfung von
die Beschreibung). Weitere Informationen finden Sie in der entsprechenden Referenzdokumentation
Metadatenfelder.
Sprachbedienung unterstützen
Ihre Medien-App muss die Sprachbedienung unterstützen, damit Fahrer und die praktische Erfahrung, die Ablenkungen minimiert. Wenn Ihre App zum Beispiel ein Medienelement spielt, kann der Nutzer sagen: "Spiel [Titel] ab. um einen anderen Song abzuspielen, ohne den Sensor des Autos Display. Nutzer können Abfragen starten, indem sie auf die entsprechenden Schaltflächen das Lenkrad verwenden oder die Hotwords Ok Google sagen.
Wenn Android Auto oder Android Automotive OS eine Stimme erkennen und interpretiert
Aktion wird diese Sprachbedienung der App über
onPlayFromSearch()
Beim Empfang dieses Callbacks findet die App Inhalte, die mit der query
übereinstimmen.
String und startet die Wiedergabe.
Nutzer können in ihrer Suchanfrage verschiedene Kategorien von Begriffen angeben: Genre, Künstler,
Album, Titelname, Radiosender oder Playlist. Beim Erstellen
unterstützen. Berücksichtigen Sie dabei alle Kategorien, die für Ihre App sinnvoll sind.
Wenn Android Auto oder Android Automotive OS erkennt,
bestimmten Kategorien hinzugefügt werden, werden Extras im extras
-Parameter angehängt. Die
können folgende Extras gesendet werden:
Berücksichtigen Sie einen leeren query
-String, der gesendet werden kann durch
Android Auto oder Android Automotive OS, wenn der Nutzer keine Suchbegriffe angibt.
Beispiel: Der Nutzer sagt „Spiel Musik“. In diesem Fall könnte Ihre App
einen vor Kurzem angehörten oder einen neu vorgeschlagenen Titel starten.
Wenn eine Suchanfrage nicht schnell verarbeitet werden kann, solltest du sie nicht in onPlayFromSearch()
blockieren.
Setze stattdessen den Wiedergabestatus auf STATE_CONNECTING
.
und die Suche in einem asynchronen Thread durchführen.
Sobald die Wiedergabe beginnt, können Sie die Warteschlange der Mediensitzung mit verwandte Inhalte. Wenn der Nutzer beispielsweise die Wiedergabe eines Albums anfordert, App die Wiedergabeliste möglicherweise mit der Titelliste des Albums füllt. Erwägen Sie auch, durchsuchbare Suchergebnisse werden unterstützt, sodass Nutzer einen anderen Track suchen, der ihrer Suchanfrage entspricht.
Neben play Android Auto und Android Automotive OS
Sprachbefehle erkennen, um die Wiedergabe zu steuern, z. B. „Musik pausieren“ und "nächste
Song“ und ordnen Sie diese Befehle
den entsprechenden Mediensitzungs-Callbacks zu.
wie onPause()
und onSkipToNext()
.
Ein detailliertes Beispiel für die Implementierung von sprachgesteuerten Wiedergabeaktionen in finden Sie unter Google Assistant und Medien-Apps.
Ablenkungsmaßnahmen implementieren
Weil das Smartphone eines Nutzers während der Nutzung von Android mit den Lautsprechern im Auto verbunden ist Automatisch angezeigt wird, müssen Sie zusätzliche Vorkehrungen treffen, damit der Fahrer nicht abgelenkt wird.
Alarme im Auto unterdrücken
Android Auto-Medien-Apps dürfen keine Audiowiedergabe über die Autolautsprecher starten wenn der Nutzer die Wiedergabe beispielsweise durch Drücken einer Wiedergabetaste startet. Auch ein vom Nutzer geplanter Wecker in deiner Medien-App darf nicht gestartet werden. Musik über die Autolautsprecher abzuspielen.
Um diese Anforderung zu erfüllen,
kann CarConnection
verwenden
als Signal hinzu, bevor Audio wiedergegeben wird. Deine App kann prüfen, ob das Smartphone
auf ein Autodisplay zu projizieren, indem LiveData
für die Autoverbindung beobachtet wird.
Typ
und zu prüfen, ob der Wert
CONNECTION_TYPE_PROJECTION
Wenn das Smartphone des Nutzers eine Projektion startet, müssen Medien-Apps, die Wecker unterstützen, eine Aktion ausführen Folgendes tun:
- Deaktiviere den Alarm.
- Alarm über
STREAM_ALARM
abspielen und über eine Benutzeroberfläche auf dem Smartphone-Display, um den Alarm zu deaktivieren.
Umgang mit Medienwerbung
Standardmäßig zeigt Android Auto eine Benachrichtigung an, wenn sich die Medienmetadaten ändern
während einer Audiowiedergabesitzung. Wenn eine Medien-App von der Musikwiedergabe wechselt
Werbung zu präsentieren, lenkt von einer
Benachrichtigung an den Nutzer. So verhindern Sie, dass Android Auto eine Benachrichtigung anzeigt
müssen Sie den Schlüssel für die Medienmetadaten
METADATA_KEY_IS_ADVERTISEMENT
bis
METADATA_VALUE_ATTRIBUTE_PRESENT
,
Dies wird im folgenden Code-Snippet gezeigt:
Kotlin
import androidx.media.utils.MediaConstants override fun onPlayFromMediaId(mediaId: String, extras: Bundle?) { MediaMetadataCompat.Builder().apply { if (isAd(mediaId)) { putLong( MediaConstants.METADATA_KEY_IS_ADVERTISEMENT, MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT) } // ...add any other properties you normally would. mediaSession.setMetadata(build()) } }
Java
import androidx.media.utils.MediaConstants; @Override public void onPlayFromMediaId(String mediaId, Bundle extras) { MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); if (isAd(mediaId)) { builder.putLong( MediaConstants.METADATA_KEY_IS_ADVERTISEMENT, MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT); } // ...add any other properties you normally would. mediaSession.setMetadata(builder.build()); }
Allgemeine Fehler beheben
Wenn in der App ein Fehler auftritt, setze den Wiedergabestatus auf STATE_ERROR
und geben Sie mithilfe des setErrorMessage()
eine Fehlermeldung an.
. Weitere Informationen finden Sie unter PlaybackStateCompat
.
finden Sie eine Liste mit Fehlercodes, die Sie beim Festlegen der Fehlermeldung verwenden können.
Fehlermeldungen müssen für den Nutzer sichtbar und mit den aktuellen
Sprache. Android Auto und Android Automotive OS können dann den Fehler
Nachricht an den Nutzer.
Wenn Inhalte in der aktuellen Region des Nutzers nicht verfügbar sind, haben Sie folgende Möglichkeiten:
ERROR_CODE_NOT_AVAILABLE_IN_REGION
verwenden
Fehlercode beim Festlegen der Fehlermeldung.
Kotlin
mediaSession.setPlaybackState( PlaybackStateCompat.Builder() .setState(PlaybackStateCompat.STATE_ERROR) .setErrorMessage(PlaybackStateCompat.ERROR_CODE_NOT_AVAILABLE_IN_REGION, getString(R.string.error_unsupported_region)) // ...and any other setters. .build())
Java
mediaSession.setPlaybackState( new PlaybackStateCompat.Builder() .setState(PlaybackStateCompat.STATE_ERROR) .setErrorMessage(PlaybackStateCompat.ERROR_CODE_NOT_AVAILABLE_IN_REGION, getString(R.string.error_unsupported_region)) // ...and any other setters. .build());
Weitere Informationen zu Fehlerstatus finden Sie unter Verwenden einer Mediensitzung: Status und Fehler.
Wenn ein Android Auto-Nutzer die App auf Ihrem Smartphone öffnen muss, um einen Fehler zu beheben, um dem Nutzer diese Informationen in Ihrer Nachricht zur Verfügung zu stellen. Beispiel: Ihr Fehler könnte die Meldung „In [Name Ihrer App] anmelden“ angezeigt werden. statt "Bitte melden Sie sich an".