媒體控制器會與媒體工作階段互動,查詢及控制媒體應用程式的播放作業。在 Media3 中,MediaController
API 會實作 Player
介面。使用媒體控制器的用戶端應用程式範例包括:
- Android 系統媒體控制項
- Android Wear OS 隨附應用程式
- Android Auto 和 Automotive OS
- 語音助理,例如 Google 助理
- 媒體遙控器測試應用程式
媒體控制器在媒體應用程式中也很有用,舉例來說,如果播放器和媒體工作階段位於 Service
與 UI 或 Fragment
不同的位置,媒體控制器就派得上用場。Activity
建立 MediaController
如要建立 MediaController
,請先為對應的 MediaSession
建立 SessionToken
。Activity
或 Fragment
的 onStart()
方法是個不錯的選擇。
Kotlin
val sessionToken =
SessionToken(context, ComponentName(context, PlaybackService::class.java))
Java
SessionToken sessionToken =
new SessionToken(context, new ComponentName(context, PlaybackService.class));
使用這個 SessionToken
建構 MediaController
,即可將控制器連結至指定工作階段。這項作業會以非同步方式進行,因此您應監聽結果,並在結果可用時使用。
Kotlin
val controllerFuture =
MediaController.Builder(context, sessionToken).buildAsync()
controllerFuture.addListener({
// MediaController is available here with controllerFuture.get()
}, MoreExecutors.directExecutor())
Java
ListenableFuture<MediaController> controllerFuture =
new MediaController.Builder(context, sessionToken).buildAsync();
controllerFuture.addListener(() -> {
// MediaController is available here with controllerFuture.get()
}, MoreExecutors.directExecutor());
使用 MediaController
MediaController
會實作 Player
介面,因此您可以使用介面中定義的指令,控制已連線 MediaSession
的播放功能。也就是說,在 MediaController
上呼叫 play()
會將指令傳送至已連線的 MediaSession
,後者隨後會將指令委派給基礎 Player
。
您可以在控制器中新增 Player.Listener
,監聽 Player
狀態的變化。如要進一步瞭解如何使用 Player.Listener
,請參閱玩家事件指南。
MediaController.Listener
介面會為連線的 MediaSession
定義事件和其他回呼,以及自訂指令。例如:工作階段傳送自訂指令時 (onCustomCommand()
)、工作階段變更可用工作階段指令時 (onAvailableSessionCommandsChanged()
),或控制器與工作階段中斷連線時 (onDisconnected()
)。
使用 Builder
建構控制器時,可以設定 MediaController.Listener
:
Kotlin
MediaController.Builder(context, sessionToken)
.setListener(
object : MediaController.Listener {
override fun onCustomCommand(
controller: MediaController,
command: SessionCommand,
args: Bundle,
): ListenableFuture<SessionResult> {
// Handle custom command.
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
}
override fun onDisconnected(controller: MediaController) {
// Handle disconnection.
}
}
)
.buildAsync()
Java
new MediaController.Builder(context, sessionToken)
.setListener(
new MediaController.Listener() {
@Override
public ListenableFuture<SessionResult> onCustomCommand(
MediaController controller, SessionCommand command, Bundle args) {
// Handle custom command.
return Futures.immediateFuture(new SessionResult(SessionResult.RESULT_SUCCESS));
}
@Override
public void onDisconnected(MediaController controller) {
// Handle disconnection.
}
})
.buildAsync();
與其他元件一樣,請記得在不再需要 MediaController
時釋放該物件,例如在 Activity
或 Fragment
的 onStop()
方法中。
Kotlin
MediaController.releaseFuture(controllerFuture)
Java
MediaController.releaseFuture(controllerFuture);
放開遙控器後,系統仍會將所有待處理的指令傳送至工作階段,並在處理完這些指令或逾時後,才會解除與工作階段服務的繫結 (以先發生者為準)。
建立及使用 MediaBrowser
MediaBrowser
會以 MediaController
提供的功能為基礎,同時啟用瀏覽媒體應用程式 MediaLibraryService
提供的媒體庫。
Kotlin
val browserFuture = MediaBrowser.Builder(context, sessionToken).buildAsync()
browserFuture.addListener({
// MediaBrowser is available here with browserFuture.get()
}, MoreExecutors.directExecutor())
Java
ListenableFuture<MediaBrowser> browserFuture =
new MediaBrowser.Builder(context, sessionToken).buildAsync();
browserFuture.addListener(() -> {
// MediaBrowser is available here with browserFuture.get()
}, MoreExecutors.directExecutor());
如要開始瀏覽媒體應用程式的內容庫,請先使用 getLibraryRoot()
擷取根節點:
Kotlin
// Get the library root to start browsing the library tree.
val rootFuture = mediaBrowser.getLibraryRoot(/* params= */ null)
rootFuture.addListener({
// Root node MediaItem is available here with rootFuture.get().value
}, MoreExecutors.directExecutor())
Java
// Get the library root to start browsing the library tree.
ListenableFuture<LibraryResult<MediaItem>> rootFuture =
mediaBrowser.getLibraryRoot(/* params= */ null);
rootFuture.addListener(() -> {
// Root node MediaItem is available here with rootFuture.get().value
}, MoreExecutors.directExecutor());
接著,您可以在程式庫中擷取 MediaItem
的子項,藉此瀏覽媒體庫。getChildren()
舉例來說,如要擷取根節點 MediaItem
的子項:
Kotlin
// Get the library root to start browsing the library tree.
val childrenFuture =
mediaBrowser.getChildren(rootMediaItem.mediaId, 0, Int.MAX_VALUE, null)
childrenFuture.addListener({
// List of children MediaItem nodes is available here with
// childrenFuture.get().value
}, MoreExecutors.directExecutor())
Java
ListenableFuture<LibraryResult<ImmutableList<MediaItem>>> childrenFuture =
mediaBrowser.getChildren(rootMediaItem.mediaId, 0, Integer.MAX_VALUE, null);
childrenFuture.addListener(() -> {
// List of children MediaItem nodes is available here with
// childrenFuture.get().value
}, MoreExecutors.directExecutor());
顯示其他媒體應用程式的播放控制項
顯示其他媒體應用程式的按鈕 UI 控制項時,請務必遵循該應用程式宣告的媒體按鈕偏好設定。
如要解決應用程式偏好設定、UI 限制和需求,最好的方法是使用 CommandButton.DisplayConstraints
。您可以定義 UI 的限制,resolve
方法會提供明確的按鈕清單,顯示按鈕的圖示、位置和預期動作。