الفواصل الإعلانية
توفِّر حزمة تطوير البرامج (SDK) لأداة Android Sender دعم الفواصل الإعلانية والإعلانات المصاحبة ضمن بث وسائط معيّن.
يمكنك الاطّلاع على نظرة عامة على الفواصل الإعلانية في أجهزة استقبال الويب لمزيد من المعلومات حول طريقة عمل الفواصل الإعلانية.
يمكن تحديد الفواصل على كلّ من المرسِل والمستلِم، ولكن يُنصح بتحديدها في جهاز الاستقبال على الويب وجهاز استقبال Android TV للحفاظ على سلوك متّسق على مختلف الأنظمة الأساسية.
على نظام التشغيل 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)
عندما يتوقف المستخدم عن البث.
بناءً على طريقة إنشاء مربّعات حوار البث، قد تحتاج إلى تنفيذ إجراءات إضافية:
- إذا أنشأت مربعات حوار "البث" باستخدام
MediaRouteChooserDialog
وMediaRouteControllerDialog
، ستعدّل مربّعات الحوار هذه اختيار المسار في "MediaRouter
" تلقائيًا، لذا لن تحتاج إلى اتخاذ أي إجراء. - في حال إعداد زر البث باستخدام
CastButtonFactory.setUpMediaRouteButton(Context, Menu, int)
أوCastButtonFactory.setUpMediaRouteButton(Context, MediaRouteButton)
، سيتم إنشاء مربّعات الحوار باستخدامMediaRouteChooserDialog
وMediaRouteControllerDialog
، لذا لن تحتاج إلى تنفيذ أي إجراء أيضًا. - في الحالات الأخرى، سيتم إنشاء مربعات حوار مخصصة للبث، لذا يجب اتباع الإرشادات الواردة أعلاه لتعديل حالة اختيار المسار في
MediaRouter
.
حالة الأجهزة الصفرية
إذا أنشأت مربّعات حوار مخصّصة للبث، يجب أن يتعامل MediaRouteChooserDialog
المخصّص على نحو سليم مع حالة عدم العثور على أي أجهزة. ويجب أن يشتمل مربع الحوار على مؤشرات توضّح للمستخدمين ما إذا كان تطبيقك لا يزال يحاول العثور على أجهزة أو عندما تتوقف محاولة الاكتشاف عن العمل.
إذا كنت تستخدم خيار MediaRouteChooserDialog
التلقائي، يعني ذلك أنّه سبق أن تم التعامل مع حالة "صفر أجهزة".
الخطوات التالية
بهذه الطريقة، ستحصل على الميزات التي يمكنك إضافتها إلى تطبيق Android Sender. يمكنك الآن إنشاء تطبيق مُرسِل لنظام أساسي آخر (iOS أو Web)، أو إنشاء تطبيق WebRecipient.