Audiofokus verwalten

Zwei oder mehr Android-Apps können Audioinhalte über denselben Ausgabestream abspielen und das System vermischt alles. Während dies technisch beeindruckend ist, kann das für Nutzende sehr ärgerlich sein. Um alle Musik-App gleichzeitig abgespielt wird, führt Android die Idee von Audio fokus. Es kann jeweils nur eine App den Audiofokus beibehalten.

Wenn Ihre App Audio ausgeben muss, sollte sie den Audiofokus anfordern. Wenn es kann er Ton abspielen. Nachdem Sie den Audiofokus aufgenommen haben, können Sie sie behalten, bis Sie fertig gespielt haben. Eine andere App kann den Fokus anfordern, beendet das Halten des Audiofokus. In diesem Fall wird Ihre App pausiert die Wiedergabe 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. Also: App-Entwickler sollten sich an die Richtlinien für den Audiofokus halten, Eine App wird weiterhin laut abgespielt, auch nachdem der Audiofokus auf einem Gerät verloren gegangen ist. mit Android 11 (API-Level 30) oder niedriger kann das System dies nicht verhindern. Dieses App-Verhalten führt jedoch zu einer schlechten Nutzererfahrung und kann oft dazu führen, damit Nutzer die fehlerhafte App deinstallieren können.

Eine gut gestaltete Audio-App sollte den Audiofokus anhand dieser allgemeinen Richtlinien:

  • Rufe requestAudioFocus() unmittelbar vor dem Start der Wiedergabe auf und prüfe, ob wird der Aufruf zurückgegeben, AUDIOFOCUS_REQUEST_GRANTED Rufen Sie die requestAudioFocus() im onPlay()-Callback deiner Mediensitzung.

  • Wenn eine andere App den Audiofokus erhöht, die Wiedergabe anhält oder pausiert Lautstärke verringern.

  • Wenn die Wiedergabe beendet wird, z. B. wenn in der App keine Inhalte mehr abgespielt werden können Audiofokus verwerfen. Ihre App muss den Audiofokus nicht aufgeben, wenn der Nutzer pausiert die Wiedergabe, setzt sie aber möglicherweise später fort.

  • Verwenden Sie AudioAttributes für Folgendes: die Art des Audios, das Ihre App abspielt. Bei Apps, die Sprache abspielen, angeben CONTENT_TYPE_SPEECH

Der Audiofokus wird je nach Android-Version, die wird ausgeführt:

Android 12 (API-Level 31) oder höher
Der Audiofokus wird vom System verwaltet. Das System erzwingt die Audiowiedergabe von einem App wird ausgeblendet, wenn eine andere App den Audiofokus anfordert. Das System schaltet auch die Audiowiedergabe stumm, wenn ein eingehender Anruf eingeht.
Android 8.0 (API-Level 26) bis Android 11 (API-Level 30)
Der Audiofokus wird nicht vom System verwaltet, beinhaltet jedoch einige Änderungen, die ab Android 8.0 (API-Level 26) eingeführt.
Android 7.1 (API-Level 25) und niedriger
Der Audiofokus wird nicht vom System verwaltet und Apps steuern den Audiofokus mithilfe von Das requestAudioFocus() und abandonAudioFocus()

Audiofokus in Android 12 und höher

Eine Medien- oder Spiele-App, die Audiofokus verwendet, sollte den Ton nicht wiedergeben, wenn der Ton verloren geht fokussiert. Unter Android 12 (API-Level 31) und höher erzwingt das System dies verhalten. Wenn eine App Audiofokus anfordert, während eine andere App den Fokus hat abgespielt wird, erzwingt das System das Ausblenden der App. Die Hinzufügung des sorgt für einen flüssigeren Übergang von einer App zur anderen.

Dieses Ausblenden-Verhalten tritt auf, wenn die folgenden Bedingungen erfüllt sind:

  1. Die erste, derzeit abgespielte App erfüllt alle folgenden Kriterien:

  2. Eine zweite App fordert den Audiofokus mit AudioManager.AUDIOFOCUS_GAIN an.

Wenn diese Bedingungen erfüllt sind, schaltet das Audiosystem die erste App aus. Im Ende der Ausblendung benachrichtigt, benachrichtigt das System die erste App, wenn der Fokus verschwunden ist. Die -Player bleiben stummgeschaltet, bis die App den Audiofokus erneut anfordert.

Vorhandene Audiofokus-Verhaltensweisen

Beachten Sie auch die folgenden Fälle, in denen die Audiowiedergabe umgeschaltet wird. fokussiert.

Automatisches Ducking

