1- نظرة عامة
سيعلّمك هذا الدرس التطبيقي حول الترميز كيفية تعديل تطبيق حالي على Android TV لإتاحة الإرسال والتواصل من تطبيقات الإرسال الحالية.
ما المقصود بتكنولوجيا Google Cast وCast Connect؟
يتيح Google Cast للمستخدمين إرسال المحتوى من جهاز جوّال إلى جهاز تلفزيون. تتألف جلسة Google Cast النموذجية من مكوّنين هما: المرسل وتطبيق المستلم. تبدأ تطبيقات المُرسِل، مثل تطبيق الجوّال أو موقع ويب، مثل YouTube.com، في تشغيل تطبيق مستقبِل Cast والتحكم فيه. تطبيقات جهاز استقبال الإرسال هي تطبيقات HTML 5 التي تعمل على أجهزة Chromecast وAndroid TV.
يتم تخزين كل أجزاء الحالة تقريبًا في جلسة الإرسال على تطبيق المستقبِل. عند تحديث الحالة، على سبيل المثال في حالة تحميل عنصر وسائط جديد، يتم بث حالة الوسائط لجميع المرسلين. تحتوي عمليات البث هذه على الحالة الحالية لجلسة البث. تستخدم تطبيقات المرسل حالة الوسائط هذه لعرض معلومات التشغيل في واجهة المستخدم.
يعتمد Cast Cast على هذه البنية الأساسية، حيث يعمل تطبيق Android TV كجهاز استقبال. تسمح مكتبة Cast Connect لتطبيق Android TV بتلقي الرسائل وبث حالة الوسائط كما لو كانت تطبيقًا لجهاز استقبال البث.
ما الذي سنبنيه؟
عند الانتهاء من هذا الدرس التطبيقي حول الترميز، ستتمكّن من استخدام تطبيقات "إرسال الإرسال" لإرسال الفيديوهات إلى تطبيق Android TV. ويمكن أيضًا لتطبيق Android TV التواصل مع تطبيقات المُرسِل من خلال بروتوكول الإرسال.
ما ستتعرَّف عليه
- كيفية إضافة مكتبة Cast Connect إلى نموذج تطبيق ATV.
- كيفية توصيل مُرسِل Cast وتشغيل تطبيق ATV.
- كيفية بدء تشغيل الوسائط على تطبيق ATV من تطبيق "إرسال الإرسال".
- كيفية إرسال حالة الوسائط من تطبيق ATV إلى تطبيقات "إرسال المُرسِل".
المتطلبات
- أحدث إصدار من Android SDK.
- أحدث إصدار من Android Studio.
Chipmunk | 2021.2.1
أو الإصدارات الأحدث تحديدًا. - جهاز Android TV تم تفعيل خيارات مطوّري البرامج عليه وتصحيح أخطاء USB
- هاتف يعمل بنظام التشغيل Android فعَّل خيارات المطوّرين وتصحيح أخطاء USB.
- كابل بيانات USB لتوصيل هاتف Android وأجهزة Android TV بجهاز كمبيوتر للتطوير.
- معرفة أساسية بتطوير تطبيقات Android باستخدام لغة Kotlin.
2- الحصول على نموذج الشفرة
يمكنك تنزيل كل نماذج الشفرة إلى جهاز الكمبيوتر...
وفكّ ضغط الملف المضغوط الذي تم تنزيله.
3. تشغيل نموذج التطبيق
لنرى أولاً كيف يبدو نموذج التطبيق المكتمل. يستخدم تطبيق Android TV واجهة مستخدم Leanback ومشغل الفيديو الأساسي. ويمكن للمستخدم اختيار فيديو من قائمة يتم تشغيلها بعد ذلك على التلفزيون عند اختياره. وباستخدام تطبيق المُرسِل المتوافق مع الأجهزة الجوّالة، يمكن للمستخدم أيضًا إرسال فيديو إلى تطبيق Android TV.
تسجيل أجهزة مطوّري البرامج
لتفعيل إمكانات Cast Connect لتطوير التطبيقات، يجب تسجيل الرقم التسلسلي لـ Chromecast المدمج في جهاز Android TV الذي ستستخدمه في وحدة تحكم مطوّري برامج Cast. يمكنك العثور على الرقم التسلسلي من خلال الانتقال إلى الإعدادات > الإعدادات المفضّلة للجهاز > Chromecast Built-in > الرقم التسلسلي على Android TV. لاحظ أن هذا الرقم يختلف عن الرقم التسلسلي للجهاز الفعلي ويجب الحصول عليه من الطريقة الموضحة أعلاه.
بدون التسجيل، لن يعمل Cast Connect إلا للتطبيقات التي تم تثبيتها من متجر Google Play لأسباب أمنية. بعد 15 دقيقة من بدء عملية التسجيل، أعد تشغيل الجهاز.
تثبيت تطبيق المُرسِل الذي يعمل بنظام التشغيل Android
لاختبار إرسال الطلبات من جهاز جوّال، قدّمنا تطبيقًا بسيطًا للمُرسِل يُسمى "إرسال الفيديوهات" كملف mobile-sender-0629.apk
في ملف zip للرمز المصدر. سنستفيد من ADB لتثبيت ملف APK. وإذا سبق لك تثبيت إصدار مختلف من مقاطع فيديو Cast، فالرجاء إزالة هذا الإصدار من جميع الملفات الشخصية الموجودة على الجهاز قبل المتابعة.
- مكِّن خيارات المطورين وتصحيح أخطاء USB على هاتف Android.
- وصِّل كابل بيانات USB لتوصيل هاتف Android بكمبيوتر التطوير.
- ثبِّت
mobile-sender-0629.apk
على هاتف Android.
- يمكنك العثور على تطبيق المُرسِل إرسال الفيديوهات على هاتف Android.
تثبيت تطبيق Android TV
توضح التعليمات التالية كيفية فتح نموذج التطبيق المكتمل وتشغيله في Android Studio:
- حدد استيراد المشروع على شاشة الترحيب أو خيارات القائمة ملف > جديد > استيراد المشروع....
- اختَر الدليل
app-done
من مجلد الرمز النموذجي وانقر على "حسنًا". - انقر على ملف >
مزامنة المشروع مع ملفات Gradle.
- مكِّن خيارات المطورين وتصحيح أخطاء USB على جهاز Android TV.
- يمكنك توصيل ADB مع جهاز Android TV، ومن المفترض أن يظهر الجهاز في Android Studio.
- انقر على الزر
تشغيل، من المفترض أن يظهر تطبيق ATV الذي يحمل اسم Cast Connect Codelab بعد بضع ثوانٍ.
هيا نشغِّل Cast Connect باستخدام تطبيق ATV
- انتقل إلى شاشة Android TV الرئيسية.
- افتح تطبيق مُرسِل فيديوهات Cast من هاتفك الذي يعمل بنظام التشغيل Android. انقر على زر الإرسال
واختَر جهاز ATV.
- سيتم تشغيل تطبيق Cast Code Codelab ATV على جهاز ATV، وسيشير زر الإرسال في المُرسِل إلى أنّه متّصل بـ
.
- اختَر فيديو من تطبيق ATV وسيبدأ تشغيل الفيديو على ATV.
- على هاتفك الجوّال، تظهر الآن وحدة تحكّم مصغّرة في الجزء السفلي من تطبيق المُرسِل. ويمكنك استخدام زر التشغيل/الإيقاف المؤقت للتحكم في التشغيل.
- اختَر فيديو من الهاتف الجوّال وشغِّله. سيبدأ تشغيل الفيديو على ATV وسيتم عرض وحدة التحكم الموسعة على مرسل الجوال.
- يمكنك قفل هاتفك وعند فتح قفله، من المفترض أن ترى إشعارًا على شاشة القفل للتحكم في تشغيل الوسائط أو إيقاف الإرسال.
4. إعداد المشروع الافتتاحي
الآن وبعد التحقُّق من دمج Cast Connect المكتمل للتطبيق، علينا إضافة الدعم إلى Cast Connect إلى التطبيق الذي تم تنزيله. أصبحت الآن جاهزًا للبدء في إنجاز المشروع الأول باستخدام Android Studio:
- حدد استيراد المشروع على شاشة الترحيب أو خيارات القائمة ملف > جديد > استيراد المشروع....
- اختَر الدليل
app-start
من مجلد الرمز النموذجي وانقر على "حسنًا". - انقر على ملف >
مزامنة المشروع مع ملفات Gradle.
- اختَر جهاز ATV وانقر على الزر
تشغيل لتشغيل التطبيق واستكشاف واجهة المستخدم.
تصميم التطبيقات
يوفر التطبيق قائمة بمقاطع الفيديو التي يمكن للمستخدم تصفحها. يمكن للمستخدمين اختيار فيديو لتشغيله على Android TV. يتكون التطبيق من نشاطين أساسيين: MainActivity
وPlaybackActivity
.
MainActivity
يحتوي هذا النشاط على جزء (MainFragment
). تم ضبط قائمة الفيديوهات والبيانات الوصفية المرتبطة بها في فئة MovieList
، ويتم استدعاء طريقة setupMovies()
لإنشاء قائمة تحتوي على Movie
كائنات.
يشير الكائن Movie
إلى كيان فيديو يتضمّن عنوانًا ووصفًا وصورًا مصغّرة رائعة وعنوان URL للفيديو. يتم ربط كل عنصر Movie
بـ CardPresenter
لتقديم صورة مصغّرة للفيديو مع عنوان واستوديو وتمريرها إلى ArrayObjectAdapter
.
عند اختيار عنصر، يتم تمرير الكائن Movie
المقابل إلى PlaybackActivity
.
نشاط التشغيل
يتضمن هذا النشاط جزءًا (PlaybackVideoFragment
) يستضيف VideoView
مع ExoPlayer
، وبعض عناصر التحكّم في الوسائط، ومساحة نصية لعرض وصف الفيديو المختار، ويسمح للمستخدم بتشغيل الفيديو على Android TV. ويمكن للمستخدم استخدام وحدة التحكم عن بُعد لتشغيل مقاطع الفيديو أو إيقافها مؤقتًا أو طلب تشغيل مقاطع الفيديو.
المتطلبات الأساسية لجهاز Cast Connect
يستخدم Cast Connect إصدارات جديدة من خدمات Google Play تتطلب تحديث تطبيق ATV لكي يستخدم مساحة الاسم 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
هي كائن فردي لتنسيق جميع تفاعلات الإرسال. يجب تنفيذ واجهة 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 من مُرسِل الإرسال، اختَر نشاطًا تريد تشغيله. في هذا الدرس التطبيقي حول الترميز، سنشغّل MainActivity
من التطبيق عند بدء جلسة "إرسال". في ملف AndroidManifest.xml
، أضِف فلتر الرغبة في الإطلاق في 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()
، CastReceiverContext
عند استئناف التطبيق وstop()
عند إيقاف التطبيق مؤقتًا:
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)
...
}
لنبدأ تشغيل نموذج التطبيق
انقر على الزر تشغيل لنشر التطبيق على جهاز ATV، ثم أغلِق التطبيق وعُد إلى الشاشة الرئيسية ATV. من المُرسِل، انقر على زر الإرسال
واختَر جهاز ATV. سيظهر لك أنّه تمّ تشغيل تطبيق ATV على جهاز ATV وأنّ حالة زر الإرسال متصلة.
6. جارٍ تحميل الوسائط
يتم إرسال أمر التحميل عبر intent باسم الحزمة الذي حدّدته في وحدة تحكم مطوّري البرامج. يجب إضافة فلتر الأهداف المحدّد مسبقًا التالي في تطبيق Android TV لتحديد النشاط المستهدف الذي سيتلقّى هدف intent هذا. في ملف 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
الآن وبعد تهيئة النشاط لاستلام هذه intent التي تحتوي على طلب تحميل، سنحتاج إلى التعامل معه.
يستدعي التطبيق طريقة خاصة تسمى processIntent
عند بدء النشاط. تحتوي هذه الطريقة على منطق معالجة الأهداف الواردة. لمعالجة طلب التحميل، سنعدّل هذه الطريقة ونرسل intent إلى مزيد من المعالجة من خلال استدعاء طريقة onNewIntent
لمثيل MediaManager
. إذا اكتشف MediaManager
أن الهدف هو طلب تحميل، فإنه يستخرج الكائن MediaLoadRequestData
من intent ويطلب MediaLoadCommandCallback.onLoad()
. عدّل طريقة processIntent
في ملف PlaybackVideoFragment.kt
للتعامل مع intent التي تحتوي على طلب التحميل:
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())
}
}
}
لنبدأ تشغيل نموذج التطبيق
انقر على الزر تشغيل لنشر التطبيق على جهاز ATV. من المُرسِل، انقر على زر الإرسال
واختَر جهاز ATV. سيتم تشغيل تطبيق ATV على جهاز ATV. اختَر فيديو على جهاز جوّال، وسيبدأ تشغيل الفيديو على ATV. تحقق مما إذا كنت تتلقى إشعارًا على هاتفك يتضمن عناصر التحكم في التشغيل. حاوِل استخدام عناصر التحكّم مثل الإيقاف المؤقت، ويجب إيقاف الفيديو مؤقتًا على جهاز ATV.
7. دعم أوامر التحكم في الإرسال
يتوافق التطبيق الحالي الآن مع الأوامر الأساسية التي تتوافق مع جلسة الوسائط، مثل التشغيل والإيقاف المؤقت والبحث. ومع ذلك، لا تتوفّر بعض أوامر التحكّم في البث في جلسة الوسائط. عليك تسجيل MediaCommandCallback
لدعم أوامر التحكّم في البث هذه.
إضافة MyMediaCommandCallback
إلى المثيل MediaManager
باستخدام setMediaCommandCallback
عند إعداد المشغّل:
private fun initializePlayer() {
...
castReceiverContext = CastReceiverContext.getInstance()
if (castReceiverContext != null) {
val mediaManager = castReceiverContext!!.mediaManager
...
mediaManager.setMediaCommandCallback(MyMediaCommandCallback())
}
}
يمكنك إنشاء فئة MyMediaCommandCallback
لإلغاء الطرق، مثل onQueueUpdate()
لدعم أوامر التحكّم في البث هذه:
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 الذي يعمل بتكنولوجيا Google Cast باستخدام مكتبة Cast Connect.
ويمكنك الاطّلاع على دليل مطوّري البرامج للحصول على مزيد من التفاصيل: /cast/docs/android_tv_receiver.