Audiofokus

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:

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, CarAudioContexts nur an dasselbe Ausgabegerät wie CarAudioContexts 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.

Interaktionen mit dem Audiofokus

Abbildung 1. Interaktionen für den Audiofokus

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 von AUDIOFOCUS_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.