İki veya daha fazla Android uygulaması aynı çıkış akışında aynı anda ses çalabilir ve sistem tüm sesleri karıştırır. Bu durum teknik olarak etkileyici olsa da kullanıcıları çok sinirlendirebilir. Android, tüm müzik uygulamalarının aynı anda çalmasını önlemek için ses odaklanması kavramını sunar. Aynı anda yalnızca bir uygulama ses odağını tutabilir.
Uygulamanızın ses çıkışı yapması gerektiğinde ses odağı isteğinde bulunması gerekir. Odaklandığında ses çalabilir. Ancak ses odağını aldıktan sonra, oynatma işlemini bitirene kadar odağı koruyamayabilirsiniz. Başka bir uygulama odak isteğinde bulunabilir. Bu durumda, ses odağı üzerindeki kontrolünüz iptal edilir. Bu durumda, uygulamanızın yeni ses kaynağını daha kolay duyabilmeleri için kullanıcıların oynatmayı duraklatması veya sesini kısması gerekir.
Android 12'den (API düzeyi 31) önce ses odağı sistem tarafından yönetilmez. Bu nedenle, uygulama geliştiricilerin ses odağı yönergelerine uyması önerilse de Android 11 (API düzeyi 30) veya önceki sürümlerin yüklü olduğu bir cihazda ses odağını kaybettikten sonra bile yüksek sesle çalmaya devam eden uygulamalar sistem tarafından engellenemez. Ancak bu uygulama davranışı, kötü bir kullanıcı deneyimine yol açar ve genellikle kullanıcıların hatalı uygulamayı kaldırmasına neden olabilir.
İyi tasarlanmış bir ses uygulaması, ses odağını şu genel yönergelere göre yönetmelidir:
Oynamaya başlamadan hemen önce
requestAudioFocus()
numaralı telefonu arayın ve aramanınAUDIOFOCUS_REQUEST_GRANTED
döndürdüğünü doğrulayın. Medya oturumunuzunonPlay()
geri çağırmasındarequestAudioFocus()
işlevini çağırın.Başka bir uygulama ses odağı kazandığında oynatmayı durdurun veya duraklatın ya da sesi kısın.
Oynatma durduğunda (örneğin, uygulamada oynatılacak başka içerik kalmadığında) ses odağını bırakın. Kullanıcı oynatmayı duraklatırsa ancak daha sonra oynatmaya devam edebilirse uygulamanızın ses odağını bırakması gerekmez.
Uygulamanızın çaldığı ses türünü açıklamak için
AudioAttributes
kullanın. Örneğin, konuşma oynatan uygulamalar içinCONTENT_TYPE_SPEECH
değerini belirtin.
Ses odağı, çalıştırılan Android sürümüne bağlı olarak farklı şekilde işlenir:
- Android 12 (API düzeyi 31) veya sonraki sürümler
- Ses odağı sistem tarafından yönetilir. Sistem, başka bir uygulama ses odağı istediğinde bir uygulamadan ses çalmayı zorla kapatır. Sistem, gelen arama olduğunda ses çalmayı da kapatır.
- Android 8.0 (API düzeyi 26) ile Android 11 (API düzeyi 30)
- Ses odağı sistem tarafından yönetilmez ancak Android 8.0 (API düzeyi 26) sürümünden itibaren kullanıma sunulan bazı değişiklikleri içerir.
- Android 7.1 (API düzeyi 25) ve önceki sürümler
- Ses odağı sistem tarafından yönetilmez ve uygulamalar ses odağını
requestAudioFocus()
veabandonAudioFocus()
kullanarak yönetir.
Android 12 ve sonraki sürümlerde ses odağı
Ses odağını kullanan bir medya veya oyun uygulaması, odağı kaybettikten sonra ses çalmamalıdır. Android 12 (API düzeyi 31) ve sonraki sürümlerde sistem bu davranışı zorunlu kılar. Bir uygulama, başka bir uygulama odaklanmış ve oynatılırken ses odağı istediğinde sistem, oynatılan uygulamanın sesini yavaş yavaş azaltır. Solma efektinin eklenmesi, bir uygulamadan diğerine geçişi daha sorunsuz hale getirir.
Bu solma davranışı aşağıdaki koşullar karşılandığında gerçekleşir:
Şu anda oynatılan ilk uygulama, bu ölçütlerin tümünü karşılıyor:
- Uygulamada
AudioAttributes.USAGE_MEDIA
veyaAudioAttributes.USAGE_GAME
kullanım özelliği var. - Uygulama,
AudioManager.AUDIOFOCUS_GAIN
ile ses odağı isteğini başarıyla gönderdi. - Uygulama,
AudioAttributes.CONTENT_TYPE_SPEECH
içerik türüyle ses çalmıyor.
- Uygulamada
İkinci bir uygulama,
AudioManager.AUDIOFOCUS_GAIN
ile ses odağı istiyor.
Bu koşullar karşılandığında ses sistemi ilk uygulamayı yavaşça kapatır. Yavaşça kapatma işleminin sonunda sistem, ilk uygulamaya odak kaybı olduğunu bildirir. Uygulama, ses odağını tekrar isteyene kadar uygulamanın oynatıcıları sessiz kalır.
Mevcut ses odağı davranışları
Ses odağının değiştiği diğer durumlar hakkında da bilgi sahibi olmanız gerekir.
Otomatik ses kısma
Otomatik sesi kısma (bir uygulamanın ses seviyesini geçici olarak azaltarak başka bir uygulamanın net bir şekilde duyulmasını sağlama) özelliği Android 8.0 (API düzeyi 26) sürümünde kullanıma sunuldu.
Sistemde ducking uygulanması sayesinde uygulamanızda ducking uygulamanız gerekmez.
Otomatik ses azaltma, bir sesli bildirim oynatılan uygulamanın odağını aldığında da gerçekleşir. Bildirim oynatmanın başlangıcı, ses azaltma eğrisinin sonuyla senkronize edilir.
Aşağıdaki koşullar karşılandığında otomatik ses kısma gerçekleşir:
Şu anda oynatılan ilk uygulama aşağıdaki tüm ölçütleri karşılıyor:
- Uygulama, herhangi bir focus gain türüyle ses odağı isteğinde başarıyla bulundu.
- Uygulama, içerik türü
AudioAttributes.CONTENT_TYPE_SPEECH
olan sesleri oynatmıyor. - Uygulama,
AudioFocusRequest.Builder.setWillPauseWhenDucked(true)
değerini ayarlamadı.
İkinci bir uygulama,
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
ile ses odağı istiyor.
Bu koşullar karşılandığında ses sistemi, ikinci uygulama odaklanmışken birinci uygulamanın tüm etkin oynatıcılarının sesini kısar. İkinci uygulama odağı bıraktığında diğer uygulamalar da ayrılır. İlk uygulama, odak kaybedildiğinde bildirim almaz. Bu nedenle herhangi bir işlem yapması gerekmez.
Kullanıcı programın bir kısmını kaçırabileceği için, konuşma içeriklerini dinlerken otomatik ses kısma işleminin yapılmadığını unutmayın. Örneğin, sürüş yol tarifleri için sesli yönlendirme özelliği kısılmaz.
Gelen telefon aramaları için mevcut ses çalmayı sessize alma
Bazı uygulamalar düzgün çalışmaz ve telefon görüşmeleri sırasında ses çalmaya devam eder. Bu durumda kullanıcı, görüşmesini duyabilmek için sorunlu uygulamayı bulup sessize almaya veya uygulamadan çıkmaya zorlanır. Bunu önlemek için sistem, gelen arama olduğunda diğer uygulamalardan gelen sesi kapatabilir. Sistem, gelen bir telefon araması alındığında ve bir uygulama şu koşulları karşıladığında bu özelliği etkinleştirir:
- Uygulamada
AudioAttributes.USAGE_MEDIA
veyaAudioAttributes.USAGE_GAME
kullanım özelliği var. - Uygulama, ses odağı isteğini başarıyla aldı (herhangi bir odak kazanımı) ve ses çalıyor.
Görüşme sırasında oynatmaya devam eden uygulamaların oynatması, görüşme sona erene kadar sessize alınır. Ancak, arama sırasında bir uygulama oynatmaya başlarsa kullanıcının oynatmayı kasıtlı olarak başlattığı varsayılarak bu oynatıcı sessize alınmaz.
Android 8.0-11 sürümlerinde ses odağı
Android 8.0 (API düzeyi 26) sürümünden itibaren, requestAudioFocus()
işlevini çağırdığınızda AudioFocusRequest
parametresini sağlamanız gerekir. AudioFocusRequest
Uygulamanızın ses bağlamı ve özellikleri hakkında bilgiler içerir. Sistem, ses odağının kazancını ve kaybını otomatik olarak yönetmek için bu bilgileri kullanır. Ses odağını serbest bırakmak için abandonAudioFocusRequest()
yöntemini çağırın. Bu yöntem, bağımsız değişken olarak AudioFocusRequest
alır. Hem odaklanma isteğinde bulunduğunuzda hem de odaklanmayı bıraktığınızda aynı AudioFocusRequest
örneğini kullanın.
AudioFocusRequest
oluşturmak için AudioFocusRequest.Builder
kullanın. Odaklanma isteğinde her zaman istek türü belirtilmesi gerektiğinden tür, oluşturucunun oluşturucu için olanına dahil edilir. İsteğin diğer alanlarını ayarlamak için oluşturucunun yöntemlerini kullanın.
FocusGain
alanı zorunludur, diğer tüm alanlar isteğe bağlıdır.
Yöntem | Notlar |
---|---|
setFocusGain()
|
Bu alan her istekte zorunludur. Android 8.0 öncesi requestAudioFocus() çağrısında kullanılan durationHint ile aynı değerleri alır:
AUDIOFOCUS_GAIN , AUDIOFOCUS_GAIN_TRANSIENT ,
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK veya AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE .
|
setAudioAttributes()
|
AudioAttributes , uygulamanızın kullanım alanını açıklar. Sistem, bir uygulama ses odağı kazandığında ve kaybettiğinde bu alanlara bakar. Özellikler, yayın türü kavramının yerini alır. Android 8.0 (API düzeyi 26) ve sonraki sürümlerde, ses kontrolleri dışındaki tüm işlemler için akış türleri kullanımdan kaldırılmıştır. Odaklanma isteğinde, ses oynatıcınızda kullandığınız özelliklerin aynısını kullanın (bu tablonun ardından gelen örnekte gösterildiği gibi).
Önce özellikleri belirtmek için
Belirtilmezse |
setWillPauseWhenDucked()
|
Başka bir uygulama AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK ile odaklanma isteğinde bulunduğunda, odaklanmış uygulama genellikle onAudioFocusChange()
geri çağırma işlemi almaz çünkü sistem kendi başına odaklanma isteğini karşılayabilir. Sesi azaltmak yerine oynatmayı duraklatmanız gerektiğinde setWillPauseWhenDucked(true) işlevini çağırın ve otomatik ses azaltma bölümünde açıklandığı gibi bir OnAudioFocusChangeListener oluşturup ayarlayın.
|
setAcceptsDelayedFocusGain()
|
Odak başka bir uygulama tarafından kilitlendiğinde ses odağı isteği başarısız olabilir.
Bu yöntem, gecikmeli odak kazanımını sağlar: odak kullanılabilir hale geldiğinde eşzamansız olarak odak kazanma özelliği.
Uygulamanızın odağın verildiğini bilmesi için geri aramayı alması gerektiğinden, gecikmeli odak kazanımının yalnızca ses isteğinde bir |
setOnAudioFocusChangeListener()
|
OnAudioFocusChangeListener yalnızca istekte willPauseWhenDucked(true) veya setAcceptsDelayedFocusGain(true) de belirtirseniz gereklidir.
Dinleyiciyi ayarlamak için iki yöntem vardır: biri işleyici bağımsız değişkeniyle, diğeri ise işleyici bağımsız değişkeni olmadan. İşleyici, dinleyicinin çalıştığı iş parçacığıdır. Bir işleyici belirtmezseniz ana |
Aşağıdaki örnekte, AudioFocusRequest.Builder
kullanarak AudioFocusRequest
oluşturma, ses odağı isteme ve ses odağını bırakma işlemleri gösterilmektedir:
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; } } }
Otomatik ses kısma
Android 8.0'da (API düzeyi 26) başka bir uygulama AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
ile odak istediğinde sistem, uygulamanın onAudioFocusChange()
geri çağırmasını çağırmadan sesi kısabilir ve geri yükleyebilir.
Otomatik ses kısma, müzik ve video oynatma uygulamaları için kabul edilebilir bir davranış olsa da sesli içerik oynatılırken (ör. sesli kitap uygulamalarında) kullanışlı değildir. Bu durumda uygulama, sesi kısma yerine duraklatmalıdır.
Uygulamanızın sesini azaltmak yerine eğilme istendiğinde duraklatılmasını istiyorsanız istenen duraklatma/devam ettirme davranışını uygulayan bir onAudioFocusChange()
geri çağırma yöntemiyle OnAudioFocusChangeListener
oluşturun.
Dinleyiciyi kaydetmek için setOnAudioFocusChangeListener()
'ı, sisteme otomatik ses kısma işlemi yerine geri arama özelliğini kullanmasını söylemek için setWillPauseWhenDucked(true)
'ı arayın.
Gecikmeli odak kazanma
Bazen odak başka bir uygulama tarafından "kilitlendiği" için (ör. telefon görüşmesi sırasında) sistem ses odağı isteğini veremez. Bu durumda, requestAudioFocus()
işlevi AUDIOFOCUS_REQUEST_FAILED
değerini döndürür. Bu durumda, odaklanmadığı için uygulamanız ses oynatmaya devam etmemelidir.
Uygulamanızın odaklanma isteğini eşzamansız olarak işlemesini sağlayan yöntem (setAcceptsDelayedFocusGain(true)
). Bu işaret ayarlandığında, odak kilitliyken yapılan bir istek AUDIOFOCUS_REQUEST_DELAYED
değerini döndürür. Ses odağını kilitleyen koşul artık mevcut olmadığında (ör. telefon görüşmesi sona erdiğinde) sistem, bekleyen odak isteğini verir ve uygulamanızı bilgilendirmek için onAudioFocusChange()
işlevini çağırır.
Odak kazanma işleminin gecikmesini yönetmek için istenen davranışı uygulayan bir onAudioFocusChange()
geri çağırma yöntemiyle OnAudioFocusChangeListener
oluşturmanız ve setOnAudioFocusChangeListener()
çağırarak dinleyiciyi kaydetmeniz gerekir.
Android 7.1 ve önceki sürümlerde ses odağı
Arama yaptığınızda
requestAudioFocus()
şu anda odaklanmış ve oynayan başka bir uygulama tarafından dikkate alınabilecek bir süre ipucu belirtmeniz gerekir:
- Öngörülebilir bir süre boyunca ses çalmayı planladığınızda (ör. müzik çalarken) ve ses odağının önceki sahibinin çalmayı durdurmasını beklediğinizde kalıcı ses odağı isteğinde bulunun (
AUDIOFOCUS_GAIN
). - Yalnızca kısa bir süre ses çalmayı ve önceki tutucunun çalmayı duraklatmasını beklediğinizde geçici odak isteğinde bulunun (
AUDIOFOCUS_GAIN_TRANSIENT
). - Yalnızca kısa bir süre ses çalmayı beklediğinizi ve önceki odak sahibinin ses çıkışını "kısıp" (düşürüp) çalmaya devam etmesinin sorun olmayacağını belirtmek için ducking (
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
) ile geçici odak isteğinde bulunun. Her iki ses çıkışı da ses akışına karıştırılır. Ses azaltma, özellikle sesli yol tarifleri gibi ses akışını aralıklı olarak kullanan uygulamalar için uygundur.
requestAudioFocus()
yöntemi için de AudioManager.OnAudioFocusChangeListener
gerekir. Bu dinleyici, medya oturumunuzun sahibi olan etkinliğin veya hizmetin içinde oluşturulmalıdır. Başka bir uygulama ses odağını aldığında veya bıraktığında uygulamanızın aldığı geri çağırmayı onAudioFocusChange()
uygular.
Aşağıdaki snippet, akışta STREAM_MUSIC
kalıcı ses odağı ister ve ses odağındaki sonraki değişiklikleri işlemek için OnAudioFocusChangeListener
kaydeder. (Değişiklik dinleyicisi, Ses odağı değişikliğine yanıt verme bölümünde ele alınmıştır.)
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 }
Oynatmayı bitirdiğinizde abandonAudioFocus()
numaralı telefonu arayın.
Kotlin
audioManager.abandonAudioFocus(afChangeListener)
Java
// Abandon audio focus when playback complete audioManager.abandonAudioFocus(afChangeListener);
Bu işlem, sisteme artık odaklanmaya ihtiyacınız olmadığını bildirir ve ilişkili OnAudioFocusChangeListener
öğesinin kaydını siler. Geçici odaklanma isteğinde bulunduysanız bu, duraklatılmış veya sesi kısılmış bir uygulamaya oynatmaya devam edebileceğini ya da sesini geri yükleyebileceğini bildirir.
Ses odağı değişikliğine yanıt verme
Bir uygulama ses odağı kazandığında, başka bir uygulama kendisi için ses odağı istediğinde bu odağı bırakabilmelidir. Bu durumda, uygulamanız requestAudioFocus()
'ı çağırdığında belirttiğiniz AudioFocusChangeListener
içindeki onAudioFocusChange()
yöntemine yapılan bir çağrı alır.
onAudioFocusChange()
'e aktarılan focusChange
parametresi, gerçekleşen değişiklik türünü gösterir. Odak kazanan uygulama tarafından kullanılan süre ipucuna karşılık gelir. Uygulamanız uygun şekilde yanıt vermelidir.
- Geçici odak kaybı
-
Odak değişikliği geçiciyse (
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
veyaAUDIOFOCUS_LOSS_TRANSIENT
), uygulamanız otomatik ses kısma özelliğini kullanmıyorsanız sesi kısmalı veya oynatmayı duraklatmalı ancak aksi takdirde aynı durumu korumalıdır.Ses odağının geçici olarak kaybolduğu durumlarda, ses odağındaki değişiklikleri izlemeye devam etmeli ve odağı tekrar kazandığınızda normal oynatmaya devam etmeye hazır olmalısınız. Engelleme uygulaması odağı bıraktığında geri çağırma (
AUDIOFOCUS_GAIN
) alırsınız. Bu noktada, sesi normal seviyeye geri yükleyebilir veya oynatmayı yeniden başlatabilirsiniz. - Odaklanmanın kalıcı olarak kaybolması
-
Ses odağı kaybı kalıcıysa (
AUDIOFOCUS_LOSS
) başka bir uygulama ses çalıyor demektir. Uygulamanız,AUDIOFOCUS_GAIN
geri çağırması almayacağı için oynatmayı hemen duraklatmalıdır. Oynatmayı yeniden başlatmak için kullanıcının, bildirimde veya uygulama kullanıcı arayüzünde oynatma taşıma kontrolüne basma gibi açık bir işlem yapması gerekir.
Aşağıdaki kod snippet'inde, OnAudioFocusChangeListener
ve onAudioFocusChange()
geri çağırmasının nasıl uygulanacağı gösterilmektedir. Ses odağı kalıcı olarak kaybolduğunda durdurma geri arama işlemini geciktirmek için Handler
kullanıldığını fark edin.
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 } } };
İşleyici, aşağıdaki gibi bir Runnable
kullanır:
Kotlin
private var delayedStopRunnable = Runnable { mediaController.transportControls.stop() }
Java
private Runnable delayedStopRunnable = new Runnable() { @Override public void run() { getMediaController().getTransportControls().stop(); } };
Kullanıcı oynatmayı yeniden başlatırsa gecikmeli durdurmanın devreye girmemesini sağlamak için herhangi bir durum değişikliğine yanıt olarak mHandler.removeCallbacks(mDelayedStopRunnable)
işlevini çağırın. Örneğin, geri çağırma işlevinizin onPlay()
, onSkipToNext()
vb. içinde removeCallbacks()
işlevini çağırın. Ayrıca, hizmetiniz tarafından kullanılan kaynakları temizlerken hizmetinizin onDestroy()
geri çağırma işlevinde de bu yöntemi çağırmanız gerekir.