Zwei oder mehr Android-Apps können Audioinhalte gleichzeitig über denselben Ausgabestream wiedergeben und das System vermischt alles. Das ist zwar technisch beeindruckend, kann aber für Nutzer sehr ärgerlich sein. Damit nicht jede Musik-App gleichzeitig abgespielt wird, führt Android das Konzept des Audiofokus ein. Der Audiofokus kann jeweils nur von einer App gehalten werden.
Wenn Ihre App Audio ausgeben muss, sollte sie den Audiofokus anfordern. Wenn es fokussiert ist, kann es Ton wiedergeben. Nachdem Sie den Audiofokus erhalten haben, können Sie ihn aber möglicherweise nicht behalten, bis Sie fertig sind. Eine andere App kann einen Fokus anfordern, wodurch das Halten des Audiofokus vorzeitig beendet wird. In diesem Fall sollte Ihre App die Wiedergabe pausieren oder die Lautstärke verringern, damit Nutzer die neue Audioquelle besser hören können.
Vor Android 12 (API-Level 31) wird der Audiofokus nicht vom System verwaltet. App-Entwickler werden zwar dazu angehalten, die Richtlinien für den Audiofokus einzuhalten. Wenn eine App jedoch auch nach dem Verlust des Audiofokus auf einem Gerät mit Android 11 (API-Level 30) oder niedriger weiterhin laut wiedergegeben wird, kann das System dies nicht verhindern. Dieses Verhalten der Anwendung beeinträchtigt jedoch die Nutzerfreundlichkeit und kann dazu führen, dass Nutzer die fehlerhafte App deinstallieren.
Eine gut gestaltete Audio-App sollte den Audiofokus gemäß den folgenden allgemeinen Richtlinien verwalten:
Rufen Sie
requestAudioFocus()
unmittelbar vor Beginn der Wiedergabe auf und prüfen Sie, ob der AufrufAUDIOFOCUS_REQUEST_GRANTED
zurückgibt. Rufen SierequestAudioFocus()
imonPlay()
-Callback Ihrer Mediensitzung auf.Wenn eine andere App den Audiofokus erhält, können Sie die Wiedergabe stoppen oder pausieren oder die Lautstärke verringern.
Verlassen Sie den Audiofokus, wenn die Wiedergabe beendet wird, z. B. wenn in der App nichts mehr zur Verfügung steht. Ihre App muss den Audiofokus nicht verlassen, wenn der Nutzer die Wiedergabe pausiert, aber möglicherweise später wieder ansetzt.
Verwende
AudioAttributes
, um zu beschreiben, welche Art von Audio deine App wiedergibt. Geben Sie beispielsweise für Anwendungen, die Sprache wiedergeben,CONTENT_TYPE_SPEECH
an.
Der Audiofokus wird je nach ausgeführter Android-Version unterschiedlich gehandhabt:
- Android 12 (API-Level 31) oder höher
- Der Audiofokus wird vom System verwaltet. Das System erzwingt, dass die Audiowiedergabe in einer App ausgeblendet wird, wenn eine andere App den Audiofokus anfordert. Das System schaltet außerdem die Audiowiedergabe bei einem eingehenden Anruf stumm.
- Android 8.0 (API-Level 26) bis Android 11 (API-Level 30)
- Der Audiofokus wird nicht vom System verwaltet, umfasst aber einige Änderungen, die ab Android 8.0 (API-Level 26) eingeführt wurden.
- Android 7.1 (API-Level 25) und niedriger
- Der Audiofokus wird nicht vom System verwaltet und Apps verwalten den Audiofokus mithilfe von
requestAudioFocus()
undabandonAudioFocus()
.
Audiofokus in Android 12 und höher
Eine Medien- oder Spiele-App, die den Audiofokus verwendet, sollte keine Audioinhalte mehr wiedergeben, wenn sie den Fokus verliert. Ab Android 12 (API-Level 31) und höher wird dieses Verhalten durch das System erzwungen. Wenn eine App den Audiofokus anfordert, während eine andere App im Fokus ist und wiedergegeben wird, erzwingt das System das Ausblenden der abspielenden App. Das Hinzufügen der Ausblendung ermöglicht einen reibungsloseren Übergang beim Wechsel von einer App zur anderen.
Dieses Ausblendverhalten tritt auf, wenn die folgenden Bedingungen erfüllt sind:
Die erste, aktuell wiedergegebene App erfüllt alle folgenden Kriterien:
- Die App hat entweder das Nutzungsattribut
AudioAttributes.USAGE_MEDIA
oderAudioAttributes.USAGE_GAME
. - Die App hat den Audiofokus mit
AudioManager.AUDIOFOCUS_GAIN
angefordert. - Die App spielt keine Audioinhalte mit dem Inhaltstyp
AudioAttributes.CONTENT_TYPE_SPEECH
ab.
- Die App hat entweder das Nutzungsattribut
Eine zweite App fordert den Audiofokus mit
AudioManager.AUDIOFOCUS_GAIN
an.
Wenn diese Bedingungen erfüllt sind, wird die erste App vom Audiosystem ausgeblendet. Am Ende der Ausblenden benachrichtigt das System die erste App über Fokusverlust. Die Player der App bleiben stummgeschaltet, bis die App wieder den Audiofokus anfordert.
Vorhandenes Verhalten des Audiofokus
Sie sollten auch auf diese anderen Fälle achten, bei denen ein Schalter im Audiofokus verwendet wird.
Automatisches Entladen
Automatisches Ducking (die vorübergehende Reduzierung des Audiopegels einer App, damit eine andere deutlich zu hören ist) wurde in Android 8.0 (API-Level 26) eingeführt.
Wenn das System Ducking implementiert, müssen Sie kein Ducking in Ihrer App implementieren.
Automatisches Ducking tritt auch auf, wenn der Fokus einer Audiobenachrichtigung von einer laufenden App liegt. Der Beginn der Benachrichtigungswiedergabe wird mit dem Ende der Ducking-Rampe synchronisiert.
Automatisches Ducking erfolgt, wenn die folgenden Bedingungen erfüllt sind:
Die erste, derzeit spielende App erfüllt alle folgenden Kriterien:
- Die App hat den Audiofokus mit einer beliebigen Fokusverstärkung angefordert.
- Die App spielt keine Audioinhalte mit dem Inhaltstyp
AudioAttributes.CONTENT_TYPE_SPEECH
ab. - Die App hat
AudioFocusRequest.Builder.setWillPauseWhenDucked(true)
nicht festgelegt.
Eine zweite App fordert den Audiofokus mit
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
an.
Sind diese Bedingungen erfüllt, werden alle aktiven Spieler der ersten App vom Audiosystem herausgefiltert, während die zweite App im Fokus ist. Wenn die zweite App nicht mehr den Fokus aufnimmt, werden sie wieder entfernt. Die erste App wird nicht benachrichtigt, wenn sie den Fokus verliert, sodass sie nichts tun muss.
Beachten Sie, dass automatisches Ducking nicht ausgeführt wird, wenn der Nutzer Sprachinhalte anhört, da er möglicherweise einen Teil des Programms übersehen könnte. Beispielsweise wird die Sprachführung für Wegbeschreibungen nicht verdunkelt.
Aktuelle Audiowiedergabe für eingehende Anrufe stummschalten
Einige Apps funktionieren nicht richtig und führen die Audiowiedergabe bei Anrufen nicht weiter. In dieser Situation muss der Nutzer die anstößige App suchen und stummschalten oder beenden, um den Anruf zu hören. Um dies zu verhindern, kann das System den Ton von anderen Apps während eines eingehenden Anrufs stummschalten. Das System ruft diese Funktion auf, wenn ein eingehender Anruf eingeht und eine App die folgenden Bedingungen erfüllt:
- Die App hat entweder das Nutzungsattribut
AudioAttributes.USAGE_MEDIA
oderAudioAttributes.USAGE_GAME
. - Die App hat den Audiofokus (beliebige Fokuserhöhung) angefordert und gibt Audio wieder.
Wird die Wiedergabe einer App während des Anrufs fortgesetzt, wird sie stummgeschaltet, bis der Anruf beendet wird. Wenn eine App jedoch während des Aufrufs mit der Wiedergabe beginnt, wird dieser Player nicht in der Annahme, dass der Nutzer die Wiedergabe absichtlich gestartet hat, stummgeschaltet.
Audiofokus unter Android 8.0 bis Android 11
Ab Android 8.0 (API-Level 26) musst du beim Aufrufen von requestAudioFocus()
einen AudioFocusRequest
-Parameter angeben. Das AudioFocusRequest
enthält Informationen zum Audiokontext und zu den Funktionen Ihrer App. Das System verwendet diese Informationen, um Verstärkung und Verlust des Audiofokus automatisch zu steuern. Wenn Sie den Audiofokus freigeben möchten, rufen Sie die Methode abandonAudioFocusRequest()
auf, die auch ein AudioFocusRequest
als Argument verwendet. Verwenden Sie dieselbe AudioFocusRequest
-Instanz sowohl, wenn Sie den Fokus anfordern als auch verwerfen.
Verwenden Sie zum Erstellen eines AudioFocusRequest
eine AudioFocusRequest.Builder
. Da bei einer Fokusanfrage immer der Typ der Anfrage angegeben werden muss, ist der Typ im Konstruktor für den Builder enthalten. Verwenden Sie die Methoden des Builders, um die anderen Felder der Anfrage festzulegen.
Das Feld „FocusGain
“ ist erforderlich, alle anderen Felder sind optional.
Methode | Hinweise |
---|---|
setFocusGain()
|
Dieses Feld ist bei jeder Anfrage erforderlich. Es werden die gleichen Werte wie der durationHint verwendet, der vor Android 8.0 im Aufruf von requestAudioFocus() verwendet wurde: AUDIOFOCUS_GAIN , AUDIOFOCUS_GAIN_TRANSIENT , AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK oder AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE .
|
setAudioAttributes()
|
AudioAttributes beschreibt den Anwendungsfall für Ihre Anwendung. Das System prüft sie, wenn eine App den Audiofokus erhält bzw. verliert. Attribute ersetzen das Konzept des Streamtyps. In Android 8.0 (API-Level 26) und höher werden Streamtypen für alle Vorgänge mit Ausnahme der Lautstärkeregelung eingestellt. Verwenden Sie für die Fokusanfrage dieselben Attribute wie im Audioplayer (wie im Beispiel nach dieser Tabelle gezeigt).
Verwenden Sie
Wenn keine Angabe erfolgt, wird für |
setWillPauseWhenDucked()
|
Wenn eine andere Anwendung den Fokus mit AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK anfordert, erhält diese Anwendung in der Regel keinen onAudioFocusChange() -Callback, da das System das Ducking selbst vornehmen kann. Wenn Sie die Wiedergabe pausieren müssen, anstatt die Lautstärke zu verringern, rufen Sie setWillPauseWhenDucked(true) auf, erstellen Sie ein OnAudioFocusChangeListener und legen Sie es fest, wie unter Automatisches Eindocken beschrieben.
|
setAcceptsDelayedFocusGain()
|
Eine Anfrage für den Audiofokus kann fehlschlagen, wenn der Fokus durch eine andere App gesperrt wird. Diese Methode ermöglicht die verzögerte Fokuserhöhung, d. h. die Möglichkeit, den Fokus asynchron zu erfassen, wenn er verfügbar wird.
Beachten Sie, dass die verzögerte Fokuserhöhung nur funktioniert, wenn Sie in der Audioanfrage auch ein |
setOnAudioFocusChangeListener()
|
Ein OnAudioFocusChangeListener ist nur erforderlich, wenn Sie in der Anfrage auch willPauseWhenDucked(true) oder setAcceptsDelayedFocusGain(true) angeben.
Es gibt zwei Methoden zum Festlegen des Listeners: eine mit und eine ohne Handler-Argument. Der Handler ist der Thread, auf dem der Listener ausgeführt wird. Wenn Sie keinen Handler angeben, wird der Handler verwendet, der dem Haupt- |
Das folgende Beispiel zeigt, wie Sie mit AudioFocusRequest.Builder
ein AudioFocusRequest
erstellen und den Audiofokus anfordern und verwerfen können:
Kotlin
// initializing variables for audio focus and playback management audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager focusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).run { setAudioAttributes(AudioAttributes.Builder().run { setUsage(AudioAttributes.USAGE_GAME) setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) build() }) setAcceptsDelayedFocusGain(true) setOnAudioFocusChangeListener(afChangeListener, handler) build() } val focusLock = Any() var playbackDelayed = false var playbackNowAuthorized = false // requesting audio focus and processing the response val res = audioManager.requestAudioFocus(focusRequest) synchronized(focusLock) { playbackNowAuthorized = when (res) { AudioManager.AUDIOFOCUS_REQUEST_FAILED -> false AudioManager.AUDIOFOCUS_REQUEST_GRANTED -> { playbackNow() true } AudioManager.AUDIOFOCUS_REQUEST_DELAYED -> { playbackDelayed = true false } else -> false } } // implementing OnAudioFocusChangeListener to react to focus changes override fun onAudioFocusChange(focusChange: Int) { when (focusChange) { AudioManager.AUDIOFOCUS_GAIN -> if (playbackDelayed || resumeOnFocusGain) { synchronized(focusLock) { playbackDelayed = false resumeOnFocusGain = false } playbackNow() } AudioManager.AUDIOFOCUS_LOSS -> { synchronized(focusLock) { resumeOnFocusGain = false playbackDelayed = false } pausePlayback() } AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> { synchronized(focusLock) { // only resume if playback is being interrupted resumeOnFocusGain = isPlaying() playbackDelayed = false } pausePlayback() } AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> { // ... pausing or ducking depends on your app } } }
Java
// initializing variables for audio focus and playback management audioManager = (AudioManager) Context.getSystemService(Context.AUDIO_SERVICE); playbackAttributes = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_GAME) .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .build(); focusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN) .setAudioAttributes(playbackAttributes) .setAcceptsDelayedFocusGain(true) .setOnAudioFocusChangeListener(afChangeListener, handler) .build(); final Object focusLock = new Object(); boolean playbackDelayed = false; boolean playbackNowAuthorized = false; // requesting audio focus and processing the response int res = audioManager.requestAudioFocus(focusRequest); synchronized(focusLock) { if (res == AudioManager.AUDIOFOCUS_REQUEST_FAILED) { playbackNowAuthorized = false; } else if (res == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { playbackNowAuthorized = true; playbackNow(); } else if (res == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) { playbackDelayed = true; playbackNowAuthorized = false; } } // implementing OnAudioFocusChangeListener to react to focus changes @Override public void onAudioFocusChange(int focusChange) { switch (focusChange) { case AudioManager.AUDIOFOCUS_GAIN: if (playbackDelayed || resumeOnFocusGain) { synchronized(focusLock) { playbackDelayed = false; resumeOnFocusGain = false; } playbackNow(); } break; case AudioManager.AUDIOFOCUS_LOSS: synchronized(focusLock) { resumeOnFocusGain = false; playbackDelayed = false; } pausePlayback(); break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: synchronized(focusLock) { // only resume if playback is being interrupted resumeOnFocusGain = isPlaying(); playbackDelayed = false; } pausePlayback(); break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: // ... pausing or ducking depends on your app break; } } }
Automatisches Entladen
Wenn in Android 8.0 (API-Ebene 26) eine andere App den Fokus mit AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
stellt, kann das System die Lautstärke verringern und die Lautstärke wiederherstellen, ohne den onAudioFocusChange()
-Callback der App aufzurufen.
Automatisches Ducking ist zwar für Apps zur Musik- und Videowiedergabe akzeptabel, bei der Wiedergabe von gesprochenen Inhalten, z. B. in einer Hörbuch-App, jedoch nicht nützlich. In diesem Fall sollte die App stattdessen pausiert werden.
Wenn Sie möchten, dass Ihre App bei Aufforderung zum Ducken pausiert, anstatt die Lautstärke zu verringern, erstellen Sie ein OnAudioFocusChangeListener
mit einer onAudioFocusChange()
-Callback-Methode, die das gewünschte Verhalten zum Pausieren/Fortsetzen implementiert.
Rufen Sie setOnAudioFocusChangeListener()
auf, um den Listener zu registrieren, und setWillPauseWhenDucked(true)
, um das System anzuweisen, Ihren Callback zu verwenden, anstatt automatisches Ducking durchzuführen.
Verzögerte Fokussierung
Manchmal kann das System keine Anfrage für den Audiofokus genehmigen, weil der Fokus von einer anderen App, z. B. während eines Telefonanrufs, "gesperrt" wurde. In diesem Fall gibt requestAudioFocus()
AUDIOFOCUS_REQUEST_FAILED
zurück. In diesem Fall sollte Ihre App nicht mit der Audiowiedergabe fortfahren, da sie den Fokus nicht verstärkt.
Die Methode setAcceptsDelayedFocusGain(true)
, mit der Ihre Anwendung eine Anfrage für den asynchronen Fokus verarbeiten kann. Wenn dieses Flag gesetzt ist, gibt eine Anfrage, die bei gesperrtem Fokus gestellt wurde, AUDIOFOCUS_REQUEST_DELAYED
zurück. Wenn die Bedingung, durch die der Audiofokus gesperrt wurde, nicht mehr besteht, z. B. wenn ein Telefonanruf endet, erteilt das System die ausstehende Fokusanfrage und ruft onAudioFocusChange()
auf, um die App zu benachrichtigen.
Um die verzögerte Fokussierung zu verarbeiten, müssen Sie eine OnAudioFocusChangeListener
mit einer onAudioFocusChange()
-Callback-Methode erstellen, die das gewünschte Verhalten implementiert, und den Listener durch Aufrufen von setOnAudioFocusChangeListener()
registrieren.
Audiofokus unter Android 7.1 und niedriger
Wenn du requestAudioFocus()
aufrufst, musst du einen Hinweis für die Dauer angeben, der von einer anderen App übernommen werden kann, die derzeit den Fokus hält und spielt:
- Fordern Sie einen dauerhaften Audiofokus (
AUDIOFOCUS_GAIN
) an, wenn Sie auf absehbare Zeit Audio wiedergeben möchten (z. B. bei der Musikwiedergabe), und Sie erwarten, dass der vorherige Inhaber des Audiofokus die Wiedergabe beenden wird. - Fordern Sie den vorübergehenden Fokus (
AUDIOFOCUS_GAIN_TRANSIENT
) an, wenn die Audiowiedergabe voraussichtlich nur für kurze Zeit erfolgt und Sie erwarten, dass der vorherige Inhaber die Wiedergabe pausiert. - Fordern Sie mit Ducking (
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
) den vorübergehenden Fokus an, um anzugeben, dass Sie Audio vermutlich nur für kurze Zeit wiedergeben und dass der vorherige Fokusinhaber die Wiedergabe fortsetzen darf, wenn er die Audioausgabe „duckt“ (verringert). Beide Audioausgänge werden in den Audiostream gemischt. Ducking eignet sich besonders für Apps, die den Audiostream unregelmäßig nutzen, z. B. für hörbare Wegbeschreibungen.
Für die Methode requestAudioFocus()
ist außerdem ein AudioManager.OnAudioFocusChangeListener
erforderlich. Dieser Listener sollte in derselben Aktivität oder in demselben Dienst erstellt werden, der auch Ihre Mediensitzung besitzt. Er implementiert den Callback-onAudioFocusChange()
, den deine App empfängt, wenn eine andere App den Audiofokus aktiviert oder aufhebt.
Mit dem folgenden Snippet wird der dauerhafte Audiofokus für den Stream STREAM_MUSIC
angefordert und ein OnAudioFocusChangeListener
registriert, um nachfolgende Änderungen am Audiofokus zu verarbeiten. Der Änderungs-Listener wird unter Reagieren auf eine Änderung des Audiofokus erläutert.
Kotlin
audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager lateinit var afChangeListener AudioManager.OnAudioFocusChangeListener ... // Request audio focus for playback val result: Int = audioManager.requestAudioFocus( afChangeListener, // Use the music stream. AudioManager.STREAM_MUSIC, // Request permanent focus. AudioManager.AUDIOFOCUS_GAIN ) if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { // Start playback }
Java
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); AudioManager.OnAudioFocusChangeListener afChangeListener; ... // Request audio focus for playback int result = audioManager.requestAudioFocus(afChangeListener, // Use the music stream. AudioManager.STREAM_MUSIC, // Request permanent focus. AudioManager.AUDIOFOCUS_GAIN); if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { // Start playback }
Rufen Sie nach Abschluss der Wiedergabe abandonAudioFocus()
auf.
Kotlin
audioManager.abandonAudioFocus(afChangeListener)
Java
// Abandon audio focus when playback complete audioManager.abandonAudioFocus(afChangeListener);
Dadurch wird das System darüber informiert, dass Sie keinen Fokus mehr benötigen, und die Registrierung der zugehörigen OnAudioFocusChangeListener
wird aufgehoben. Wenn Sie den vorübergehenden Fokus angefordert haben, wird eine pausierte oder verdunkelte App darüber informiert, dass die Wiedergabe fortgesetzt oder die Lautstärke wiederherstellen kann.
Auf eine Änderung des Audiofokus reagieren
Wenn eine App den Audiofokus erhält, muss sie ihn freigeben können, wenn eine andere App den Audiofokus für sich selbst anfordert. In diesem Fall erhält Ihre Anwendung einen Aufruf an die Methode onAudioFocusChange()
in der AudioFocusChangeListener
, die Sie beim Aufrufen der Anwendung requestAudioFocus()
angegeben haben.
Der an onAudioFocusChange()
übergebene Parameter focusChange
gibt die Art der Änderung an. Es entspricht dem Hinweis für die Dauer, der von der App verwendet wird, die den Fokus erhält. Ihre App sollte angemessen reagieren.
- Vorübergehender Fokusverlust
-
Bei einer vorübergehenden Fokusänderung (
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
oderAUDIOFOCUS_LOSS_TRANSIENT
) sollte Ihre App ducken (falls Sie kein automatisches Ducken verwenden) oder die Wiedergabe pausieren, aber ansonsten denselben Status beibehalten.Während eines vorübergehenden Verlusts des Audiofokus sollten Sie den Audiofokus weiterhin beobachten und darauf vorbereitet sein, die normale Wiedergabe fortzusetzen, sobald der Fokus wieder hergestellt ist. Wenn der Fokus der blockierenden App nicht mehr angezeigt wird, erhalten Sie einen Callback (
AUDIOFOCUS_GAIN
). Anschließend können Sie die Lautstärke auf die normale Lautstärke wiederherstellen oder die Wiedergabe neu starten. - Dauerhafter Fokusverlust
-
Wenn der Audiofokus dauerhaft verloren geht (
AUDIOFOCUS_LOSS
), spielt eine andere App Audio ab. Die App sollte die Wiedergabe sofort anhalten, da sie keinenAUDIOFOCUS_GAIN
-Callback erhält. Um die Wiedergabe neu zu starten, muss der Nutzer eine explizite Aktion ausführen, z. B. das Steuerelement „Transport wiedergeben“ in einer Benachrichtigung oder App-Benutzeroberfläche.
Das folgende Code-Snippet zeigt, wie OnAudioFocusChangeListener
und dessen onAudioFocusChange()
-Callback implementiert werden. Beachten Sie die Verwendung von Handler
, um den Stopp-Callback bei einem dauerhaften Verlust des Audiofokus zu verzögern.
Kotlin
private val handler = Handler() private val afChangeListener = AudioManager.OnAudioFocusChangeListener { focusChange -> when (focusChange) { AudioManager.AUDIOFOCUS_LOSS -> { // Permanent loss of audio focus // Pause playback immediately mediaController.transportControls.pause() // Wait 30 seconds before stopping playback handler.postDelayed(delayedStopRunnable, TimeUnit.SECONDS.toMillis(30)) } AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> { // Pause playback } AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> { // Lower the volume, keep playing } AudioManager.AUDIOFOCUS_GAIN -> { // Your app has been granted audio focus again // Raise volume to normal, restart playback if necessary } } }
Java
private Handler handler = new Handler(); AudioManager.OnAudioFocusChangeListener afChangeListener = new AudioManager.OnAudioFocusChangeListener() { public void onAudioFocusChange(int focusChange) { if (focusChange == AudioManager.AUDIOFOCUS_LOSS) { // Permanent loss of audio focus // Pause playback immediately mediaController.getTransportControls().pause(); // Wait 30 seconds before stopping playback handler.postDelayed(delayedStopRunnable, TimeUnit.SECONDS.toMillis(30)); } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) { // Pause playback } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) { // Lower the volume, keep playing } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { // Your app has been granted audio focus again // Raise volume to normal, restart playback if necessary } } };
Der Handler verwendet einen Runnable
, der so aussieht:
Kotlin
private var delayedStopRunnable = Runnable { mediaController.transportControls.stop() }
Java
private Runnable delayedStopRunnable = new Runnable() { @Override public void run() { getMediaController().getTransportControls().stop(); } };
Damit der verzögerte Stopp nicht aktiviert wird, wenn der Nutzer die Wiedergabe neu startet, rufen Sie als Reaktion auf Statusänderungen mHandler.removeCallbacks(mDelayedStopRunnable)
auf. Rufen Sie beispielsweise removeCallbacks()
in den onPlay()
, onSkipToNext()
usw. Ihres Callbacks auf. Sie sollten diese Methode auch im onDestroy()
-Callback Ihres Dienstes aufrufen, wenn Sie die von Ihrem Dienst verwendeten Ressourcen bereinigen.