Merespons tombol media

Tombol media adalah tombol hardware yang ada di perangkat Android dan perangkat periferal lainnya, seperti tombol jeda/putar di headset Bluetooth. Saat pengguna menekan tombol media, Android akan membuat KeyEvent yang berisi kode kunci yang mengidentifikasi tombol itu. Kode kunci untuk tombol media KeyEvents adalah konstanta yang dimulai dengan KEYCODE_MEDIA (misalnya KEYCODE_MEDIA_PLAY).

Aplikasi harus bisa menangani kejadian tombol media dalam tiga kasus, dalam urutan ini prioritas:

  • Saat aktivitas UI aplikasi terlihat
  • Saat aktivitas UI tersembunyi dan sesi media aplikasi aktif
  • Saat aktivitas UI tersembunyi dan sesi media aplikasi tidak aktif dan perlu dimulai ulang

Menangani tombol media dalam aktivitas latar depan

Aktivitas latar depan menerima peristiwa utama tombol media di onKeyDown()-nya . Bergantung pada versi Android yang berjalan, ada dua cara yang digunakan sistem untuk merutekan peristiwa tersebut ke pengontrol media:

  • Jika Anda menjalankan Android 5.0 (API level 21) atau yang lebih baru, panggil FLAG_HANDLES_MEDIA_BUTTONS MediaBrowserCompat.ConnectionCallback.onConnected. Hal ini akan otomatis memanggil dispatchMediaButtonEvent(), yang menerjemahkan kode tombol ke callback sesi media.
  • Sebelum Android 5.0 (API level 21), Anda perlu mengubah onKeyDown() untuk menangani acara itu sendiri. (Lihat Menangani tombol media dalam sesi media yang aktif untuk penjelasan selengkapnya.) Cuplikan kode berikut menunjukkan cara mencegat kode tombol dan memanggil dispatchMediaButtonEvent(). Pastikan untuk mengembalikan true ke menunjukkan bahwa peristiwa telah ditangani:

    Kotlin

        fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                return super.onKeyDown(keyCode, event)
            }
            when (keyCode) {
                KeyEvent.KEYCODE_MEDIA_PLAY -> {
                    yourMediaController.dispatchMediaButtonEvent(event)
                    return true
                }
            }
            return super.onKeyDown(keyCode, event)
        }
        

    Java

        @Override
        boolean onKeyDown(int keyCode, KeyEvent event) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                  return super.onKeyDown(keyCode, event);
                }
                switch (keyCode) {
                  case KeyEvent.KEYCODE_MEDIA_PLAY:
                          yourMediaController.dispatchMediaButtonEvent(event);
                          return true;
                }
                return super.onKeyDown(keyCode, event);
        }
        

Mencari sesi media

Jika aktivitas latar depan tidak menangani peristiwa, Android akan mencoba menemukan sesi media yang dapat menanganinya. Sekali lagi, tergantung pada versi yang berjalan dari Di Android, ada dua cara untuk menelusuri sesi media:

  • Jika Anda menjalankan Android 8.0 (API level 26) atau yang lebih baru, sistem akan mencoba menemukan aplikasi terakhir dengan MediaSession yang memutar audio secara lokal. Jika sesi masih aktif, Android akan mengirim peristiwa itu langsung kepadanya. Atau, jika sesi tidak aktif dan memiliki penerima tombol media, Android mengirimkan peristiwa ke penerima, yang akan memulai ulang sesi sehingga dapat menerima peristiwa tersebut. (Lihat Menggunakan tombol media untuk memulai ulang sesi media yang tidak aktif untuk penjelasan selengkapnya.) Jika sesi tidak memiliki penerima tombol media, sistem akan membuang media tersebut kejadian tombol dan tidak akan terjadi apa pun. Logikanya ditunjukkan sebagai berikut diagram:

  • Sebelum Android 8.0 (API level 26), sistem akan mencoba mengirim peristiwa ke sesi media aktif. Jika ada beberapa sesi media yang aktif, Android akan mencoba memilih sesi media yang sedang disiapkan untuk diputar (buffering/menghubungkan), yang diputar, atau dijeda, bukan yang berhenti. (Lihat Menangani tombol media dalam sesi media yang aktif untuk detail selengkapnya.) Jika tidak ada yang aktif Android akan mencoba mengirimkan peristiwa ke sesi yang terakhir aktif. (Lihat Menggunakan tombol media untuk memulai ulang sesi media yang tidak aktif untuk penjelasan selengkapnya.) Logika ini ditampilkan dalam diagram berikut:

Menangani tombol media dalam sesi media yang aktif

Di Android 5.0 (API level 21) dan yang lebih tinggi, Android secara otomatis mengirimkan peristiwa tombol media ke sesi media aktif Anda dengan memanggil onMediaButtonEvent(). Secara default, callback ini menerjemahkan KeyEvent menjadi metode Callback sesi media yang sesuai, yang cocok dengan kode kuncinya.

