İki veya daha fazla Android uygulaması aynı çıkış akışına aynı anda ses oynatabilir ve sistem her şeyi birlikte karıştırır. Bu teknik açıdan etkileyici olsa da kullanıcılar için çok can sıkıcı olabilir. Android, tüm müzik uygulamalarının aynı anda çalmasını önlemek için ses odak noktası fikrini sunar. Aynı anda yalnızca bir uygulama ses odağına sahip olabilir.
Uygulamanızın ses çıkarması gerektiğinde ses odağını istemelidir. Odaklandığında ses çalabilir. Ancak ses odağını aldıktan sonra oyunu bitirinceye kadar bu özelliği koruyamayabilirsiniz. Başka bir uygulama, ses odağına sahip olmanızı engelleyecek şekilde odak isteğinde bulunabilir. Bu durumda uygulamanız, kullanıcıların yeni ses kaynağını daha kolay duyabilmesi için oynatmayı duraklatmalı veya ses seviyesini düşürmelidir.
Android 12'den (API düzeyi 31) önce ses odak noktası sistem tarafından yönetilmez. Bu nedenle, uygulama geliştiricilerin ses odak yönergelerine uymaları önerilir. Ancak bir uygulama, Android 11 (API düzeyi 30) veya önceki sürümleri çalıştıran bir cihazda ses odağını kaybettikten sonra bile yüksek sesle çalmaya devam ederse sistem bunu engelleyemez. Ancak bu uygulama davranışı, kullanıcı deneyimini olumsuz yönde etkiler ve genellikle kullanıcıların sorunlu uygulamayı kaldırmasına neden olur.
İyi tasarlanmış bir ses uygulaması, ses odağını aşağıdaki genel yönergelere göre yönetmelidir:
Oynamaya başlamadan hemen önce
requestAudioFocus()
'ü arayın ve aramanınAUDIOFOCUS_REQUEST_GRANTED
numarası ile yanıtlandığını doğrulayın. Medya oturumunuzunonPlay()
geri çağırma işlevinderequestAudioFocus()
çağrısını yapın.Başka bir uygulama ses odağını aldığında oynatmayı durdurun veya duraklatın ya da sesi kısın (yani azaltın).
Oynatma durduğunda (örneğin, uygulamada çalınacak bir şey kalmadığında) ses odağını bırakın. Kullanıcı oynatmayı duraklatırsa uygulamanızın ses odağını kaybetmesi gerekmez. Kullanıcı daha sonra oynatmayı devam ettirebilir.
Uygulamanızın çaldığı ses türünü belirtmek için
AudioAttributes
öğesini kullanın. Örneğin, konuşma çalan uygulamalar içinCONTENT_TYPE_SPEECH
değerini belirtin.
Ses odak noktası, çalıştırılan Android sürümüne bağlı olarak farklı şekilde ele alınır:
- 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 oynatmanın yavaşça sona ermesini sağlar. Sistem, gelen bir arama olduğunda ses oynatmayı da kapatır.
- Android 8.0 (API düzeyi 26) ile Android 11 (API düzeyi 30) arasındaki sürümler
- Ses odak noktası 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. Uygulamalar,
requestAudioFocus()
veabandonAudioFocus()
öğelerini kullanarak ses odağını yönetir.
Android 12 ve sonraki sürümlerde ses odak noktası
İşitsel odak 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. Odak başka bir uygulamadayken ve bu uygulama ses çalarken bir uygulama ses odağını istediğinde sistem, çalan uygulamanın ses seviyesini azaltır. Eklenen karartma özelliği, bir uygulamadan diğerine geçişi daha sorunsuz hale getirir.
Bu karartma davranışı aşağıdaki koşullar karşılandığında gerçekleşir:
Şu anda oynatılan ilk uygulama aşağıdaki ölçütlerin tümünü karşılamalıdır:
- Uygulamada
AudioAttributes.USAGE_MEDIA
veyaAudioAttributes.USAGE_GAME
kullanım özelliği var. - Uygulama,
AudioManager.AUDIOFOCUS_GAIN
ile ses odağını başarıyla istedi. - Uygulama,
AudioAttributes.CONTENT_TYPE_SPEECH
içerik türüne sahip sesler çalmıyor.
- Uygulamada
İkinci bir uygulama,
AudioManager.AUDIOFOCUS_GAIN
ile ses odağı ister.
Bu koşullar karşılandığında ses sistemi ilk uygulamanın sesini yavaşça azaltır. Ses azaltmanın sonunda sistem, ilk uygulamayı odak kaybı konusunda bilgilendirir. Uygulamanın oynatıcıları, uygulama ses odağını tekrar isteyene kadar sessiz kalır.
Mevcut ses odağı davranışları
Ses odağında geçiş içeren diğer durumlara da dikkat etmeniz gerekir.
Otomatik ses kısma
Otomatik ses azaltma (bir uygulamanın ses seviyesini geçici olarak azaltarak başka bir uygulamanın net bir şekilde duyulmasını sağlama), Android 8.0 (API düzeyi 26) sürümünde kullanıma sunulmuştur.
Sistemin ses azaltma özelliğini uygulamasını sağlayarak uygulamanızda ses azaltma özelliğini uygulamanız gerekmez.
Otomatik ses azaltma, sesli bildirim oynatılan bir uygulamadan odağı aldığında da gerçekleşir. Bildirim oynatmanın başlangıcı, ses azaltma rampasının sonuyla senkronize edilir.
Otomatik ses azaltma, aşağıdaki koşullar karşılanırsa gerçekleşir:
Şu anda oynatılan ilk uygulama aşağıdaki ölçütlerin tümünü karşılamalıdır:
- Uygulama, herhangi bir odak kazanımı türüyle işitsel odak isteğinde bulundu.
- Uygulama,
AudioAttributes.CONTENT_TYPE_SPEECH
içerik türüne sahip sesler çalmıyor. - Uygulama,
AudioFocusRequest.Builder.setWillPauseWhenDucked(true)
değerini ayarlamadı.
İkinci uygulama,
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
ile ses odağını ister.
Bu koşullar karşılandığında ses sistemi, ikinci uygulamanın odakta olduğu sırada ilk uygulamanın tüm etkin oynatıcılarını susturur. İkinci uygulama odaktan çıktığında, bu uygulamaların üstündeki örtü kaldırılır. İlk uygulama, odağı kaybettiğinde bilgilendirilmez. Bu nedenle, herhangi bir işlem yapması gerekmez.
Kullanıcı konuşma içeriği dinlerken otomatik ses azaltmanın yapılmadığını unutmayın. Aksi takdirde kullanıcı, programın bir kısmını kaçırabilir. Örneğin, sürüş yol tarifleri için sesli rehberlik azaltılmaz.
Gelen telefon aramaları için mevcut ses çalmayı kapatma
Bazı uygulamalar düzgün çalışmaz ve telefon görüşmeleri sırasında ses çalmaya devam eder. Bu durum, kullanıcının aramayı duymak için rahatsız edici uygulamayı bulup sessize almasını veya uygulamadan çıkmasını zorunlu kılar. Bunu önlemek için sistem, gelen bir arama sırasında diğer uygulamalardan gelen sesleri kapatabilir. Sistem, gelen bir telefon araması alındığında ve bir uygulama aşağıdaki koşulları karşıladığında bu özelliği çağırır:
- Uygulamada
AudioAttributes.USAGE_MEDIA
veyaAudioAttributes.USAGE_GAME
kullanım özelliği var. - Uygulama, ses odağını (herhangi bir odak kazanımı) başarıyla istedi ve ses çalıyor.
Arama sırasında oynatmaya devam eden uygulamaların sesi, arama sona erene kadar kapatılı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ı kapatılmaz.
Android 8.0 ile Android 11 arasındaki sürümlerde ses odak noktası
Android 8.0 (API düzeyi 26) sürümünden itibaren requestAudioFocus()
işlevini çağırırken bir AudioFocusRequest
parametresi sağlamanız gerekir. AudioFocusRequest
, uygulamanızın ses bağlamı ve özellikleri hakkında bilgi içerir. Sistem, ses odağının kazanılmasını ve kaybedilmesini otomatik olarak yönetmek için bu bilgileri kullanır. Ses odağını bırakmak için, bağımsız değişkeni AudioFocusRequest
olan abandonAudioFocusRequest()
yöntemini çağırın. Hem odaklanmayı istediğinizde hem de odaklanmayı bıraktığınızda aynı AudioFocusRequest
örneğini kullanın.
AudioFocusRequest
oluşturmak için AudioFocusRequest.Builder
kullanın. Odak isteği her zaman isteğin türünü belirtmesi gerektiğinden, tür oluşturucu için yapıcıya 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ı tanımlar. Sistem, bir uygulama ses odağını kazandığında ve kaybettiğinde bu bilgilere bakar. Özellikler, yayın türü kavramının önüne geçer. Android 8.0 (API düzeyi 26) ve sonraki sürümlerde, ses kontrolleri dışındaki işlemler için akış türlerinin desteği sonlandırılmıştır. Odak isteğinde, ses oynatıcınızda kullandığınız özellikleri kullanın (bu tablonun altındaki örnekte gösterildiği gibi).
Önce özellikleri belirtmek için bir
Belirtilmezse |
setWillPauseWhenDucked()
|
Başka bir uygulama AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK ile odaklanmayı istediğinde, sistem gizlemeyi kendi başına yapabildiğinden odaklanmaya sahip uygulama genellikle bir onAudioFocusChange() geri çağırma almaz. 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 kazanmayı (odak kullanıma sunulduğunda asenkron olarak odak elde etme) etkinleştirir.
Gecikmeli odağı kazanma özelliğinin yalnızca ses isteğinde bir |
setOnAudioFocusChangeListener()
|
OnAudioFocusChangeListener yalnızca isteğinde 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şkeni olan, diğeri ise işleyici bağımsız değişkeni olmayan. İşleyici, dinleyicinin çalıştığı iş parçacığıdır. Bir işleyici belirtmezseniz ana |
Aşağıdaki örnekte, AudioFocusRequest
oluşturmak ve ses odağını istemek ve bırakmak için AudioFocusRequest.Builder
'ün nasıl kullanılacağı gösterilmektedir:
// 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 } } }
// 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 odaklanmayı istediğinde sistem, uygulamanın onAudioFocusChange()
geri çağırma işlevini çağırmadan sesi kısabilir ve geri yükleyebilir.
Otomatik ses azaltma, müzik ve video oynatma uygulamaları için kabul edilebilir bir davranış olsa da sesli kitap uygulaması gibi sözlü içerik oynatırken kullanışlı değildir. Bu durumda uygulamanın duraklatması gerekir.
Uygulamanızın ses düzeyini azaltmak yerine sessiz moduna geçmesini istiyorsanız istenen duraklatma/devam ettirme davranışını uygulayan bir onAudioFocusChange()
geri çağırma yöntemi içeren bir OnAudioFocusChangeListener
oluşturun.
Dinleyiciyi kaydetmek için setOnAudioFocusChangeListener()
, sistemi otomatik ses azaltma yerine geri aramanızı kullanması için setWillPauseWhenDucked(true)
işlevini çağırın.
Gecikmeli odaklanma
Bazen sistem, odak başka bir uygulama tarafından "kilitlendiği" için (ör. telefon görüşmesi sırasında) ses odağına yönelik isteği yerine getiremez. Bu durumda, requestAudioFocus()
AUDIOFOCUS_REQUEST_FAILED
değerini döndürür. Bu durumda, uygulamanız odak alamadığı için ses oynatmaya devam etmemelidir.
Uygulamanızın, odaklanma isteğini eşzamansız olarak işlemesine olanak tanıyan setAcceptsDelayedFocusGain(true)
yöntemi. Bu işaret ayarlandığında, odak kilitliyken yapılan bir istek AUDIOFOCUS_REQUEST_DELAYED
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 onaylar ve uygulamanızı bilgilendirmek için onAudioFocusChange()
çağrısı yapar.
Odaklanma süresinin gecikmesini ele almak için, istenen davranışı uygulayan bir onAudioFocusChange()
geri çağırma yöntemi içeren bir OnAudioFocusChangeListener
oluşturmanız ve setOnAudioFocusChangeListener()
çağrısını yaparak dinleyiciyi kaydetmeniz gerekir.
Android 7.1 ve önceki sürümlerde ses odağı
requestAudioFocus()
işlevini çağırırken, şu anda odak noktasında olan ve oynatılan başka bir uygulama tarafından dikkate alınabilecek bir süre ipucu belirtmeniz gerekir:
- Önümüzdeki 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ğını (
AUDIOFOCUS_GAIN
) isteyin. - Sesi yalnızca kısa bir süre oynatmayı ve önceki sahibin oynatmayı duraklatmasını beklediğinizde geçici odak (
AUDIOFOCUS_GAIN_TRANSIENT
) isteyin. - Ses oynatmayı yalnızca kısa bir süre beklediğinizi ve önceki odak sahibinin ses çıkışını "azaltarak" (düşük sesle) oynatmaya devam etmesinin uygun olduğunu belirtmek için ses azaltma (
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 özelliği, özellikle ses akışını aralıklı olarak kullanan uygulamalar (ör. sesli yol tarifleri) için uygundur.
requestAudioFocus()
yöntemi için bir AudioManager.OnAudioFocusChangeListener
de gereklidir. Bu dinleyici, medya oturumunuzun sahibi olan etkinlikte veya hizmette oluşturulmalıdır. Başka bir uygulama ses odağını aldığında veya terk ettiğinde uygulamanızın aldığı geri çağırma işlevini onAudioFocusChange()
uygular.
Aşağıdaki snippet, akışta kalıcı ses odak isteğinde bulunur STREAM_MUSIC
ve ses odağındaki sonraki değişiklikleri işlemek için bir OnAudioFocusChangeListener
kaydeder. (Değişiklik dinleyicisi, Ses odak değişikliğine yanıt verme bölümünde ele alınmıştır.)
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 }
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 }
Oynatma işlemini tamamladığınızda abandonAudioFocus()
numaralı telefonu arayın.
audioManager.abandonAudioFocus(afChangeListener)
// 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 duraklatılmış veya sessize alınmış bir uygulama, oynatmaya devam edebileceğini veya sesini geri yükleyebileceğini bildirir.
Ses odağındaki bir değişikliğe yanıt verme
Bir uygulama ses odağını aldığında, başka bir uygulama ses odağını kendisi için istediğinde bu odağı bırakabilmelidir. Bu durumda, uygulamanız requestAudioFocus()
adlı uygulamayı çağırırken belirttiğiniz AudioFocusChangeListener
sınıfındaki onAudioFocusChange()
yöntemine çağrı alır.
onAudioFocusChange()
parametresine iletilen focusChange
parametresi, gerçekleşen değişiklik türünü belirtir. Odak alan uygulama tarafından kullanılan süre ipucuyla aynıdır. Uygulamanız uygun şekilde yanıt vermelidir.
- Geçici odaklanma kaybı
-
Odak değişikliği geçiciyse (
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
veyaAUDIOFOCUS_LOSS_TRANSIENT
) uygulamanız, otomatik olarak karartma özelliğini kullanmıyorsanız karartmalı veya oynatmayı duraklatmalı ancak aksi takdirde aynı durumda kalmalıdır.Geçici olarak ses odağını kaybetmeniz durumunda ses odağındaki değişiklikleri izlemeye devam etmeniz ve odağı tekrar kazandığınızda normal oynatmayı devam ettirmeye hazır olmanız gerekir. Engelleyen uygulama odaktan çıktığında geri çağırma alırsınız (
AUDIOFOCUS_GAIN
). Bu noktada sesi normal seviyeye geri getirebilir veya oynatmayı yeniden başlatabilirsiniz. - Odak kaybının kalıcı olması
-
Ses odak kaybı kalıcıysa (
AUDIOFOCUS_LOSS
) başka bir uygulama ses çalıyordur.AUDIOFOCUS_GAIN
geri çağırma çağrısı almayacağından uygulamanız oynatmayı hemen duraklatmalıdır. Oynatma işlemini yeniden başlatmak için kullanıcının, bildirimde veya uygulama kullanıcı arayüzünde oynatma taşıma kontrolüne basmak gibi açık bir işlem yapması gerekir.
Aşağıdaki kod snippet'inde, OnAudioFocusChangeListener
ve onAudioFocusChange()
geri çağırma işlevinin nasıl uygulanacağı gösterilmektedir. Ses odağının kalıcı olarak kaybedilmesi durumunda durdurma geri çağırmasını geciktirmek için Handler
kullanıldığını fark edin.
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 } } }
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:
private var delayedStopRunnable = Runnable { mediaController.transportControls.stop() }
private Runnable delayedStopRunnable = new Runnable() { @Override public void run() { getMediaController().getTransportControls().stop(); } };
Kullanıcı oynatmayı yeniden başlatırsa gecikmeli durdurma işleminin devreye girmemesini sağlamak için durum değişikliklerine yanıt olarak mHandler.removeCallbacks(mDelayedStopRunnable)
işlevini çağırın. Örneğin, geri çağırma işlevinin onPlay()
, onSkipToNext()
vb. parametrelerinde removeCallbacks()
'ü ç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.