Co najmniej 2 aplikacje na Androida mogą odtwarzać dźwięk w tym samym strumieniu wyjściowym jednocześnie, a system łączy wszystko w jedną całość. Choć jest to imponujące technicznie może być dla użytkownika bardzo przykre. Aby uniknąć: w tym samym czasie odtwarzania aplikacji muzycznych, Android wprowadza pomysł dźwięku. skupienie. Tylko jedna aplikacja może utrzymywać skupienie dźwięku w danym momencie.
Gdy aplikacja musi odtwarzać dźwięk, powinna zażądać fokusu audio. Kiedy zostanie może odtwarzać dźwięk. Po uzyskaniu ostrości dźwięku można jednak który możesz przechowywać, aż skończysz grać. Inna aplikacja może poprosić o koncentrację, zapobiega skupieniu się na dźwięku. W takim przypadku aplikacja powinna zostać wstrzymana włącza lub zmniejsza głośność, aby użytkownicy mogli lepiej słyszeć nowe źródło dźwięku.
W starszych wersjach Androida 12 (poziom interfejsu API 31) system nie zarządza aktywnością audio. A więc, zachęcamy deweloperów aplikacji do stosowania się do wytycznych dotyczących skupienia na dźwięku, jeśli aplikacja nadal gra głośno nawet po utracie ostrości audio na urządzeniu; z Androidem 11 (poziom interfejsu API 30) lub niższym, system nie może temu zapobiec. Takie działanie aplikacji negatywnie wpływa jednak na wrażenia użytkowników i często prowadzi odinstalowanie wadliwej aplikacji.
Dobrze zaprojektowana aplikacja audio powinna zarządzać ostrością audio zgodnie z wytycznymi:
Zadzwoń pod numer
requestAudioFocus()
tuż przed rozpoczęciem gry i sprawdź, czy połączenie zostanie przywróconeAUDIOFOCUS_REQUEST_GRANTED
Zadzwoń dorequestAudioFocus()
w wywołaniu zwrotnymonPlay()
sesji multimediów.Gdy inna aplikacja uzyska ostrość dźwięku, zatrzyma lub wstrzyma odtwarzanie albo wycisz (czyli zmniejsz głośność).
Po zatrzymaniu odtwarzania (np. gdy w aplikacji nie ma nic do odtworzenia) porzucić aktywność audio. Aplikacja nie musi rezygnować z fokusu, jeśli użytkownik wstrzyma odtwarzanie, ale może wznowić je później.
Użyj
AudioAttributes
, aby opisać typu audio odtwarzanej przez aplikację. Na przykład w przypadku aplikacji, które odtwarzają mowę, określCONTENT_TYPE_SPEECH
Obsługa dźwięku różni się w zależności od wersji Androida jest uruchomiony:
- Android 12 (poziom interfejsu API 31) lub nowszy
- Koncentracja dźwięku jest zarządzana przez system. System wymusza odtwarzanie dźwięku aplikacja ma zanikać, gdy inna aplikacja poprosi o tryb audio. System wycisza też odtwarzanie dźwięku po nadejściu połączenia.
- Android od 8.0 (poziom interfejsu API 26) do Androida 11 (poziom interfejsu API 30)
- System dźwięku nie zarządza ustawieniami dźwięku, ale zawiera zmiany, które zostały wprowadzone w Androidzie 8.0 (poziom interfejsu API 26).
- Android 7.1 (poziom interfejsu API 25) lub niższy
- System dźwięku nie jest zarządzany dźwiękiem, a aplikacje zarządzają skupieniem na dźwięku za pomocą
requestAudioFocus()
orazabandonAudioFocus()
Aktywność audio na Androidzie 12 i nowszych
Aplikacja do multimediów lub gry, która wykorzystuje aktywność audio, nie powinna odtwarzać dźwięku, gdy zostanie utracony ostrość. W Androidzie 12 (poziom interfejsu API 31) i nowszych wersjach system wymusza to zachowanie użytkownika. Gdy aplikacja prosi o aktywację dźwięku, a inna aplikacja jest zaznaczona podczas odtwarzania, system wymusza wyciszenie odtwarzanej aplikacji. Dodanie funkcji pozwala płynniej przechodzić między aplikacjami.
Efekt zanikania ma miejsce, gdy są spełnione te warunki:
Pierwsza odtwarzana aplikacja spełnia wszystkie te kryteria:
- Aplikacja ma:
AudioAttributes.USAGE_MEDIA
lub Atrybut wykorzystaniaAudioAttributes.USAGE_GAME
. - Aplikacja zażądała aktywności audio za pomocą urządzenia
AudioManager.AUDIOFOCUS_GAIN
. - Aplikacja nie odtwarza dźwięku z typem treści
AudioAttributes.CONTENT_TYPE_SPEECH
.
- Aplikacja ma:
Druga aplikacja prosi o fokus za pomocą funkcji
AudioManager.AUDIOFOCUS_GAIN
.
Po spełnieniu tych warunków system audio w pierwszej aplikacji wyciszy dźwięk. Na do końca zanikania, system powiadamia pierwszą aplikację o utracie ostrości. Parametr aplikacji odtwarzacze pozostaną wyciszone, dopóki aplikacja nie zażąda ponownego skupienia się na dźwięku.
Dotychczasowe zachowania skupienia względem dźwięku
Musisz też pamiętać o innych przypadkach, które wiążą się ze zmianą dźwięku. ostrość.
Automatyczne wyciszanie
automatyczne wyciszanie (tymczasowe obniżenie poziomu dźwięku w jednej aplikacji, innego wyraźnie słychać) został wprowadzony w Androidzie 8.0 (poziom API 26).
Dzięki wdrożeniu przez system funkcji wyciszania tła nie trzeba do aplikacji.
Automatyczne wyciszanie tła pojawia się też wtedy, gdy powiadomienie dźwiękowe przyciąga uwagę w aplikacji z grafiką. Początek odtwarzania powiadomienia jest zsynchronizowany na końcu rampy ścigającej się.
Automatyczne wyciszanie ma miejsce, gdy są spełnione te warunki:
Pierwsza odtwarzana aplikacja spełnia wszystkie te kryteria:
- Aplikacja zażądała ostrości audio z dowolnym ostrością .
- Aplikacja nie odtwarza dźwięku z typem treści
AudioAttributes.CONTENT_TYPE_SPEECH
- Aplikacja nie została ustawiona
AudioFocusRequest.Builder.setWillPauseWhenDucked(true)
Druga aplikacja prosi o aktywowanie dźwięku za pomocą:
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
Gdy te warunki są spełnione, system audio duplikuje wszystkie aktywne odtwarzacze jest ustawiona na pierwszą aplikację, podczas gdy druga jest zaznaczony. Gdy druga aplikacja przestanie działać i usuwają koncentrację. Pierwsza aplikacja nie jest powiadamiana, gdy straci ważność, więc nie trzeba nic robić.
Pamiętaj, że automatyczne wyciszanie nie działa, gdy użytkownik słucha utworu treści głosowych, ponieważ użytkownik może ominąć część programu. Przykład: wskazówki głosowe dotyczące wskazówek dojazdu nie są wyciszone.
Wycisz bieżące odtwarzanie dźwięku przychodzących połączeń telefonicznych
Niektóre aplikacje działają nieprawidłowo i nadal odtwarzają dźwięk podczas rozmów telefonicznych. Użytkownik musi wtedy znaleźć i wyciszyć lub zamknąć problematyczną aplikację w aby usłyszeć jego połączenie. Aby temu zapobiec, system może wyciszyć dźwięk z innych aplikacji podczas połączenia przychodzącego. System wywołuje tę funkcję, gdy odebrane połączenie telefoniczne, a aplikacja spełnia te warunki:
- Aplikacja ma
AudioAttributes.USAGE_MEDIA
lub Atrybut wykorzystaniaAudioAttributes.USAGE_GAME
. - Aplikacja zażądała aktywności audio (dowolne wzmocnienie ostrości) i jest odtwarzana audio.
Jeśli w trakcie rozmowy aplikacja będzie nadal odtwarzać treści, jej odtwarzanie zostanie wyciszone do czasu zakończono połączenie. Jeśli jednak aplikacja zacznie grać w trakcie rozmowy, nie będzie wyciszono przy założeniu, że użytkownik rozpoczął odtwarzanie celowo.
Skupienie na dźwięku na Androidzie w wersji od 8.0 do 11
Począwszy od Androida 8.0 (poziom interfejsu API 26), gdy wywołujesz
requestAudioFocus()
musisz podać parametr AudioFocusRequest
. AudioFocusRequest
zawiera informacje o kontekście audio i możliwościach aplikacji.
system wykorzystuje te informacje do zarządzania wzmocnieniem i utratą ostrości audio
automatycznie. Aby zwolnić aktywność audio, wywołaj metodę
abandonAudioFocusRequest()
który również przyjmuje AudioFocusRequest
jako argument. Użyj tego samego
AudioFocusRequest
zarówno po wysłaniu żądania, jak i porzuceniu fokusu.
Aby utworzyć AudioFocusRequest
, użyj
AudioFocusRequest.Builder
Ponieważ prośba o fokus musi
zawsze określaj typ żądania, typ jest zawarty w konstruktorze
dla konstruktora. Użyj metod kreatora, aby ustawić pozostałe pola wartości
użytkownika.
Pole FocusGain
jest wymagane. Wszystkie pozostałe pola są opcjonalne.
Metoda | Uwagi |
---|---|
setFocusGain()
|
To pole jest wymagane w każdym żądaniu. Przyjmuje takie same wartości, jak
durationHint używane w wywołaniu requestAudioFocus() w systemie starszym niż Android 8.0:
AUDIOFOCUS_GAIN , AUDIOFOCUS_GAIN_TRANSIENT ,
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK , czy AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE .
|
setAudioAttributes()
|
AudioAttributes opisuje przypadek użycia Twojej aplikacji.
system na nie patrzy, gdy aplikacja zyskuje i utraca ostrość obrazu. Atrybuty
pozwalają zastąpić pojęcie typu strumieniowania. W Androidzie 8.0 (poziom interfejsu API 26) i nowszych
typy strumieniowania na potrzeby operacji innych niż sterowanie głośnością zostały wycofane. Używaj
te same atrybuty w żądaniu fokusu, których używasz w odtwarzaczu dźwięku (jak
w przykładzie poniżej tabeli).
Użyj
Jeśli nie określono tej wartości, |
setWillPauseWhenDucked()
|
Gdy inna aplikacja prosi o skupienie się na
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK , aktywna aplikacja nie
zwykle otrzymują
onAudioFocusChange()
ponieważ system może wykonać
lub ukrycie się. Gdy musisz wstrzymać odtwarzanie, a nie
niż zmniejszyć głośność, wywołaj setWillPauseWhenDucked(true) , utwórz i ustaw
OnAudioFocusChangeListener , zgodnie z opisem w sekcji automatycznej
ukrywanie uczuć.
|
setAcceptsDelayedFocusGain()
|
Żądanie aktywności audio może się nie powieść, gdy zaznaczenie jest zablokowane przez inną aplikację.
Ta metoda umożliwia opóźnione wzmocnienie ostrości:
asynchronicznie, gdy tylko staje się dostępne.
Pamiętaj, że opóźnione wzmocnienie ostrości działa tylko wtedy, gdy określisz też
|
setOnAudioFocusChangeListener()
|
OnAudioFocusChangeListener jest wymagany tylko wtedy, gdy określisz także
willPauseWhenDucked(true) lub setAcceptsDelayedFocusGain(true) w żądaniu.
Istnieją 2 sposoby ustawienia detektora: jedna z użyciem parametru i druga bez
z argumentem obsługi. Moduł obsługi to wątek, w którym działa detektor. Jeśli
nie określają modułu obsługi, czyli elementu powiązanego z główną funkcją
Zajęte miejsce: |
Poniższy przykład pokazuje, jak za pomocą AudioFocusRequest.Builder
utworzyć kompilację
AudioFocusRequest
i żądanie oraz porzucanie ścieżki dźwiękowej:
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; } } }
Automatyczne wyciszanie
W Androidzie 8.0 (poziom interfejsu API 26), gdy inna aplikacja żąda od Ciebie dostępu, koncentruje się ona na
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
system może wyciszyć i przywrócić głośność
bez wywoływania wywołania zwrotnego aplikacji onAudioFocusChange()
.
Automatyczne wyciszanie jest dopuszczalne w przypadku odtwarzania muzyki i filmów aplikacji, nie przydaje się podczas odtwarzania treści głosowych, np. Audiobooki. W takim przypadku aplikacja powinna zostać wstrzymana.
Jeśli chcesz, żeby aplikacja wstrzymywała się na żądanie, a nie wyciszała, a nie wyciszała, utwórz OnAudioFocusChangeListener
z
metodę wywołania zwrotnego onAudioFocusChange()
, która wdraża odpowiednie działanie wstrzymywania/wznawiania.
Wywołaj setOnAudioFocusChangeListener()
, aby zarejestrować detektora, a następnie nawiąż połączenie
setWillPauseWhenDucked(true)
, żeby wskazać systemowi, że użyje wywołania zwrotnego, a nie automatycznego wyciszania.
Opóźniony wzmocnienie ostrości
Czasami system nie może spełnić żądania włączenia aktywności audio, ponieważ
„zablokowany” przez inną aplikację, na przykład podczas połączenia telefonicznego. W tym przypadku
requestAudioFocus()
zwraca wartość AUDIOFOCUS_REQUEST_FAILED
. W takim przypadku
aplikacja nie powinna kontynuować odtwarzania dźwięku, ponieważ nie uzyskała wzmocnienia
ostrość.
Metoda setAcceptsDelayedFocusGain(true)
, która umożliwia aplikacji obsługę żądania zaznaczenia
asynchronicznie. Po ustawieniu tej flagi żądanie wysyłane, gdy zaznaczenie jest zablokowane
zwraca AUDIOFOCUS_REQUEST_DELAYED
. Gdy warunek, który doprowadził do zablokowania dźwięku,
już nie ma zaznaczenia, np. po zakończeniu połączenia telefonicznego system
zezwala na oczekującą prośbę o koncentrację i wywołuje onAudioFocusChange()
, aby powiadomić
.
Aby uwzględnić opóźnione wzmocnienie ostrości, musisz utworzyć
OnAudioFocusChangeListener
z metodą wywołania zwrotnego onAudioFocusChange()
, która
implementuje oczekiwane działanie i rejestruje detektor, wywołując
setOnAudioFocusChangeListener()
.
Aktywność audio na Androidzie 7.1 i starszych
Gdy dzwonisz
requestAudioFocus()
musisz określić wskazówkę dotyczącą czasu trwania, która może
może zostać uhonorowana przez inną aplikację, która jest obecnie wspierana i gra:
- Gdy zamierzasz odtworzyć dźwięk, poproś o stały obszar aktywności audio (
AUDIOFOCUS_GAIN
) w najbliższej przyszłości (np. gdy grasz muzykę) i spodziewasz się, aby zatrzymać odtwarzanie. - Gdy spodziewasz się gry, poproś o tymczasowe fokus (
AUDIOFOCUS_GAIN_TRANSIENT
) będzie słychać dźwięk tylko przez krótki czas i oczekujesz, że poprzedni użytkownik się wstrzyma. gra. - Zażądaj chwilowego skupienia dzięki wyciszaniu
(
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
), aby wskazać, że zamierzasz odtworzyć dźwięk. tylko przez krótki czas i czy poprzedni właściciel może zachować jak się kaczy (zmniejsza) głośność. Oba wyjścia audio są mieszane do strumienia audio. Wyciszanie tła jest szczególnie przydatne w aplikacjach, które korzystają z przerywanego strumienia audio, np. w przypadku dźwiękowych wskazówek dojazdu.
Metoda requestAudioFocus()
wymaga też AudioManager.OnAudioFocusChangeListener
. Ten detektor powinien być
utworzone w ramach tej samej aktywności lub usługi, do której należy Twoja sesja multimediów. it
implementuje wywołanie zwrotne onAudioFocusChange()
, które aplikacja otrzymuje, gdy
inna aplikacja pozyskuje lub porzuca aktywność audio.
Ten fragment wymaga stałego fokusu audio w strumieniu
STREAM_MUSIC
i rejestruje OnAudioFocusChangeListener
do obsługi
kolejne zmiany w ostrości. (Detektor zmian jest omówiony w
Reagowanie na zmianę ostrości dźwięku).
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 }
Po zakończeniu odtwarzania zadzwoń
abandonAudioFocus()
Kotlin
audioManager.abandonAudioFocus(afChangeListener)
Java
// Abandon audio focus when playback complete audioManager.abandonAudioFocus(afChangeListener);
Jest to powiadomienie dla systemu, że nie musisz już być fokusem, i wyrejestrowanie
powiązane konto OnAudioFocusChangeListener
. Jeśli Twoje pytanie dotyczy chwilowego skupienia,
spowoduje to powiadomienie aplikacji, która wstrzymała lub wstrzymała odtwarzanie, że może ona kontynuować odtwarzanie lub
przywrócić jego głośność.
Reagowanie na zmianę ostrości dźwięku
Gdy aplikacja uzyska aktywność audio, musi być w stanie ją opublikować, gdy inna aplikacja
żądają skupienia się na dźwięku. W takim przypadku aplikacja
odbiera połączenie z
onAudioFocusChange()
w AudioFocusChangeListener
określonego przez Ciebie, gdy aplikacja o nazwie requestAudioFocus()
.
Parametr focusChange
przekazany do onAudioFocusChange()
wskazuje rodzaj
zachodzących w niej zmian. Odpowiada to
do wskazówki dotyczącej czasu trwania wykorzystywanej przez aplikację, na której skupiasz uwagę. Aplikacja powinna
odpowiednio zareagować.
- Przejściowa utrata ostrości
-
Jeśli zmiana ostrości jest przejściowa (
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
lubAUDIOFOCUS_LOSS_TRANSIENT
), aplikacja powinna zostać wycofana (jeśli nie jest taka potrzeba) na automatycznym wyciszaniu wyciszania) lub wstrzymać odtwarzanie, ale w przeciwnym razie zachowają taki sam stan.Gdy występuje chwilowa utrata ostrości audio, należy kontynuować monitorowanie zmian i przygotuj się do wznowienia normalnego odtwarzania, gdy odzyskasz ostrość. Gdy aplikacja blokująca przestanie się ruszać, otrzymasz oddzwonienie. (
AUDIOFOCUS_GAIN
). W tym momencie możesz przywrócić normalny poziom głośności. lub uruchom odtwarzanie ponownie. - Trwała utrata ostrości
-
Jeśli utrata ostrości w dźwięku jest trwała (
AUDIOFOCUS_LOSS
), inna aplikacja jest odtwarzania dźwięku. Aplikacja powinna od razu wstrzymać odtwarzanie, ponieważ nigdy nie zostanie wstrzymane oddzwonić pod numerAUDIOFOCUS_GAIN
. Aby wznowić odtwarzanie, użytkownik musi wykonać wyraźne działanie, np. nacisnąć element sterujący odtwarzaniem transportu. w powiadomieniu lub interfejsie aplikacji.
Fragment kodu poniżej pokazuje, jak zaimplementować
OnAudioFocusChangeListener
i jego wywołanie zwrotne onAudioFocusChange()
. Zwróć uwagę na
użycie funkcji Handler
do opóźnienia wywołania zwrotnego w przypadku trwałej utraty dźwięku
ostrość.
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 } } };
Moduł obsługi używa pola Runnable
, które wygląda tak:
Kotlin
private var delayedStopRunnable = Runnable { mediaController.transportControls.stop() }
Java
private Runnable delayedStopRunnable = new Runnable() { @Override public void run() { getMediaController().getTransportControls().stop(); } };
Aby mieć pewność, że opóźnione zatrzymanie nie rozpocznie się po ponownym uruchomieniu odtwarzania, wywołaj polecenie
mHandler.removeCallbacks(mDelayedStopRunnable)
w odpowiedzi na dowolny stan
zmian. Na przykład zadzwoń do removeCallbacks()
, używając numeru onPlay()
wywołania zwrotnego,
onSkipToNext()
itp. Tę metodę należy też wywołać w instrukcji obsługi
onDestroy()
wywołanie zwrotne podczas czyszczenia zasobów używanych przez usługę.