Automatisches Ducking (vorübergehende Reduzierung des Audiopegels einer App, sodass ist mit Android 8.0 (API-Level 26) eingeführt.

Wenn das System Ducking implementiert, müssen Sie es nicht für Ihre App.

Das automatische Ducking erfolgt auch, wenn eine Audiobenachrichtigung den Fokus auf sich zieht. über eine App, die gerade läuft. Der Beginn der Benachrichtigungswiedergabe wird synchronisiert mit dem Ende der Ducking-Rampe.

Das automatische Ducking erfolgt, wenn die folgenden Bedingungen erfüllt sind:

  1. Die erste, die gerade läuft, erfüllt alle folgenden Kriterien:

  2. Eine zweite App fordert den Audiofokus mit AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK

Wenn diese Bedingungen erfüllt sind, schaltet das Audiosystem alle aktiven Player die erste App, während die zweite im Fokus liegt. Wenn die zweite App die wurden sie vom Boden gerissen. Die erste App wird nicht benachrichtigt, wenn sie den Fokus verliert. Sie müssen also nichts unternehmen.

Hinweis: Während der Nutzerwiedergabe Sprachinhalte, da Nutzende einen Teil des Programms übersehen könnten. Beispiel: Die Sprachführung für Wegbeschreibungen funktioniert nicht eingedämmt.

Aktuelle Audiowiedergabe für eingehende Anrufe stummschalten

Einige Apps funktionieren nicht wie vorgesehen und können deshalb bei Anrufen die Audiowiedergabe nicht fortsetzen. In diesem Fall ist der Nutzer gezwungen, die anstößige App in um ihren Anruf zu hören. Um dies zu verhindern, kann das System Audio von anderen Apps während eines eingehenden Anrufs. Das System ruft diese Funktion auf, wenn ein ein eingehender Anruf eingeht und eine App die folgenden Bedingungen erfüllt:

  • Die App hat entweder AudioAttributes.USAGE_MEDIA oder Nutzungsattribut AudioAttributes.USAGE_GAME.
  • Die App hat den Audiofokus (beliebige Fokusverstärkung) angefordert und wird wiedergegeben Audio.

Wenn die Wiedergabe einer App während des Anrufs fortgesetzt wird, wird die Wiedergabe stummgeschaltet, bis das wird beendet. Wenn eine App jedoch während des Anrufs abgespielt wird, ist dieser Player nicht da der Nutzer die Wiedergabe absichtlich gestartet hat.

Audiofokus unter Android 8.0 bis Android 11

Ab Android 8.0 (API-Level 26) gilt Folgendes: requestAudioFocus() müssen Sie einen AudioFocusRequest-Parameter angeben. Das AudioFocusRequest enthält Informationen zum Audiokontext und zu den Funktionen Ihrer App. Die verwendet das System diese Informationen, um die Verstärkung und den Verlust des Audiofokus zu steuern. automatisch. Um den Audiofokus loszulassen, rufen Sie die Methode abandonAudioFocusRequest() für die auch AudioFocusRequest als Argument verwendet wird. Gleiche AudioFocusRequest-Instanz sowohl beim Anfordern als auch beim Verwerfen des Fokus.

Verwenden Sie zum Erstellen eines AudioFocusRequest einen AudioFocusRequest.Builder Da eine Fokusanfrage immer den Typ der Anfrage angeben, der Typ ist im Konstruktor enthalten für den Builder. Legen Sie mit den Builder-Methoden die anderen Felder des

Das Feld FocusGain ist ein Pflichtfeld. Alle anderen Felder sind optional.

MethodHinweise
setFocusGain() Dieses Feld ist in jeder Anfrage erforderlich. Es werden dieselben Werte verwendet wie Den durationHint, der im Aufruf von requestAudioFocus() vor Android 8.0 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 App. Die wenn die Audiofokussierung einer App zu- oder abnimmt. Attribute die das Konzept des Streamtyps ersetzen. Ab Android 8.0 (API-Level 26) Streamtypen für andere Vorgänge als die Lautstärkeregelung wurden eingestellt. Verwenden Sie dieselben Attribute in der Fokusanfrage, die Sie in Ihrem Audioplayer verwenden (als wie im Beispiel nach dieser Tabelle dargestellt).

Verwenden Sie AudioAttributes.Builder, um die und weisen Sie dann mit dieser Methode die Attribute dem

Wenn keine Angabe erfolgt, wird AudioAttributes standardmäßig auf AudioAttributes.USAGE_MEDIA gesetzt.

setWillPauseWhenDucked() Wenn eine andere App den Fokus mit AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, die App im Fokus erhalten in der Regel eine onAudioFocusChange() weil das System die von sich entfernen. Wenn Sie die Wiedergabe pausieren möchten, als Lautstärke ändern, rufen Sie setWillPauseWhenDucked(true) auf, erstellen Sie OnAudioFocusChangeListener, wie in automatischen Ducking
setAcceptsDelayedFocusGain() Eine Anfrage für den Audiofokus kann fehlschlagen, wenn der Fokus von einer anderen App gesperrt wird. Diese Methode ermöglicht eine verzögerte Fokussierung: Die Fähigkeit, um den Fokus asynchron zu generieren, sobald er verfügbar ist.

Die verzögerte Fokusverstärkung funktioniert nur, wenn Sie auch eine AudioManager.OnAudioFocusChangeListener in der Audioanfrage, da Ihre App den Rückruf erhalten, um zu wissen, dass der Fokus gewährt wurde.

setOnAudioFocusChangeListener() Ein OnAudioFocusChangeListener ist nur erforderlich, wenn Sie auch willPauseWhenDucked(true) oder setAcceptsDelayedFocusGain(true) in der Anfrage.

Es gibt zwei Methoden zum Festlegen des Listeners: eine mit und eine ohne Handler-Argument. Beim Handler handelt es sich um den Thread, in dem der Listener ausgeführt wird. Wenn Sie keinen Handler angeben, wird der Handler, der mit der Looper wird verwendet.

Das folgende Beispiel zeigt, wie Sie mit einem AudioFocusRequest.Builder AudioFocusRequest und fordern den Audiofokus an und verwerfen den Audiofokus:

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 Ducking

In Android 8.0 (API-Level 26): Wenn eine andere App den Fokus auf AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK kann das System die Lautstärke regeln und die Lautstärke wiederherstellen ohne den onAudioFocusChange()-Callback der App aufzurufen.

Automatisches Ducking ist bei der Musik- und Videowiedergabe akzeptabel. Apps sind, ist sie nicht nützlich, wenn gesprochene Inhalte abgespielt werden, wie z. B. in einer Hörbuch-App In diesem Fall sollte die App stattdessen pausiert werden.

Wenn du möchtest, dass deine App pausiert, wenn du dazu aufgefordert wirst, statt die Lautstärke zu verringern, erstelle ein OnAudioFocusChangeListener mit Eine onAudioFocusChange()-Callback-Methode, die das gewünschte Verhalten zum Pausieren/Fortsetzen implementiert. Rufen Sie setOnAudioFocusChangeListener() auf, um den Listener zu registrieren, und rufen Sie setWillPauseWhenDucked(true) um das System anzuweisen, Ihren Callback zu verwenden und kein automatisches Ducking durchzuführen.

Verzögerte Fokusverstärkung

Manchmal kann das System keine Anfrage für den Audiofokus gewähren, da der Fokus "gesperrt" beispielsweise während eines Telefonanrufs. In diesem Fall requestAudioFocus() gibt AUDIOFOCUS_REQUEST_FAILED zurück. In diesem Fall sollte Ihre App nicht mit der Audiowiedergabe fortfahren, fokussiert.

Die Methode setAcceptsDelayedFocusGain(true), mit der Ihre App eine Anfrage für den Fokus verarbeiten kann asynchron programmiert. Ist dieses Flag gesetzt, wird eine Anfrage gesendet, wenn der Fokus gesperrt ist. gibt AUDIOFOCUS_REQUEST_DELAYED zurück. Wenn die Bedingung, die das Audio gesperrt hat, nicht mehr vorhanden ist, etwa wenn ein Anruf beendet wird, erteilt die ausstehende Fokusanfrage und ruft onAudioFocusChange() auf, um Ihr

Um die verzögerte Vergrößerung zu bewältigen, müssen Sie eine OnAudioFocusChangeListener durch die Callback-Methode onAudioFocusChange(), die implementiert das gewünschte Verhalten und registriert den Listener durch Aufrufen von setOnAudioFocusChangeListener()

Audiofokus in Android 7.1 und niedriger

Wenn du anrufst requestAudioFocus() müssen Sie einen Hinweis für die Dauer angeben, auch von einer anderen App gewürdigt werden, die derzeit im Fokus ist und läuft:

  • Für die Audiowiedergabe dauerhaften Audiofokus anfordern (AUDIOFOCUS_GAIN) absehbar (z. B. beim Abspielen von Musik), und du erwartest, dass vorherigen Inhaber des Audiofokus, um die Wiedergabe zu beenden.
  • Vorübergehenden Fokus (AUDIOFOCUS_GAIN_TRANSIENT) anfordern, wenn du mit dem Spielen erwartest Audio nur für kurze Zeit hören und erwarten, dass der vorherige Eigentümer gespielt wird.
  • Vorübergehenden Fokus mit Ducking anfordern (AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) gibt an, dass Sie eine Audiowiedergabe erwarten. und dass der vorherige Fokusinhaber spielt, wenn es „ducks“ ist (senkt) die Audioausgabe. Beide Audioausgänge sind gemischt in den Audiostream ein. Ducking eignet sich besonders für Apps, die das mit Unterbrechungen, z. B. für hörbare Routen.

Für die Methode requestAudioFocus() ist außerdem ein AudioManager.OnAudioFocusChangeListener erforderlich. Dieser Listener sollte die in derselben Aktivität oder demselben Dienst erstellt wurden, zu dem auch Ihre Mediensitzung gehört. Es Implementiert den Callback onAudioFocusChange(), den deine App empfängt, wenn eine andere App den Audiofokus aufnimmt oder aufgibt.

Mit dem folgenden Snippet wird ein dauerhafter Audiofokus auf den Stream angefordert STREAM_MUSIC und registriert eine OnAudioFocusChangeListener zur Verarbeitung Änderungen des Audiofokus ändern. (Der Änderungs-Listener wird im Reagieren auf eine Änderung des Audiofokus)

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
}

