الربط بتطبيق وسائط

يتفاعل عنصر التحكّم في الوسائط مع جلسة وسائط للاستعلام عن تشغيل تطبيق وسائط والتحكّم فيه. في Media3، تنفّذ واجهة برمجة التطبيقات MediaController الواجهة Player. في ما يلي أمثلة على تطبيقات العميل التي تستخدم أداة تحكّم في الوسائط:

يمكن أن يكون عنصر التحكّم في الوسائط مفيدًا أيضًا داخل تطبيق وسائط، مثلاً إذا كان مشغّل الوسائط وجلسة الوسائط في 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

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 عندما لا تكون هناك حاجة إليه، مثلاً في طريقة onStop() الخاصة بـ Activity أو Fragment.

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());

عرض عناصر التحكّم في التشغيل لتطبيق وسائط آخر

عند عرض عناصر تحكّم في واجهة المستخدم تتضمّن أزرارًا لتطبيق وسائط آخر، من المهم اتّباع إعدادات أزرار الوسائط المحدّدة لهذا التطبيق.

أفضل طريقة لحلّ المشاكل المتعلقة بإعدادات التطبيق المفضّلة والقيود والمتطلبات الخاصة بواجهة المستخدم هي استخدام CommandButton.DisplayConstraints. يمكنك تحديد حدود وقيود لما يمكن أن تفعله واجهة المستخدم، كما توفّر الطريقة resolve قائمة محددة بالأزرار التي سيتم عرضها مع الرمز والموضع والإجراء المقصود.