Media-Apps, die die Vorlagen der Car App Library verwenden, können das Browsen und die Wiedergabe von Medien anpassen und gleichzeitig dafür sorgen, dass die Nutzerfreundlichkeit für Autodisplays optimiert wird und Ablenkungen während der Fahrt minimiert werden.
In dieser Anleitung wird davon ausgegangen, dass Sie bereits eine Media-App haben, die Audioinhalte auf einem Smartphone abspielt, und dass Ihre Media-App der Android-Architektur für Media-Apps entspricht. Mit der
Car App Library können Sie die In-App-Oberfläche durch
Vorlagen ersetzen, anstatt die
MediaBrowserDatenstruktur zu verwenden, die unter Medien-Apps für Autos entwickeln beschrieben wird. Sie müssen weiterhin ein MediaSession für die Wiedergabesteuerung und ein MediaBrowserService oder MediaLibraryService für Empfehlungen und andere smarte Funktionen bereitstellen.
Manifest der App konfigurieren
Zusätzlich zu den in Android for Cars App-Bibliothek verwenden beschriebenen Schritten sind für Vorlagen-Medien-Apps folgende Anforderungen zu erfüllen:
Kategorieunterstützung im Manifest deklarieren
In Ihrer App muss die androidx.car.app.category.MEDIA
App-Kategorie für Autos im Intent
-Filter des CarAppService deklariert sein.
<application>
...
<service
...
android:name=".MyCarAppService"
android:exported="true">
<intent-filter>
<action android:name="androidx.car.app.CarAppService" />
<category android:name="androidx.car.app.category.MEDIA"/>
</intent-filter>
</service>
...
<application>
Damit Ihre App auf MediaPlaybackTemplate zugreifen kann, muss sie in ihrer Manifestdatei auch die Berechtigung androidx.car.app.MEDIA_TEMPLATES deklarieren:
<manifest ...>
...
<uses-permission android:name="androidx.car.app.MEDIA_TEMPLATES"/>
...
</manifest>
Mindest-API-Level für Auto-Apps festlegen
Medien-Apps, die MediaPlaybackTemplate verwenden, werden nur in CAL API 8 und höher unterstützt. Achten Sie darauf, dass das Mindest-Car App API level auf 8 festgelegt ist.
<application ...>
...
<meta-data
android:name="androidx.car.app.minCarApiLevel"
android:value="8"/>
...
</application>
Symbol für die Namensnennung bereitstellen
Fügen Sie Medien-Apps, die mit der Programmbibliothek Car App erstellt wurden, ein Attributionssymbol hinzu.
Android Auto-Unterstützung deklarieren
Das Manifest Ihrer App muss Folgendes enthalten:
<application>
...
<meta-data android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc"/>
...
</application>
Fügen Sie dann die template-Deklaration zu automotive_app_desc.xml in Ihren XML-Ressourcen hinzu. Die Ausgabe sollte so aussehen:
<automotiveApp xmlns:android="http://schemas.android.com/apk/res/android">
<uses name="media"/>
<uses name="template"/>
</automotiveApp>
Android Automotive OS-Unterstützung deklarieren
Es gibt zwei Möglichkeiten, eine Media-App mit Car App Library-Unterstützung für Android Automotive OS bereitzustellen: als einzelnes APK oder als zwei separate APKs. Wenn Sie ein einzelnes APK verteilen, wird es von Fahrzeugen unterstützt, die für Android Automotive OS mit dem Car App Library-Host aktiviert sind. Andernfalls wird auf eine MediaBrowserService- oder MediaLibraryService-Anwendung zurückgegriffen, auch bei älteren Android-Versionen (Android 10 bis Android 13). Wenn Sie zwei separate APKs verteilen, können Sie die neuen Ergänzungen der Car App Library-Version aktualisieren, ohne dass sich dies auf die MediaBrowserService- oder MediaLibraryService-Version Ihrer App auswirkt.
Einzelnes APK bereitstellen
Wenn Sie ein einzelnes APK für die Car App Library und MediaBrowserService- oder MediaLibraryService-Versionen Ihrer App bereitstellen, ist es wichtig, android.software.car.templates_host.media auf android:required="false" festzulegen.
<uses-feature android:name="android.software.car.templates_host.media" android:required="false"/>
Folgen Sie als Nächstes den Richtlinien für die Car App Library für AAOS und führen Sie eine startfähige CarAppActivity (oder Trampolin-Aktivität) ein. Sie müssen die Aktivität im Manifest auf android:enabled="false" festlegen. Fügen Sie als Nächstes der MediaBrowserService-Deklaration ein Metadaten-Tag hinzu, das die CarAppActivity-Komponente als Ersatz angibt. Hier ein Beispielmanifest:
<service android:name=".media.MyMediaService"
android:exported="true"
android:label="@string/app_name">
<intent-filter>
<action android:name="androidx.media3.session.MediaLibraryService"/>
</intent-filter>
<!-- Link to Car App Library Activity -->
<meta-data
android:name="androidx.car.app.media.CalMediaActivityComponent"
android:value="com.example.mediaapp.LaunchableTrampoline"/>
</service>
<activity
android:name=".LaunchableTrampoline"
android:exported="true"
android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
android:launchMode="singleTask"
android:label="@string/app_name_cal"
android:enabled="false"> <!-- Set to false -->
<meta-data android:name="distractionOptimized" android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="androidx.car.app.media.action.SHOW_MEDIA_PLAYBACK"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
Play-Vertrieb
Ihr APK mit der Car App Library und MediaBrowserService oder MediaLibraryService sollte mit einem höheren Versionscode und minSdk für Android 14 (34) aktiviert werden.
Bereitstellung mit zwei APKs
Wenn Sie zwei separate APKs verteilen möchten, eines mit der Car App Library und eines mit MediaBrowserService oder MediaLibraryService, gehen Sie so vor, um sicherzustellen, dass die richtigen Fahrzeugfunktionen richtig ausgerichtet sind.
Wenn Sie ein separates APK für die Car App Library-Version Ihrer App erstellen, müssen Sie android.software.car.templates_host.media auf android:required=true festlegen. So wird sichergestellt, dass die App nur auf Android Automotive OS-Builds verteilt wird, die für die Unterstützung des Car App Library-Hosts zertifiziert sind.
<uses-feature android:name="android.software.car.templates_host.media" android:required="true"/>
Abgesehen von der Verwendung von android.software.car.templates_host.media und der Festlegung auf android:required=true, müssen Sie die folgenden Schritte ausführen, um Android Automotive OS für Ihre startbare Car App Library-Aktivität zu aktivieren.
Google Play-Verteilung
Das APK, das die Car App-Bibliothek verwendet, sollte über den speziellen Automotive OS-Track verteilt werden.
Sprachbedienung unterstützen
Wenn Sie Ihre App für die Sprachsteuerung optimieren, können Nutzer häufige Aktionen freihändig ausführen.
Eine ausführlichere Implementierungsanleitung findest du unter Sprachbefehle für Medien unterstützen. Bei einer Media-App mit Vorlage müssen Sie MediaBrowserService oder MediaLibraryService nicht mit Suchergebnissen aktualisieren, wenn Sie einen Sprachbefehl erhalten. Fügen Sie stattdessen in Ihre Vorlage für die Medienwiedergabe eine Aktion ein, mit der der Nutzer basierend auf dieser Wiedergabe- oder Suchanfrage weitere Inhalte finden kann. Die Unterstützung von Sprachbefehlen ist erforderlich, um die VC-1-Qualitätsrichtlinie zu erfüllen.
Wiedergabevorlage erstellen
Auf dem MediaPlaybackTemplate werden Informationen zur Medienwiedergabe in der Media App der Car App Library angezeigt. Mit dieser Vorlage kann ein Header mit einem Titel und anpassbaren Aktionen festgelegt werden. Die Medieninformationen und Wiedergabesteuerelemente werden vom Host basierend auf dem Status des MediaSession Ihrer App eingefügt.
Abbildung 1:MediaPlaybackTemplate mit einer Header-Aktion zum Öffnen der Warteschlange oben.
In diesem Codebeispiel wird gezeigt, wie Sie eine Beispielvorlage für die Wiedergabe erstellen, in der eine Header-Aktion festgelegt wird, mit der der Nutzer zu einem Bildschirm mit der Warteschlange von Songs navigieren kann.
val playbackTemplate = MediaPlaybackTemplate.Builder()
.setHeader(
Header.Builder()
.setStartHeaderAction(Action.BACK)
.addEndHeaderAction(
Action.Builder()
.setTitle(model.context.getString(R.string.queue_button_title))
.setIcon(
CarIcon.Builder(
IconCompat.createWithResource(
model.context,
R.drawable.gs_queue_music_vd_theme_24,
))
.build())
.setOnClickListener(showQueueScreen())
.build())
.setTitle(model.context.getString(R.string.media_playback_view_title))
.build())
.build()
Wenn Sie MediaPlaybackTemplate verwenden, registrieren Sie ein MediaSession-Token mit MediaPlaybackManager in Ihrem CarAppService. Andernfalls wird ein Fehler angezeigt, wenn ein MediaPlaybackTemplate an den Host gesendet wird.
import androidx.car.app.media.MediaPlaybackManager
…
override fun onCreateSession(sessionInfo: SessionInfo): Session {
return object : Session() {
…
init {
lifecycle.addObserver(
LifecycleEventObserver { _, event ->
if (event == ON_CREATE) {
val token = ... // MediaSessionCompat.Token
(carContext.getCarService(CarContext.MEDIA_PLAYBACK_SERVICE) as MediaPlaybackManager)
.registerMediaPlaybackToken(token)
}
...
}
)
}
}
}
.registerMediaPlaybackToken ist erforderlich, um Informationen zur Medienwiedergabe und Steuerelemente für Android Auto bereitzustellen. Das ist auch wichtig, damit der Host benachrichtigungen für bestimmte Medien erstellen kann.
Bei Apps, die die Media3-Bibliothek verwenden und einen PlatformToken anstelle eines Standard-MediaSessionCompat.Token verwenden, müssen Sie in Ihrem MediaLibrarySession.Callback einen benutzerdefinierten SessionCommand implementieren, der das zugrunde liegende Plattform-Token der Sitzung zurückgibt: session.platformToken. Senden Sie in Ihrem CarAppService diesen benutzerdefinierten Befehl an die Sitzung. Sobald Sie das Plattform-Token erhalten haben, wandeln Sie es mit MediaSessionCompat.Token.fromToken(platformToken) um und übergeben Sie dieses kompatible Token in .registerMediaPlaybackToken() an die Car App Library.
Medien mithilfe von Vorlagen organisieren
Wenn Sie Medien wie Songs oder Alben zum Durchsuchen organisieren möchten, empfehlen wir die Verwendung von SectionedItemTemplate. Damit können Sie GridSection und RowSection zusammen verwenden, um Layouts zu erstellen, in denen Listen mit Bildern und Textelementen kombiniert werden.
Abbildung 2:Ein SectionedItemTemplate mit einem RowSection, gefolgt von einem GridSection
SectionedItemTemplate in einem TabTemplate verwenden
Eine praktische Möglichkeit, Medien in Ihrer App zu kategorisieren, ist die Verwendung von SectionedItemTemplate in einem TabTemplate.
val template =
SectionedItemTemplate.Builder()...build();
val tabTemplate =
TabTemplate.Builder(tabCallback)
.setTabContents(TabContents.Builder(template).build)
.setHeaderAction(Action.APP_ICON)
…
.build();
Komponenten und Funktionen der Car App Library 1.9
Mit der Car App Library API Version 1.9 werden benutzerdefinierte Komponenten für einzigartige Browsing-Funktionen eingeführt, z. B. Chips, Fortschrittsbalken, komprimierte Elemente, interaktive und erweiterte Kopfzeilen, Spotlight-Bereiche und Banner.
Abbildung 3:Ein SectionedItemTemplate mit Chips, Condensed Items, einem Interactive Header, Grid Items und einem Minimized Control Panel
Abbildung 4:Zwei Bildschirme zum Durchsuchen von Medien mit den Schaltflächen Expanded Header, Spotlight Sections und Progress Bars
Weitere Informationen zum Entwerfen der Benutzeroberfläche Ihrer Media-App mit diesen Vorlagen finden Sie unter Media-Apps.
Wiedergabesteuerung aufrufen
Beim Durchsuchen von Medien ist es wichtig, dass der Nutzer schnell und ohne Ablenkung zur MediaPlaybackTemplate navigieren kann.Um die Qualitätsanforderung MFT-1 zu erfüllen, muss Ihre App eine Möglichkeit bieten, von allen Medienbrowsing-Bildschirmen aus auf die MediaPlaybackTemplate zuzugreifen.
Wenn Sie SectionedItemTemplate verwenden, können Sie dies erreichen, indem Sie einen Aktionsbutton hinzufügen, der Sie zum Bildschirm für die Medienwiedergabe weiterleitet. Verwenden Sie die Standardaktion Action.MEDIA_PLAYBACK der Car App Library. In einer Medien-App wird diese Aktion als minimierte Steuerleiste angezeigt. Dies ist erforderlich, um die Qualitätsanforderung MFT-1 zu erfüllen, wenn Sie die Car App Library API 1.9 oder höher verwenden. Bei anderen Vorlagen ist eine Kopfzeilenaktion eine weitere Möglichkeit, dies zu erreichen.
System-Intents für die Medienwiedergabe verarbeiten
Der Nutzer muss zum MediaPlaybackTemplate weitergeleitet werden, wenn eine Anwendung über eine Systemoberfläche für die Medienwiedergabe, z. B. eine Medienkarte, gestartet wird. Media-Anwendungen müssen dieses Intent Action verarbeiten, um Nutzern eine nahtlose Nutzung zu ermöglichen.
Fügen Sie die Aktion androidx.car.app.media.action.SHOW_MEDIA_PLAYBACK dem Intent-Filter der Car App Library-Komponente (entweder CarAppActivity oder Ihrem Trampolin Activity) hinzu.
Ihre Aktivität muss einen launchMode von singleTask oder singleTop verwenden, damit onNewIntent() aufgerufen wird.
<activity
android:name=".LaunchableTrampoline"
android:exported="true"
android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
android:launchMode="singleTask"
android:label="@string/app_name_cal"
android:enabled="false">
<meta-data android:name="distractionOptimized" android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="androidx.car.app.media.action.SHOW_MEDIA_PLAYBACK"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
Überschreiben Sie in der Klasse Session die Methode onNewIntent(), um den eingehenden Intent zu parsen.
Wenn die eingehende Intent-Aktion mit SHOW_MEDIA_PLAYBACK übereinstimmt, leite den Nutzer zum Bildschirm „Now Playing“ weiter.
@Override
public void onNewIntent(@NonNull Intent intent) {
super.onNewIntent(intent);
if (SHOW_MEDIA_PLAYBACK.equals(intent.getAction())) {
ScreenManager screenManager = getCarContext().getCarService(ScreenManager.class);
// Avoid redundant navigation if already on the playing screen
if (screenManager.getTop() instanceof MyMediaPlayScreen) {
return;
}
screenManager.push(MyMediaPlayScreen.createScreenFromPlaying(
getCarContext(), mMediaSessionController));
}
}
Wenn Sie eine Trampolinaktivität verwenden, suchen Sie in onCreate() nach der Intent-Aktion. Übergeben Sie diese Aktion an die Intent zum Erstellen von CarAppActivity, bevor Sie finish() aufrufen.
public class LaunchableTrampoline extends AppCompatActivity {
private static final String SHOW_MEDIA_PLAYBACK = "androidx.car.app.media.action.SHOW_MEDIA_PLAYBACK";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent receivedIntent = getIntent();
String action;
if (SHOW_MEDIA_PLAYBACK.equals(receivedIntent.getAction())) {
action = SHOW_MEDIA_PLAYBACK;
} else {
action = Intent.ACTION_MAIN;
}
Intent intent = new Intent(action);
intent.setClassName(getPackageName(), "androidx.car.app.activity.CarAppActivity");
startActivity(intent);
finish();
}
}