Wenn die Wiedergabe beendet ist, abandonAudioFocus()

Kotlin

audioManager.abandonAudioFocus(afChangeListener)

Java

// Abandon audio focus when playback complete
audioManager.abandonAudioFocus(afChangeListener);

Dadurch wird das System informiert, dass Sie keinen Fokus mehr benötigen, und die Registrierung des verknüpfte OnAudioFocusChangeListener. Wenn Sie einen vorübergehenden Fokus angefordert haben, wird eine pausierte oder entfernte App darauf hingewiesen, dass die Wiedergabe fortgesetzt oder die Lautstärke wiederherstellen.

Auf eine Audiofokusänderung reagieren

Wenn eine App Audiofokus erhält, muss sie in der Lage sein, ihn loszulassen, wenn eine andere App fordert Audiofokus für sich selbst an. In diesem Fall kann Ihre App erhält einen Anruf bei der onAudioFocusChange() in AudioFocusChangeListener die Sie angegeben haben, als die App requestAudioFocus() aufgerufen hat.

Der an onAudioFocusChange() übergebene Parameter focusChange gibt die Art an die gerade stattfindende Veränderungen. Sie entspricht auf den Hinweis für die Dauer der App, die den Fokus auf sich zieht. Ihre App sollte angemessen reagieren.

