Bevor eine App einen logischen Stream startet, sollte sie den Audiofokus mit denselben Audioattributen anfordern, die für den logischen Stream verwendet werden. Es wird zwar empfohlen, eine solche Anfrage zu senden, sie wird vom System jedoch nicht erzwungen. Einige Apps überspringen das Senden der Anfrage möglicherweise ausdrücklich, um bestimmte Verhaltensweisen zu erreichen, z. B. um während eines Telefongesprächs absichtlich Töne abzuspielen.
Aus diesem Grund sollten Sie den Fokus als Möglichkeit zur indirekten Steuerung und Behebung von Konflikten bei der Wiedergabe betrachten und nicht als primären Mechanismus zur Audiosteuerung. Das Fahrzeug sollte nicht vom Fokussystem für den Betrieb des Audio-Subsystems abhängig sein.
Fokusinteraktionen
Um die Anforderungen von AAOS zu erfüllen, werden Anfragen für den Audiofokus basierend auf vordefinierten Interaktionen zwischen dem CarAudioContext
der Anfrage und dem des aktuellen Fokusinhabers verarbeitet. Es gibt drei Arten von Interaktionen: exklusiv, ablehnend und gleichzeitig.
Exklusive Interaktion
Bei exklusiven Interaktionen darf jeweils nur eine Anwendung den Fokus haben.
Daher wird der eingehenden Fokusanfrage der Fokus gewährt, während der aktuelle Fokusinhaber den Fokus verliert. Ein Beispiel hierfür wäre, wenn ein Nutzer eine neue Musik-App startet, während in einer anderen App bereits Musik abgespielt wird. Da in beiden Apps Medien abgespielt werden, darf nur eine der Anwendungen gleichzeitig den Fokus haben. Daher wird die Fokusanfrage der neu gestarteten Anwendung mit AUDIOFOCUS_REQUEST_GRANTED
zurückgegeben und die Anwendung, in der gerade Musik wiedergegeben wird, erhält ein Ereignis zur Fokusänderung mit einem Verluststatus, der der Art der Anfrage entspricht. Dies ist das Interaktionsmodell, das bei Android am häufigsten zu sehen ist.
Interaktion ablehnen
Bei Interaktionen vom Typ „Ablehnen“ wird die eingehende Anfrage immer abgelehnt. Ein Beispiel für eine abgelehnte Interaktion ist der Versuch, während eines Anrufs Musik abzuspielen. In diesem Fall, wenn der Anrufer derzeit den Audiofokus für einen Anruf hält und eine zweite Anwendung den Fokus für die Wiedergabe von Musik anfordert, erhält die Musikanwendung AUDIOFOCUS_REQUEST_FAILED
als Antwort auf ihre Anfrage. Da die Fokusanfrage abgelehnt wird, wird dem aktuellen Fokusinhaber keine Art von Fokusverlust gesendet.
Gleichzeitige Interaktion
Das Besondere an AAOS sind die gleichzeitigen Interaktionen. So können Apps, die den Audiofokus im Auto anfordern, den Fokus gleichzeitig mit anderen Apps halten. Damit eine gleichzeitige Interaktion stattfinden kann, müssen die folgenden Bedingungen erfüllt sein. Die:
- Eingehende Anfragen für den Fokus müssen
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
anfordern. - Der aktuelle Fokusinhaber
setPauseWhenDucked(true)
nicht. - Der aktuelle Fokusinhaber hat keine Duck-Ereignisse aktiviert.
Wenn diese Kriterien erfüllt sind, wird die Fokusanfrage mit AUDIOFOCUS_REQUEST_GRANTED
zurückgegeben, während der aktuelle Fokusinhaber keinen Fokuswechsel feststellt. Wenn der aktuelle Fokusinhaber jedoch festlegt, dass er Duck-Ereignisse erhalten oder bei Ducking pausieren möchte, verliert er den Fokus genau wie bei einer exklusiven Interaktion.
Gleichzeitige Streams verarbeiten
Die gleichzeitige Interaktion hat viele nützliche Anwendungen, aber OEMs müssen das Mischen und Ducking auf Hardwareebene über alle Ausgabegeräte hinweg übernehmen. Aus diesem Grund wird dringend empfohlen, CarAudioContext
s nur an dasselbe Ausgabegerät wie CarAudioContext
s weiterzuleiten, die nicht gleichzeitig wiedergegeben werden können. Durch separate Ausgabegeräte für gleichzeitige Streams kann der HAL einen der Streams stummschalten, bevor sie zusammengeführt werden, oder die physischen Streams an verschiedene Lautsprecher im Fahrzeug weiterleiten. Wenn die logischen Streams in Android gemischt werden, werden ihre Verstärkungen nicht geändert und sie werden als Teil desselben physischen Streams gesendet.
Wenn beispielsweise Navigation und Medien gleichzeitig übertragen werden, kann die Verstärkung für den Medienstream vorübergehend reduziert (geduckt) werden, damit die Navigationsanweisungen besser zu hören sind. Alternativ kann der Navigationsstream an die Lautsprecher auf der Fahrerseite weitergeleitet werden, während Medien im Rest des Fahrzeugs weiter abgespielt werden.
Interaktionsmatrix
Die folgende Tabelle zeigt die Interaktionsmatrix gemäß CarAudioService
.
Die Zeilen stellen die CarAudioContext
des aktuellen Fokuseigners dar und die Spalten die der eingehenden Anfrage.
In einem Beispiel, in dem eine Musik-Media-App derzeit den Fokus hat und eine Navigations-App den Fokus anfordert, zeigt die Matrix, dass die beiden Interaktionen gleichzeitig ausgeführt werden können, sofern die anderen Kriterien für gleichzeitige Interaktionen erfüllt sind.
Aufgrund der gleichzeitigen Interaktionen kann es mehr als einen Fokushalter geben. In diesem Fall wird eine eingehende Fokusanfrage mit allen aktuellen Fokusinhabern verglichen, bevor entschieden wird, welche Art von Interaktion angewendet werden soll. In diesem Fall wird die konservativste Interaktion ausgewählt (zuerst „Ablehnen“, dann „Exklusiv“ und schließlich „Gleichzeitig“).
In der folgenden Tabelle sind die Fokusinteraktionen zwischen dem CarAudioContext für eine eingehende Fokusanfrage (Spalten) und dem Kontext vorhandener Fokushalter (Zeilen) aufgeführt. Jede Zelle steht für den erwarteten Interaktionstyp für die beiden Kontexte.
Abbildung 1. Interaktionen für den Audiofokus
Navigation während eines Telefongesprächs
In Android 11 wurde eine neue Nutzereinstellung eingeführt, mit der Nutzer das Interaktionsverhalten zwischen Navigation und Telefonanrufen ändern können. Wenn android.car.KEY_AUDIO_FOCUS_NAVIGATION_REJECTED_DURING_CALL
festgelegt ist, ändert sich die Interaktion zwischen eingehenden NAVIGATION
-Fokusanfragen und aktuellen CALL
-Fokusinhabern von gleichzeitig zu ablehnen.
Wenn ein Nutzer nicht möchte, dass sein Anruf durch Navigationsanweisungen unterbrochen wird, kann er diese Einstellung aktivieren. Dieser Wert wird für den Nutzer gespeichert und kann dynamisch festgelegt werden, damit bei nachfolgenden Fokusanfragen der neue Einstellungswert berücksichtigt wird.
Verzögerbarer Audiofokus
In Android 11 wurde in AAOS die Unterstützung für die Anforderung eines verzögerbaren Audiofokus hinzugefügt. So können nicht vorübergehende Fokusanfragen verzögert werden, wenn ihre Interaktion mit den aktuellen Fokusinhabern normalerweise dazu führen würde, dass sie abgelehnt werden. Sobald eine Änderung des Fokus zu einem Zustand führt, in dem die verzögerte Anfrage den Fokus erhalten kann, wird die Anfrage gewährt.
Regeln für verzögerte Anfragen zum Audiofokus
- Nur nicht sitzungsspezifische Anfragen: Wie bereits erwähnt, kann eine verzögerte Anfrage nur für nicht sitzungsspezifische Quellen gestellt werden. So wird verhindert, dass ein transienter Ton lange nach dem relevanten Ereignis abgespielt wird.
- Nur eine Anfrage kann verzögert werden: Wenn eine verzögerbare Anfrage gestellt wird, während bereits eine verzögerte Anfrage vorliegt, erhält die ursprüngliche verzögerte Anfrage ein
AUDIOFOCUS_LOSS
-Änderungsereignis und die neue Anfrage eine synchrone Antwort vonAUDIOFOCUS_REQUEST_DELAYED
. - Verzögerbare Anfragen müssen einen
OnAudioFocusChangeListener
haben. Wenn eine Anfrage verzögert wird, wird der Listener verwendet, um den Anfragenden zu benachrichtigen, wenn die Anfrage genehmigt (AUDIOFOCUS_GAIN
) oder später abgelehnt (AUDIOFOCUS_LOSS
) wird.
Verzögerbaren Fokus anfordern
Wenn Sie eine Anfrage erstellen möchten, die verzögert werden kann, verwenden Sie Folgendes:
AudioFocusRequest.Builder#setAcceptsDelayedFocusGain
mMediaWithDelayedFocusListener = new MediaWithDelayedFocusListener(); mDelayedFocusRequest = new AudioFocusRequest .Builder(AudioManager.AUDIOFOCUS_GAIN) .setAudioAttributes(mMusicAudioAttrib) .setOnAudioFocusChangeListener(mMediaWithDelayedFocusListener) .setForceDucking(false) .setWillPauseWhenDucked(false) .setAcceptsDelayedFocusGain(true) .build();
Wenn du die Anfrage sendest, musst du die AUDIOFOCUS_REQUEST_DELAYED
-Antwort verarbeiten:
int delayedFocusRequestResults = mAudioManager.requestAudioFocus(mDelayedFocusRequest); if (delayedFocusRequestResults == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { // start audio playback return; } if (delayedFocusRequestResults == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) { // audio playback delayed to audio focus listener return; }
Wenn die Anfrage verzögert wird, ist der Fokus-Listener für die Verarbeitung von Fokusänderungen verantwortlich:
private final class MediaWithDelayedFocusListener implements OnAudioFocusChangeListener { @Override public void onAudioFocusChange(int focusChange) { synchronized (mLock) { switch (focusChange) { case AudioManager.AUDIOFOCUS_GAIN: … // Start focus playback case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: … // Pause media transiently case AudioManager.AUDIOFOCUS_LOSS: … // Stop media
Verwaltung des Fokus in mehreren Zonen
In Fahrzeugen mit mehreren Audiozonen wird der Audiofokus für jede Zone unabhängig voneinander verwaltet. Daher wird bei einer Anfrage an eine Zone nicht berücksichtigt, was in anderen Zonen den Fokus hält, und es wird auch nicht dazu geführt, dass der Fokus in anderen Zonen verloren geht. So kann der Fokus der Hauptkabine getrennt von einem Entertainmentsystem für die Rücksitze verwaltet werden, sodass die Audiowiedergabe in einer Zone nicht durch Änderungen des Fokus in einer anderen unterbrochen wird.
Die Fokusverwaltung für alle Anwendungen wird automatisch vom CarAudioService
übernommen. Die Audiozone einer Fokusanfrage wird anhand der zugehörigen UserId
oder UID
bestimmt. Weitere Informationen finden Sie unter Audio-Routing.
Audio aus mehreren Zonen gleichzeitig anfordern
Wenn eine App Audio in mehreren Zonen gleichzeitig abspielen möchte, muss sie für jede Zone den Fokus anfordern, indem sie AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID
in das Bundle aufnimmt:
// Create attribute with bundle and AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID Bundle bundle = new Bundle(); bundle.putInt(CarAudioManager.AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID, zoneId); AudioAttributes attributesWithZone = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_MEDIA) .addBundle(bundle) .build(); // Create focus request using built attributesWithZone
Mit diesem Bundle-Parameter kann der Anfragende die automatischen Audiozonenzuordnungen überschreiben, um stattdessen die angegebene Zonen-ID zu verwenden. So kann eine App separate Anfragen für verschiedene Audiozonen senden.
HAL Audio Focus
Ab Android 11 kann die HAL den Fokus im Namen externer Streams anfordern. Diese APIs sind zwar optional, werden aber dringend empfohlen, damit externe Töne besser in das Android-System eingebunden werden und die Nutzerfreundlichkeit verbessert wird.
Die HAL ist jedoch weiterhin dafür verantwortlich, welche Töne Vorrang haben. In diesem Zusammenhang sollten Notfall- und sicherheitskritische Töne unabhängig davon abgespielt werden, ob der HAL der Audiofokus gewährt wird, und auch dann fortgesetzt werden, wenn der HAL den Audiofokus verliert. Das gilt auch für alle Töne, die aufgrund von Vorschriften erforderlich sind.
Ebenso sollte die HAL Android-Streams proaktiv stummschalten, wenn Notfall- oder sicherheitsrelevante Töne abgespielt werden, damit diese deutlich zu hören sind.
AudioControl@2.0
Version 2.0 der AudioControl HAL führt mehrere neue APIs ein:
API | Zweck |
---|---|
IAudioControl#registerFocusListener |
Registriert eine Instanz von IFocusListener bei der AudioControl HAL.
Über diesen Listener kann die HAL den Audiofokus anfordern und aufheben. Der HAl muss eine ICloseHandle -Instanz bereitstellen, die von Android zum Aufheben der Registrierung des Listeners verwendet wird.
|
IAudioControl#onAudioFocusChange |
Benachrichtigt den HAL über Statusänderungen, um Anfragen zu fokussieren, die vom HAL über die IFocusListener gesendet werden. Dazu gehören auch Antworten auf erste Anfragen zum Fokus.
|
IFocusListener#requestAudioFocus |
Anfragen werden im Namen des HAL für eine bestimmte Verwendung, Zonen-ID und einen bestimmten Fokusgewinntyp gesendet. |
IFocusListener#abandonAudioFocus |
Gibt vorhandene HAL-Fokusanfragen für die angegebene Verwendung und Zonen-ID auf. |
Der HAL kann mehrere Fokusanfragen gleichzeitig haben, ist aber auf eine Anfrage pro Paarung von Nutzungs- und Zonen-ID beschränkt. Android geht davon aus, dass die HAL sofort nach einer Anfrage mit der Wiedergabe von Tönen für eine Nutzung beginnt und dies so lange fortsetzt, bis der Fokus aufgehoben wird.
Mit Ausnahme von registerFocusListener
sind diese Anfragen alle oneway
, damit Android die HAL nicht verzögert, während eine Fokusanfrage verarbeitet wird. Der HAL sollte nicht warten, bis er den Fokus erlangt hat, bevor er sicherheitsrelevante Töne abspielt. Es ist optional, dass die HAL über IAudioControl#onAudioFocusChange
auf Änderungen des Audiofokus achtet und darauf reagiert. Wir empfehlen dies jedoch, wenn es angebracht ist.