Nút nội dung đa phương tiện là các nút phần cứng có trên thiết bị Android và các thiết bị ngoại vi khác, chẳng hạn như nút tạm dừng/phát trên tai nghe Bluetooth. Khi người dùng nhấn vào một nút đa phương tiện, Android sẽ tạo một KeyEvent
chứa mã phím xác định nút đó. Mã phím cho KeyEvents của nút đa phương tiện là các hằng số bắt đầu bằng KEYCODE_MEDIA
(ví dụ: KEYCODE_MEDIA_PLAY
).
Ứng dụng có thể xử lý các sự kiện nút đa phương tiện trong ba trường hợp, theo thứ tự sau mức độ ưu tiên:
- Khi hoạt động trên giao diện người dùng của ứng dụng hiển thị
- Khi hoạt động trên giao diện người dùng bị ẩn và phiên phát nội dung nghe nhìn của ứng dụng đang hoạt động
- Khi hoạt động trên giao diện người dùng bị ẩn và phiên đa phương tiện của ứng dụng không hoạt động và cần được khởi động lại
Xử lý các nút đa phương tiện trong hoạt động trên nền trước
Hoạt động trên nền trước nhận sự kiện chính của nút đa phương tiện trong onKeyDown()
. Tuỳ thuộc vào phiên bản Android đang chạy, hệ thống có 2 cách để chuyển sự kiện đến
trình điều khiển nội dung nghe nhìn:
- Nếu bạn đang chạy Android 5.0 (API cấp 21) trở lên, hãy gọi
FLAG_HANDLES_MEDIA_BUTTONS
MediaBrowserCompat.ConnectionCallback.onConnected
Thao tác này sẽ tự động gọidispatchMediaButtonEvent()
, lệnh này sẽ dịch mã phím sang lệnh gọi lại phiên đa phương tiện. - Trước Android 5.0 (API cấp 21), bạn cần sửa đổi
onKeyDown()
để xử lý sự kiện đó. (Xem bài viết Xử lý các nút đa phương tiện trong một phiên phát nội dung nghe nhìn đang hoạt động để biết thông tin chi tiết.) Đoạn mã sau đây cho biết cách chặn mã khoá và gọi dispatchMediaButtonEvent(). Hãy nhớ trả lạitrue
để cho biết rằng sự kiện đã được xử lý: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); }
Tìm một phiên phát nội dung nghe nhìn
Nếu hoạt động trên nền trước không xử lý sự kiện, Android sẽ cố gắng tìm một có thể xử lý nó. Một lần nữa, tuỳ thuộc vào phiên bản đang chạy của Trên Android, có 2 cách để tìm kiếm một phiên phát nội dung đa phương tiện:
Nếu bạn đang chạy Android 8.0 (API cấp 26) trở lên, hệ thống sẽ cố gắng tìm ứng dụng cuối cùng có MediaSession phát âm thanh trên thiết bị. Nếu phiên hoạt động vẫn đang hoạt động. Android sẽ gửi trực tiếp sự kiện đến ứng dụng đó. Ngược lại, nếu phiên hoạt động không hoạt động và có bộ nhận mediabutton, Android sẽ gửi sự kiện đến trình nhận, trình nhận này sẽ khởi động lại phiên và để có thể nhận được sự kiện. (Xem bài viết Sử dụng các nút đa phương tiện để bắt đầu lại phiên phát nội dung nghe nhìn không hoạt động để biết thông tin chi tiết.) Nếu phiên không có bộ nhận nút nội dung nghe nhìn, hệ thống sẽ loại bỏ nội dung nghe nhìn và sẽ không có gì xảy ra. Logic này được thể hiện như sau sơ đồ:
Trước Android 8.0 (API cấp 26), hệ thống sẽ cố gắng gửi sự kiện đến một phiên phát nội dung nghe nhìn đang hoạt động. Nếu có nhiều phiên phát nội dung nghe nhìn đang hoạt động, Android sẽ cố gắng để chọn phiên đa phương tiện đang chuẩn bị phát (lưu vào bộ đệm/kết nối), đang phát hoặc tạm dừng, thay vì một video bị dừng. (Xem Xử lý các nút đa phương tiện trong một phiên phát nội dung nghe nhìn đang hoạt động để biết thêm chi tiết.) Nếu không có mã nào đang hoạt động Android sẽ cố gắng gửi sự kiện này đến phiên hoạt động gần đây nhất. (Xem bài viết Sử dụng các nút đa phương tiện để bắt đầu lại phiên phát nội dung nghe nhìn không hoạt động để biết thông tin chi tiết.) Logic này được thể hiện trong sơ đồ sau:
Xử lý các nút nội dung nghe nhìn trong một phiên nội dung nghe nhìn đang hoạt động
Trên Android 5.0 (API cấp 21) trở lên, Android sẽ tự động gửi các sự kiện nút đa phương tiện đến phiên phát nội dung đa phương tiện đang hoạt động bằng cách gọi
onMediaButtonEvent()
.
Theo mặc định, lệnh gọi lại này sẽ dịch KeyEvent thành phương thức Gọi lại phiên phát nội dung nghe nhìn thích hợp khớp với mã phím.
Trước Android 5.0 (API cấp 21), Android xử lý các sự kiện nút đa phương tiện bằng cách truyền một ý định
bằng thao tác ACTION_MEDIA_BUTTON
. Ứng dụng của bạn phải đăng ký
BroadcastReceiver để chặn các ý định này. Chiến lược phát hành đĩa đơn
MediaButtonReceiver
được thiết kế dành riêng cho
cho mục đích này. Đó là một lớp tiện lợi trong
Android
media-compat và
xử lý ACTION_MEDIA_BUTTON
và chuyển Ý định đến thành
lệnh gọi phương thức MediaSessionCompat.Callback
thích hợp.
MediaButtonReceiver
là một BroadcastReceiver tồn tại trong thời gian ngắn. Nó chuyển tiếp cuộc gọi đến
ý định đối với dịch vụ đang quản lý phiên phát nội dung đa phương tiện của bạn. Nếu bạn muốn sử dụng
các nút đa phương tiện trong các hệ thống trước phiên bản Android 5.0, bạn phải đưa vào
MediaButtonReceiver
trong tệp kê khai của bạn bằng bộ lọc ý định 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
chuyển tiếp ý định đến dịch vụ của bạn. Để phân tích cú pháp ý định
và tạo lệnh gọi lại cho phiên phát nội dung đa phương tiện, hãy đưa phương thức MediaButtonReceiver.handleIntent()
vào onStartCommand()
của dịch vụ.
Thao tác này sẽ dịch mã khoá thành phương thức gọi lại phiên thích hợp.
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); }
Sử dụng các nút nội dung nghe nhìn để khởi động lại phiên phát nội dung nghe nhìn không hoạt động
Nếu có thể xác định phiên phát nội dung đa phương tiện hoạt động gần đây nhất, thì Android sẽ cố gắng khởi động lại phiên đó bằng cách gửi một Ý định ACTION_MEDIA_BUTTON
đến một thành phần đã đăng ký tệp kê khai (chẳng hạn như một dịch vụ hoặc BroadcastReceiver
).
Việc này cho phép ứng dụng bắt đầu lại quá trình phát trong khi giao diện người dùng của ứng dụng không hiển thị, trường hợp này xảy ra với hầu hết các ứng dụng âm thanh.
Hành vi này được tự động bật khi bạn sử dụng MediaSessionCompat
. Nếu bạn
sử dụng MediaSession
của khung Android hoặc Thư viện hỗ trợ 24.0.0 cho đến
25.1.1 Bạn phải gọi setMediaButtonReceiver
để cho phép nút đa phương tiện khởi động lại
phiên phát nội dung nghe nhìn không hoạt động.
Bạn có thể vô hiệu hoá hành vi này trong Android 5.0 (API cấp 21) trở lên bằng cách đặt bộ nhận nút đa phương tiện rỗng:
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);
Tuỳ chỉnh trình xử lý nút đa phương tiện
Hành vi mặc định của onMediaButtonEvent()
trích xuất mã phím và sử dụng trạng thái hiện tại của phiên phát nội dung đa phương tiện cũng như danh sách các thao tác được hỗ trợ để xác định phương thức cần gọi. Ví dụ: KEYCODE_MEDIA_PLAY
gọi onPlay()
.
Để mang đến trải nghiệm nhất quán khi dùng nút đa phương tiện trên tất cả ứng dụng, bạn nên dùng
hành vi mặc định và chỉ đi chệch cho một mục đích cụ thể. Nếu một nút nội dung nghe nhìn
cần xử lý tuỳ chỉnh, hãy ghi đè lệnh gọi lại
onMediaButtonEvent()
hãy trích xuất KeyEvent
bằng cách sử dụng
intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT)
,
tự xử lý sự kiện đó rồi trả về true
.
Tóm tắt
Để xử lý đúng cách các sự kiện nút đa phương tiện trong tất cả phiên bản Android, bạn phải
chỉ định FLAG_HANDLES_MEDIA_BUTTONS
khi bạn tạo một phiên phát nội dung nghe nhìn.
Ngoài ra, tuỳ thuộc vào phiên bản Android mà bạn định hỗ trợ, bạn cũng phải đáp ứng các yêu cầu sau:
Khi chạy trong Android 5.0 trở lên:
- Gọi
MediaControllerCompat.setMediaController()
từ lệnh gọi lạionConnected()
của trình điều khiển nội dung nghe nhìn - Để cho phép một nút nội dung đa phương tiện khởi động lại một phiên không hoạt động, hãy tự động tạo một
MediaButtonReceiver
bằng cách gọisetMediaButtonReceiver()
và truyền cho nó mộtPendingIntent
Khi chạy trong các hệ thống cũ hơn Android 5.0:
- Ghi đè
onKeyDown()
của hoạt động để xử lý các nút đa phương tiện - Tạo tĩnh một
MediaButtonReceiver
bằng cách thêm mã này vào tệp kê khai của ứng dụng