يتفاعل جهاز التحكّم في الوسائط مع جلسة وسائط لطلب تشغيل تطبيق وسائط والتحكّم فيه. في Media3، تُنفِّذ واجهة برمجة التطبيقات MediaController
واجهة Player
. تشمل أمثلة التطبيقات العميلة التي تستخدم وحدة تحكّم في الوسائط ما يلي:
- عناصر التحكّم في الوسائط في نظام Android
- تطبيق مصاحب لنظام التشغيل Android Wear OS
- Android Auto ونظام التشغيل Automotive
- أدوات المساعدة الصوتية، مثل مساعد Google
- تطبيق اختبار وحدة التحكّم بالوسائط
يمكن أن يكون جهاز التحكّم في الوسائط مفيدًا أيضًا في تطبيق وسائط، على سبيل المثال إذا كان
مشغّل الوسائط وجلسة الوسائط معروضَين في 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
قائمة محدّدة بالأزرار التي يمكن عرضها مع رمزها وموقعها والإجراء المقصود.