الفواصل الإعلانية
توفّر حزمة تطوير البرامج (SDK) لمرسل الرسائل على Android إمكانية استخدام الفواصل الإعلانية والإعلانات المصاحبة ضمن مجرى وسائط معيّن.
اطّلِع على نظرة عامة على الفواصل الإعلانية لمستقبل الويب للحصول على مزيد من المعلومات حول آلية عمل الفواصل الإعلانية.
على الرغم من أنّه يمكن تحديد الفواصل على كلّ من جهاز الإرسال وجهاز الاستقبال، إلا أنّه يُنصح تحديدها على Web Receiver و Android TV Receiver للحفاظ على سلوك متّسق على جميع المنصّات.
على Android، حدِّد الفواصل الإعلانية في أمر التحميل باستخدام
AdBreakClipInfo
وAdBreakInfo
:
val breakClip1: AdBreakClipInfo = AdBreakClipInfo.Builder("bc0") .setTitle("Clip title") .setPosterUrl("https://www.some.url") .setDuration(60000) .setWhenSkippableInMs(5000) // Set this field so that the ad is skippable .build() val breakClip2: AdBreakClipInfo = … val breakClip3: AdBreakClipInfo = … val break1: AdBreakClipInfo = AdBreakInfo.Builder(/* playbackPositionInMs= */ 10000) .setId("b0") .setBreakClipIds({"bc0","bc1","bc2"}) … .build() val mediaInfo: MediaInfo = MediaInfo.Builder() … .setAdBreaks({break1}) .setAdBreakClips({breakClip1, breakClip2, breakClip3}) .build() val mediaLoadRequestData: MediaLoadRequestData = MediaInfo.Builder() … .setMediaInfo(mediaInfo) .build() remoteMediaClient.load(mediaLoadRequestData)
AdBreakClipInfo breakClip1 = new AdBreakClipInfo.Builder("bc0") .setTitle("Clip title") .setPosterUrl("https://www.some.url") .setDuration(60000) .setWhenSkippableInMs(5000) // Set this field so that the ad is skippable .build(); AdBreakClipInfo breakClip2 = … AdBreakClipInfo breakClip3 = … AdBreakInfo break1 = new AdBreakInfo.Builder(/* playbackPositionInMs= */ 10000) .setId("b0") .setBreakClipIds({"bc0","bc1","bc2"}) … .build(); MediaInfo mediaInfo = new MediaInfo.Builder() … .setAdBreaks({break1}) .setAdBreakClips({breakClip1, breakClip2, breakClip3}) .build(); MediaLoadRequestData mediaLoadRequestData = new MediaInfo.Builder() … .setMediaInfo(mediaInfo) .build(); remoteMediaClient.load(mediaLoadRequestData);
إضافة إجراءات مخصّصة
يمكن لتطبيق المُرسِل توسيع نطاق استخدام
MediaIntentReceiver
لمعالجة الإجراءات المخصّصة أو إلغاء سلوكه. إذا نفّذت
MediaIntentReceiver
خاصًا بك، عليك إضافته إلى البيان، وضبط
اسمه أيضًا في CastMediaOptions
. يقدّم هذا المثال إجراءات مخصّصة تتجاوز تفعيل/إيقاف تشغيل الوسائط عن بُعد، والضغط على زر الوسائط وأنواع أخرى من الإجراءات.
// In AndroidManifest.xml
<receiver android:name="com.example.MyMediaIntentReceiver" />
// In your OptionsProvider var mediaOptions = CastMediaOptions.Builder() .setMediaIntentReceiverClassName(MyMediaIntentReceiver::class.java.name) .build() // Implementation of MyMediaIntentReceiver internal class MyMediaIntentReceiver : MediaIntentReceiver() { override fun onReceiveActionTogglePlayback(currentSession: Session) { } override fun onReceiveActionMediaButton(currentSession: Session, intent: Intent) { } override fun onReceiveOtherAction(context: Context?, action: String, intent: Intent) { } }
// In your OptionsProvider CastMediaOptions mediaOptions = new CastMediaOptions.Builder() .setMediaIntentReceiverClassName(MyMediaIntentReceiver.class.getName()) .build(); // Implementation of MyMediaIntentReceiver class MyMediaIntentReceiver extends MediaIntentReceiver { @Override protected void onReceiveActionTogglePlayback(Session currentSession) { } @Override protected void onReceiveActionMediaButton(Session currentSession, Intent intent) { } @Override protected void onReceiveOtherAction(Context context, String action, Intent intent) { } }
إضافة قناة مخصّصة
لكي يتواصل التطبيق المُرسِل مع التطبيق المُستلِم، يجب أن يُنشئ تطبيقك قناة مخصّصة. يمكن للمُرسِل استخدام القناة المخصّصة لإرسال سلاسل رسائل إلى المُستلِم. يتم تحديد كل قناة مخصّصة باستخدام اسم مساحة فريد
ويجب أن تبدأ بالبادئة urn:x-cast:
، على سبيل المثال،
urn:x-cast:com.example.custom
. من الممكن أن يكون لديك عدة قنوات
مخصّصة، ولكل منها مساحة اسم فريدة. يمكن أيضًا للتطبيق المستلِم
إرسال الرسائل واستلامها
باستخدام مساحة الاسم نفسها.
يتم تنفيذ القناة المخصّصة باستخدام واجهة
Cast.MessageReceivedCallback
:
class HelloWorldChannel : MessageReceivedCallback { val namespace: String get() = "urn:x-cast:com.example.custom" override fun onMessageReceived(castDevice: CastDevice, namespace: String, message: String) { Log.d(TAG, "onMessageReceived: $message") } }
class HelloWorldChannel implements Cast.MessageReceivedCallback { public String getNamespace() { return "urn:x-cast:com.example.custom"; } @Override public void onMessageReceived(CastDevice castDevice, String namespace, String message) { Log.d(TAG, "onMessageReceived: " + message); } }
بعد ربط التطبيق المرسِل بالتطبيق المستلِم، يمكن
إنشاء القناة المخصّصة باستخدام الأسلوب
setMessageReceivedCallbacks
:
try { mCastSession.setMessageReceivedCallbacks( mHelloWorldChannel.namespace, mHelloWorldChannel) } catch (e: IOException) { Log.e(TAG, "Exception while creating channel", e) }
try { mCastSession.setMessageReceivedCallbacks( mHelloWorldChannel.getNamespace(), mHelloWorldChannel); } catch (IOException e) { Log.e(TAG, "Exception while creating channel", e); }
بعد إنشاء القناة المخصّصة، يمكن للمُرسِل استخدام الوسيطة
sendMessage
لإرسال رسائل سلاسل إلى المستلِم عبر هذه القناة:
private fun sendMessage(message: String) { if (mHelloWorldChannel != null) { try { mCastSession.sendMessage(mHelloWorldChannel.namespace, message) .setResultCallback { status -> if (!status.isSuccess) { Log.e(TAG, "Sending message failed") } } } catch (e: Exception) { Log.e(TAG, "Exception while sending message", e) } } }
private void sendMessage(String message) { if (mHelloWorldChannel != null) { try { mCastSession.sendMessage(mHelloWorldChannel.getNamespace(), message) .setResultCallback( status -> { if (!status.isSuccess()) { Log.e(TAG, "Sending message failed"); } }); } catch (Exception e) { Log.e(TAG, "Exception while sending message", e); } } }
تفعيل ميزة التشغيل التلقائي
اطّلِع على قسم واجهات برمجة التطبيقات للتشغيل التلقائي وإضافة المحتوى إلى "قائمة المحتوى التالي".
إلغاء اختيار الصور للتطبيقات المصغّرة لتجربة المستخدم
ستعرض مكوّنات مختلفة من إطار العمل (أي مربّع حوار Cast ووحدة التحكّم المصغرة
وUIMediaController، في حال ضبطها على هذا النحو) العمل الفني
للوسائط التي يتم بثّها حاليًا. يتم عادةً
تضمين عناوين URL الخاصة بالعمل الفني للصورة في MediaMetadata
للوسائط، ولكن قد يتضمّن تطبيق المُرسِل
مصدرًا بديلاً لعناوين URL.
تحدِّد فئة
ImagePicker
وسيلة لاختيار صورة مناسبة من قائمة الصور
في MediaMetadata
، استنادًا إلى استخدام الصورة، على سبيل المثال، رمز مصغر للإشعار
أو خلفية ملء الشاشة. يختار التنفيذ التلقائي لImagePicker
دائمًا الصورة الأولى، أو يعرض قيمة فارغة إذا لم تتوفّر صورة في
MediaMetadata
. يمكن لتطبيقك إنشاء فئة فرعية من ImagePicker
وإلغاء طريقة
onPickImage(MediaMetadata, ImageHints)
لتوفير طريقة تنفيذ بديلة، ثم اختيار هذه الفئة الفرعية
باستخدام طريقة
setImagePicker
في CastMediaOptions.Builder
.
ImageHints
يقدّم تلميحات إلى ImagePicker
عن نوع الصورة وحجمها المطلوب
اختيارهما للعرض في واجهة المستخدم.
تخصيص مربّعات حوار "البث"
إدارة دورة حياة الجلسة
SessionManager
هو المكان المركزي لإدارة دورة حياة الجلسة. يستمع SessionManager
إلى Android
MediaRouter
لرصد التغييرات في حالة اختيار المسار لبدء الجلسات واستئنافها وإنهائها. عند تحديد مسار، سينشئ SessionManager
عنصر
Session
ويحاول تشغيله أو استئنافه. عند إلغاء اختيار مسار، يؤدي الرمز
SessionManager
إلى إنهاء الجلسة الحالية.
لذلك، لضمان أن يدير SessionManager
دورات حياة الجلسات بشكلٍ صحيح،
يجب التأكّد ممّا يلي:
- في مربّع حوار أداة اختيار المسار،
اطلب
MediaRouter.selectRoute(MediaRouter.RouteInfo)
عندما يختار المستخدم جهازًا. - في مربّع حوار وحدة التحكّم في المسار (إما في حالة الربط أو
حالة البث)،
اطلب
MediaRouter.unselect(int)
عندما يتوقف المستخدم عن البث.
استنادًا إلى كيفية إنشاء مربّعات حوار "البث"، قد تحتاج إلى تنفيذ إجراءات إضافية:
- إذا أنشأت مربّعات حوار لتطبيق Cast باستخدام
MediaRouteChooserDialog
وMediaRouteControllerDialog
، ستُحدِّث مربّعات الحوار هذه اختيار المسار فيMediaRouter
تلقائيًا، لذلك ليس عليك اتّخاذ أي إجراء. - إذا أعددت زرّ البث باستخدام
CastButtonFactory.setUpMediaRouteButton(Context, Menu, int)
أوCastButtonFactory.setUpMediaRouteButton(Context, MediaRouteButton)
، يتم إنشاء مربّعات الحوار باستخدامMediaRouteChooserDialog
وMediaRouteControllerDialog
، وبالتالي، لا يلزم اتخاذ أي إجراء أيضًا. - في الحالات الأخرى، ستُنشئ مربّعات حوار مخصّصة لبث الوسائط، لذا عليك
اتّباع التعليمات أعلاه لتعديل حالة اختيار المسار في
MediaRouter
.
حالة "ما مِن أجهزة"
في حال إنشاء مربّعات حوار مخصّصة لبث الوسائط، يجب أن يتعامل الرمز المخصّص
MediaRouteChooserDialog
بشكلٍ سليم مع حالة عدم العثور على أي أجهزة. يجب أن يتضمّن مربّع الحوار مؤشرات توضّح للمستخدمين متى كان
تطبيقك لا يزال يحاول العثور على الأجهزة ومتى لم تعُد محاولة الاكتشاف فعالة.
إذا كنت تستخدم الإجراء التلقائي MediaRouteChooserDialog
، سبق أن تم التعامل مع حالة عدم توفّر أي أجهزة.
الخطوات التالية
تنتهي هذه المقالة بعرض الميزات التي يمكنك إضافتها إلى تطبيق المُرسِل المتوافق مع Android. يمكنك الآن إنشاء تطبيق مُرسِل لنظام أساسي آخر (iOS أو الويب)، أو إنشاء تطبيق مُستلِم على الويب.