1. نظرة عامة

سيعلّمك هذا الدرس التطبيقي حول الترميز كيفية تعديل تطبيق Android TV حالي لإتاحة البث والتواصل من تطبيقات البث الحالية.
ما هما Google Cast وCast Connect؟
تتيح تكنولوجيا Google Cast للمستخدمين بث المحتوى من جهاز جوّال إلى التلفزيون. تتألف جلسة Google Cast النموذجية من مكوّنين، وهما تطبيق المرسِل وتطبيق المستلِم. تبدأ تطبيقات المرسِل، مثل تطبيق على جهاز جوّال أو موقع إلكتروني مثل Youtube.com، عملية تشغيل تطبيق جهاز الاستقبال Cast وتتحكّم فيها. تطبيقات استقبال البث هي تطبيقات HTML 5 تعمل على أجهزة Chromecast وAndroid TV.
يتم تخزين جميع حالات جلسة Cast تقريبًا في تطبيق الجهاز المستقبِل. عند تعديل الحالة، مثلاً إذا تم تحميل عنصر وسائط جديد، يتم إرسال حالة الوسائط إلى جميع أجهزة الإرسال. تحتوي عمليات البث هذه على الحالة الحالية لجلسة البث. تستخدم تطبيقات المرسِل حالة الوسائط هذه لعرض معلومات التشغيل في واجهة المستخدم.
تستند ميزة Cast Connect إلى هذه البنية الأساسية، حيث يعمل تطبيق Android TV كجهاز استقبال. تتيح مكتبة Cast Connect لتطبيق Android TV تلقّي الرسائل وبث حالة الوسائط كما لو كان تطبيقًا لاستقبال البث.
ما الذي سنقوم بإنشائه؟
بعد إكمال هذا الدرس التطبيقي حول الترميز، ستتمكّن من استخدام تطبيقات مُرسِل البث لإرسال الفيديوهات إلى تطبيق Android TV. ويمكن لتطبيق Android TV أيضًا التواصل مع تطبيقات المُرسِل من خلال بروتوكول Cast.
أهداف الدورة التعليمية
- كيفية إضافة مكتبة Cast Connect إلى نموذج تطبيق ATV
- كيفية ربط جهاز إرسال Cast وتشغيل تطبيق ATV
- كيفية بدء تشغيل الوسائط على تطبيق Android TV من تطبيق إرسال متوافق مع ميزة "الإرسال"
- كيفية إرسال حالة الوسائط من تطبيق Android TV إلى تطبيقات الإرسال في Cast
المتطلبات
- أحدث إصدار من حزمة تطوير البرامج (SDK) لنظام التشغيل Android
- أحدث إصدار من استوديو Android على وجه التحديد، الإصدار
Chipmunk | 2021.2.1أو الإصدارات الأحدث. - جهاز Android TV تم تفعيل خيارات المطوّرين وتصحيح أخطاء الجهاز عبر USB عليه
- هاتف Android تم تفعيل خيارات المطوّرين وتصحيح أخطاء الجهاز عبر USB عليه
- كابل بيانات USB لتوصيل هاتف Android وأجهزة Android TV بجهاز الكمبيوتر المخصّص للتطوير
- معرفة أساسية بتطوير تطبيقات Android باستخدام لغة Kotlin
2. الحصول على الرمز النموذجي
يمكنك تنزيل كل الرموز النموذجية على جهاز الكمبيوتر...
وفكّ ضغط ملف ZIP الذي تم تنزيله.
3- تشغيل نموذج التطبيق
لنبدأ بالاطّلاع على الشكل الذي سيبدو عليه نموذج التطبيق المكتمل. يستخدم تطبيق Android TV واجهة مستخدم Leanback ومشغّل فيديو أساسيًا. يمكن للمستخدم اختيار فيديو من قائمة ثم تشغيله على التلفزيون. باستخدام تطبيق الإرسال المتوافق مع الأجهزة الجوّالة، يمكن للمستخدم أيضًا بث فيديو إلى تطبيق Android TV.

