İstemci/sunucu tasarımını tamamlamak için, kullanıcı arayüzü kodunuzu, ilişkili bir MediaController'ı ve bir MediaTarayıcı'yı içeren bir etkinlik bileşeni oluşturmanız gerekir.
MediaTarayıcı iki önemli işlev gerçekleştirir: Bir MediaTarayıcı Hizmeti'ne bağlanır ve bağlandıktan sonra kullanıcı arayüzünüz için MediaController'ı oluşturur.
Not: MediaTarayıcı için önerilen uygulama, Media-Compat destek kitaplığında tanımlanmış olan MediaBrowserCompat
'dir.
Bu sayfada "MediaTarayıcı" terimi MediaTarayıcıCompat'ın bir örneğini ifade etmektedir.
MediaTarayıcı Hizmeti'ne bağlanın
İstemci etkinliğiniz oluşturulduğunda MediaTarayıcı Hizmeti'ne bağlanır. Biraz el sıkışma ve dans etme işini içerir. Etkinliğin yaşam döngüsü geri çağırmalarını aşağıdaki gibi değiştirin:
onCreate()
, bir MediaTarayıcıCompat oluşturur. MediaTarayıcı Hizmetinizin ve tanımladığınız MediaTarayıcıCompat.ConnectionCallback öğesinin adını iletin.onStart()
, MediaTarayıcı Hizmeti'ne bağlanır. MediaTarayıcıCompat.ConnectionCallback işte burada devreye giriyor. Bağlantı başarılı olursa onConnect() geri çağırması medya denetleyicisini oluşturur, medya oturumuna bağlar, kullanıcı arayüzü kontrollerinizi MediaController'a bağlar ve denetleyiciyi medya oturumundan geri çağırmalar alacak şekilde kaydeder.onResume()
, ses akışını uygulamanızın cihazdaki ses seviyesi kontrolüne yanıt vereceği şekilde ayarlar.onStop()
, MediaTarayıcınızın bağlantısını keser ve etkinliğiniz durduğunda MediaController.Callback'in kaydını iptal eder.
Kotlin
class MediaPlayerActivity : AppCompatActivity() { private lateinit var mediaBrowser: MediaBrowserCompat override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... // Create MediaBrowserServiceCompat mediaBrowser = MediaBrowserCompat( this, ComponentName(this, MediaPlaybackService::class.java), connectionCallbacks, null // optional Bundle ) } public override fun onStart() { super.onStart() mediaBrowser.connect() } public override fun onResume() { super.onResume() volumeControlStream = AudioManager.STREAM_MUSIC } public override fun onStop() { super.onStop() // (see "stay in sync with the MediaSession") MediaControllerCompat.getMediaController(this)?.unregisterCallback(controllerCallback) mediaBrowser.disconnect() } }
Java
public class MediaPlayerActivity extends AppCompatActivity { private MediaBrowserCompat mediaBrowser; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... // Create MediaBrowserServiceCompat mediaBrowser = new MediaBrowserCompat(this, new ComponentName(this, MediaPlaybackService.class), connectionCallbacks, null); // optional Bundle } @Override public void onStart() { super.onStart(); mediaBrowser.connect(); } @Override public void onResume() { super.onResume(); setVolumeControlStream(AudioManager.STREAM_MUSIC); } @Override public void onStop() { super.onStop(); // (see "stay in sync with the MediaSession") if (MediaControllerCompat.getMediaController(MediaPlayerActivity.this) != null) { MediaControllerCompat.getMediaController(MediaPlayerActivity.this).unregisterCallback(controllerCallback); } mediaBrowser.disconnect(); } }
MediaTarayıcıCompat.ConnectionCallback'i Özelleştir
Etkinliğiniz MediaTarayıcıCompat oluşturduğunda, ConnectionCallback'in bir örneğini oluşturmanız gerekir. Medya oturumu jetonunu MediaTarayıcıService'ten almak için onConnected()
yöntemini değiştirin ve bir MediaControllerCompat oluşturmak için jetonu kullanın.
Kumandaya bağlantı kaydetmek için kolaylık yöntemini
MediaControllerCompat.setMediaController()
kullanın. Bu, medya düğmelerinin işlenmesini sağlar. Ayrıca, aktarım denetimlerini oluştururken denetleyiciyi almak için MediaControllerCompat.getMediaController()
yöntemini çağırmanıza olanak tanır.
Aşağıdaki kod örneğinde, onConnected()
yönteminin nasıl değiştirileceği gösterilmektedir.
Kotlin
private val connectionCallbacks = object : MediaBrowserCompat.ConnectionCallback() { override fun onConnected() { // Get the token for the MediaSession mediaBrowser.sessionToken.also { token -> // Create a MediaControllerCompat val mediaController = MediaControllerCompat( this@MediaPlayerActivity, // Context token ) // Save the controller MediaControllerCompat.setMediaController(this@MediaPlayerActivity, mediaController) } // Finish building the UI buildTransportControls() } override fun onConnectionSuspended() { // The Service has crashed. Disable transport controls until it automatically reconnects } override fun onConnectionFailed() { // The Service has refused our connection } }
Java
private final MediaBrowserCompat.ConnectionCallback connectionCallbacks = new MediaBrowserCompat.ConnectionCallback() { @Override public void onConnected() { // Get the token for the MediaSession MediaSessionCompat.Token token = mediaBrowser.getSessionToken(); // Create a MediaControllerCompat MediaControllerCompat mediaController = new MediaControllerCompat(MediaPlayerActivity.this, // Context token); // Save the controller MediaControllerCompat.setMediaController(MediaPlayerActivity.this, mediaController); // Finish building the UI buildTransportControls(); } @Override public void onConnectionSuspended() { // The Service has crashed. Disable transport controls until it automatically reconnects } @Override public void onConnectionFailed() { // The Service has refused our connection } };
Kullanıcı arayüzünüzü medya denetleyicisine bağlayın
Yukarıdaki ConnectionCallback örnek kodunda, kullanıcı arayüzünüzü geliştirmek için bir buildTransportControls()
çağrısı yer alır. Oynatıcıyı kontrol eden kullanıcı arayüzü öğeleri için onClickListeners öğesini ayarlamanız gerekir. Her biri için uygun MediaControllerCompat.TransportControls
yöntemini seçin.
Kodunuz, her düğme için bir onClickListener içeren, aşağıdaki gibi görünür:
Kotlin
fun buildTransportControls() { val mediaController = MediaControllerCompat.getMediaController(this@MediaPlayerActivity) // Grab the view for the play/pause button playPause = findViewById<ImageView>(R.id.play_pause).apply { setOnClickListener { // Since this is a play/pause button, you'll need to test the current state // and choose the action accordingly val pbState = mediaController.playbackState.state if (pbState == PlaybackStateCompat.STATE_PLAYING) { mediaController.transportControls.pause() } else { mediaController.transportControls.play() } } } // Display the initial state val metadata = mediaController.metadata val pbState = mediaController.playbackState // Register a Callback to stay in sync mediaController.registerCallback(controllerCallback) }
Java
void buildTransportControls() { // Grab the view for the play/pause button playPause = (ImageView) findViewById(R.id.play_pause); // Attach a listener to the button playPause.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Since this is a play/pause button, you'll need to test the current state // and choose the action accordingly int pbState = MediaControllerCompat.getMediaController(MediaPlayerActivity.this).getPlaybackState().getState(); if (pbState == PlaybackStateCompat.STATE_PLAYING) { MediaControllerCompat.getMediaController(MediaPlayerActivity.this).getTransportControls().pause(); } else { MediaControllerCompat.getMediaController(MediaPlayerActivity.this).getTransportControls().play(); } }); MediaControllerCompat mediaController = MediaControllerCompat.getMediaController(MediaPlayerActivity.this); // Display the initial state MediaMetadataCompat metadata = mediaController.getMetadata(); PlaybackStateCompat pbState = mediaController.getPlaybackState(); // Register a Callback to stay in sync mediaController.registerCallback(controllerCallback); } }
TransportControls yöntemleri, hizmetinizin medya oturumuna geri çağırmalar gönderir. Her kontrol için karşılık gelen bir MediaSessionCompat.Callback
yöntemi tanımladığınızdan emin olun.
Medya oturumuyla senkronize kalın
Kullanıcı arayüzü, medya oturumunun mevcut durumunu, PlaybackState ve Metadata'da açıklandığı şekilde görüntülemelidir. Aktarım denetimlerini oluşturduğunuzda oturumun mevcut durumunu alabilir, kullanıcı arayüzünüzde görüntüleyebilir, duruma ve kullanılabilir işlemlere bağlı olarak aktarım denetimlerini etkinleştirip devre dışı bırakabilirsiniz.
Durumu veya meta verileri her değiştiğinde medya oturumundan geri çağırmalar almak için aşağıdaki iki yöntemi kullanarak bir MediaControllerCompat.Callback
tanımlayın:
Kotlin
private var controllerCallback = object : MediaControllerCompat.Callback() { override fun onMetadataChanged(metadata: MediaMetadataCompat?) {} override fun onPlaybackStateChanged(state: PlaybackStateCompat?) {} }
Java
MediaControllerCompat.Callback controllerCallback = new MediaControllerCompat.Callback() { @Override public void onMetadataChanged(MediaMetadataCompat metadata) {} @Override public void onPlaybackStateChanged(PlaybackStateCompat state) {} };
Aktarım denetimlerini oluşturduğunuzda geri çağırmayı kaydedin (buildTransportControls()
yöntemine bakın) ve etkinlik durduğunda kaydını iptal edin (etkinliğin onStop()
yaşam döngüsü yönteminde).
Medya oturumu silindiğinde bağlantıyı kes
Medya oturumu geçersiz hale gelirse onSessionDestroyed()
geri çağırması yapılır. Bu durumda oturum, MediaBrowserService
kullanım ömrü içinde tekrar işlevsel hale getirilemez. MediaBrowser
ile ilgili işlevler çalışmaya devam etse de kullanıcı, kaldırılan bir medya oturumunun oynatılmasını görüntüleyemez veya kontrol edemez. Bu da uygulamanızın değerini büyük olasılıkla azaltacaktır.
Bu nedenle, oturum kaldırıldığında disconnect()
yöntemini çağırarak MediaBrowserService
ile bağlantınızı kesmeniz gerekir.
Bu, tarayıcı hizmetinin bağlı istemcileri olmamasını ve işletim sistemi tarafından kaldırılabilmesini sağlar.
Daha sonra MediaBrowserService
cihazına yeniden bağlanmanız gerekirse (örneğin, uygulamanız medya uygulamasıyla kalıcı bir bağlantı sürdürmek istiyorsa) eskisini yeniden kullanmak yerine yeni bir MediaBrowser
örneği oluşturun.
Aşağıdaki kod snippet'i, medya oturumu kaldırıldığında tarayıcı hizmetiyle bağlantıyı kesen bir geri çağırma uygulamasını göstermektedir:
Kotlin
private var controllerCallback = object : MediaControllerCompat.Callback() { override fun onSessionDestroyed() { mediaBrowser.disconnect() // maybe schedule a reconnection using a new MediaBrowser instance } }
Java
MediaControllerCompat.Callback controllerCallback = new MediaControllerCompat.Callback() { @Override public void onSessionDestroyed() { mediaBrowser.disconnect(); // maybe schedule a reconnection using a new MediaBrowser instance } };