Medien-App mit Vorlage erstellen

Vorlagenbasierte Medien-Apps befinden sich in der Betaphase
Derzeit kann jeder, der möchte, vorlagenbasierte Medien-Apps in den Tracks für interne und geschlossene Tests im Google Play Store veröffentlichen. Die Veröffentlichung in Tracks für offene Tests und Produktions-Tracks wird zu einem späteren Zeitpunkt zugelassen.

Medien-Apps, die die Vorlagen der Programmbibliothek Car App verwenden, können die Medienwiedergabe und das Durchsuchen von Medien anpassen. Gleichzeitig wird dafür gesorgt, dass die Nutzerfreundlichkeit für Autodisplays optimiert ist und Ablenkungen während der Fahrt minimiert werden.

In dieser Anleitung wird davon ausgegangen, dass Sie bereits eine Medien-App haben, die Audio auf einem Smartphone abspielt und dass Ihre Medien-App der Android-Architektur für Medien-Apps entspricht. Mit der Programmbibliothek Car App können Sie die In-App-Funktionen durch Vorlagen ersetzen, anstatt die Datenstruktur Medien-Apps für Autos erstellen MediaBrowser zu verwenden. Sie müssen weiterhin eine MediaSession für die Wiedergabesteuerung und einen MediaBrowserService oder MediaLibraryService bereitstellen, der für Empfehlungen und andere intelligente Funktionen verwendet wird.

Manifest Ihrer App konfigurieren

Zusätzlich zu den Schritten unter Android for Cars-App-Bibliothek verwenden sind für vorlagenbasierte Medien-Apps folgende Schritte erforderlich:

Kategorieunterstützung im Manifest deklarieren

Ihre App muss die androidx.car.app.category.MEDIA Car App-Kategorie im Intent Filter ihres CarAppService deklarieren.

<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>

Um auf MediaPlaybackTemplate zuzugreifen, muss Ihre App außerdem die Berechtigung androidx.car.app.MEDIA_TEMPLATES in ihrer Manifestdatei deklarieren:

<manifest ...>
  ...
  <uses-permission android:name="androidx.car.app.MEDIA_TEMPLATES"/>
  ...
</manifest>

Mindest-API-Level für Car App festlegen

Medien-Apps, die MediaPlaybackTemplate verwenden, werden nur in CAL API 8 und höher unterstützt. Achten Sie darauf, dass das 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 ein Symbol für die Namensnennung für Medien-Apps hinzu, die mit der Programmbibliothek Car App erstellt wurden.

Android Auto-Unterstützung deklarieren

Folgendes muss im Manifest Ihrer App enthalten sein:

<application>
  ...
  <meta-data android:name="com.google.android.gms.car.application"
      android:resource="@xml/automotive_app_desc"/>
  ...
</application>

Fügen Sie dann die Vorlagendeklaration in automotive_app_desc.xml in Ihren XML-Ressourcen hinzu. Sie 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 verschiedene Möglichkeiten, eine Medien-App, die mit der Programmbibliothek Car App erstellt wurde, unter Android Automotive OS zu vertreiben: als einzelnes APK oder als zwei separate APKs. Wenn Sie ein einzelnes APK vertreiben, werden Fahrzeuge unterstützt, die für Android Automotive OS mit dem Host der Programmbibliothek Car App 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 vertreiben, können Sie die neuen Ergänzungen der Version der Programmbibliothek Car App einfacher aktualisieren, ohne die Version von MediaBrowserService oder MediaLibraryService Ihrer App zu beeinträchtigen.

Einzelnes APK vertreiben

Wenn Sie ein einzelnes APK für die Versionen der Programmbibliothek Car App und MediaBrowserService oder MediaLibraryService Ihrer App vertreiben, müssen Sie die "" auf android:required="false". setzen.

<uses-feature android:name="android.software.car.templates_host.media" android:required="false"/>

Folgen Sie dann den Richtlinien der Programmbibliothek Car App für Android Automotive OS 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" setzen. Fügen Sie dann der Deklaration MediaBrowserService ein Metadatentag hinzu, das die Komponente CarAppActivity als Ersatz angibt. Unten sehen Sie 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>

