Medya uygulamaları genellikle hiyerarşik olarak düzenlenmiş medya öğeleri koleksiyonları içerir. Örneğin, bir albümdeki şarkılar veya bir oynatma listesindeki TV bölümleri. Bu medya öğeleri hiyerarşisine medya kitaplığı adı verilir.
MediaLibraryService, medya kitaplığınıza hizmet vermek ve erişmek için standartlaştırılmış bir API sağlar. Örneğin, medya kitaplığınız için sürücü güvenli kullanıcı arayüzü sağlayan Android Auto desteği eklerken bu özellikten yararlanabilirsiniz.
MediaLibraryService oluşturma
MediaLibraryService uygulamak, MediaSessionService uygulamaya benzer. Ancak onGetSession() yönteminde MediaSession yerine MediaLibrarySession döndürmeniz gerekir.
Kotlin
class PlaybackService : MediaLibraryService() { private var mediaLibrarySession: MediaLibrarySession? = null private val callback: MediaLibrarySession.Callback = object : MediaLibrarySession.Callback { /* ... */ } override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaLibrarySession? { // If desired, validate the controller before returning the media library session return mediaLibrarySession } // Create your player and media library session in the onCreate lifecycle event override fun onCreate() { super.onCreate() val player = ExoPlayer.Builder(this).build() mediaLibrarySession = MediaLibrarySession.Builder(this, player, callback).build() } // Remember to release the player and media library session in onDestroy override fun onDestroy() { mediaLibrarySession?.run { player.release() release() mediaLibrarySession = null } super.onDestroy() } }
Java
class PlaybackService extends MediaLibraryService { MediaLibrarySession mediaLibrarySession = null; MediaLibrarySession.Callback callback = new MediaLibrarySession.Callback() { /* ... */ }; @Override public MediaLibrarySession onGetSession(MediaSession.ControllerInfo controllerInfo) { // If desired, validate the controller before returning the media library session return mediaLibrarySession; } // Create your player and media library session in the onCreate lifecycle event @Override public void onCreate() { super.onCreate(); ExoPlayer player = new ExoPlayer.Builder(this).build(); mediaLibrarySession = new MediaLibrarySession.Builder(this, player, callback).build(); } // Remember to release the player and media library session in onDestroy @Override public void onDestroy() { if (mediaLibrarySession != null) { mediaLibrarySession.getPlayer().release(); mediaLibrarySession.release(); mediaLibrarySession = null; } super.onDestroy(); } }
Service ve gerekli izinlerinizi manifest dosyasında da belirtmeyi unutmayın:
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaLibraryService"/>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
Hizmetinizi hem platform hem de Media3 hizmet arayüzü olarak kaydetmeniz önerilir:
Platform medya oturumu API'lerini kullanan istemcilerle uyumluluk için
<action android:name="android.media.browse.MediaBrowserService"/>öğesineintent-filtereklemeniz önerilir. Media3, bu hizmet arayüzüyle geriye dönük uyumluluğu otomatik olarak sağlar.Geleceğe hazır bir kurulum için ve Media3'ü kullanan uygulamaların Media3 API'yi kullanarak hizmetinizle iletişim kurabilmesini sağlamak amacıyla
<action android:name="androidx.media3.session.MediaLibraryService"/>, platform seçeneğiyle birlikte sağlanmalıdır.
Bu sayede uygulamalar, PackageManager üzerinden hizmetinizi bulabilir ve bu arayüzlerden biri aracılığıyla MediaBrowser ile bağlantı kurabilir.
MediaLibrarySession kullanın
MediaLibraryService API, medya kitaplığınızın tek bir kök düğüm ve oynatılabilir veya daha fazla göz atılabilir alt düğümlerle birlikte ağaç biçiminde yapılandırılmasını bekler.
MediaLibrarySession, içeriklere göz atma API'leri eklemek için MediaSession API'sini genişletir. MediaSession geri çağırma ile karşılaştırıldığında MediaLibrarySession geri çağırma aşağıdaki gibi yöntemler ekler:
- Bir istemci, içerik ağacının
MediaItemkökünü istediğindeonGetLibraryRoot() onGetChildren(), bir istemci içerik ağacındakiMediaItemöğesinin alt öğelerini istediğindeonGetSearchResult(), bir istemci belirli bir sorgu için içerik ağacından arama sonuçları istediğinde
İlgili geri çağırma yöntemleri, bir istemci uygulamasının ilgilendiği içerik ağacı türüyle ilgili ek sinyaller içeren bir LibraryParams nesnesi içerecektir.
Medya öğeleri için komut düğmeleri
Oturum uygulaması, MediaItem tarafından desteklenen komut düğmelerini MediaMetadata içinde tanımlayabilir. Bu, bir denetleyicinin görüntüleyebileceği ve öğe için özel komutu oturuma kolayca göndermek üzere kullanabileceği bir medya öğesine bir veya daha fazla CommandButton girişi atamaya olanak tanır.
Oturum tarafında kurulum komutu düğmeleri
Oturum oluşturulurken bir oturum uygulaması, oturumun özel komut olarak işleyebileceği komut düğmeleri grubunu bildirir:
Kotlin
val allCommandButtons = listOf( CommandButton.Builder(CommandButton.ICON_PLAYLIST_ADD) .setDisplayName(context.getString(R.string.add_to_playlist)) .setSessionCommand(SessionCommand(COMMAND_PLAYLIST_ADD, Bundle.EMPTY)) .setExtras(playlistAddExtras) .build(), CommandButton.Builder(CommandButton.ICON_RADIO) .setDisplayName(context.getString(R.string.radio_station)) .setSessionCommand(SessionCommand(COMMAND_RADIO, Bundle.EMPTY)) .setExtras(radioExtras) .build(), ) // Add all command buttons for media items supported by the session. val session = MediaSession.Builder(context, player) .setCommandButtonsForMediaItems(allCommandButtons) .build()
Java
ImmutableList<CommandButton> allCommandButtons = ImmutableList.of( new CommandButton.Builder(CommandButton.ICON_PLAYLIST_ADD) .setDisplayName(context.getString(R.string.add_to_playlist)) .setSessionCommand(new SessionCommand(COMMAND_PLAYLIST_ADD, Bundle.EMPTY)) .setExtras(playlistAddExtras) .build(), new CommandButton.Builder(CommandButton.ICON_RADIO) .setDisplayName(context.getString(R.string.radio_station)) .setSessionCommand(new SessionCommand(COMMAND_RADIO, Bundle.EMPTY)) .setExtras(radioExtras) .build()); // Add all command buttons for media items supported by the session. MediaSession session = new MediaSession.Builder(context, player) .setCommandButtonsForMediaItems(allCommandButtons) .build();
Bir medya öğesi oluştururken oturum uygulaması, oturum oluşturulurken ayarlanan komut düğmelerinin oturum komutlarına referans veren bir dizi desteklenen komut kimliği ekleyebilir:
Kotlin
val mediaItem = MediaItem.Builder() .setMediaMetadata( MediaMetadata.Builder() .setSupportedCommands(listOf(COMMAND_PLAYLIST_ADD, COMMAND_RADIO)) .build() ) .build()
Java
MediaItem mediaItem = new MediaItem.Builder() .setMediaMetadata( new MediaMetadata.Builder() .setSupportedCommands(ImmutableList.of(COMMAND_PLAYLIST_ADD, COMMAND_RADIO)) .build()) .build();
Bir kumanda veya tarayıcı bağlandığında ya da oturumun başka bir yöntemini çağırdığında
Callback, oturum uygulaması, bir kumandanın veya tarayıcının görüntüleyebileceği maksimum komut düğmesi sayısını almak için geri çağırmaya iletilen ControllerInfo değerini inceleyebilir. Geri çağırma yöntemine iletilen ControllerInfo, bu değere kolayca erişmek için bir alıcı sağlar. Değer varsayılan olarak 0'a ayarlanır. Bu, tarayıcının veya kumandanın bu özelliği desteklemediğini gösterir:
Kotlin
override fun onGetItem( session: MediaLibrarySession, browser: MediaSession.ControllerInfo, mediaId: String, ): ListenableFuture<LibraryResult<MediaItem>> { val settableFuture = SettableFuture.create<LibraryResult<MediaItem>>() val maxCommandsForMediaItems = browser.maxCommandsForMediaItems loadMediaItemAsync(settableFuture, mediaId, maxCommandsForMediaItems) return settableFuture }
Java
@Override public ListenableFuture<LibraryResult<MediaItem>> onGetItem( MediaLibraryService.MediaLibrarySession session, ControllerInfo browser, String mediaId) { SettableFuture<LibraryResult<MediaItem>> settableFuture = SettableFuture.create(); int maxCommandsForMediaItems = browser.getMaxCommandsForMediaItems(); loadMediaItemAsync(settableFuture, mediaId, maxCommandsForMediaItems); return settableFuture; }
Bir medya öğesi için gönderilen özel bir işlem işlenirken oturum uygulaması, Bundle içine iletilen bağımsız değişkenlerden medya öğesi kimliğini alabilir
onCustomCommand:
Kotlin
override fun onCustomCommand( session: MediaSession, controller: MediaSession.ControllerInfo, customCommand: SessionCommand, args: Bundle, ): ListenableFuture<SessionResult> { val mediaItemId = args.getString(MediaConstants.EXTRA_KEY_MEDIA_ID) return if (mediaItemId != null) handleCustomCommandForMediaItem(controller, customCommand, mediaItemId, args) else handleCustomCommand(controller, customCommand, args) }
Java
@Override public ListenableFuture<SessionResult> onCustomCommand( MediaSession session, ControllerInfo controller, SessionCommand customCommand, Bundle args) { String mediaItemId = args.getString(MediaConstants.EXTRA_KEY_MEDIA_ID); return mediaItemId != null ? handleCustomCommandForMediaItem(controller, customCommand, mediaItemId, args) : handleCustomCommand(controller, customCommand, args); }
Komut düğmelerini tarayıcı veya kumanda olarak kullanma
MediaController tarafında, bir uygulama MediaController veya MediaBrowser oluştururken bir medya öğesi için desteklediği maksimum komut düğmesi sayısını bildirebilir:
Kotlin
val browserFuture = MediaBrowser.Builder(context, sessionToken).setMaxCommandsForMediaItems(3).buildAsync()
Java
ListenableFuture<MediaBrowser> browserFuture = new MediaBrowser.Builder(context, sessionToken).setMaxCommandsForMediaItems(3).buildAsync();
Oturuma bağlandığında kumanda uygulaması, medya öğesi tarafından desteklenen ve kumandanın oturum uygulaması tarafından verilen kullanılabilir komut iznine sahip olduğu komut düğmelerini alabilir:
Kotlin
val commandButtonsForMediaItem = controller.getCommandButtonsForMediaItem(mediaItem)
Java
ImmutableList<CommandButton> commandButtonsForMediaItem = controller.getCommandButtonsForMediaItem(mediaItem);
Kotlin
val future = controller.sendCustomCommand( requireNotNull(addToPlaylistButton.sessionCommand), mediaItem, Bundle.EMPTY, )
Java
ListenableFuture<SessionResult> future = controller.sendCustomCommand( checkNotNull(addToPlaylistButton.sessionCommand), mediaItem, Bundle.EMPTY);