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