Vorübergehender Fokusverlust
Wenn die Fokusänderung vorübergehend ist (AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK oder AUDIOFOCUS_LOSS_TRANSIENT) sollte sich Ihre App entfernen (falls Sie sich nicht auf beim automatischen Ducking) oder beim Pausieren der Wiedergabe, behalten ansonsten denselben Zustand bei.

Während des vorübergehenden Verlusts des Audiofokus sollten Sie Änderungen weiterhin beobachten. im Audiofokus. Die normale Wiedergabe wird fortgesetzt, wenn die fokussiert. Wenn die blockierende App den Fokus verlässt, erhalten Sie einen Callback. (AUDIOFOCUS_GAIN) Jetzt kannst du die Lautstärke auf die normale Lautstärke wiederherstellen. oder die Wiedergabe neu starten.

Dauerhafter Verlust des Fokus
Wenn der Verlust des Audiofokus dauerhaft ist (AUDIOFOCUS_LOSS), ist eine andere App bei der Audiowiedergabe. Ihre App sollte die Wiedergabe sofort pausieren, AUDIOFOCUS_GAIN-Rückruf erhalten. Um die Wiedergabe neu zu starten, muss eine explizite Aktion ausführen, z. B. das Drücken der Transportsteuerung für die Wiedergabe. in einer Benachrichtigung oder App-Benutzeroberfläche.

Im folgenden Code-Snippet sehen Sie, wie das Tag OnAudioFocusChangeListener und der zugehörige onAudioFocusChange()-Callback. Beachten Sie die Verwendung eines Handler, um den Stopp-Callback bei einem dauerhaften Audioverlust zu verzögern fokussiert.

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 ein Runnable, das so aussieht:

Kotlin

private var delayedStopRunnable = Runnable {
    mediaController.transportControls.stop()
}

Java

private Runnable delayedStopRunnable = new Runnable() {
    @Override
    public void run() {
        getMediaController().getTransportControls().stop();
    }
};

Um sicherzustellen, dass der verzögerte Stopp nicht funktioniert, wenn der Nutzer die Wiedergabe neu startet, rufen Sie mHandler.removeCallbacks(mDelayedStopRunnable) als Reaktion auf einen beliebigen Status Änderungen. Rufen Sie beispielsweise removeCallbacks() in der onPlay() Ihres Callbacks auf. onSkipToNext() usw. Sie sollten diese Methode auch im onDestroy()-Callback beim Bereinigen der von Ihrem Dienst verwendeten Ressourcen.