Genellikle bir uygulama ön planda değilken medya oynatılması istenir. Örneğin, Örneğin, bir müzik çalar genellikle kullanıcı kilitlendiğinde veya başka bir uygulama kullanıyor olabilir. Media3 kitaplığı bir dizi arka planda oynatmayı destekleyen arabirimler kullanır.
MediaSessionService kullanma
Arka planda oynatmayı etkinleştirmek için Player
ve
MediaSession
ayrı bir Hizmet içinde.
Bu şekilde, uygulamanız kapalıyken bile cihaz medya yayınlamaya devam edebilir
görebilirsiniz.
Bir oyuncuyu Hizmet'in içinde barındırırken MediaSessionService
kullanmanız gerekir.
Bunu yapmak için MediaSessionService
öğesini genişleten bir sınıf oluşturun ve
bir kontrol noktası
olduğunu unutmayın.
MediaSessionService
kullanımı, Google gibi harici müşterilerin işini kolaylaştırır
Keşfetmek için Asistan, sistem medya kontrolleri veya Wear OS gibi tamamlayıcı cihazlar
hizmete bağlanabilir, hizmete bağlanabilir ve oynatmayı kontrol edebilir. Üstelik tüm bunları
kullanıcı arayüzü etkinliği. Hatta birden fazla istemci uygulaması birbirine bağlı olabilir.
aynı anda aynı MediaSessionService
öğesine; her uygulamanın kendine ait
MediaController
.
Hizmet yaşam döngüsünü uygulayın
Hizmetinizle ilgili üç yaşam döngüsü yöntemini uygulamanız gerekir:
onCreate()
, ilk kumanda bağlanmak üzereyken çağrılır ve ve başlatıldığına dair bir ipucudur. BurasıPlayer
oluşturmak için en iyi yerdirMediaSession
.onTaskRemoved(Intent)
, kullanıcı uygulamayı son görevlerden bahsetmeye devam edelim. Oynatma işlemi devam ediyorsa uygulama, hizmeti kullanmaya devam etmeyi tercih edebilir. ön planda çalışıyor. Oynatıcı duraklatılmışsa hizmet şurada değildir: durdurulması gerekiyor.- Hizmet durdurulurken
onDestroy()
çağrılır. Tüm kaynaklar ve oturumun serbest bırakılması gerekir.
Kotlin
class PlaybackService : MediaSessionService() { private var mediaSession: MediaSession? = null // Create your player and media session in the onCreate lifecycle event override fun onCreate() { super.onCreate() val player = ExoPlayer.Builder(this).build() mediaSession = MediaSession.Builder(this, player).build() } // The user dismissed the app from the recent tasks override fun onTaskRemoved(rootIntent: Intent?) { val player = mediaSession?.player!! if (!player.playWhenReady || player.mediaItemCount == 0 || player.playbackState == Player.STATE_ENDED) { // Stop the service if not playing, continue playing in the background // otherwise. stopSelf() } } // Remember to release the player and media session in onDestroy override fun onDestroy() { mediaSession?.run { player.release() release() mediaSession = null } super.onDestroy() } }
Java
public class PlaybackService extends MediaSessionService { private MediaSession mediaSession = null; // Create your Player and MediaSession in the onCreate lifecycle event @Override public void onCreate() { super.onCreate(); ExoPlayer player = new ExoPlayer.Builder(this).build(); mediaSession = new MediaSession.Builder(this, player).build(); } // The user dismissed the app from the recent tasks @Override public void onTaskRemoved(@Nullable Intent rootIntent) { Player player = mediaSession.getPlayer(); if (!player.getPlayWhenReady() || player.getMediaItemCount() == 0 || player.getPlaybackState() == Player.STATE_ENDED) { // Stop the service if not playing, continue playing in the background // otherwise. stopSelf(); } } // Remember to release the player and media session in onDestroy @Override public void onDestroy() { mediaSession.getPlayer().release(); mediaSession.release(); mediaSession = null; super.onDestroy(); } }
Uygulama, arka planda oynatmayı devam ettirmenin alternatifi olarak Kullanıcı uygulamayı kapattığında her durumda hizmeti durdurma:
Kotlin
override fun onTaskRemoved(rootIntent: Intent?) { val player = mediaSession.player if (player.playWhenReady) { // Make sure the service is not in foreground. player.pause() } stopSelf() }
Java
@Override public void onTaskRemoved(@Nullable Intent rootIntent) { Player player = mediaSession.getPlayer(); if (player.getPlayWhenReady()) { // Make sure the service is not in foreground. player.pause(); } stopSelf(); }
Medya oturumuna erişim izni ver
Diğer istemcilerin medyanıza erişmesine izin vermek için onGetSession()
yöntemini geçersiz kılın
oturumdaki bilgileri sunar.
Kotlin
class PlaybackService : MediaSessionService() { private var mediaSession: MediaSession? = null // [...] lifecycle methods omitted override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? = mediaSession }
Java
public class PlaybackService extends MediaSessionService { private MediaSession mediaSession = null; // [...] lifecycle methods omitted @Override public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) { return mediaSession; } }
Manifest dosyasında hizmeti beyan edin
Bir uygulamanın, ön plan hizmetini çalıştırmak için izne ihtiyacı var. URL'yi
manifest dosyası için FOREGROUND_SERVICE
izninizi kontrol edin ve API 34 ile
yukarıdaki de FOREGROUND_SERVICE_MEDIA_PLAYBACK
üzerinde:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
Manifest'te Service
sınıfınızı bir intent filtresiyle de bildirmeniz gerekir.
/ MediaSessionService
.
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
</intent-filter>
</service>
Hedef kitlenizin kim olduğunu
foregroundServiceType
Uygulamanız Android yüklü bir cihazda çalışırken mediaPlayback
dahil
10 (API düzeyi 29) ve sonraki sürümler.
Çalmayı MediaController
kullanarak kontrol edin
Oynatıcı kullanıcı arayüzünüzü içeren Etkinlik veya Parçada
bir MediaController
kullanarak kullanıcı arayüzü ile medya oturumunuz arasında. Kullanıcı arayüzünüz
komutlarını kullanıcı arayüzünden oynatıcıya
kabul edilir. Bkz.
MediaController
oluşturun
kullanma ve MediaController
kullanma hakkında ayrıntılı bilgiler için kılavuza bakın.
Kullanıcı arayüzü komutlarını işleme
MediaSession
, aşağıdakileri kullanarak kumandadan komut alır:
MediaSession.Callback
. MediaSession
ilk kez başlatıldığında varsayılan oluşturulur
tüm geçiş işlemlerini otomatik olarak işleyen MediaSession.Callback
MediaController
tarafından oynatıcınıza gönderdiği komutlar arasındadır.
Bildirim
MediaSessionService
, sizin için otomatik olarak aşağıdaki özelliklere sahip bir MediaNotification
oluşturur:
çoğu durumda işe yarar. Varsayılan olarak, yayınlanan bildirim
MediaStyle
bildirim
en son bilgilerle güncellenen bir
oynatma kontrollerini görüntüler. MediaNotification
oturumunuzun farkındadır ve diğer uygulamaların oynatmayı kontrol etmek için kullanılabilir
arasında bağlantı oluşturur.
Örneğin, MediaSessionService
kullanan bir müzik yayın uygulaması
Öğeye ait başlığı, sanatçıyı ve albüm resmini gösteren MediaNotification
bağlı olarak, oynatma kontrolleriyle birlikte oynatılan mevcut medya öğesi
MediaSession
yapılandırması.
Gerekli meta veriler medyada sağlanabilir veya medya öğesini seçin:
Kotlin
val mediaItem = MediaItem.Builder() .setMediaId("media-1") .setUri(mediaUri) .setMediaMetadata( MediaMetadata.Builder() .setArtist("David Bowie") .setTitle("Heroes") .setArtworkUri(artworkUri) .build() ) .build() mediaController.setMediaItem(mediaItem) mediaController.prepare() mediaController.play()
Java
MediaItem mediaItem = new MediaItem.Builder() .setMediaId("media-1") .setUri(mediaUri) .setMediaMetadata( new MediaMetadata.Builder() .setArtist("David Bowie") .setTitle("Heroes") .setArtworkUri(artworkUri) .build()) .build(); mediaController.setMediaItem(mediaItem); mediaController.prepare(); mediaController.play();
Uygulamalar, Android Medya denetimlerinin komut düğmelerini özelleştirebilir. Devamını okuyun özelleştirme konusunda kontrol eder.
Bildirim özelleştirme
Bildirimi özelleştirmek için bir oluşturun
MediaNotification.Provider
DefaultMediaNotificationProvider.Builder
ile
veya sağlayıcı arayüzünün özel bir uygulamasını oluşturarak.
MediaSessionService
ile kullanmak üzere
setMediaNotificationProvider
Oynatmayı devam ettirme
Medya düğmeleri, Android cihazlarda ve diğer çevre birimlerinde bulunan donanım düğmeleridir. cihazları (örneğin, Bluetooth mikrofonlu kulaklıktaki oynat veya duraklat düğmesi) kullanın. Medya3 hizmet çalışırken medya düğmesi girişlerini sizin için işler.
Media3 medya düğmesi alıcısını bildir
Media3, kullanıcıların
bir uygulama sonlandırıldıktan sonra ve cihaz tamamlandıktan sonra bile oynatma
yeniden başlatıldı. Varsayılan olarak, oynatmayı devam ettirme kapalıdır. Bu, kullanıcının
hizmetiniz çalışmadığında oynatmaya devam edilemez. Etkinleştirmek için önce
manifest dosyanızda MediaButtonReceiver
belirtmeniz gerekir:
<receiver android:name="androidx.media3.session.MediaButtonReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
Oynatmayı devam ettirme geri çağırmasını uygula
Bluetooth cihazı veya
Android sistem kullanıcı arayüzünün devam ettirme özelliği,
onPlaybackResumption()
çağrılır.
Kotlin
override fun onPlaybackResumption( mediaSession: MediaSession, controller: ControllerInfo ): ListenableFuture<MediaItemsWithStartPosition> { val settable = SettableFuture.create<MediaItemsWithStartPosition>() scope.launch { // Your app is responsible for storing the playlist and the start position // to use here val resumptionPlaylist = restorePlaylist() settable.set(resumptionPlaylist) } return settable }
Java
@Override public ListenableFuture<MediaItemsWithStartPosition> onPlaybackResumption( MediaSession mediaSession, ControllerInfo controller ) { SettableFuture<MediaItemsWithStartPosition> settableFuture = SettableFuture.create(); settableFuture.addListener(() -> { // Your app is responsible for storing the playlist and the start position // to use here MediaItemsWithStartPosition resumptionPlaylist = restorePlaylist(); settableFuture.set(resumptionPlaylist); }, MoreExecutors.directExecutor()); return settableFuture; }
Oynatma hızı, tekrarlama modu veya
karıştırma modu. onPlaybackResumption()
, oynatıcıyı yapılandırmak için iyi bir yerdir
medya 3 oynatıcıyı hazırlamadan önce bu parametrelerle çalışır ve
geri arama tamamlanır.
Gelişmiş kumanda yapılandırması ve geriye dönük uyumluluk
Yaygın bir senaryo, kontrol etmek için uygulamanın kullanıcı arayüzünde MediaController
kullanmaktır.
oynatma ve oynatma listesini görüntüleme. Aynı anda oturum açılmış durumda
Google Asistan gibi harici
istemcilere veri aktarıyor.
Saatler için Wear OS ve arabalarda Android Auto. Media3 oturum demo uygulaması
, bu tür bir senaryo uygulayan uygulamalara örnek gösterilebilir.
Bu harici istemciler eskinin MediaControllerCompat
gibi API'leri kullanabilir
AndroidX kitaplığı veya Android'in android.media.session.MediaController
sürümü
bahsedeceğim. Media3 eski kitaplıkla tamamen geriye dönük uyumludur ve
Android Framework API ile birlikte çalışabilirlik özelliği sunar.
Medya bildirim denetleyicisini kullanma
Bu eski veya çerçeve denetleyicilerinin
PlaybackState.getActions()
çerçevesinden aynı değerlere ve
PlaybackState.getCustomActions()
. Şu öğenin eylemlerini ve özel işlemlerini belirlemek için:
çerçeve oturumunda, uygulamalar medya bildirim denetleyicisini kullanabilir.
ve kullanılabilir komutlarını ve özel düzenini ayarlayın. Hizmet, medya dosyalarını
için bir bildirim denetleyicisi kullanıyorsanız, oturumda
ConnectionResult
, yapılandırmak için geri aramanızın onConnect()
tarafından döndürüldü
çerçeve oturumunun eylemlerini ve özel eylemlerini içerir.
Yalnızca mobil kullanıma yönelik bir senaryo göz önünde bulundurulduğunda bir uygulama,
Mevcut komutları ayarlamak için MediaSession.Callback.onConnect()
çerçeve oturumu için özel olarak aşağıdaki gibi özel düzen:
Kotlin
override fun onConnect( session: MediaSession, controller: MediaSession.ControllerInfo ): ConnectionResult { if (session.isMediaNotificationController(controller)) { val sessionCommands = ConnectionResult.DEFAULT_SESSION_COMMANDS.buildUpon() .add(customCommandSeekBackward) .add(customCommandSeekForward) .build() val playerCommands = ConnectionResult.DEFAULT_PLAYER_COMMANDS.buildUpon() .remove(COMMAND_SEEK_TO_PREVIOUS) .remove(COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM) .remove(COMMAND_SEEK_TO_NEXT) .remove(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM) .build() // Custom layout and available commands to configure the legacy/framework session. return AcceptedResultBuilder(session) .setCustomLayout( ImmutableList.of( createSeekBackwardButton(customCommandSeekBackward), createSeekForwardButton(customCommandSeekForward)) ) .setAvailablePlayerCommands(playerCommands) .setAvailableSessionCommands(sessionCommands) .build() } // Default commands with default custom layout for all other controllers. return AcceptedResultBuilder(session).build() }
Java
@Override public ConnectionResult onConnect( MediaSession session, MediaSession.ControllerInfo controller) { if (session.isMediaNotificationController(controller)) { SessionCommands sessionCommands = ConnectionResult.DEFAULT_SESSION_COMMANDS .buildUpon() .add(customCommandSeekBackward) .add(customCommandSeekForward) .build(); Player.Commands playerCommands = ConnectionResult.DEFAULT_PLAYER_COMMANDS .buildUpon() .remove(COMMAND_SEEK_TO_PREVIOUS) .remove(COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM) .remove(COMMAND_SEEK_TO_NEXT) .remove(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM) .build(); // Custom layout and available commands to configure the legacy/framework session. return new AcceptedResultBuilder(session) .setCustomLayout( ImmutableList.of( createSeekBackwardButton(customCommandSeekBackward), createSeekForwardButton(customCommandSeekForward))) .setAvailablePlayerCommands(playerCommands) .setAvailableSessionCommands(sessionCommands) .build(); } // Default commands without default custom layout for all other controllers. return new AcceptedResultBuilder(session).build(); }
Android Auto'yu özel komutlar göndermesi için yetkilendirin
MediaLibraryService
kullanırken
Android Auto'yu mobil uygulamada desteklemek için Android Auto kumandası
kullanılabilir uygun komutlar gerektirir, aksi takdirde Media3 bunu reddeder.
gelen özel komutlar:
Kotlin
override fun onConnect( session: MediaSession, controller: MediaSession.ControllerInfo ): ConnectionResult { val sessionCommands = ConnectionResult.DEFAULT_SESSION_AND_LIBRARY_COMMANDS.buildUpon() .add(customCommandSeekBackward) .add(customCommandSeekForward) .build() if (session.isMediaNotificationController(controller)) { // [...] See above. } else if (session.isAutoCompanionController(controller)) { // Available session commands to accept incoming custom commands from Auto. return AcceptedResultBuilder(session) .setAvailableSessionCommands(sessionCommands) .build() } // Default commands with default custom layout for all other controllers. return AcceptedResultBuilder(session).build() }
Java
@Override public ConnectionResult onConnect( MediaSession session, MediaSession.ControllerInfo controller) { SessionCommands sessionCommands = ConnectionResult.DEFAULT_SESSION_COMMANDS .buildUpon() .add(customCommandSeekBackward) .add(customCommandSeekForward) .build(); if (session.isMediaNotificationController(controller)) { // [...] See above. } else if (session.isAutoCompanionController(controller)) { // Available commands to accept incoming custom commands from Auto. return new AcceptedResultBuilder(session) .setAvailableSessionCommands(sessionCommands) .build(); } // Default commands without default custom layout for all other controllers. return new AcceptedResultBuilder(session).build(); }
Oturum demo uygulaması, otomotiv modülü, Bu makale, ayrı bir APK gerektiren Automotive OS desteği gösterir.