Dua aplikasi Android atau lebih dapat memutar audio ke streaming output yang sama secara bersamaan, dan sistem mencampur semuanya. Meskipun ini adalah secara teknis mengesankan, maka hal ini bisa sangat menjengkelkan bagi pengguna. Untuk menghindari setiap aplikasi musik yang diputar secara bersamaan, Android memperkenalkan ide audio fokus. Hanya satu aplikasi yang dapat menerima fokus audio pada satu waktu.
Saat perlu meng-output audio, aplikasi Anda harus meminta fokus audio. Ketika terdapat fokus, model ini dapat memutar suara. Namun, setelah mendapatkan fokus audio, Anda mungkin tidak Anda simpan sampai Anda selesai bermain. Aplikasi lain dapat meminta fokus, yang mendahului penahanan fokus audio Anda. Jika itu terjadi, aplikasi Anda harus dijeda memutar atau menurunkan volume agar pengguna dapat mendengar sumber audio baru dengan lebih mudah.
Sebelum Android 12 (level API 31), fokus audio tidak dikelola oleh sistem. Jadi, sementara developer aplikasi dianjurkan untuk mematuhi panduan fokus audio, jika aplikasi terus diputar dengan keras bahkan setelah kehilangan fokus audio di perangkat menjalankan Android 11 (level API 30) atau yang lebih rendah, sistem tidak dapat mencegahnya. Namun, perilaku aplikasi ini menyebabkan pengalaman pengguna yang buruk dan sering kali dapat menyebabkan pengguna untuk menghapus instalan aplikasi yang bermasalah.
Aplikasi audio yang dirancang dengan baik harus mengelola fokus audio sesuai dengan panduan:
Panggil
requestAudioFocus()
tepat sebelum mulai memutar dan pastikan bahwa panggilan akan mengembalikanAUDIOFOCUS_REQUEST_GRANTED
. Lakukan panggilan kerequestAudioFocus()
dalam callbackonPlay()
sesi media Anda.Saat aplikasi lain memperoleh fokus audio, menghentikan atau menjeda pemutaran, atau mengecilkan (yaitu, mengurangi) volume.
Saat pemutaran berhenti (misalnya, saat aplikasi tidak memiliki sisa untuk diputar), meninggalkan fokus audio. Aplikasi Anda tidak perlu mengabaikan fokus audio jika pengguna menjeda pemutaran, tetapi dapat melanjutkan pemutaran nanti.
Gunakan
AudioAttributes
untuk mendeskripsikan jenis audio yang diputar oleh aplikasi Anda. Misalnya, untuk aplikasi yang memutar ucapan, sebutkanCONTENT_TYPE_SPEECH
Fokus audio ditangani secara berbeda bergantung pada versi Android yang sedang berjalan:
- Android 12 (level API 31) atau yang lebih baru
- Fokus audio dikelola oleh sistem. Sistem memaksa pemutaran audio dari aplikasi untuk memudar saat aplikasi lain meminta fokus audio. Sistem juga akan membisukan pemutaran audio saat panggilan masuk diterima.
- Android 8.0 (level API 26) hingga Android 11 (level API 30)
- Fokus audio tidak dikelola oleh sistem, tetapi menyertakan beberapa perubahan yang diperkenalkan mulai Android 8.0 (level API 26).
- Android 7.1 (level API 25) dan yang lebih lama
- Fokus audio tidak dikelola oleh sistem, dan aplikasi mengelola fokus audio menggunakan
requestAudioFocus()
danabandonAudioFocus()
.
Fokus audio di Android 12 dan yang lebih baru
Aplikasi media atau game yang menggunakan fokus audio seharusnya tidak memutar audio setelah kehilangan fokus. Di Android 12 (level API 31) dan yang lebih tinggi, sistem menerapkan ini perilaku model. Saat aplikasi meminta fokus audio, sementara aplikasi lain memiliki fokus, sedang diputar, sistem memaksa aplikasi yang sedang diputar agar memudar. Penambahan atribut {i>fade-out<i} memberikan transisi yang lebih lancar saat beralih dari satu aplikasi ke aplikasi lainnya.
Perilaku fade out ini terjadi jika kondisi berikut terpenuhi:
Aplikasi pertama yang sedang diputar memenuhi semua kriteria berikut:
- Aplikasi memiliki
AudioAttributes.USAGE_MEDIA
atau Atribut penggunaanAudioAttributes.USAGE_GAME
. - Aplikasi berhasil meminta fokus audio dengan
AudioManager.AUDIOFOCUS_GAIN
. - Aplikasi tidak memutar audio dengan jenis konten
AudioAttributes.CONTENT_TYPE_SPEECH
.
- Aplikasi memiliki
Aplikasi kedua meminta fokus audio dengan
AudioManager.AUDIOFOCUS_GAIN
.
Jika kondisi ini terpenuhi, sistem audio akan memudarkan aplikasi pertama. Di akhir fade out, sistem akan memberi tahu aplikasi pertama tentang hilangnya fokus. Aplikasi pemutar tetap dibisukan hingga aplikasi meminta fokus audio lagi.
Perilaku fokus audio yang ada
Anda juga harus mengetahui kasus lain yang melibatkan pengalihan fokus audio.
Pengecilan volume otomatis
Pengecilan volume otomatis (mengurangi sementara level audio satu aplikasi sehingga satu lagi dapat didengar dengan jelas) diperkenalkan di Android 8.0 (API level 26).
Dengan membuat sistem mengimplementasikan pengecilan volume, Anda tidak perlu mengimplementasikan pengecilan volume pada aplikasi Anda.
Pengecilan volume otomatis juga terjadi saat notifikasi audio mengambil fokus dari aplikasi yang sedang diputar. Awal pemutaran notifikasi disinkronkan dengan pengoptimalan penurunan volume.
Pengecilan volume otomatis terjadi jika kondisi berikut terpenuhi:
Aplikasi pertama yang sedang diputar memenuhi semua kriteria berikut:
- Aplikasi berhasil meminta fokus audio dengan jenis fokus apa pun keuntungan.
- Aplikasi tidak memutar audio dengan jenis konten
AudioAttributes.CONTENT_TYPE_SPEECH
. - Aplikasi tidak disetel
AudioFocusRequest.Builder.setWillPauseWhenDucked(true)
Aplikasi kedua meminta fokus audio dengan
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
Jika kondisi ini terpenuhi, sistem audio akan mengecilkan semua pemutar aktif aplikasi pertama dan aplikasi kedua memiliki fokus. Saat aplikasi kedua mengabaikan fokus, hal itu akan membuat mereka tidak fokus. Aplikasi pertama tidak diberi tahu saat kehilangan fokus, jadi tidak perlu melakukan apa pun.
Perhatikan bahwa pengecilan volume otomatis tidak dilakukan saat pengguna mendengarkan isi ucapan, karena pengguna mungkin melewatkan beberapa program. Misalnya, panduan suara untuk petunjuk arah mengemudi tidak dikecilkan.
Bisukan pemutaran audio saat ini untuk panggilan telepon masuk
Beberapa aplikasi tidak berperilaku baik dan terus memutar audio selama panggilan telepon. Situasi ini memaksa pengguna untuk menemukan dan membisukan atau menghentikan aplikasi yang melanggar mendengar panggilan mereka. Untuk mencegah hal ini, sistem dapat membisukan audio dari aplikasi saat ada panggilan masuk. Sistem memanggil fitur ini bila sebuah sebuah panggilan telepon masuk diterima dan aplikasi memenuhi ketentuan berikut:
- Aplikasi tersebut memiliki
AudioAttributes.USAGE_MEDIA
atau Atribut penggunaanAudioAttributes.USAGE_GAME
. - Aplikasi berhasil meminta fokus audio (perolehan fokus apa pun) dan sedang diputar audio.
Jika aplikasi terus diputar selama panggilan, pemutarannya akan dibisukan hingga panggilan berakhir. Namun, jika aplikasi mulai diputar selama panggilan, pemutar tersebut tidak dibisukan dengan asumsi bahwa pengguna sengaja memulai pemutaran.
Fokus audio di Android 8.0 hingga Android 11
Mulai dari Android 8.0 (API level 26), saat Anda memanggil
requestAudioFocus()
Anda harus memberikan parameter AudioFocusRequest
. AudioFocusRequest
berisi informasi tentang konteks dan kemampuan audio aplikasi Anda. Tujuan
menggunakan informasi ini untuk mengelola perolehan dan hilangnya fokus audio
secara otomatis. Untuk melepaskan fokus audio, panggil metode tersebut
abandonAudioFocusRequest()
yang juga menggunakan AudioFocusRequest
sebagai argumennya. Gunakan kata kunci yang sama
AudioFocusRequest
saat Anda meminta dan mengabaikan fokus.
Untuk membuat AudioFocusRequest
, gunakan
AudioFocusRequest.Builder
. Karena permintaan fokus harus
selalu menentukan tipe permintaan, tipe itu disertakan dalam konstruktor
untuk builder. Gunakan metode builder untuk menetapkan kolom lain dari
permintaan.
Kolom FocusGain
wajib diisi; semua kolom lainnya bersifat opsional.
Metode | Catatan |
---|---|
setFocusGain()
|
Kolom ini wajib diisi dalam setiap permintaan. Dibutuhkan nilai
yang sama dengan
durationHint yang digunakan dalam panggilan pra-Android 8.0 ke requestAudioFocus() :
AUDIOFOCUS_GAIN , AUDIOFOCUS_GAIN_TRANSIENT ,
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK , atau AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE .
|
setAudioAttributes()
|
AudioAttributes menjelaskan kasus penggunaan untuk aplikasi Anda. Tujuan
sistem melihatnya saat aplikasi memperoleh dan kehilangan fokus audio. Atribut
menggantikan konsep jenis aliran. Di Android 8.0 (level API 26) dan yang lebih baru,
jenis aliran data untuk operasi apa pun selain kontrol volume tidak digunakan lagi. Gunakan
atribut yang sama dalam permintaan fokus yang Anda gunakan di pemutar audio (seperti
yang ditunjukkan dalam contoh setelah tabel ini).
Gunakan
Jika tidak ditentukan, |
setWillPauseWhenDucked()
|
Saat aplikasi lain meminta fokus dengan
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK , aplikasi yang memiliki fokus tidak
biasanya menerima
onAudioFocusChange()
karena sistem bisa melakukan
mengecilkan dirinya sendiri. Saat Anda perlu menjeda pemutaran,
daripada mengecilkan volume, panggil setWillPauseWhenDucked(true) lalu buat dan setel
OnAudioFocusChangeListener , seperti yang dijelaskan dalam otomatis
pengecilan volume.
|
setAcceptsDelayedFocusGain()
|
Permintaan fokus audio dapat gagal jika fokus dikunci oleh aplikasi lain.
Metode ini mengaktifkan perolehan fokus tertunda: kemampuan
mendapatkan fokus secara asinkron saat tersedia.
Perhatikan bahwa perolehan fokus tertunda hanya berfungsi jika Anda juga menentukan
|
setOnAudioFocusChangeListener()
|
OnAudioFocusChangeListener hanya diperlukan jika Anda juga menentukan
willPauseWhenDucked(true) atau setAcceptsDelayedFocusGain(true) dalam permintaan.
Ada dua metode untuk menyetel pemroses: satu dengan dan satu tanpa
pengendali. Pengendali ini adalah thread tempat pemroses berjalan. Jika Anda
tidak menentukan pengendali, pengendali yang terkait dengan
|
Contoh berikut menunjukkan cara menggunakan AudioFocusRequest.Builder
untuk membangun
AudioFocusRequest
dan meminta serta mengabaikan fokus audio:
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; } } }
Pengecilan volume otomatis
Di Android 8.0 (API level 26), saat aplikasi lain meminta fokus dengan
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
sistem dapat mengecilkan dan memulihkan volume
tanpa memanggil callback onAudioFocusChange()
aplikasi.
Meskipun pengecilan volume otomatis merupakan perilaku yang dapat diterima untuk pemutaran musik dan video aplikasi, layanan tidak berguna saat memutar konten lisan, seperti dalam aplikasi buku audio. Dalam hal ini, aplikasi harus dijeda.
Jika Anda ingin aplikasi berhenti sejenak saat diminta mengecilkan volume, bukan menurunkan volumenya, buat OnAudioFocusChangeListener
dengan
metode callback onAudioFocusChange()
yang menerapkan perilaku jeda/lanjutkan yang diinginkan.
Panggil setOnAudioFocusChangeListener()
untuk mendaftarkan pemroses, dan memanggil
setWillPauseWhenDucked(true)
untuk memberi tahu sistem agar menggunakan callback Anda, bukan melakukan pengecilan volume otomatis.
Perolehan fokus tertunda
Terkadang sistem tidak dapat memenuhi permintaan fokus audio karena fokusnya
"terkunci" oleh aplikasi lain, seperti saat menelepon. Dalam kasus ini,
requestAudioFocus()
menampilkan AUDIOFOCUS_REQUEST_FAILED
. Ketika ini terjadi,
aplikasi Anda tidak boleh melanjutkan pemutaran audio karena tidak mendapatkan
fokus.
Metode, setAcceptsDelayedFocusGain(true)
, yang memungkinkan aplikasi Anda menangani permintaan fokus
secara asinkron. Dengan menetapkan tanda ini, permintaan dibuat saat fokus terkunci
akan menampilkan AUDIOFOCUS_REQUEST_DELAYED
. Saat kondisi yang mengunci audio
fokus sudah tidak ada, seperti saat panggilan telepon berakhir, sistem
menyetujui permintaan fokus yang tertunda dan memanggil onAudioFocusChange()
untuk memberi tahu
.
Untuk menangani perolehan fokus tertunda, Anda harus membuat
OnAudioFocusChangeListener
dengan metode callback onAudioFocusChange()
yang
mengimplementasikan perilaku yang diinginkan dan mendaftarkan pemroses dengan memanggil
setOnAudioFocusChangeListener()
Fokus audio di Android 7.1 dan yang lebih lama
Saat Anda menelepon
requestAudioFocus()
Anda harus menentukan petunjuk durasi, yang mungkin
dipenuhi oleh aplikasi lain yang saat ini sedang memegang fokus dan memutar:
- Minta fokus audio permanen (
AUDIOFOCUS_GAIN
) saat Anda berencana memutar audio di masa mendatang (misalnya, saat memutar musik) dan Anda mengharapkan pemegang fokus audio sebelumnya untuk berhenti memutar. - Minta fokus sementara (
AUDIOFOCUS_GAIN_TRANSIENT
) saat Anda ingin bermain audio hanya untuk waktu yang singkat dan Anda mengharapkan pemegang audio sebelumnya menjeda sedang diputar. - Meminta fokus sementara dengan ducking
(
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
) untuk menunjukkan bahwa Anda ingin memutar audio untuk waktu yang singkat dan tidak apa-apa bagi pemilik fokus sebelumnya untuk sedang diputar jika "mengelokkan" (menurunkan) output audionya. Kedua output audio digabungkan ke streaming audio. Pengecilan volume sangat cocok untuk aplikasi yang menggunakan streaming audio secara terputus-putus, misalnya untuk audio petunjuk arah mengemudi.
Metode requestAudioFocus()
juga memerlukan AudioManager.OnAudioFocusChangeListener
. Pemroses ini harus
yang dibuat dalam aktivitas atau layanan yang sama yang memiliki sesi media Anda. Ini
menerapkan callback onAudioFocusChange()
yang diterima aplikasi Anda saat
beberapa aplikasi lain memperoleh atau mengabaikan fokus audio.
Cuplikan berikut meminta fokus audio permanen pada streaming
STREAM_MUSIC
dan mendaftarkan OnAudioFocusChangeListener
untuk menangani
perubahan selanjutnya dalam fokus audio. (Pemroses perubahan dibahas di
Merespons perubahan fokus audio.)
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 }
Setelah pemutaran selesai, panggil
abandonAudioFocus()
Kotlin
audioManager.abandonAudioFocus(afChangeListener)
Java
// Abandon audio focus when playback complete audioManager.abandonAudioFocus(afChangeListener);
Cara ini akan memberi tahu sistem bahwa Anda tidak lagi memerlukan fokus dan membatalkan pendaftaran
OnAudioFocusChangeListener
terkait. Jika Anda meminta fokus sementara,
ini akan memberi tahu aplikasi yang menjeda atau mengecilkan bahwa aplikasi dapat terus diputar atau
memulihkan volumenya.
Merespons perubahan fokus audio
Saat memperoleh fokus audio, aplikasi harus dapat melepaskannya ketika aplikasi lain
meminta fokus audio untuk dirinya sendiri. Jika hal ini terjadi, aplikasi Anda
menerima panggilan ke
onAudioFocusChange()
dalam AudioFocusChangeListener
yang Anda tentukan saat aplikasi memanggil requestAudioFocus()
.
Parameter focusChange
yang diteruskan ke onAudioFocusChange()
menunjukkan jenis
perubahan yang sedang terjadi. Sesuai
ke petunjuk durasi yang digunakan oleh aplikasi yang mendapatkan fokus. Aplikasi Anda harus
merespons dengan tepat.
- Kehilangan fokus sementara
-
Jika perubahan fokus bersifat sementara (
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
atauAUDIOFOCUS_LOSS_TRANSIENT
), aplikasi Anda harus mengecilkan (jika Anda tidak mengandalkan pada pengecilan volume otomatis) atau menjeda pemutaran, tetapi atau mempertahankan status yang sama.Selama kehilangan fokus audio sementara, Anda harus terus memantau perubahan dalam fokus audio dan bersiaplah untuk melanjutkan pemutaran normal ketika Anda mendapatkan kembali fokus. Saat aplikasi yang memblokir mengabaikan fokus, Anda akan menerima callback (
AUDIOFOCUS_GAIN
). Pada tahap ini, Anda dapat memulihkan volume ke level normal atau memulai ulang pemutaran. - Kehilangan fokus permanen
-
Jika kehilangan fokus audio bersifat permanen (
AUDIOFOCUS_LOSS
), aplikasi lain akan memutar audio. Aplikasi Anda akan segera menjeda pemutaran, karena tidak akan pernah terima callbackAUDIOFOCUS_GAIN
. Untuk memulai ulang pemutaran, pengguna harus melakukan tindakan eksplisit, seperti menekan kontrol putar di notifikasi atau UI aplikasi.
Cuplikan kode berikut menunjukkan cara menerapkan
OnAudioFocusChangeListener
dan callback onAudioFocusChange()
-nya. Perhatikan
penggunaan Handler
untuk menunda callback penghentian saat kehilangan audio secara permanen
fokus.
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 } } };
Pengendali menggunakan Runnable
yang terlihat seperti ini:
Kotlin
private var delayedStopRunnable = Runnable { mediaController.transportControls.stop() }
Java
private Runnable delayedStopRunnable = new Runnable() { @Override public void run() { getMediaController().getTransportControls().stop(); } };
Untuk memastikan perhentian tertunda tidak dimulai jika pengguna memulai ulang pemutaran, panggil
mHandler.removeCallbacks(mDelayedStopRunnable)
sebagai respons terhadap status apa pun
perubahan. Misalnya, panggil removeCallbacks()
dalam onPlay()
Callback Anda,
onSkipToNext()
, dll. Anda juga harus memanggil metode ini dalam class
Callback onDestroy()
saat membersihkan resource yang digunakan oleh layanan Anda.