تسجيل أجهزة المطوّرين
لتفعيل إمكانات Cast Connect لتطوير التطبيقات، يجب تسجيل الرقم التسلسلي لجهاز Android TV الذي سيتم استخدامه في Cast Developer Console. يمكنك العثور على الرقم التسلسلي من خلال الانتقال إلى الإعدادات > إعدادات الجهاز > Google Cast > الرقم التسلسلي على Android TV. يُرجى العِلم أنّ هذا الرقم يختلف عن الرقم التسلسلي لجهازك الفعلي ويجب الحصول عليه من خلال الطريقة الموضّحة أعلاه.

بدون التسجيل، لن تعمل ميزة Cast Connect إلا مع التطبيقات المثبَّتة من "متجر Google Play" لأسباب تتعلّق بالأمان. بعد 15 دقيقة من بدء عملية التسجيل، أعِد تشغيل جهازك.
تثبيت تطبيق المرسِل على جهاز Android
لاختبار إرسال الطلبات من جهاز جوّال، وفّرنا تطبيق إرسال بسيطًا باسم Cast Videos كملف mobile-sender-0629.apk في حزمة zip التي يمكن تنزيلها من رمز المصدر. سنستخدم أداة تصحيح أخطاء Android (ADB) لتثبيت حزمة APK. إذا سبق لك تثبيت إصدار مختلف من تطبيق "بث الفيديوهات"، يُرجى إلغاء تثبيت هذا الإصدار من جميع الملفات الشخصية على الجهاز قبل المتابعة.
- فعِّل خيارات المطوّرين وتصحيح أخطاء الجهاز عبر USB على هاتف Android.
- وصِّل كابل بيانات USB لتوصيل هاتف Android بجهاز الكمبيوتر المخصّص للتطوير.
- ثبِّت تطبيق
mobile-sender-0629.apkعلى هاتف Android.

- يمكنك العثور على تطبيق الإرسال بثّ الفيديوهات على هاتف Android.


تثبيت تطبيق Android TV
توضّح التعليمات التالية كيفية فتح نموذج التطبيق المكتمل وتشغيله في "استوديو Android":
- اختَر استيراد مشروع (Import Project) من شاشة الترحيب أو خيارات القائمة ملف (File) > جديد (New) > استيراد مشروع (Import Project)....
- اختَر الدليل

app-doneمن مجلد نموذج الرمز البرمجي وانقر على "حسنًا". - انقر على ملف >
مزامنة المشروع مع ملفات Gradle. - فعِّل خيارات المطوّرين وتصحيح أخطاء الجهاز عبر USB على جهاز Android TV.
- اربط ADB بجهاز Android TV، وسيظهر الجهاز في استوديو Android.

- انقر على الزر
تشغيل، وسيظهر تطبيق Android TV باسم Cast Connect Codelab بعد بضع ثوانٍ.
لنلعب Cast Connect باستخدام تطبيق ATV
- انتقِل إلى الشاشة الرئيسية في Android TV.
- افتح تطبيق إرسال الفيديوهات على هاتف Android. انقر على زر "البث"
واختَر جهاز Apple TV. - سيتم تشغيل تطبيق Cast Connect Codelab على Android TV، وسيشير زر "البث" في جهاز الإرسال إلى أنّه متصل
. - اختَر فيديو من تطبيق ATV وسيبدأ تشغيله على جهاز ATV.
- على هاتفك الجوّال، يظهر الآن جهاز تحكّم مصغّر في أسفل تطبيق المرسِل. ويمكنك استخدام زر التشغيل/الإيقاف المؤقت للتحكّم في التشغيل.
- اختَر فيديو من الهاتف الجوّال وشغِّله. سيبدأ تشغيل الفيديو على جهاز ATV وسيتم عرض وحدة التحكّم الموسّعة على جهازك الجوّال.
- اقفل هاتفك، وعند فتح قفله، من المفترض أن يظهر إشعار على شاشة القفل للتحكّم في تشغيل الوسائط أو إيقاف البث.