Vertrieb bei Google Play

Ihr APK mit der Programmbibliothek Car App und MediaBrowserService oder MediaLibraryService sollte mit einem höheren Versionscode und minSdk für Android 14 (34) aktiviert werden.

Vertrieb mit zwei APKs

Wenn Sie zwei separate APKs vertreiben möchten, eines mit der Programmbibliothek Car App und eines mit MediaBrowserService oder MediaLibraryService, folgen Sie dieser Anleitung, um sicherzustellen, dass die richtigen Fahrzeugfunktionen korrekt angesprochen werden.

Wenn Sie ein separates APK für die Version der Programmbibliothek Car App erstellen, müssen Sie android.software.car.templates_host.media auf android:required=true setzen. So wird sichergestellt, dass die App nur in Android Automotive OS-Builds vertrieben wird, die mit Unterstützung für den Host der Programmbibliothek Car App zertifiziert sind.

<uses-feature android:name="android.software.car.templates_host.media" android:required="true"/>

Neben der Verwendung von android.software.car.templates_host.media und der Einstellung auf android:required=true oben müssen Sie die folgenden Schritte ausführen, um Android Automotive OS zu aktivieren für Ihre startfähige Aktivität der Programmbibliothek Car App.

Vertrieb bei Google Play

Das APK, das die Programmbibliothek Car App verwendet, sollte im speziellen Track für Automotive OS vertrieben werden.

Sprachbefehle unterstützen

Aktivieren Sie die Sprachsteuerung für Ihre App, damit Nutzer häufige Aktionen freihändig ausführen können. Weitere Informationen zur Implementierung finden Sie unter Sprachbefehle für Medien unterstützen. Wenn Sie eine vorlagenbasierte Medien-App verwenden und einen Sprachbefehl erhalten, müssen Sie MediaBrowserService oder MediaLibraryService nicht mit Suchergebnissen aktualisieren. Stattdessen können Sie in Ihrer Vorlage für die Medienwiedergabe eine Aktion hinzufügen, 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ät Richtlinie zu erfüllen.

Wiedergabevorlage erstellen

In MediaPlaybackTemplate werden Informationen zur Medienwiedergabe in Ihrer Medien-App der Programmbibliothek Car App angezeigt. Mit dieser Vorlage können Sie einen Header mit einem Titel und anpassbaren Aktionen festlegen. Die Medieninformationen und die Wiedergabesteuerung werden vom Host basierend auf dem Status von MediaSession Ihrer App ausgefüllt.

Ein Musikplayer zeigt „Sounds of Spring“ von Summer Fielding mit einem quadratischen Porträt einer Frau, die Gitarre spielt.

Abbildung 1:MediaPlaybackTemplate mit einer Header-Aktion zum Öffnen der Warteschlange oben

Dieses Codebeispiel zeigt, wie Sie eine Beispielvorlage für die Wiedergabe erstellen, die eine Header-Aktion festlegt, mit der der Nutzer zu einem Bildschirm mit der Warteschlange der 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 und Steuerelemente zur Medienwiedergabe für Android Auto verfügbar zu machen. Dies ist auch wichtig, damit der Host medienspezifische Benachrichtigungen erstellen kann.

Bei Apps, die die Media3-Bibliothek verwenden und ein PlatformToken anstelle eines Standard-MediaSessionCompat.Token verwenden, müssen Sie in Ihrem MediaLibrarySession.Callback einen benutzerdefinierten SessionCommand implementieren, der das zugrunde liegende Plattformtoken der Sitzung zurückgibt: session.platformToken. Senden Sie diesen benutzerdefinierten Befehl in Ihrem CarAppService an die Sitzung. Sobald Sie das Plattformtoken erhalten haben, konvertieren Sie es mit MediaSessionCompat.Token.fromToken(platformToken) und übergeben Sie dieses Kompatibilitätstoken in .registerMediaPlaybackToken() an die Programmbibliothek Car App.

Medien mit Vorlagen organisieren

