Passen Sie bestehende Android-Video-Apps, Spiele und Webbrowser an, damit sie als geparkte Apps auf Android Auto und Android Automotive OS laufen. Befolgen Sie diese Schritte, um die Qualitätsrichtlinien für Auto-Apps für die Verteilung über Google Play zu erfüllen.
Voraussetzungen
- Beginnen Sie mit einer bestehenden adaptiven Android-App aus einer der unterstützten Kategorien für geparkte Apps: Videostreaming-Apps, Spiele oder Webbrowser.
Glossar
- Geparkte Apps: Geparkte Apps laufen auf Android Auto und Android Automotive OS nur, während das Fahrzeug geparkt ist. Die drei Kategorien sind Video, Spiele und Browser; andere Kategorien können nicht als geparkte Apps veröffentlicht werden.
- Android Auto: Android Auto ist ein telefonbasiertes Projektionssystem. Apps werden auf dem Telefon des Benutzers ausgeführt und über eine Kabel- oder Drahtlosverbindung auf das Fahrzeugdisplay projiziert. Android Auto ist eine separate Plattform von Android Automotive OS.
- Android Automotive OS: Android Automotive OS (AAOS) ist eine Android-Variante, die direkt auf dem Fahrzeug läuft. Android Automotive OS ist eine separate Plattform von Android Auto.
- Kategorie Video: Video-Apps zeigen gestreamte Videos an, während das Fahrzeug geparkt ist. Im Allgemeinen auf Android Automotive OS verfügbar; auf Android Auto nicht unterstützt.
- Kategorie Spiele: Spiele-Apps bieten Spielmöglichkeiten, während das Fahrzeug geparkt ist. Im Allgemeinen auf Android Automotive OS und Android Auto verfügbar.
- Kategorie Browser: Webbrowser ermöglichen Benutzern das Surfen im Internet, während das Fahrzeug geparkt ist. In der Beta auf Android Automotive OS verfügbar; auf Android Auto nicht unterstützt.
- Kategorie Medien: Keine geparkte Kategorie. Medien-Apps spielen Audioinhalte (Musik, Radio, Hörbücher, ohne Video) während der Fahrt oder im geparkten Zustand ab.
- Android for Cars-Plattform: Android for Cars ist ein Oberbegriff, der Android Auto und Android Automotive OS umfasst.
- Allgemein verfügbare Kategorien: Erlaubt auf den Google Play-Tracks für internes Testen, geschlossenes Testen, offenes Testen und Produktion für eine unterstützte Plattform.
- Beta-Kategorien: Erlaubt auf Tracks für internes oder geschlossenes Testen; offene Test- und Produktionstracks erfordern die Aufnahme in ein Early-Access-Programm.
- Audio während der Fahrt: Eine Beta-Funktion auf Android Automotive OS, die Video-Apps erlaubt, Audio abzuspielen, während das Fahrzeug in Bewegung ist.
- Qualitätsrichtlinien für Auto-Apps: Wenn Sie eine App anhand der Kriterien der Stufe 3 (Car ready), Stufe 2 (Car optimized) oder Stufe 1 (Car differentiated) prüfen, MÜSSEN Sie die Qualitätsrichtlinien für Auto-Apps überprüfen.
- Kompatibilitätsmodus von Android Automotive OS: Der Kompatibilitätsmodus (
android.software.car.display_compatibility) ist eine Systemfunktion auf ausgewählten Fahrzeugen, die eine systemweite Zurück-Geste, sichere Darstellungsbereiche, Dichteskalierung und eine undurchsichtige Blockade im Fahrbetrieb (Verschieben von Aktivitäten in den Zustand Stopped) bereitstellt. Der Kompatibilitätsmodus ist nur für Apps relevant, die Android Automotive OS unterstützen; er ist nicht relevant für Apps, die nur Android Auto unterstützen.
Codebase-Erkundung
Durchsuchen Sie die Codebase nach AndroidManifest.xml (oder erstellen Sie
Assets/Plugins/Android/AndroidManifest.xml in Unity-Projekten),
res/xml/automotive_app_desc.xml, build.gradle, build.gradle.kts,
oder gradle/libs.versions.toml-Dateien. Finden Sie vorhandene Videoplayer,
MediaSession-Klassen, requestedOrientation-Aufrufe und WindowInsets-
Handler. Fragen Sie, sofern nicht anders vom Benutzer angewiesen, um Erlaubnis, bevor Sie
Abhängigkeiten hinzufügen.
Schritt 1: Konfigurieren des App-Manifests
Deklarieren Sie die App-Kategorie, Zielplattformen, Hardware-Feature-Anforderungen und
Aktivitätskonfiguration in AndroidManifest.xml.
1.1: Identifizieren der App-Kategorie
- Video-Apps : Video-Apps MÜSSEN
android:appCategory="video"auf<application>setzen und DÜRFEN NICHTapp/src/main/res/xml/automotive_app_desc.xmlmituses name="video"einfügen. - Spiele : Spiele MÜSSEN
android:appCategory="game"auf<application>setzen. Deklarieren Sieandroid.hardware.gamepadmitandroid:required="false", wenn die App Controller-Eingabe unterstützt. - Browser : Browser MÜSSEN
<category android:name="android.intent.category.APP_BROWSER"/>imMAIN<intent-filter>einer exportierten<activity>(android:exported="true") enthalten.
1.2: Zielplattformen und Hardware-Features identifizieren
- Android Auto : Apps, die auf Android Auto (Android 15+) abzielen, MÜSSEN
<category android:name="android.intent.category.CAR_LAUNCHER"/>zu einem<intent-filter>in derAndroidManifest.xmlhinzufügen. Fügen Sie es zumMAIN<intent-filter>hinzu, es sei denn, der Benutzer gibt einen anderen Intent-Filter an. FÜGEN SIE DIESE KATEGORIE NIE HINZU, wenn die App ausschließlich auf Android Automotive OS abzielt. - Android Automotive OS : Apps, die auf Android Automotive OS abzielen, MÜSSEN
<uses-feature android:name="android.hardware.type.automotive" android:required="false"/>("false"für Mobil- oder Multi-Formfaktor-Tracks;"true"nur, wenn die App auf dem dedizierten Automotive OS-Track veröffentlicht wird) in derAndroidManifest.xmldeklarieren. FÜGEN SIE DIESES FEATURE-TAG NIE HINZU, wenn die App ausschließlich auf Android Auto abzielt. - Nicht erforderliche Hardware-Features (
DO-1) : Um die Google Play-Feature-Anforderungen undDO-1zu erfüllen, deklarieren Sie nicht unterstützte Features (android.hardware.wifi,android.hardware.screen.portrait,android.hardware.screen.landscape,android.hardware.camera) mitandroid:required="false"und entfernen Sieandroid:required="true"bei Features, die in Autos nicht vorhanden sind. - Display-Kontinuität (
LS-C1) : Konfigurieren Sieandroid:configChangesfürscreenSize,smallestScreenSize,orientation,screenLayoutunddensityauf<activity>, damit ein Wechsel zu oder von einem entfernten Display die Aktivität nicht neu erstellt oder die Wiedergabe stottert. - Kompatibilitätsmodus und Ablenkung : Die Deklaration des Kompatibilitätsmodus ist optional und nur für Apps relevant, die Android Automotive OS unterstützen. FÜGEN SIE DEN KOMPATIBILITÄTSMODUS NIE für Apps hinzu, die nur Android Auto unterstützen. Das Hinzufügen von
android.hardware.type.automotivedeaktiviert den Kompatibilitätsmodus, es sei denn,<meta-data android:name="android.software.car.display_compatibility" android:value="true"/>wird zu<application>hinzugefügt. Wenn eine Appandroid.software.car.display_compatibilityinAndroidManifest.xmldeklariert, MUSS die App zur LaufzeitPackageManager.hasSystemFeature("android.software.car.display_compatibility")prüfen und doppelte app-interne Zurück- oder Schließen-Elemente ausblenden, wenntruezurückgegeben wird. Geparkte Apps DÜRFEN NICHT<meta-data android:name="distractionOptimized" android:value="true"/>auf irgendeiner<activity>enthalten (DD-2,DD-3).
Schritt 2: Bereitstellen von Rücknavigation und Ausrichtungsunterstützung
2.1: App-interne Zurück- und Schließen-Elemente hinzufügen
Android Automotive OS-Fahrzeuge müssen keine Hardware- oder Software-
Zurück-Taste oder Gestennavigation haben (AN-1). Stellen Sie explizite UI-
Zurück- und Schließen-Steuerelemente auf jedem nicht-root-Bildschirm bereit, einschließlich Detailbildschirmen und Vollbild-Playern:
- Wenn
AndroidManifest.xmlnichtandroid.software.car.display_compatibilitydeklariert: Zeigen Sie bedingungslos explizite app-interne Zurück- und Schließen-Steuerelemente an. - Wenn
AndroidManifest.xmlandroid.software.car.display_compatibilitymitandroid:value="true"deklariert: Zeigen Sie app-interne Zurück- und Schließen-Steuerelemente nur an, wennPackageManager.hasSystemFeature("android.software.car.display_compatibility")falsezurückgibt.
2.2: Laufzeit-Ausrichtungsanfragen absichern
Fahrzeugdisplays haben feste Ausrichtungen. Das Anfordern von Querformat auf einem
display mit festem Hochformat verursacht Letterboxing oder Endlosschleifen (DO-1).
Entfernen Sie hartcodierte android:screenOrientation-Manifestattribute und prüfen Sie
PackageManager.FEATURE_SCREEN_LANDSCAPE und
PackageManager.FEATURE_SCREEN_PORTRAIT, bevor Sie requestedOrientation setzen.
Schritt 3: An Systemleisten und unregelmäßige Display-Aussparungen anpassen
3.1: Steuerbare Systemleisten-Einzüge verfolgen
Auf Android Automotive OS dürfen OEMs Systemleisten sichtbar sperren, damit
Klima- und Fahrzeugsteuerungen zugänglich bleiben (AR-1). Verfolgen Sie steuerbare
Einzüge mit OnControllableInsetsChangedListener, blenden Sie nur steuerbare Leisten aus
und wenden Sie windowInsetsPadding für nicht steuerbare statusBars,
navigationBars und displayCutout-Einzüge an.
3.2: Sicheres Rendern in unregelmäßige Display-Aussparungen
Um das Kriterium der Stufe 1 AR-2 auf gebogenen oder nicht-rechteckigen Fahrzeugdisplays zu
erfüllen, VERWENDEN SIE NIE LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT (0) oder
LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES (1). Konfigurieren Sie
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS (3) oder
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER (2) mit dem car-Ressourcenqualifizierer
in res/values-car-v30/integers.xml:
<integer name="windowLayoutInDisplayCutoutMode">3</integer>
Schützen Sie interaktive UI, App-Leisten und scrollbare Listen mit
WindowInsets.safeDrawing.
Schritt 4: Anforderungen an Fahrerablenkung und Medienwiedergabe erfüllen
4.1: Wiedergabe bei Lebenszyklusübergängen pausieren und Wiederaufnahme während der Fahrt blockieren
Wenn ein Fahrzeug zu fahren beginnt, überlagert das Betriebssystem geparkte Aktivitäten mit einer
blockierenden Überlagerung und löst onPause (und onStop bei Fahrzeugen im Kompatibilitätsmodus) aus. Um
DD-2, DD-3 und MC-1 zu erfüllen:
- Pausieren Sie die Wiedergabe bei
ON_PAUSEoderON_STOPmitLifecycleEventEffectausandroidx.lifecycle:lifecycle-runtime-compose. - Machen Sie eine
MediaSession(androidx.media3:media3-session) mit Play-, Pause- oder Stop-Befehlen und Elementmetadaten (MC-1) verfügbar und geben Sie sie inonClearedfrei. - Fügen Sie
useLibrary("android.car")inbuild.gradle.ktshinzu, umschließen SieExoPlayerinForwardingSimpleBasePlayer, hören Sie aufCarUxRestrictionsManager, pausieren Sie die Wiedergabe, wennisRequiresDistractionOptimizationtruewird, und entfernen SieCOMMAND_PLAY_PAUSEingetState, damit externeMediaSession-Steuerungen die Wiedergabe während der Fahrt nicht fortsetzen können:
@UnstableApi
class CarAwarePlayer(context: Context) :
ForwardingSimpleBasePlayer(ExoPlayer.Builder(context).build()) {
private var shouldPreventPlay = false
private var pausedByUxRestrictions = false
private lateinit var carUxRestrictionsManager: CarUxRestrictionsManager
init {
if (context.packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
val car = Car.createCar(context)
carUxRestrictionsManager =
car.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE) as CarUxRestrictionsManager
shouldPreventPlay =
carUxRestrictionsManager.currentCarUxRestrictions.isRequiresDistractionOptimization
invalidateState()
carUxRestrictionsManager.registerListener { restrictions: CarUxRestrictions ->
shouldPreventPlay = restrictions.isRequiresDistractionOptimization
if (!shouldPreventPlay && pausedByUxRestrictions) {
handleSetPlayWhenReady(true)
invalidateState()
} else if (shouldPreventPlay && isPlaying) {
pausedByUxRestrictions = true
handleSetPlayWhenReady(false)
invalidateState()
}
}
}
}
override fun getState(): State {
val state = super.getState()
return state.buildUpon()
.setAvailableCommands(
state.availableCommands.buildUpon()
.removeIf(COMMAND_PLAY_PAUSE, shouldPreventPlay)
.build()
)
.build()
}
override fun handleRelease(): ListenableFuture<*> {
if (::carUxRestrictionsManager.isInitialized) {
carUxRestrictionsManager.unregisterListener()
}
return super.handleRelease()
}
}
4.2: Hintergrundaudio während der Fahrt unterstützen (optionale Beta-Funktion)
Da dies eine optionale Beta-Funktion ist, IMPLEMENTIEREN SIE DIESE FUNKTION NIE, es sei denn, der Benutzer fordert sie an. So implementieren Sie die Funktion:
- Deklarieren Sie
<uses-feature android:name="com.android.car.background_audio_while_driving" android:required="false" />inAndroidManifest.xml, zusammen mitFOREGROUND_SERVICE- undFOREGROUND_SERVICE_MEDIA_PLAYBACK-Berechtigungen. - Prüfen Sie die Fahrzeugunterstützung zur Laufzeit mit
CarFeatures.isFeatureEnabled(context, CarFeatures.FEATURE_BACKGROUND_AUDIO_WHILE_DRIVING)ausandroidx.car.app:app. Setzen SieshouldPreventPlaynur, wenn!isBackgroundAudioWhileDrivingSupported && restrictions.isRequiresDistractionOptimization. - Hostet die
MediaSessionund den Player in einem exportiertenMediaSessionServicemitandroid:foregroundServiceType="mediaPlayback"und verbinden Sie sich von der UI mitMediaController.BuilderundbuildAsync.
Schritt 5: Schützen sensibler Daten in Browser-Apps
Da Fahrzeuge gemeinsam genutzte Geräte sind, MÜSSEN Browser den Zugriff auf
gespeicherte Passwörter und Zahlungsmethoden blockieren, es sei denn, sie sind durch eine Profilsperre geschützt (SD-1).
Vor dem Synchronisieren von Passwörtern oder Zahlungsdaten mit dem Fahrzeug MÜSSEN Browser
den Benutzer zur Authentifizierung auffordern und eine Mitteilung auf dem Fahrzeugbildschirm anzeigen, dass
seine Daten mit dem Auto synchronisiert werden (SD-2).
Prüfen Sie, ob eine PIN, ein Muster oder ein Passwort mit KeyguardManager festgelegt ist, öffnen Sie
Settings.ACTION_SECURITY_SETTINGS, falls nicht, und authentifizieren Sie sich mit
BiometricPrompt mit nur
BiometricManager.Authenticators.DEVICE_CREDENTIAL (Fahrzeuge haben keine biometrische Hardware):
val keyguardManager = context.getSystemService<KeyguardManager>()
val isDeviceSecure = keyguardManager?.isDeviceSecure == true
lateinit var biometricPrompt: BiometricPrompt
if (!isDeviceSecure) {
context.startActivity(
Intent(Settings.ACTION_SECURITY_SETTINGS).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
)
} else {
val promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle(context.getString(R.string.auth_title))
.setSubtitle(context.getString(R.string.sync_data_to_car_notice))
.setAllowedAuthenticators(BiometricManager.Authenticators.DEVICE_CREDENTIAL)
.build()
biometricPrompt.authenticate(promptInfo)
}
Schritt 6: Implementierung überprüfen
Erstellen Sie die App mit ./gradlew assembleDebug. Finden und beheben Sie alle Build-Fehler.
Nach der Implementierung
…
[truncated for translation]