4. إعداد مشروع البدء
بعد أن تحقّقنا من اكتمال عملية دمج تطبيق Cast Connect، علينا إضافة إمكانية استخدام Cast Connect إلى تطبيق البداية الذي نزّلته. أنت الآن جاهز للبناء على أساس المشروع المبدئي باستخدام "استوديو Android":
- اختَر استيراد مشروع (Import Project) من شاشة الترحيب أو خيارات القائمة ملف (File) > جديد (New) > استيراد مشروع (Import Project)....
- اختَر الدليل

app-startمن مجلد نموذج الرمز البرمجي وانقر على "حسنًا". - انقر على ملف >
مزامنة المشروع مع ملفات Gradle. - اختَر جهاز ATV وانقر على الزر
تشغيل لتشغيل التطبيق واستكشاف واجهة المستخدم. 

تصميم التطبيقات
يوفّر التطبيق قائمة بالفيديوهات يمكن للمستخدم تصفّحها. يمكن للمستخدمين اختيار فيديو لتشغيله على Android TV. يتألف التطبيق من نشاطَين رئيسيَّين: MainActivity وPlaybackActivity.
MainActivity
يحتوي هذا النشاط على جزء (MainFragment). يتم إعداد قائمة الفيديوهات والبيانات الوصفية المرتبطة بها في الفئة MovieList ويتم استدعاء الطريقة setupMovies() لإنشاء قائمة بعناصر Movie.
يمثّل العنصر Movie كيان فيديو يتضمّن عنوانًا ووصفًا وصورًا مصغّرة وعنوان URL للفيديو. يرتبط كل عنصر Movie بعنصر CardPresenter لعرض الصورة المصغّرة للفيديو مع العنوان والاستوديو، ويتم تمريره إلى ArrayObjectAdapter.
عند اختيار عنصر، يتم تمرير عنصر Movie المقابل إلى PlaybackActivity.
PlaybackActivity
يحتوي هذا النشاط على جزء (PlaybackVideoFragment) يستضيف VideoView مع ExoPlayer وبعض أدوات التحكّم في الوسائط ومساحة نصية لعرض وصف الفيديو المحدّد والسماح للمستخدم بتشغيل الفيديو على Android TV. يمكن للمستخدم استخدام جهاز التحكّم عن بُعد لتشغيل الفيديوهات أو إيقافها مؤقتًا أو تقديمها وترجيعها.
المتطلبات الأساسية لاستخدام ميزة Cast Connect
تستخدم ميزة Cast Connect إصدارات جديدة من "خدمات Google Play" تتطلّب تحديث تطبيق Android TV لاستخدام مساحة الاسم AndroidX.
لاستخدام Cast Connect في تطبيق Android TV، عليك إنشاء أحداث من جلسة وسائط وإتاحتها. تنشئ مكتبة Cast Connect حالة الوسائط استنادًا إلى حالة جلسة الوسائط. تستخدم مكتبة Cast Connect أيضًا جلسة الوسائط للإشارة إلى وقت تلقّي رسائل معيّنة من المُرسِل، مثل الإيقاف المؤقت.
5. ضبط إعدادات ميزة "البث"
الاعتمادية
عدِّل ملف build.gradle الخاص بالتطبيق لتضمين المكتبات اللازمة التي يعتمد عليها التطبيق:
dependencies {
....
// Cast Connect libraries
implementation 'com.google.android.gms:play-services-cast-tv:20.0.0'
implementation 'com.google.android.gms:play-services-cast:21.1.0'
}
زامِن المشروع للتأكّد من إمكانية إنشائه بدون أخطاء.
الإعداد
CastReceiverContext هو عنصر فردي لتنسيق جميع تفاعلات Cast. يجب تنفيذ واجهة ReceiverOptionsProvider لتوفير CastReceiverOptions عند تهيئة CastReceiverContext.
أنشئ ملف CastReceiverOptionsProvider.kt وأضِف الفئة التالية إلى المشروع:
package com.google.sample.cast.castconnect
import android.content.Context
import com.google.android.gms.cast.tv.ReceiverOptionsProvider
import com.google.android.gms.cast.tv.CastReceiverOptions
class CastReceiverOptionsProvider : ReceiverOptionsProvider {
override fun getOptions(context: Context): CastReceiverOptions {
return CastReceiverOptions.Builder(context)
.setStatusText("Cast Connect Codelab")
.build()
}
}
بعد ذلك، حدِّد موفِّر خيارات جهاز الاستقبال ضمن العلامة <application> في ملف AndroidManifest.xml للتطبيق:
<application>
...
<meta-data
android:name="com.google.android.gms.cast.tv.RECEIVER_OPTIONS_PROVIDER_CLASS_NAME"
android:value="com.google.sample.cast.castconnect.CastReceiverOptionsProvider" />
</application>
لربط تطبيق ATV بجهاز الإرسال الذي يعمل بتكنولوجيا Cast، اختَر نشاطًا تريد تشغيله. في هذا الدرس العملي، سنطلق MainActivity التطبيق عند بدء جلسة Cast. في ملف AndroidManifest.xml، أضِف فلتر intent في MainActivity.
<activity android:name=".MainActivity">
...
<intent-filter>
<action android:name="com.google.android.gms.cast.tv.action.LAUNCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
دورة حياة سياق جهاز استقبال البث
يجب بدء CastReceiverContext عند تشغيل تطبيقك وإيقافه عند نقل تطبيقك إلى الخلفية.CastReceiverContext ننصحك باستخدام LifecycleObserver من مكتبة androidx.lifecycle لإدارة استدعاء CastReceiverContext.start() وCastReceiverContext.stop().
افتح ملف MyApplication.kt، وابدأ سياق البث من خلال استدعاء initInstance() في طريقة onCreate للتطبيق. في فئة AppLifeCycleObserver، يتم استدعاء start() عند استئناف التطبيق، ويتم استدعاء stop() عند إيقاف التطبيق مؤقتًا:CastReceiverContext
package com.google.sample.cast.castconnect
import com.google.android.gms.cast.tv.CastReceiverContext
...
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
CastReceiverContext.initInstance(this)
ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifecycleObserver())
}
class AppLifecycleObserver : DefaultLifecycleObserver {
override fun onResume(owner: LifecycleOwner) {
Log.d(LOG_TAG, "onResume")
CastReceiverContext.getInstance().start()
}
override fun onPause(owner: LifecycleOwner) {
Log.d(LOG_TAG, "onPause")
CastReceiverContext.getInstance().stop()
}
}
}
ربط MediaSession بـ MediaManager
MediaManager هي سمة من سمات العنصر الفردي CastReceiverContext، وتدير حالة الوسائط، وتتعامل مع نية التحميل، وتحوّل رسائل مساحة اسم الوسائط من المُرسِلين إلى أوامر وسائط، وتعيد حالة الوسائط إلى المُرسِلين.
عند إنشاء MediaSession، عليك أيضًا تقديم الرمز المميز الحالي MediaSession إلى MediaManager لكي يعرف المكان الذي يجب إرسال الأوامر إليه واسترداد حالة تشغيل الوسائط منه. في ملف PlaybackVideoFragment.kt، تأكَّد من تهيئة MediaSession قبل ضبط الرمز المميّز على MediaManager.
import com.google.android.gms.cast.tv.CastReceiverContext
import com.google.android.gms.cast.tv.media.MediaManager
...
class PlaybackVideoFragment : VideoSupportFragment() {
private var castReceiverContext: CastReceiverContext? = null
...
private fun initializePlayer() {
if (mPlayer == null) {
...
mMediaSession = MediaSessionCompat(getContext(), LOG_TAG)
...
castReceiverContext = CastReceiverContext.getInstance()
if (castReceiverContext != null) {
val mediaManager: MediaManager = castReceiverContext!!.getMediaManager()
mediaManager.setSessionCompatToken(mMediaSession!!.getSessionToken())
}
}
}
}
عند تحرير MediaSession بسبب عدم تشغيل المحتوى، يجب ضبط رمز مميّز فارغ على MediaManager:
private fun releasePlayer() {
mMediaSession?.release()
castReceiverContext?.mediaManager?.setSessionCompatToken(null)
...
}
لننفِّذ تطبيق العيّنة
انقر على الزر
تشغيل لنشر التطبيق على جهاز Android TV، ثم أغلق التطبيق وارجع إلى الشاشة الرئيسية في Android TV. من جهاز الإرسال، انقر على زر "البث"
واختَر جهاز Android TV. سيظهر لك أنّه تم تشغيل تطبيق Android TV على جهاز Android TV وأنّ حالة زر "البث" هي "متصل".
6. جارٍ تحميل الوسائط
يتم إرسال أمر التحميل من خلال هدف مع اسم الحزمة الذي حدّدته في "وحدة تحكّم المطوّر". عليك إضافة فلتر الأهداف المحدّد مسبقًا التالي في تطبيق Android TV لتحديد النشاط المستهدف الذي سيتلقّى هذا الهدف. في ملف AndroidManifest.xml، أضِف فلتر الأهداف إلى PlayerActivity:
<activity android:name="com.google.sample.cast.castconnect.PlaybackActivity"
android:launchMode="singleTask"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.cast.tv.action.LOAD"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
التعامل مع طلبات التحميل على Android TV
بعد ضبط النشاط لتلقّي هذه النية التي تتضمّن طلب تحميل، علينا معالجتها.
يستدعي التطبيق طريقة خاصة باسم processIntent عند بدء النشاط. تحتوي هذه الطريقة على منطق معالجة الأهداف الواردة. للتعامل مع طلب تحميل، سنعدّل هذه الطريقة ونرسل الغرض ليتمّت معالجته بشكل أكبر من خلال استدعاء طريقة onNewIntent في مثيل MediaManager. إذا رصدت MediaManager أنّ الغرض هو طلب تحميل، فإنّها تستخرج العنصر MediaLoadRequestData من الغرض وتستدعي MediaLoadCommandCallback.onLoad(). عدِّل طريقة processIntent في الملف PlaybackVideoFragment.kt للتعامل مع الغرض الذي يتضمّن طلب التحميل:
fun processIntent(intent: Intent?) {
val mediaManager: MediaManager = CastReceiverContext.getInstance().getMediaManager()
// Pass intent to Cast SDK
if (mediaManager.onNewIntent(intent)) {
return
}
// Clears all overrides in the modifier.
mediaManager.getMediaStatusModifier().clear()
// If the SDK doesn't recognize the intent, handle the intent with your own logic.
...
}
بعد ذلك، سنوسّع الفئة المجردة MediaLoadCommandCallback التي ستتجاوز الطريقة onLoad() التي يستدعيها MediaManager. يتلقّى هذا الإجراء بيانات طلب التحميل ويحوّلها إلى عنصر Movie. بعد التحويل، يتم تشغيل الفيلم باستخدام مشغّل الفيديو المحلي. بعد ذلك، يتم تعديل MediaManager باستخدام MediaLoadRequest وبث MediaStatus إلى أجهزة الإرسال المرتبطة. أنشئ فئة خاصة متداخلة باسم MyMediaLoadCommandCallback في الملف PlaybackVideoFragment.kt:
import com.google.android.gms.cast.MediaLoadRequestData
import com.google.android.gms.cast.MediaInfo
import com.google.android.gms.cast.MediaMetadata
import com.google.android.gms.cast.MediaError
import com.google.android.gms.cast.tv.media.MediaException
import com.google.android.gms.cast.tv.media.MediaCommandCallback
import com.google.android.gms.cast.tv.media.QueueUpdateRequestData
import com.google.android.gms.cast.tv.media.MediaLoadCommandCallback
import com.google.android.gms.tasks.Task
import com.google.android.gms.tasks.Tasks
import android.widget.Toast
...
private inner class MyMediaLoadCommandCallback : MediaLoadCommandCallback() {
override fun onLoad(
senderId: String?, mediaLoadRequestData: MediaLoadRequestData): Task<MediaLoadRequestData> {
Toast.makeText(activity, "onLoad()", Toast.LENGTH_SHORT).show()
return if (mediaLoadRequestData == null) {
// Throw MediaException to indicate load failure.
Tasks.forException(MediaException(
MediaError.Builder()
.setDetailedErrorCode(MediaError.DetailedErrorCode.LOAD_FAILED)
.setReason(MediaError.ERROR_REASON_INVALID_REQUEST)
.build()))
} else Tasks.call {
play(convertLoadRequestToMovie(mediaLoadRequestData)!!)
// Update media metadata and state
val mediaManager = castReceiverContext!!.mediaManager
mediaManager.setDataFromLoad(mediaLoadRequestData)
mediaLoadRequestData
}
}
}
private fun convertLoadRequestToMovie(mediaLoadRequestData: MediaLoadRequestData?): Movie? {
if (mediaLoadRequestData == null) {
return null
}
val mediaInfo: MediaInfo = mediaLoadRequestData.getMediaInfo() ?: return null
var videoUrl: String = mediaInfo.getContentId()
if (mediaInfo.getContentUrl() != null) {
videoUrl = mediaInfo.getContentUrl()
}
val metadata: MediaMetadata = mediaInfo.getMetadata()
val movie = Movie()
movie.videoUrl = videoUrl
movie.title = metadata?.getString(MediaMetadata.KEY_TITLE)
movie.description = metadata?.getString(MediaMetadata.KEY_SUBTITLE)
if(metadata?.hasImages() == true) {
movie.cardImageUrl = metadata.images[0].url.toString()
}
return movie
}
بعد تحديد دالة معاودة الاتصال، علينا تسجيلها في MediaManager. يجب تسجيل دالة معاودة الاتصال قبل استدعاء MediaManager.onNewIntent(). أضِف setMediaLoadCommandCallback عند تهيئة المشغّل:
private fun initializePlayer() {
if (mPlayer == null) {
...
mMediaSession = MediaSessionCompat(getContext(), LOG_TAG)
...
castReceiverContext = CastReceiverContext.getInstance()
if (castReceiverContext != null) {
val mediaManager: MediaManager = castReceiverContext.getMediaManager()
mediaManager.setSessionCompatToken(mMediaSession.getSessionToken())
mediaManager.setMediaLoadCommandCallback(MyMediaLoadCommandCallback())
}
}
}
لننفِّذ تطبيق العيّنة
انقر على الزر
تشغيل لنشر التطبيق على جهاز Android TV. من جهاز الإرسال، انقر على زر "البث"
واختَر جهاز Android TV. سيتم تشغيل تطبيق ATV على جهاز ATV. اختَر فيديو على جهازك الجوّال، وسيبدأ تشغيله على جهاز Apple TV. تحقَّق ممّا إذا كنت تتلقّى إشعارًا على هاتفك يتضمّن عناصر التحكّم في التشغيل. جرِّب استخدام عناصر التحكّم، مثل الإيقاف المؤقت، ويجب إيقاف الفيديو مؤقتًا على جهاز Apple TV.
7. إتاحة طلبات التحكّم في البث
يتيح التطبيق الحالي الآن استخدام الأوامر الأساسية المتوافقة مع جلسة الوسائط، مثل التشغيل والإيقاف المؤقت والبحث. ومع ذلك، هناك بعض أوامر التحكّم في البث غير متاحة في جلسة الوسائط. يجب تسجيل MediaCommandCallback لاستخدام أوامر التحكّم هذه في Cast.
أضِف MyMediaCommandCallback إلى مثيل MediaManager باستخدام setMediaCommandCallback عند تهيئة المشغّل:
private fun initializePlayer() {
...
castReceiverContext = CastReceiverContext.getInstance()
if (castReceiverContext != null) {
val mediaManager = castReceiverContext!!.mediaManager
...
mediaManager.setMediaCommandCallback(MyMediaCommandCallback())
}
}
أنشئ فئة MyMediaCommandCallback لتجاوز الطرق، مثل onQueueUpdate()، من أجل إتاحة أوامر التحكّم في Cast التالية:
private inner class MyMediaCommandCallback : MediaCommandCallback() {
override fun onQueueUpdate(
senderId: String?,
queueUpdateRequestData: QueueUpdateRequestData
): Task<Void> {
Toast.makeText(getActivity(), "onQueueUpdate()", Toast.LENGTH_SHORT).show()
// Queue Prev / Next
if (queueUpdateRequestData.getJump() != null) {
Toast.makeText(
getActivity(),
"onQueueUpdate(): Jump = " + queueUpdateRequestData.getJump(),
Toast.LENGTH_SHORT
).show()
}
return super.onQueueUpdate(senderId, queueUpdateRequestData)
}
}
8. العمل باستخدام حالة الوسائط
تعديل حالة الوسائط
يحصل Cast Connect على حالة الوسائط الأساسية من جلسة الوسائط. لإتاحة الميزات المتقدّمة، يمكن لتطبيق Android TV تحديد سمات حالة إضافية وتجاوزها من خلال MediaStatusModifier. ستعمل MediaStatusModifier دائمًا على MediaSession الذي ضبطته في CastReceiverContext.
على سبيل المثال، لتحديد setMediaCommandSupported عند تشغيل دالة ردّ الاتصال onLoad:
import com.google.android.gms.cast.MediaStatus
...
private class MyMediaLoadCommandCallback : MediaLoadCommandCallback() {
fun onLoad(
senderId: String?,
mediaLoadRequestData: MediaLoadRequestData
): Task<MediaLoadRequestData> {
Toast.makeText(getActivity(), "onLoad()", Toast.LENGTH_SHORT).show()
...
return Tasks.call({
play(convertLoadRequestToMovie(mediaLoadRequestData)!!)
...
// Use MediaStatusModifier to provide additional information for Cast senders.
mediaManager.getMediaStatusModifier()
.setMediaCommandSupported(MediaStatus.COMMAND_QUEUE_NEXT, true)
.setIsPlayingAd(false)
mediaManager.broadcastMediaStatus()
// Return the resolved MediaLoadRequestData to indicate load success.
mediaLoadRequestData
})
}
}
اعتراض MediaStatus قبل إرساله
على غرار MessageInterceptor في حزمة تطوير البرامج (SDK) الخاصة بمستقبل الويب، يمكنك تحديد MediaStatusWriter في MediaManager لإجراء تعديلات إضافية على MediaStatus قبل بثّه إلى أجهزة الإرسال المرتبطة.
على سبيل المثال، يمكنك ضبط بيانات مخصّصة في MediaStatus قبل إرسالها إلى مرسلي الرسائل على الأجهزة الجوّالة:
import com.google.android.gms.cast.tv.media.MediaManager.MediaStatusInterceptor
import com.google.android.gms.cast.tv.media.MediaStatusWriter
import org.json.JSONObject
import org.json.JSONException
...
private fun initializePlayer() {
if (mPlayer == null) {
...
if (castReceiverContext != null) {
...
val mediaManager: MediaManager = castReceiverContext.getMediaManager()
...
// Use MediaStatusInterceptor to process the MediaStatus before sending out.
mediaManager.setMediaStatusInterceptor(
MediaStatusInterceptor { mediaStatusWriter: MediaStatusWriter ->
try {
mediaStatusWriter.setCustomData(JSONObject("{myData: 'CustomData'}"))
} catch (e: JSONException) {
Log.e(LOG_TAG,e.message,e);
}
})
}
}
}
9- تهانينا
أصبحت الآن على دراية بكيفية تفعيل ميزة الإرسال في تطبيق Android TV باستخدام مكتبة Cast Connect.
يمكنك الاطّلاع على دليل المطوّرين لمزيد من التفاصيل: /cast/docs/android_tv_receiver.