Um Medien zum Durchsuchen zu organisieren, z. B. Songs oder Alben, empfehlen wir die Verwendung von SectionedItemTemplate, Damit können Sie GridSection und RowSection zusammen verwenden, um Layouts zu erstellen, die Listen mit Bildern und Textelementen kombinieren.

Auf der Benutzeroberfläche einer Musik-App werden zuletzt gespielte Songs und Alben angezeigt, darunter zwei vertikale Reihen und drei horizontale Albumcover.

Abbildung 2: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 Programmbibliothek Car App 1.9

Mit der Programmbibliothek Car App API Version 1.9 werden benutzerdefinierte Komponenten für einzigartige Suchfunktionen eingeführt, z. B. Chips, Fortschrittsbalken, komprimierte Elemente, interaktive und erweiterte Header, Spotlight-Bereiche und Banner.

Auf der Benutzeroberfläche einer Musik-App werden zuletzt gespielte Songs und Alben angezeigt, darunter zwei vertikale Reihen und drei horizontale Albumcover.

Abbildung 3:SectionedItemTemplate mit Chips, Condensed Items, einem Interactive Header, Grid Items und einem Minimized Control Panel

Auf der Benutzeroberfläche einer Musik-App werden zuletzt gespielte Songs und Alben angezeigt, darunter zwei vertikale Reihen und drei horizontale Albumcover.

Abbildung 4:Zwei Bildschirme zum Durchsuchen von Medien mit dem Expanded Header, Spotlight Sections und Progress Bars

Weitere Informationen zum Design der Benutzeroberfläche Ihrer Medien-App mit diesen Vorlagen finden Sie unter Medien-Apps.

Beim Durchsuchen von Medien ist es wichtig, dass der Nutzer mit minimaler Ablenkung schnell zu MediaPlaybackTemplate navigieren kann.Um die MFT-1 Qualitätsanforderung zu erfüllen, muss Ihre App eine Möglichkeit bieten, von allen Bildschirmen zum Durchsuchen von Medien auf das MediaPlaybackTemplate zuzugreifen.

Wenn Sie SectionedItemTemplate verwenden, können Sie dies erreichen, indem Sie eine Aktionsbutton hinzufügen, die Siezum Bildschirm für die Medienwiedergabe führt. Verwenden Sie die Standardaktion Action.MEDIA_PLAYBACK der Programmbibliothek Car App. In einer Medien-App wird diese Aktion als minimierte Steuerungsoberfläche angezeigt. Dies ist erforderlich, um die MFT-1 Qualitätsanforderung zu erfüllen, wenn Sie die Programmbibliothek Car App API 1.9 oder höher verwenden. Bei anderen Vorlagen ist eine Header-Aktion eine weitere Möglichkeit, dies zu erreichen.

System-Intents für die Medienwiedergabe verarbeiten

Der Nutzer muss zu MediaPlaybackTemplate weitergeleitet werden, wenn eine Anwendung über eine Systemoberfläche für die Medienwiedergabe gestartet wird, z. B. eine Medienkarte. Medienanwendungen müssen diese Intent Action verarbeiten, um Nutzern eine nahtlose Nutzerfreundlichkeit zu bieten.

Fügen Sie die Aktion androidx.car.app.media.action.SHOW_MEDIA_PLAYBACK dem Intent-Filter Ihrer Komponente der Programmbibliothek Car App hinzu (entweder CarAppActivity oder Ihre Trampolin-Activity).

Achten Sie darauf, dass Ihre Aktivität einen launchMode von singleTask oder singleTop verwendet, 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 Ihrer Session-Klasse onNewIntent(), um den eingehenden Intent zu parsen. Wenn die eingehende Intent-Aktion mit SHOW_MEDIA_PLAYBACK übereinstimmt, leiten Sie den Nutzer zum Bildschirm „Wird gerade wiedergegeben“ 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 Trampolin-Aktivität verwenden, suchen Sie in onCreate() nach der Intent-Aktion. Übergeben Sie diese Aktion an den Intent zur Erstellung 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();
    }
}