İki veya daha fazla Android uygulaması aynı çıkış akışında ses çalabilir hazırlıyor ve sistem her şeyi karıştırıyor. Bu ancak teknik açıdan etkileyici, ancak kullanıcıyı son derece rahatsız edebilir. Her bir aynı anda çalan bir müzik uygulamasıyla birlikte Android, ses odak. Aynı anda yalnızca bir uygulama ses odağını koruyabilir.
Uygulamanızın ses çıkışını alması gerektiğinde ses odağı istemesi gerekir. Şu olduğunda: ses çalabilir. Ancak, ses odağını edindikten sonra bitene kadar saklamaya devam edebilirsiniz. Başka bir uygulama odaklanma isteğinde bulunabilir. Bu da ses odağını beklemeye alır. Bu durumda uygulamanız duraklatılır kullanıcıların yeni ses kaynağını daha kolay duyabilmesi için çalabilir veya sesini kısın.
Ses odağı, Android 12'den (API düzeyi 31) önce sistem tarafından yönetilmez. Dolayısıyla, uygulama geliştiricilerin ses odağı yönergelerine uymaları teşvik edilirken, Bir uygulama, cihazdaki ses odağını kaybetmiş olsa bile yüksek sesle çalmaya devam ederse sistem bunu engelleyemez. Ancak bu uygulama davranışı kötü bir kullanıcı deneyimine yol açıyor ve çoğunlukla uygulamayı kaldırmalarını isteyin.
İyi tasarlanmış bir ses uygulaması, ses odağını burada belirtilen genel kurallar:
Oynamaya başlamadan hemen önce
requestAudioFocus()
adlı satıcıyı arayın ve şunu doğrulayın: çağrıAUDIOFOCUS_REQUEST_GRANTED
Şunu ara: Medya oturumunuzunonPlay()
geri çağırmasındarequestAudioFocus()
.Başka bir uygulama sese odaklandığında, çalmayı durdurduğunda veya duraklattığında ya da içeriğin sesini kısmak (yani ses düzeyini düşürebilirsiniz.
Oynatma durduğunda (örneğin, uygulamada oynatacak bir şey kalmadığında) ses odağını terk eder. Kullanıcı aşağıdaki durumlarda ses odağını terk etmek zorunda değildir: çalmayı duraklatır, ancak oynatmaya daha sonra devam edebilir.
Açıklama için
AudioAttributes
simgesini kullanın uygulamanızın çaldığı ses türü Örneğin, konuşma oynatan uygulamalarda belirtinCONTENT_TYPE_SPEECH
.
Ses odağı, ilgili Android sürümüne bağlı olarak farklı şekillerde işlenir. çalışıyor:
- 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 uygulama kararır. Sistem ayrıca gelen bir arama alındığında ses çalmanın sesini kapatır.
- Android 8.0 (API düzeyi 26) ile Android 11 (API düzeyi 30) arası
- Ses odağı sistem tarafından yönetilmez, ancak ses odağının .
- Android 7.1 (API düzeyi 25) ve önceki sürümler
- Ses odağı sistem tarafından yönetilmez ve uygulamalar ses odağını şu komutlarla yönetir:
requestAudioFocus()
veabandonAudioFocus()
.
Android 12 ve sonraki sürümlerde ses odağı
Ses odağını kullanan bir medya veya oyun uygulaması, kaybolduktan sonra ses çalmamalıdır odaklanacağız. Sistem, Android 12 (API düzeyi 31) ve sonraki sürümlerde gösterir. Bir uygulama ses odaklama isteğinde bulunurken başka bir uygulama odaklanıp sistem, oyun uygulamasını arkadan kapanmaya zorlar. Search Ads 360'a Kararma özelliği, uygulamalar arasında geçiş yaparken daha yumuşak bir geçiş sağlar.
Bu kaybolma davranışı, aşağıdaki koşullar karşılandığında gerçekleşir:
Şu anda oynatılan ilk uygulama aşağıdaki kriterlerin tümünü karşılıyor:
- Uygulama
AudioAttributes.USAGE_MEDIA
veyaAudioAttributes.USAGE_GAME
kullanım özelliği. - Uygulama,
AudioManager.AUDIOFOCUS_GAIN
ile ses odağını başarıyla istedi. - Uygulama,
AudioAttributes.CONTENT_TYPE_SPEECH
içerik türüyle ses çalmıyor.
- Uygulama
İkinci bir uygulama ise
AudioManager.AUDIOFOCUS_GAIN
ile ses odağı istiyor.
Bu koşullar karşılandığında ses sistemi, ilk uygulamadaki sesin yavaşlamasını sağlar. Şurada: kaybolduğunda sistem, ilk odak kaybı uygulamasına bildirim gönderir. Uygulamanın oynatıcıların sesi, uygulama tekrar ses odağı isteyene kadar kapalı kalır.
Mevcut ses odağı davranışları
Seste bir değiştirmenin olduğu diğer durumları da aklınızda bulundurun. odaklanacağız.
Otomatik kısma
Otomatik kısma (bir uygulamanın ses düzeyini, diğeri net bir şekilde duyulabiliyorsa) Android 8.0'da (API düzeyi 26) kullanıma sunuldu.
Sistemin yumuşatma uygulamasını sağladığınızda, arka plana almayı planlamanız gerekmez. en iyi şekilde yararlanabilirsiniz.
Odağı sesli bildirim aldığında da otomatik kısma görülür Google Play'den Bildirim oynatmanın başlangıcı senkronize edilir sonuna kadar bekleyin.
Otomatik kısma, aşağıdaki koşullar karşılandığında gerçekleşir:
Şu anda oynatılan ilk uygulama aşağıdaki kriterlerin tümünü karşılıyor:
- Uygulama, herhangi bir odaklama türü için başarıyla ses odağı isteğinde bulundu belirtir.
- Uygulama, içerik türüyle ses çalmıyor
AudioAttributes.CONTENT_TYPE_SPEECH
- Uygulama ayarlanmadı
AudioFocusRequest.Builder.setWillPauseWhenDucked(true)
.
İkinci bir uygulama,
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
.
Bu koşullar karşılandığında ses sistemi, Google Play'deki tüm aktif ikinci uygulamaya odaklanılır. İkinci uygulama ayrıldığında dikkatlerini dağıtıyor. İlk uygulama odağı kaybettiğinde bilgilendirilmez. ve dolayısıyla herhangi bir şey yapması gerekmez.
Otomatik kısma, kullanıcı dinlerken gerçekleşmez. konuşma içeriğini kullanır, çünkü kullanıcı programın bir kısmını kaçırabilir. Örneğin, arabayla yol tariflerinde sesli yardımın kapanması engellenmiyor.
Gelen telefon aramalarında çalınan mevcut sesi kapat
Bazı uygulamalar düzgün çalışmıyor ve telefon aramaları sırasında ses çalmaya devam ediyor. Bu durum, kullanıcıyı rahatsız edici uygulamayı bulup sesini kapatmaya veya uygulamadan çıkmaya zorlar. duymak istiyor. Sistem, bunu önlemek için diğer gelen aramaları yapar. Bir gelen bir telefon araması alındığında ve bir uygulama aşağıdaki koşulları karşılıyorsa:
- Uygulamada
AudioAttributes.USAGE_MEDIA
veyaAudioAttributes.USAGE_GAME
kullanım özelliği. - Uygulama başarıyla ses odağı (herhangi bir odak kazancı) istedi ve şu anda ses çalıyor ses'e dokunun.
Bir uygulama görüşme sırasında çalmaya devam ederse, o zamana kadar çalma sesi kapatılır. çağrı sona erer. Ancak arama sırasında bir uygulama oynatılmaya başlarsa bu oynatıcı kullanıcının videoyu kasıtlı olarak oynatmaya başladığı varsayımıyla sesi kıs.
Android 8.0 ile Android 11 arasındaki sürümlerde ses odağı
Android 8.0 (API düzeyi 26) sürümünden itibaren
requestAudioFocus()
bir AudioFocusRequest
parametresi sağlamalısınız. AudioFocusRequest
uygulamanızın ses bağlamı ve özellikleri hakkında bilgiler içerir. İlgili içeriği oluşturmak için kullanılan
sistemi, bu bilgileri ses odağının kazanımını ve kaybını yönetmek için kullanır.
otomatik olarak oluşturur. Ses odağını serbest bırakmak için yöntemi çağırın
abandonAudioFocusRequest()
Bu parametre de AudioFocusRequest
bağımsız değişkeni olarak kabul edilir. Aynısını kullan
AudioFocusRequest
örneği hem istekte bulunduğunuzda hem de odağı terk ettiğinizde.
AudioFocusRequest
oluşturmak için bir
AudioFocusRequest.Builder
. Odaklanma isteği
isteğin türünü her zaman belirtin; tür, oluşturucuya dahil edilir
bahsedeceğim. Diğer alanları ayarlamak için oluşturucunun yöntemlerini kullanın
isteğinde bulunabilirsiniz.
FocusGain
alanı zorunludur; diğer tüm alanlar isteğe bağlıdır.
Yöntem | Notlar |
---|---|
setFocusGain()
|
Bu alan her istekte gereklidir. Bu,
requestAudioFocus() ile yapılan Android 8.0 öncesi aramada kullanılan durationHint :
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. İlgili içeriği oluşturmak için kullanılan
Uygulama ses odağını kazanıp kaybettiğinde sistem bunlara bakar. Öznitelikler
akış türü kavramının yerini alır. 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ıldı. Tekliflerinizi otomatikleştirmek ve optimize etmek için
odak isteğinizde, ses çalarınızda kullandığınız özelliklerin (
aşağıdaki tabloda gösterilmiştir).
Bir
Belirtilmezse |
setWillPauseWhenDucked()
|
Başka bir uygulama
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK , odağı olan uygulama
genelde bir
onAudioFocusChange()
geri çağırmamızı sağlar çünkü sistem,
kendiliğinden gizlenmesi gerekir. Oynatmayı duraklatmanız gerektiğinde
sesi kısmak yerine setWillPauseWhenDucked(true) komutunu çağırın ve
OnAudioFocusChangeListener , otomatik
de olabilir.
|
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ı, yani yeterli
kullanıma sunulduğunda eşzamansız olarak odağı elde etmek için
Gecikmeli odak kazancının yalnızca
|
setOnAudioFocusChangeListener()
|
OnAudioFocusChangeListener yalnızca aşağıdaki durumlarda gerekir:
İstekte willPauseWhenDucked(true) veya setAcceptsDelayedFocusGain(true) .
Dinleyiciyi ayarlamak için iki yöntem vardır: birincisi olan ve olmayan
işleyici bağımsız değişkenidir. İşleyici, işleyicinin üzerinde çalıştırıldığı iş parçacığıdır. Şu durumda:
bir işleyici belirtmeyin; ana
|
Aşağıdaki örnekte, derleme için AudioFocusRequest.Builder
özelliğinin nasıl kullanılacağı gösterilmektedir
bir AudioFocusRequest
ve ses odağını isteyip iptal etmek istiyor:
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 kısma
Android 8.0 (API düzeyi 26) sürümünde, başka bir uygulama isteği
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
sistem, sesi kısmak ve geri yüklemek için
uygulamanın onAudioFocusChange()
geri çağırması çağrılmadan.
Otomatik kısma, müzik ve video oynatma için kabul edilebilir bir davranış olsa da Bu özellik, konuşmalı içerik oynatırken (örneğin, sesli kitap uygulaması. Bu durumda, uygulama duraklatılmalıdır.
Uygulamanızın ses düzeyini azaltmak yerine kısması istendiğinde duraklatılmasını istiyorsanızOnAudioFocusChangeListener
İstenen duraklatma/devam ettirme davranışını uygulayan bir onAudioFocusChange()
geri çağırma yöntemidir.
Dinleyiciyi kaydetmek için setOnAudioFocusChangeListener()
numaralı telefonu arayın ve şu numarayı arayın:
setWillPauseWhenDucked(true)
özelliği kullanmanızı öneririz.
Gecikmeli odak kazancı
Bazı durumlarda sistem, odaklamanın odak noktası
"kilitli" başka bir uygulama tarafından (örneğin, telefon görüşmesi sırasında) Böyle durumlarda
requestAudioFocus()
, AUDIOFOCUS_REQUEST_FAILED
değerini döndürür. Böyle bir durumda,
Ses çalmaya devam etmemeli çünkü
odaklanacağız.
Uygulamanızın odaklanma isteğini işleme almasını sağlayan setAcceptsDelayedFocusGain(true)
yöntemi
eşzamansız olarak ayarlayabilirsiniz. Bu işaret ayarlandığında odak kilitliyken istek yapılır
AUDIOFOCUS_REQUEST_DELAYED
değerini döndürür. Sesi kilitleyen koşul
görüşme sona erdiğinde sistem
Beklemedeki odaklanma isteğini verir ve onAudioFocusChange()
uygulamasını indirin.
Gecikmeli odak kazancını ele almak için
Şu özelliklere sahip onAudioFocusChange()
geri çağırma yöntemiyle OnAudioFocusChangeListener
:
istenen davranışı uygular ve
setOnAudioFocusChangeListener()
.
Android 7.1 ve önceki sürümlerde ses odağı
Aradığınızda
requestAudioFocus()
bir süre ipucu belirtmeniz gerekiyor.
o anda odaklanıp oynayan başka bir uygulama tarafından onurlandırılacaktır:
- Ses çalmayı planladığınızda kalıcı ses odağı (
AUDIOFOCUS_GAIN
) isteyin yakın gelecekte de (örneğin, müzik çalarken) çalmayı durdurması için ses odağının önceki sahibine gidin. - Oynatmayı beklediğinizde geçici odak (
AUDIOFOCUS_GAIN_TRANSIENT
) iste kısa bir süre kullanılabiliyorsa ve önceki sahibinin duraklamasını bekliyorsanız çalıyor. - Sesi kısma ile geçici odak isteği
(
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
) (ses çalmayı beklediğinizi belirtir) kısa bir süre için geçerli olduğundan ve önceki odak sahibinin "ördekler" ise oynamak ses çıkışını (küçültür). İki ses çıkışı da karışık bulunur. Sesi kısma özelliği özellikle (ör. sesli yol tarifi için) aralıklı olarak ses yayını.
requestAudioFocus()
yöntemi ayrıca bir AudioManager.OnAudioFocusChangeListener
gerektirir. Bu işleyici
medya oturumunuzun sahibi olan aynı etkinlik veya hizmette oluşturulmuş olmalıdır. Google
uygulamanızınonAudioFocusChange()
Başka bir uygulama, ses odağını edinir veya terk eder.
Aşağıdaki snippet, akışta kalıcı ses odağı istiyor
STREAM_MUSIC
ve işlenmesi için bir OnAudioFocusChangeListener
kaydeder
ses odağında değişiklikler olabilir. (Değişim dinleyicisi
Ses odağı değişikliğine yanıt verme.)
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 şunu arayın:
abandonAudioFocus()
.
Kotlin
audioManager.abandonAudioFocus(afChangeListener)
Java
// Abandon audio focus when playback complete audioManager.abandonAudioFocus(afChangeListener);
Bu işlem, sisteme artık odaklanmaya ihtiyaç duymadığınızı bildirir ve
ilişkilendirilmiş OnAudioFocusChangeListener
. Geçici odak isteğinde bulunduysanız
Bu işlem duraklatılan ya da kısılan bir uygulamaya oynamaya devam edebileceğini veya
ses düzeyini tekrar etkinleştirebilir.
Ses odağı değişikliğine yanıt verme
Bir uygulama ses odağını edindiğinde başka bir uygulama bu odağı serbest bırakabilmeli
kendisi için ses odağı istiyor. Böyle bir durumda uygulamanız
bir çağrı geldiğinde
onAudioFocusChange()
AudioFocusChangeListener
yöntemindeki
Uygulama requestAudioFocus()
adlı uygulamayı çağırdığında belirttiğiniz işlem.
onAudioFocusChange()
öğesine iletilen focusChange
parametresi, türü belirtir
görme fırsatınız olur. Şuna karşılık gelir:
uygulamanın kullandığı süre ipucuna bakalım. Uygulamanız
yanıt verebilirler.
- Geçici odak kaybı
- .
Odak değişikliği geçiciyse (
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
veyaAUDIOFOCUS_LOSS_TRANSIENT
) olduğu gibi, uygulamanız gereken otomatik kısma) veya oynatmayı duraklatarak Aksi takdirde aynı durum korunur.Ses odağının geçici olarak kaybedilmesi durumunda değişiklikleri izlemeye devam etmelisiniz. tekrar etkinleştirdiğinizde normal çalmaya devam etmeye hazır olun. odaklanacağız. Engelleyen uygulama odağı terk ettiğinde geri arama alırsınız. (
AUDIOFOCUS_GAIN
). Bu noktada ses düzeyini normal düzeye geri yükleyebilirsiniz. veya oynatmayı yeniden başlatın. - Kalıcı odak kaybı
- .
Ses odağı kaybı kalıcıysa (
AUDIOFOCUS_LOSS
) başka bir uygulama Ses çalınıyor. Uygulamanız, hiçbir zaman duraklatılmayacağı için oynatmayı hemen duraklatmalıdırAUDIOFOCUS_GAIN
geri aranacak. Kullanıcı, oynatmayı yeniden başlatmak için Aktarım denetimine basmak gibi açık bir işlem yapmalıdır. kullanıcı arayüzünde görebilirsiniz.
Aşağıdaki kod snippet'i,
OnAudioFocusChangeListener
ve onAudioFocusChange()
geri araması. Dikkat edin:
Kalıcı ses kaybı durumunda geri çağırmayı geciktirmek için Handler
kullanılması
odaklanacağız.
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ğıdakine benzer 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 geciken durdurmanın devreye girmediğinden emin olmak için
Herhangi bir duruma yanıt olarak mHandler.removeCallbacks(mDelayedStopRunnable)
anlamına gelir. Örneğin, geri aramanızın onPlay()
numarasından removeCallbacks()
numaralı telefonu arayın.
onSkipToNext()
vb.
Hizmetiniz tarafından kullanılan kaynaklar temizlenirken onDestroy()
geri arama.