Sebelum Android 5.0 (API level 21), Android menangani peristiwa tombol media dengan menyiarkan intent dengan tindakan ACTION_MEDIA_BUTTON. Aplikasi Anda harus mendaftarkan BroadcastReceiver untuk menangkap intent ini. Tujuan MediaButtonReceiver dirancang khusus untuk tujuan ini. Ini adalah class praktis di Android library media-compat yang menangani ACTION_MEDIA_BUTTON dan menerjemahkan Intent yang masuk ke dalam panggilan metode MediaSessionCompat.Callback yang sesuai.

MediaButtonReceiver adalah BroadcastReceiver yang berumur pendek. Operator ini meneruskan intent ke layanan yang mengelola sesi media Anda. Jika Anda ingin menggunakan tombol media di sistem yang lebih lama dari Android 5.0, Anda harus menyertakan MediaButtonReceiver dalam manifes Anda dengan filter intent MEDIA_BUTTON.:

<receiver android:name="android.support.v4.media.session.MediaButtonReceiver" >
   <intent-filter>
     <action android:name="android.intent.action.MEDIA_BUTTON" />
   </intent-filter>
 </receiver>

BroadcastReceiver meneruskan intent ke layanan Anda. Untuk mengurai intent dan buat callback ke sesi media Anda, sertakan metode MediaButtonReceiver.handleIntent() dalam onStartCommand() layanan Anda. Tindakan ini akan menerjemahkan kode kunci menjadi metode callback sesi yang sesuai.

Kotlin

private val mediaSessionCompat: MediaSessionCompat = ...

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    MediaButtonReceiver.handleIntent(mediaSessionCompat, intent)
    return super.onStartCommand(intent, flags, startId)
}

Java

private MediaSessionCompat mediaSessionCompat = ...;

 public int onStartCommand(Intent intent, int flags, int startId) {
   MediaButtonReceiver.handleIntent(mediaSessionCompat, intent);
   return super.onStartCommand(intent, flags, startId);
 }

Menggunakan tombol media untuk memulai ulang sesi media yang tidak aktif

Jika dapat mengidentifikasi sesi media yang terakhir aktif, Android akan mencoba memulai ulang sesi itu dengan mengirim Intent ACTION_MEDIA_BUTTON ke komponen yang terdaftar di manifes (misalnya layanan atau BroadcastReceiver).

Dengan begitu, aplikasi Anda akan dapat memulai ulang pemutaran saat UI-nya tidak terlihat, seperti yang terjadi di sebagian besar aplikasi audio.

Perilaku ini diaktifkan secara otomatis jika Anda menggunakan MediaSessionCompat. Jika Anda menggunakan MediaSession framework Android atau Support Library 24.0.0 hingga 25.1.1 Anda harus memanggil setMediaButtonReceiver untuk mengizinkan tombol media memulai ulang sesi media tidak aktif.

Anda dapat menonaktifkan perilaku ini di Android 5.0 (API level 21) dan yang lebih tinggi dengan menyetel penerima tombol media null:

Kotlin

// Create a MediaSessionCompat
mediaSession = MediaSessionCompat(context, LOG_TAG)
mediaSession.setMediaButtonReceiver(null)

Java

// Create a MediaSessionCompat
mediaSession = new MediaSessionCompat(context, LOG_TAG);
mediaSession.setMediaButtonReceiver(null);

Menyesuaikan pengendali tombol media

Perilaku default untuk onMediaButtonEvent() adalah mengekstrak kode kunci dan menggunakan status terkini sesi media dan daftar tindakan yang didukung untuk menentukan metode yang akan dihubungi. Misalnya, KEYCODE_MEDIA_PLAY memanggil onPlay().

Untuk memberikan pengalaman tombol media yang konsisten di semua aplikasi, Anda harus menggunakan perilaku {i>default<i} dan hanya menyimpang untuk tujuan tertentu. Jika tombol media memerlukan penanganan khusus, ganti callback onMediaButtonEvent() , ekstrak KeyEvent menggunakan intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT), menangani peristiwa itu sendiri, lalu menampilkan true.

Ringkasan

Untuk menangani peristiwa tombol media dengan benar di semua versi Android, Anda harus tentukan FLAG_HANDLES_MEDIA_BUTTONS saat Anda membuat sesi media.

Selain itu, bergantung pada versi Android yang ingin Anda dukung, Anda juga harus memenuhi persyaratan berikut:

Jika aplikasi berjalan di Android 5.0 atau yang lebih baru:

  • Panggil MediaControllerCompat.setMediaController() dari callback onConnected() pengontrol media
  • Untuk mengizinkan tombol media memulai ulang sesi yang tidak aktif, buat MediaButtonReceiver secara dinamis dengan memanggil setMediaButtonReceiver() dan meneruskan PendingIntent

Jika aplikasi berjalan di Android sebelum versi 5.0:

  • Ganti onKeyDown() aktivitas untuk menangani tombol media
  • Buat MediaButtonReceiver secara statis dengan menambahkannya ke manifes aplikasi