יש שתי דרכים להתחבר לאפליקציית מדיה:
MediaControllerMediaBrowser
MediaController
ממשק השליטה במדיה מקיים אינטראקציה עם סשן מדיה כדי לשלוח שאילתות לגבי ההפעלה של אפליקציית מדיה ולשלוט בה. ב-Media3, ממשק ה-API MediaController מטמיע את הממשק Player. דוגמאות לאפליקציות לקוח שמשתמשות בממשק השליטה במדיה:
- אמצעי בקרה למדיה במערכת Android
- אפליקציה נלווית ל-Android Wear OS
- Android Auto ו-Automotive OS
- עוזרים קוליים, כמו Google Assistant
- אפליקציית הבדיקה של אמצעי הבקרה של המדיה
בנוסף, כדאי להשתמש בממשק השליטה במדיה באפליקציות מדיה, למשל אם נגן המדיה והסשן של המדיה נמצאים ב-Service נפרד מ-Activity או מ-Fragment עם ממשק המשתמש.
צור MediaController
כדי ליצור MediaController, קודם צריך ליצור SessionToken בשביל MediaSession התואם. אפשר להשתמש בשיטה onStart() של Activity או Fragment.
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 המחובר.
כלומר, אם קוראים ל-play() ב-MediaController, הפקודה תישלח ל-MediaSession המחובר, שיעביר את הפקודה ל-Player הבסיסי שלו.
אפשר להוסיף Player.Listener לבקר כדי להאזין לשינויים במצב Player. פרטים נוספים על השימוש ב-Player.Listener זמינים במדריך בנושא אירועים של נגן.
ממשק MediaController.Listener מגדיר קריאות חוזרות נוספות לאירועים ולפקודות בהתאמה אישית מ-MediaSession המקושר. לדוגמה:
onCustomCommand() כשהסשן שולח פקודה מותאמת אישית,
onAvailableSessionCommandsChanged() כשהסשן משנה את הפקודות הזמינות בסשן או onDisconnected() כשהבקר מתנתק מהסשן.
אפשר להגדיר MediaController.Listener כשיוצרים את בקר באמצעות Builder:
Kotlin
val controllerFuture = 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
ListenableFuture<MediaController> controllerFuture = 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 כשאין בו יותר צורך, למשל בשיטה onStop() של Activity או Fragment.
Kotlin
MediaController.releaseFuture(controllerFuture)
Java
MediaController.releaseFuture(controllerFuture);
שחרור הבקר עדיין יעביר את כל הפקודות בהמתנה שנשלחו לסשן, והוא יבטל את הקישור משירות הסשן רק אחרי שהפקודות האלה יטופלו או אחרי תקופת המתנה, לפי המוקדם מביניהם.
MediaBrowser
MediaBrowser מבוסס על היכולות שמציע MediaController, וגם מאפשר לגלוש בספריית המדיה שמציע MediaLibraryService של אפליקציית מדיה.
צור MediaBrowser
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());
שימוש ב-MediaBrowser
כדי להתחיל לעיין בספריית התוכן של אפליקציית המדיה, קודם צריך לאחזר את צומת הבסיס באמצעות 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 להפעלה של אפליקציית מדיה אחרת
כשמציגים אמצעי בקרה בממשק המשתמש עם לחצנים לאפליקציית מדיה אחרת, חשוב לפעול בהתאם להעדפות לחצני המדיה שהוגדרו באפליקציה הזו.
כדי לפתור את הבעיות בהעדפות האפליקציה בהתאם למגבלות ולדרישות של ממשק המשתמש, אפשר להשתמש ב-CommandButton.DisplayConstraints. אתם יכולים להגדיר את המגבלות וההגבלות של ממשק המשתמש שלכם, והשיטה resolve() מספקת רשימה מוגדרת של לחצנים להצגה עם הסמל, המיקום והפעולה המיועדת שלהם. אם משתמש לוחץ על אחד מהלחצנים האלה, אפשר להשתמש ב-CommandButton.executeAction כדי להפעיל את הפעולה המשויכת באפליקציית המדיה.
Kotlin
// Get media button preferences from media app val mediaButtonPreferences = controller.getMediaButtonPreferences() // Declare constraints of UI (example: limit overflow button to one) val displayConstraints = DisplayConstraints.Builder().setMaxButtonsForSlot(CommandButton.SLOT_OVERFLOW, 1).build() // Resolve media app preferences with constraints val resolvedButtons = displayConstraints.resolve(mediaButtonPreferences, controller) // Display buttons in UI for (button in resolvedButtons) { generateUiButton( uiPosition = button.slots[0], icon = getIconRes(button.icon), onClick = { button.executeAction(controller) }, ) }
Java
// Get media button preferences from media app List<CommandButton> mediaButtonPreferences = controller.getMediaButtonPreferences(); // Declare constraints of UI (example: limit overflow button to one) DisplayConstraints displayConstraints = new DisplayConstraints.Builder() .setMaxButtonsForSlot(CommandButton.SLOT_OVERFLOW, 1) .build(); // Resolve media app preferences with constraints List<CommandButton> resolvedButtons = displayConstraints.resolve(mediaButtonPreferences, controller); // Display buttons in UI for (CommandButton button : resolvedButtons) { generateUiButton( /* uiPosition= */ button.slots.get(0), /* icon= */ getIconRes(button.icon), /* onClick= */ () -> button.executeAction(controller)); }