Medya oturumları, ses veya video ile etkileşim için evrensel bir yol sunar
oynatıcıya gitmiş olur. Media3'te varsayılan oynatıcı,ExoPlayer
Player
arayüzü. Medya oturumunu oynatıcıya bağladığınızda uygulama
harici olarak medya oynatmanın reklamını yapmak ve
harici kaynaklar.
Komutlar, kontrol düğmesindeki oynat düğmesi gibi fiziksel düğmelerden mikrofonlu kulaklık veya TV uzaktan kumandasını kullanın. Bunlar, masaüstü veya mobil "pause" (duraklatma) komutu vermek gibi Google Asistan'a bağlamalısınız. Medya oturumu, bu komutlar için medya uygulamasının oynatıcısına yetki verir.
Medya oturumu ne zaman seçilmelidir?
MediaSession
öğesini uyguladığınızda, kullanıcıların oynatmayı kontrol etmesine izin vermiş olursunuz:
- Kulaklıklarını kullanarak. Çoğunlukla bir cihazda düğmeler veya dokunma etkileşimleri kullanıcı kulaklığından medya içeriği oynatabilir veya duraklatabilir ya da sonraki veya önceki parçayı seçin.
- Google Asistan'la konuşarak. Genellikle, "Tamam" demek için " Google, duraklat" düğmesine dokunun.
- Wear OS kol saati üzerinden. Bu sayede en değerli bilgilere daha kolay genel oynatma kontrollerini kullanabilir.
- Medya kontrolleri aracılığıyla. Bu bantta, her birine ait kontroller gösterilir nasıl kullanacağınızı göstereceğim.
- TV'de. Fiziksel oynatma düğmeleri ve platform oynatma ile işlemlere izin verir ve güç yönetimi (örneğin, TV, ses çubuğu veya A/V alıcı Kullanıcı anahtarı kapanırsa veya giriş değiştirildiğinde, uygulamada oynatma durmalıdır).
- Oynatmayı etkilemesi gereken diğer harici işlemler.
Bu, birçok kullanım alanı için idealdir. Özellikle de
şu durumlarda MediaSession
kullanılarak:
- Filmler veya canlı TV gibi uzun video içeriklerini canlı oynatıyorsanız.
- Podcast veya müzik gibi uzun ses içeriklerini canlı oynatıyorsanız oynatma listeleri.
- TV uygulaması oluşturuyorsunuz.
Ancak tüm kullanım alanları MediaSession
ile uyumlu değildir. Birlikte çalıştığınız
Aşağıdaki durumlarda yalnızca Player
kullanın:
- Kullanıcı etkileşimi ve etkileşiminin yüksek olduğu kısa içerikler gösteriyorsunuz. son derece önemlidir.
- Etkin tek bir video olmaması (örneğin, kullanıcı bir listede gezinirken) ekranda aynı anda birden fazla video görüntüleniyor.
- Oynatacağınız tek seferlik bir tanıtım veya açıklama videosunu izlemelerini beklersiniz.
- İçeriğiniz gizlilik açısından hassas olup harici işlemlerin medya meta verilerine erişme (örneğin, bir tarayıcıda gizli mod)
Kullanım alanınız yukarıda listelenenlerin hiçbirine uymuyorsa
Kullanıcı aktif olarak etkileşimde bulunmadığında uygulamanızın oynatılmaya devam etmesinde bir sorun yok
pek de iyi olmadığını unutmayın. Yanıtınız evet ise büyük olasılıkla şu seçeneği
MediaSession
Yanıtınız hayırsa Player
kullanmak isteyebilirsiniz.
.
Medya oturumu oluşturma
Yönettiği oynatıcının yanında bir medya oturumu gerçekleşir. Kontrol panelinizdeki
Context
ve Player
nesnesiyle medya oturumu. Proje boyunca
gerektiğinde (ör. onStart()
veya
Activity
veya Fragment
ya da onCreate()
için onResume()
yaşam döngüsü yöntemi
medya oturumunun ve ilişkili oynatıcısının sahibi olan Service
yöntemi.
Medya oturumu oluşturmak için bir Player
başlatın ve
MediaSession.Builder
bunu beğendi:
Kotlin
val player = ExoPlayer.Builder(context).build() val mediaSession = MediaSession.Builder(context, player).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context).build(); MediaSession mediaSession = new MediaSession.Builder(context, player).build();
Otomatik durum işleme
Media3 kitaplığı, oyuncunun durumu. Bu nedenle, eşlemeyi oyuncu oturumuna geçiyorum.
Bu, eski yaklaşımdan farklı bir yaklaşıma
odaklanmak için gerekli olan,
oyuncunun kendisinden bağımsız olarak bir PlaybackStateCompat
(örneğin,
lütfen unutmayın.
Benzersiz oturum kimliği
Varsayılan olarak MediaSession.Builder
, aşağıdaki şekilde boş bir dizeyle oturum oluşturur:
oturum kimliği. Uygulama yalnızca tek bir
oturum örneğidir.
Bir uygulama aynı anda birden fazla oturum örneğini yönetmek istiyorsa
her oturumun oturum kimliğinin benzersiz olmasını sağlamalıdır. Oturum kimliği
MediaSession.Builder.setId(String id)
ile oturum oluşturulurken ayarlanmalıdır.
Hata ile uygulamanızı kilitleyen bir IllegalStateException
görürseniz
IllegalStateException: Session ID must be unique. ID=
adlı kullanıcıya mesaj gönder, o zaman
bir oturumun, kullanıcı verileri ve kimlik doğrulama bilgileri gibi, beklenmedik bir şekilde
aynı kimliğe sahip örnek yayınlandı. Oturumların bir kullanıcı tarafından sızdırılmasını önlemek için
hata ayıklaması varsa bu tür durumlar tespit edilir ve
kabul edersiniz.
Diğer istemcilere denetim izni ver
Medya oturumu, oynatmayı kontrol etmenin en önemli unsurudur. En küçük çaplı bir oynatıcıya veri aktarmak için kullanabileceğiniz komutlar medya Bu kaynaklar, videodaki oynatma düğmesi gibi fiziksel düğmeler mikrofonlu kulaklık veya TV uzaktan kumandası ya da "duraklat" talimatı gibi dolaylı komutlar Google Asistan'a bağlamalısınız. Benzer şekilde, Android'e erişim izni vermek de isteyebilirsiniz. veya Wear OS cihazları için Bu şekilde, oynatmayı kadrandan kontrol edebilirsiniz. Harici müşteriler şunları yapabilir: medya uygulamanıza oynatma komutları göndermek için medya denetleyici kullanın. Bunlar: medya oturumunuz tarafından alınır ve son olarak komutlara medya oynatıcıya gidin.
![MediaSession ve MediaController arasındaki etkileşimi gösteren bir diyagram.](https://developer.android.com/static/guide/topics/media/images/backgroundcontrols.png?authuser=6&hl=tr)
Bir kumanda medya oturumunuza bağlanmak üzereyken
onConnect()
yöntemi çağrılır. Sağlanan ControllerInfo
karar vermek için kabul etme
veya reddet
talep ediyor. Bağlantı isteğinin kabul edilmesine ilişkin bir örnek için Beyan
kullanılabilir komutlar bölümüne bakın.
Bağlantı kurulduktan sonra kumanda, oturuma oynatma komutları gönderebilir. İlgili içeriği oluşturmak için kullanılan
ardından bu komutları oyuncuya aktarır. Oynatma ve oynatma listesi
Player
arayüzünde tanımlanan komutlar, Search Ads 360'ta otomatik olarak
kabul edilir.
Diğer geri çağırma yöntemleri, örneğin
özel oynatma komutları ve
oynatma listesini değiştirme).
Bu geri çağırma işlevleri benzer şekilde, değişiklik yapabilmeniz için bir ControllerInfo
nesnesi içerir.
denetleyici bazında her isteğe nasıl yanıt verdiğinizi gösterir.
Oynatma listesini değiştirme
Bir medya oturumu, oynatıcısının oynatma listesini
"the"
Oynatma listeleri için ExoPlayer rehberi.
Kumandalar ayrıca, aşağıdakilerden biri geçerliyse oynatma listesini de değiştirebilirler
COMMAND_SET_MEDIA_ITEM
veya COMMAND_CHANGE_MEDIA_ITEMS
kullanabilir.
Oynatma listesine yeni öğeler eklenirken oynatıcı için genellikle MediaItem
gösterilmesi gerekir.
bir
tanımlı URI
bunları oynanabilir hale getirin. Varsayılan olarak, yeni eklenen öğeler otomatik olarak yönlendirilir.
oynatıcı yöntemlerine (ör. player.addMediaItem
) tanımlar.
Oynatıcıya eklenen MediaItem
örneğini özelleştirmek isterseniz şunları yapabilirsiniz:
geçersiz kılma
onAddMediaItems()
Bu adım, medya isteğinde bulunan kumandaları desteklemek istediğinizde gereklidir
tanımlanamaz. Bunun yerine MediaItem
genellikle
aşağıdaki alanlardan biri veya daha fazlası istenen medyayı açıklamak üzere ayarlanmış olmalıdır:
MediaItem.id
: Medyayı tanımlayan genel bir kimliktir.MediaItem.RequestMetadata.mediaUri
: Özel olabilecek bir istek URI'si bir şema oluşturur ve oynatıcı tarafından doğrudan oynatılamaz.MediaItem.RequestMetadata.searchQuery
: Metin biçiminde bir arama sorgusu, örneğin Google Asistan'dan.MediaItem.MediaMetadata
: "Başlık" gibi yapılandırılmış meta veriler "sanatçı" gibi düşünebilirsiniz.
Tamamen yeni oynatma listelerine yönelik daha fazla özelleştirme seçeneği için şunları yapabilirsiniz:
ek olarak geçersiz kıl
onSetMediaItems()
oynatma listesindeki başlangıç öğesini ve konumu tanımlamanızı sağlar. Örneğin,
istenen tek bir öğeyi oynatma listesinin tamamını genişletip
oynatıcısının, ilk olarak istenen öğenin dizininde başlamasını sağlar. CEVAP
onSetMediaItems()
örneğinin uygulanması
oturum demo uygulamasında bulabilirsiniz.
Özel düzeni ve özel komutları yönetin
Aşağıdaki bölümlerde, özel düzenin nasıl tanıtılacağı açıklanmaktadır. komut düğmelerini kullanarak istemci uygulamalarına komut gönderebilir ve denetleyicileri özel komutlarının ikisine katlanır.
Oturumun özel düzenini tanımlayın
İstemci uygulamalarına hangi oynatma kontrollerini görüntülemek istediğinizi belirtmek için
oturumun özel düzenini ayarlayın.
onCreate()
yönteminde MediaSession
oluşturuyorsanız
geliştirmenizi sağlar.
Kotlin
override fun onCreate() { super.onCreate() val likeButton = CommandButton.Builder() .setDisplayName("Like") .setIconResId(R.drawable.like_icon) .setSessionCommand(SessionCommand(SessionCommand.COMMAND_CODE_SESSION_SET_RATING)) .build() val favoriteButton = CommandButton.Builder() .setDisplayName("Save to favorites") .setIconResId(R.drawable.favorite_icon) .setSessionCommand(SessionCommand(SAVE_TO_FAVORITES, Bundle())) .build() session = MediaSession.Builder(this, player) .setCallback(CustomMediaSessionCallback()) .setCustomLayout(ImmutableList.of(likeButton, favoriteButton)) .build() }
Java
@Override public void onCreate() { super.onCreate(); CommandButton likeButton = new CommandButton.Builder() .setDisplayName("Like") .setIconResId(R.drawable.like_icon) .setSessionCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_SET_RATING)) .build(); CommandButton favoriteButton = new CommandButton.Builder() .setDisplayName("Save to favorites") .setIconResId(R.drawable.favorite_icon) .setSessionCommand(new SessionCommand(SAVE_TO_FAVORITES, new Bundle())) .build(); Player player = new ExoPlayer.Builder(this).build(); mediaSession = new MediaSession.Builder(this, player) .setCallback(new CustomMediaSessionCallback()) .setCustomLayout(ImmutableList.of(likeButton, favoriteButton)) .build(); }
Kullanılabilir oynatıcıyı ve özel komutları bildir
Medya uygulamaları, örneğin şurada kullanılabilecek özel komutlar tanımlayabilir:
oluşturmayı deneyin. Örneğin,
kullanıcısının bir medya öğesini favori öğeler listesine kaydetmesini sağlayın. MediaController
özel komutlar gönderir ve MediaSession.Callback
bunları alır.
Bir
Medya oturumunuza bağlandığında MediaController
. Bu hedefe ulaşmak için
MediaSession.Callback.onConnect()
geçersiz kılınıyor. Yapılandır ve geri dön
bir
onConnect
geri çağırma yönteminde MediaController
:
Kotlin
private inner class CustomMediaSessionCallback: MediaSession.Callback { // Configure commands available to the controller in onConnect() override fun onConnect( session: MediaSession, controller: MediaSession.ControllerInfo ): MediaSession.ConnectionResult { val sessionCommands = ConnectionResult.DEFAULT_SESSION_COMMANDS.buildUpon() .add(SessionCommand(SAVE_TO_FAVORITES, Bundle.EMPTY)) .build() return AcceptedResultBuilder(session) .setAvailableSessionCommands(sessionCommands) .build() } }
Java
class CustomMediaSessionCallback implements MediaSession.Callback { // Configure commands available to the controller in onConnect() @Override public ConnectionResult onConnect( MediaSession session, ControllerInfo controller) { SessionCommands sessionCommands = ConnectionResult.DEFAULT_SESSION_COMMANDS.buildUpon() .add(new SessionCommand(SAVE_TO_FAVORITES, new Bundle())) .build(); return new AcceptedResultBuilder(session) .setAvailableSessionCommands(sessionCommands) .build(); } }
MediaController
öğesinden özel komut istekleri almak için
Callback
içinde onCustomCommand()
yöntemi.
Kotlin
private inner class CustomMediaSessionCallback: MediaSession.Callback { ... override fun onCustomCommand( session: MediaSession, controller: MediaSession.ControllerInfo, customCommand: SessionCommand, args: Bundle ): ListenableFuture<SessionResult> { if (customCommand.customAction == SAVE_TO_FAVORITES) { // Do custom logic here saveToFavorites(session.player.currentMediaItem) return Futures.immediateFuture( SessionResult(SessionResult.RESULT_SUCCESS) ) } ... } }
Java
class CustomMediaSessionCallback implements MediaSession.Callback { ... @Override public ListenableFuture<SessionResult> onCustomCommand( MediaSession session, ControllerInfo controller, SessionCommand customCommand, Bundle args ) { if(customCommand.customAction.equals(SAVE_TO_FAVORITES)) { // Do custom logic here saveToFavorites(session.getPlayer().getCurrentMediaItem()); return Futures.immediateFuture( new SessionResult(SessionResult.RESULT_SUCCESS) ); } ... } }
Hangi medya denetleyicisinin istekte bulunduğunu izlemek için
MediaSession.ControllerInfo
nesnesinin packageName
özelliği
Callback
yönteme geçirildi. Bu sayede, uygulamanızın
özelliklerini
belli bir komut sistemden geliyorsa, ona yanıt olarak
veya başka istemci uygulamaları içerebilir.
Kullanıcı etkileşiminden sonra özel düzeni güncelleme
Özel bir komutu veya oynatıcınızla başka herhangi bir etkileşimi gerçekleştirdikten sonra,
kumanda arayüzünde gösterilen düzeni güncellemek isteyebilir. Tipik bir örnek
ilgili işlemi tetikledikten sonra simgesini değiştiren bir açma/kapatma düğmesidir
bu düğmeyi kullanın. Düzeni güncellemek için
MediaSession.setCustomLayout
:
Kotlin
val removeFromFavoritesButton = CommandButton.Builder() .setDisplayName("Remove from favorites") .setIconResId(R.drawable.favorite_remove_icon) .setSessionCommand(SessionCommand(REMOVE_FROM_FAVORITES, Bundle())) .build() mediaSession.setCustomLayout(ImmutableList.of(likeButton, removeFromFavoritesButton))
Java
CommandButton removeFromFavoritesButton = new CommandButton.Builder() .setDisplayName("Remove from favorites") .setIconResId(R.drawable.favorite_remove_icon) .setSessionCommand(new SessionCommand(REMOVE_FROM_FAVORITES, new Bundle())) .build(); mediaSession.setCustomLayout(ImmutableList.of(likeButton, removeFromFavoritesButton));
Oynatma komutu davranışını özelleştirme
Player
arayüzünde tanımlanan bir komutun davranışını özelleştirmek için:
play()
veya seekToNext()
olarak Player
öğesini ForwardingPlayer
içine yerleştirin.
Kotlin
val player = ExoPlayer.Builder(context).build() val forwardingPlayer = object : ForwardingPlayer(player) { override fun play() { // Add custom logic super.play() } override fun setPlayWhenReady(playWhenReady: Boolean) { // Add custom logic super.setPlayWhenReady(playWhenReady) } } val mediaSession = MediaSession.Builder(context, forwardingPlayer).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context).build(); ForwardingPlayer forwardingPlayer = new ForwardingPlayer(player) { @Override public void play() { // Add custom logic super.play(); } @Override public void setPlayWhenReady(boolean playWhenReady) { // Add custom logic super.setPlayWhenReady(playWhenReady); } }; MediaSession mediaSession = new MediaSession.Builder(context, forwardingPlayer).build();
ForwardingPlayer
hakkında daha fazla bilgi için şu adresteki ExoPlayer kılavuzuna bakın:
Özelleştirme.
Oynatıcı komutunun istekte bulunan denetleyicisini tanımlayın
Player
yöntemine yapılan bir çağrı MediaController
kaynağı tarafından gerçekleştirildiğinde şunu yapabilirsiniz:
kaynak kaynağını MediaSession.controllerForCurrentRequest
ile tanımlayın
ve mevcut istek için ControllerInfo
öğesini edinin:
Kotlin
class CallerAwareForwardingPlayer(player: Player) : ForwardingPlayer(player) { override fun seekToNext() { Log.d( "caller", "seekToNext called from package ${session.controllerForCurrentRequest?.packageName}" ) super.seekToNext() } }
Java
public class CallerAwareForwardingPlayer extends ForwardingPlayer { public CallerAwareForwardingPlayer(Player player) { super(player); } @Override public void seekToNext() { Log.d( "caller", "seekToNext called from package: " + session.getControllerForCurrentRequest().getPackageName()); super.seekToNext(); } }
Medya düğmelerine yanıt verme
Medya düğmeleri, Android cihazlarda ve diğer çevre birimlerinde bulunan donanım düğmeleridir.
cihazları (örneğin, Bluetooth mikrofonlu kulaklıktaki oynat/duraklat düğmesi) kullanın. Medya 3 herkese açık kullanıcı adları
oturuma geldiğinde ve Google Etiket Yöneticisi'ni çağırarak
oturum oynatıcısında uygun Player
yöntemini kullanın.
Bir uygulama,
MediaSession.Callback.onMediaButtonEvent(Intent)
Böyle bir durumda, uygulama
tüm API özelliklerini kendi başına ele alabilir/ihtiyaçları vardır.
Hata işleme ve raporlama
Bir oturumun yayınladığı ve denetleyicilere bildirdiği iki tür hata vardır. Önemli hatalar, oturumdaki bir teknik oynatma hatasını bildirir oynatıcıyı oluşturur. Önemli hatalar denetleyiciye bildirilir otomatik olarak devreye girer. Önemli olmayan hatalar teknik veya politika ile ilgili olmayan hatalardır oluşturmayan ve denetleyicilere manuel olarak yapabilirsiniz.
Önemli oynatma hataları
Oynatıcı tarafından oturuma önemli bir oynatma hatası bildirilir ve ardından
denetleyicilere rapor üzerinden iletilecek
Player.Listener.onPlayerError(PlaybackException)
ve
Player.Listener.onPlayerErrorChanged(@Nullable PlaybackException)
.
Böyle bir durumda, oynatma durumu STATE_IDLE
değerine geçirilir ve
MediaController.getPlaybackError()
, şunu döndürür: PlaybackException
bahsedeceğim. Kumanda, şunları almak için PlayerException.errorCode
cihazını inceleyebilir:
hatanın nedeni hakkında bilgi edinin.
Birlikte çalışabilirlik için önemli bir hata PlaybackStateCompat
cihazına çoğaltılır.
durumunu STATE_ERROR
olarak ayarlayıp
hata kodu ve mesajı gösterilir.PlaybackException
Önemli bir hatanın özelleştirilmesi
Kullanıcıya yerelleştirilmiş ve anlamlı bilgiler sağlamak için hata kodu,
önemli bir oynatma hatasına ilişkin hata mesajı ve hata ekstraları
oturumu oluştururken ForwardingPlayer
kullanarak:
Kotlin
val forwardingPlayer = ErrorForwardingPlayer(player) val session = MediaSession.Builder(context, forwardingPlayer).build()
Java
Player forwardingPlayer = new ErrorForwardingPlayer(player); MediaSession session = new MediaSession.Builder(context, forwardingPlayer).build();
Yönlendirme oynatıcı, gerçek oynatıcıya bir Player.Listener
kaydeder
ve hata bildiren geri çağırmalara müdahale eder. Özelleştirilmiş
PlaybackException
yetkisi verilen dinleyicilere verilir.
yönlendirme oynatıcıda kayıtlıdır. Bunun işe yaraması için yönlendirme oynatıcısının
Player.addListener
ve Player.removeListener
izinlerini geçersiz kılar
özelleştirilmiş hata kodu, mesaj veya ekstraların gönderileceği işleyiciler:
Kotlin
class ErrorForwardingPlayer(private val context: Context, player: Player) : ForwardingPlayer(player) { private val listeners: MutableList<Player.Listener> = mutableListOf() private var customizedPlaybackException: PlaybackException? = null init { player.addListener(ErrorCustomizationListener()) } override fun addListener(listener: Player.Listener) { listeners.add(listener) } override fun removeListener(listener: Player.Listener) { listeners.remove(listener) } override fun getPlayerError(): PlaybackException? { return customizedPlaybackException } private inner class ErrorCustomizationListener : Player.Listener { override fun onPlayerErrorChanged(error: PlaybackException?) { customizedPlaybackException = error?.let { customizePlaybackException(it) } listeners.forEach { it.onPlayerErrorChanged(customizedPlaybackException) } } override fun onPlayerError(error: PlaybackException) { listeners.forEach { it.onPlayerError(customizedPlaybackException!!) } } private fun customizePlaybackException( error: PlaybackException, ): PlaybackException { val buttonLabel: String val errorMessage: String when (error.errorCode) { PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW -> { buttonLabel = context.getString(R.string.err_button_label_restart_stream) errorMessage = context.getString(R.string.err_msg_behind_live_window) } // Apps can customize further error messages by adding more branches. else -> { buttonLabel = context.getString(R.string.err_button_label_ok) errorMessage = context.getString(R.string.err_message_default) } } val extras = Bundle() extras.putString("button_label", buttonLabel) return PlaybackException(errorMessage, error.cause, error.errorCode, extras) } override fun onEvents(player: Player, events: Player.Events) { listeners.forEach { it.onEvents(player, events) } } // Delegate all other callbacks to all listeners without changing arguments like onEvents. } }
Java
private static class ErrorForwardingPlayer extends ForwardingPlayer { private final Context context; private List<Player.Listener> listeners; @Nullable private PlaybackException customizedPlaybackException; public ErrorForwardingPlayer(Context context, Player player) { super(player); this.context = context; listeners = new ArrayList<>(); player.addListener(new ErrorCustomizationListener()); } @Override public void addListener(Player.Listener listener) { listeners.add(listener); } @Override public void removeListener(Player.Listener listener) { listeners.remove(listener); } @Nullable @Override public PlaybackException getPlayerError() { return customizedPlaybackException; } private class ErrorCustomizationListener implements Listener { @Override public void onPlayerErrorChanged(@Nullable PlaybackException error) { customizedPlaybackException = error != null ? customizePlaybackException(error, context) : null; for (int i = 0; i < listeners.size(); i++) { listeners.get(i).onPlayerErrorChanged(customizedPlaybackException); } } @Override public void onPlayerError(PlaybackException error) { for (int i = 0; i < listeners.size(); i++) { listeners.get(i).onPlayerError(checkNotNull(customizedPlaybackException)); } } private PlaybackException customizePlaybackException( PlaybackException error, Context context) { String buttonLabel; String errorMessage; switch (error.errorCode) { case PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW: buttonLabel = context.getString(R.string.err_button_label_restart_stream); errorMessage = context.getString(R.string.err_msg_behind_live_window); break; // Apps can customize further error messages by adding more case statements. default: buttonLabel = context.getString(R.string.err_button_label_ok); errorMessage = context.getString(R.string.err_message_default); break; } Bundle extras = new Bundle(); extras.putString("button_label", buttonLabel); return new PlaybackException(errorMessage, error.getCause(), error.errorCode, extras); } @Override public void onEvents(Player player, Events events) { for (int i = 0; i < listeners.size(); i++) { listeners.get(i).onEvents(player, events); } } // Delegate all other callbacks to all listeners without changing arguments like onEvents. } }
Önemli olmayan hatalar
Teknik bir istisnadan kaynaklanmayan olmayan önemli olmayan hatalar gönderilebilir denetleyiciye uygulama aracılığıyla erişim sağlar:
Kotlin
val sessionError = SessionError( SessionError.ERROR_SESSION_AUTHENTICATION_EXPIRED, context.getString(R.string.error_message_authentication_expired), ) // Sending a nonfatal error to all controllers. mediaSession.sendError(sessionError) // Interoperability: Sending a nonfatal error to the media notification controller to set the // error code and error message in the playback state of the platform media session. mediaSession.mediaNotificationControllerInfo?.let { mediaSession.sendError(it, sessionError) }
Java
SessionError sessionError = new SessionError( SessionError.ERROR_SESSION_AUTHENTICATION_EXPIRED, context.getString(R.string.error_message_authentication_expired)); // Sending a nonfatal error to all controllers. mediaSession.sendError(sessionError); // Interoperability: Sending a nonfatal error to the media notification controller to set the // error code and error message in the playback state of the platform media session. ControllerInfo mediaNotificationControllerInfo = mediaSession.getMediaNotificationControllerInfo(); if (mediaNotificationControllerInfo != null) { mediaSession.sendError(mediaNotificationControllerInfo, sessionError); }
Medya bildirim denetleyicisine gönderilen önemli olmayan bir hata,
Platform oturumunun PlaybackStateCompat
. Dolayısıyla, yalnızca hata kodu ve
hata mesajı buna göre PlaybackStateCompat
değerine ayarlanır.
PlaybackStateCompat.state
, STATE_ERROR
olarak değiştirilmedi.
Önemli olmayan hataları al
Bir MediaController
,
MediaController.Listener.onError
:
Kotlin
val future = MediaController.Builder(context, sessionToken) .setListener(object : MediaController.Listener { override fun onError(controller: MediaController, sessionError: SessionError) { // Handle nonfatal error. } }) .buildAsync()
Java
MediaController.Builder future = new MediaController.Builder(context, sessionToken) .setListener( new MediaController.Listener() { @Override public void onError(MediaController controller, SessionError sessionError) { // Handle nonfatal error. } });