دو روش برای اتصال به برنامه «رسانه» وجود دارد:
MediaControllerMediaBrowser
MediaController
کنترلکننده رسانه با جلسه رسانه تعامل برقرار میکند تا بازپخش برنامه رسانه را پُرسمان و کنترل کند. در Media3، میانای برنامهسازی کاربردی MediaController میانای Player را پیادهسازی میکند. نمونههایی از برنامههای کارخواه که از کنترلکننده رسانه استفاده میکنند عبارتند از:
- کنترلهای رسانه سیستم Android
- برنامه همراه Android Wear OS
- Android Auto و Automotive OS
- دستیارهای صوتی، مثل دستیار Google
- برنامه Media Controller Test
کنترلکننده رسانه میتواند در برنامه رسانه نیز مفید باشد، برای مثال اگر
پخشکننده و جلسه رسانه در Service جدا از Activity یا
Fragment با میانای کاربر قرار داشته باشند.
ایجاد MediaController
برای ایجاد MediaController، ابتدا SessionToken را برای MediaSession مربوطه ایجاد کنید. روش onStart() Activity یا
Fragment میتواند جای خوبی برای این کار باشد.
کاتلین
val sessionToken = SessionToken(context, ComponentName(context, PlaybackService::class.java))
جاوا
SessionToken sessionToken = new SessionToken(context, new ComponentName(context, PlaybackService.class));
استفاده از این SessionToken برای ساختن MediaController، کنترلکننده را به جلسه دادهشده متصل میکند. این کار بهصورت ناهمگام انجام میشود، بنابراین باید
منتظر نتیجه بمانید و وقتی دردسترس بود از آن استفاده کنید.
کاتلین
val controllerFuture = MediaController.Builder(context, sessionToken).buildAsync() controllerFuture.addListener( { // MediaController is available here with controllerFuture.get() }, MoreExecutors.directExecutor(), )
جاوا
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 تنظیم کرد:
کاتلین
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()
جاوا
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();
As with other components, remember to release the MediaController when it is
no longer needed, such as in the onStop() method of an Activity or
Fragment.
کاتلین
MediaController.releaseFuture(controllerFuture)
جاوا
MediaController.releaseFuture(controllerFuture);
با رها کردن کنترلکننده، همه فرمانهای معلق ارسالشده به جلسه همچنان تحویل داده میشود و فقط پساز رسیدگی به این فرمانها یا پساز دوره مهلت (هرکدام زودتر اتفاق بیفتد)، اتصال از سرویس جلسه قطع میشود.
MediaBrowser
MediaBrowser بر قابلیتهای ارائهشده توسط MediaController ساخته میشود تا مرور کتابخانه رسانهای ارائهشده توسط MediaLibraryService برنامه رسانه را نیز فعال کند.
ایجاد MediaBrowser
کاتلین
val browserFuture = MediaBrowser.Builder(context, sessionToken).buildAsync() browserFuture.addListener( { // MediaBrowser is available here with browserFuture.get() }, MoreExecutors.directExecutor(), )
جاوا
ListenableFuture<MediaBrowser> browserFuture = new MediaBrowser.Builder(context, sessionToken).buildAsync(); browserFuture.addListener( () -> { // MediaBrowser is available here with browserFuture.get() }, MoreExecutors.directExecutor());
استفاده از MediaBrowser
برای شروع مرور کتابخانه محتوای برنامه رسانه، ابتدا گره ریشه را با getLibraryRoot() بازیابی کنید:
کاتلین
// 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(), )
جاوا
// 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:
کاتلین
// 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(), )
جاوا
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());
نمایش کنترلهای بازپخش برای برنامه رسانهای دیگر
هنگام نمایش کنترلهای میانای کاربر با دکمههایی برای برنامه رسانه دیگر، مهم است که از اولویتهای دکمه رسانه اعلامشده آن برنامه پیروی کنید.
برای حل کردن اولویتهای برنامه با محدودیتها و الزامات
رابط کاربری، از CommandButton.DisplayConstraints استفاده کنید. میتوانید حدود و محدودیتهای کارهایی را که میانای کاربریتان میتواند انجام دهد تعریف کنید، و روش resolve() فهرست مشخصی از دکمهها را برای نمایش با نماد، موقعیت، و کنش موردنظرشان ارائه میدهد. اگر کاربر روی یکی از این دکمهها کلیک کند، میتوانید از
CommandButton.executeAction برای راهاندازی کنش مرتبط در برنامه
رسانه استفاده کنید.
کاتلین
// 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) }, ) }
جاوا
// 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)); }