Để hoàn tất thiết kế ứng dụng/máy chủ, bạn phải tạo thành phần hoạt động chứa mã giao diện người dùng, MediaController được liên kết và MediaBrowser.
MediaBrowser thực hiện hai chức năng quan trọng: Trình duyệt này kết nối với MediaBrowserService và sau khi kết nối, trình duyệt này sẽ tạo MediaController cho giao diện người dùng của bạn.
Lưu ý: Cách triển khai MediaBrowser được đề xuất
là MediaBrowserCompat
,
được xác định trong phần tử
Thư viện hỗ trợ Media-Compat.
Xuyên suốt trang này, thuật ngữ "MediaBrowser" đề cập đến một thực thể
của MediaBrowserCompat.
Kết nối với MediaBrowserService
Khi hoạt động của ứng dụng được tạo, hoạt động đó sẽ kết nối với MediaBrowserService. Có một chút bắt tay và nhảy múa. Sửa đổi phương thức gọi lại trong vòng đời của hoạt động như sau:
onCreate()
tạo MediaBrowserCompat. Truyền tên của MediaBrowserService và MediaBrowserCompat.ConnectionCallback mà bạn đã xác định.onStart()
kết nối với MediaBrowserService. Đây là lúc sự kỳ diệu của MediaBrowserCompat.ConnectionCallback xuất hiện. Nếu kết nối thành công, lệnh gọi lại onConnect() sẽ tạo trình điều khiển nội dung nghe nhìn, liên kết nó với phiên phát nội dung đa phương tiện, liên kết các chế độ điều khiển trên giao diện người dùng với MediaController và đăng ký trình điều khiển để nhận lệnh gọi lại từ phiên phát nội dung đa phương tiện.onResume()
thiết lập luồng âm thanh để ứng dụng của bạn phản hồi chế độ điều chỉnh âm lượng trên thiết bị.onStop()
ngắt kết nối MediaBrowser và huỷ đăng ký MediaController.Callback khi hoạt động của bạn dừng.
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(); } }
Tuỳ chỉnh MediaBrowserCompat.ConnectionCallback
Khi hoạt động của bạn tạo MediaBrowserCompat, bạn phải tạo một thực thể của ConnectionCallback. Sửa đổi phương thức onConnected()
để truy xuất mã thông báo phiên đa phương tiện từ MediaBrowserService và sử dụng mã thông báo để tạo MediaControllerCompat.
Sử dụng phương thức tiện lợi
MediaControllerCompat.setMediaController()
để lưu liên kết vào bộ điều khiển. Thao tác này cho phép xử lý các nút nội dung đa phương tiện. Ứng dụng này cũng cho phép bạn gọi
MediaControllerCompat.getMediaController()
để truy xuất trình điều khiển khi tạo bộ điều khiển phương tiện giao thông.
Mã mẫu sau đây cho biết cách sửa đổi phương thức onConnected()
.
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 } };
Kết nối giao diện người dùng với trình điều khiển nội dung nghe nhìn
Trong mã mẫu ConnectionCallback ở trên, bao gồm lệnh gọi đến buildTransportControls()
để bổ sung thêm cho giao diện người dùng của bạn. Bạn cần đặt onClickListener cho các phần tử trên giao diện người dùng điều khiển trình phát. Chọn lựa chọn phù hợp
MediaControllerCompat.TransportControls
cho mỗi phần tử.
Mã của bạn sẽ trông giống như sau, với một onClickListener cho mỗi nút:
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); } }
Các phương thức TransportControls sẽ gửi lệnh gọi lại đến phiên phát nội dung đa phương tiện của dịch vụ. Hãy đảm bảo bạn đã xác định
Phương thức MediaSessionCompat.Callback
cho từng chế độ điều khiển.
Đồng bộ hoá với phiên phát nội dung nghe nhìn
Giao diện người dùng phải cho thấy trạng thái hiện tại của phiên phát nội dung đa phương tiện, như mô tả trong PlaybackState và Metadata. Khi tạo các thành phần điều khiển phương tiện giao thông, bạn có thể lấy trạng thái hiện tại của phiên, hiển thị phiên đó trong giao diện người dùng, cũng như bật và tắt các thành phần điều khiển phương tiện giao thông dựa trên trạng thái và các hành động có sẵn.
Để nhận lệnh gọi lại từ phiên đa phương tiện mỗi khi trạng thái hoặc siêu dữ liệu của phiên thay đổi, hãy xác định
MediaControllerCompat.Callback
bằng 2 phương thức sau:
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) {} };
Đăng ký lệnh gọi lại khi bạn tạo các phương thức điều khiển truyền tải (xem phương thức buildTransportControls()
) và huỷ đăng ký lệnh gọi lại đó khi hoạt động dừng (trong phương thức vòng đời onStop()
của hoạt động).
Ngắt kết nối khi phiên đa phương tiện bị huỷ
Nếu phiên đa phương tiện không hợp lệ,
onSessionDestroyed()
lệnh gọi lại được phát hành. Khi điều đó xảy ra, phiên không thể hoạt động
trong vòng đời của MediaBrowserService
. Mặc dù hàm
liên quan đến MediaBrowser
có thể tiếp tục hoạt động, người dùng không thể xem hoặc kiểm soát
từ phiên phát nội dung đa phương tiện đã bị huỷ bỏ, điều này có thể làm giảm giá trị của
ứng dụng của bạn.
Do đó, khi phiên bị huỷ, bạn phải ngắt kết nối khỏi
MediaBrowserService
bằng cách gọi
disconnect()
.
Điều này đảm bảo rằng dịch vụ trình duyệt không có ứng dụng khách bị ràng buộc và
có thể bị huỷ bỏ bởi
Hệ điều hành.
Nếu sau này bạn cần kết nối lại với MediaBrowserService
(ví dụ: nếu
ứng dụng của bạn muốn duy trì kết nối liên tục với ứng dụng đa phương tiện),
tạo một phiên bản mới của MediaBrowser
thay vì sử dụng lại phiên bản cũ.
Đoạn mã sau đây minh hoạ cách triển khai lệnh gọi lại ngắt kết nối khỏi dịch vụ trình duyệt khi phiên đa phương tiện bị huỷ:
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 } };