הפסקות למודעות
Android Sender SDK מספק תמיכה בהפסקות פרסומות ובמודעות נלוות בתוך סטרימינג של מדיה.
מידע נוסף על אופן הפעולה של הפסקות הפרסום זמין במאמר בנושא סקירה כללית על הפסקות פרסום ב-Web Receiver.
אפשר לציין הפסקות גם בצד השולח וגם בצד המקבל, אבל מומלץ לציין אותן ב-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); } } }
תמיכה בהפעלה אוטומטית
מידע נוסף זמין בקטע ממשקי API של הפעלה אוטומטית והוספה לתור.
ביטול הבחירה של תמונות בווידג'טים של UX
רכיבים שונים של framework (בעיקר תיבת הדו-שיח של Cast, בקר המיני ובקר המדיה של ממשק המשתמש, אם הם מוגדרים כך) יציגו פוסטר של המדיה שמופעלת כרגע באמצעות Cast. כתובות ה-URL של הגרפיקה של התמונה בדרך כלל כלולות ב-MediaMetadata של המדיה, אבל יכול להיות שלאפליקציה השולחת יש מקור חלופי לכתובות ה-URL.
המחלקות
ImagePicker
מגדירות אמצעי לבחירת תמונה מתאימה מתוך רשימת התמונות
ב-MediaMetadata, על סמך השימוש בתמונה, לדוגמה, תמונה ממוזערת של התראה או רקע למסך מלא. ההטמעה של ImagePicker כברירת מחדל
תמיד בוחרת את התמונה הראשונה, או מחזירה null אם אין תמונה ב-
MediaMetadata. האפליקציה יכולה ליצור מחלקת משנה של ImagePicker ולבטל את השיטה onPickImage(MediaMetadata, ImageHints) כדי לספק הטמעה חלופית, ואז לבחור את מחלקת המשנה הזו באמצעות השיטה setImagePicker של CastMediaOptions.Builder.
ImageHints
מספק רמזים ל-ImagePicker לגבי הסוג והגודל של תמונה שצריך
לבחור להצגה בממשק המשתמש.
התאמה אישית של תיבות דו-שיח של Cast
ניהול מחזור החיים של סשן
SessionManager
הוא המקום המרכזי לניהול מחזור החיים של הסשן. SessionManager listens
to Android
MediaRouter
route selection state changes to start, resume and end sessions. כשבוחרים מסלול, SessionManager יוצר אובייקט Session ומנסה להתחיל אותו או להמשיך אותו. כשמבטלים את הבחירה במסלול,SessionManager הסשן הנוכחי יסתיים.
לכן, כדי לוודא ש-SessionManager מנהל את מחזורי החיים של הסשנים בצורה תקינה, צריך לוודא ש:
- בתיבת הדו-שיח של בורר המסלולים,
מתקשרים
אל
MediaRouter.selectRoute(MediaRouter.RouteInfo)כשמשתמש בוחר מכשיר. - בתיבת הדו-שיח של בקר המסלול (במצב מחובר או במצב הפעלה של Cast), קוראים ל-
MediaRouter.unselect(int)כשהמשתמש מפסיק את ה-Cast.
בהתאם לאופן שבו יוצרים את תיבות הדו-שיח של Cast, יכול להיות שיהיה צורך לבצע פעולות נוספות:
- אם אתם יוצרים תיבות דו-שיח של Cast באמצעות
MediaRouteChooserDialogו-MediaRouteControllerDialog, אז בחירת הנתיב ב-MediaRouterתתעדכן אוטומטית, ולא צריך לעשות כלום. - אם הגדרתם את הכפתור להפעלת Cast באמצעות
CastButtonFactory.setUpMediaRouteButton(Context, Menu, int)אוCastButtonFactory.setUpMediaRouteButton(Context, MediaRouteButton), התיבות הדו-שיח נוצרות באמצעותMediaRouteChooserDialogו-MediaRouteControllerDialog, כך שאין צורך לעשות דבר. - במקרים אחרים, תיצרו תיבות דו-שיח מותאמות אישית להעברה (Cast), ולכן תצטרכו לפעול לפי ההוראות שלמעלה כדי לעדכן את מצב בחירת המסלול ב-
MediaRouter.
Zero Devices State
אם יוצרים תיבות דו-שיח מותאמות אישית להעברה (Cast), צריך לוודא שהפונקציה המותאמת אישית
MediaRouteChooserDialog מטפלת בצורה נכונה במקרה שבו לא נמצאו מכשירים. בתיבת הדו-שיח צריכים להיות אינדיקטורים שיבהירו למשתמשים מתי האפליקציה עדיין מנסה למצוא מכשירים ומתי הניסיון לאיתור כבר לא פעיל.
אם אתם משתמשים ב-MediaRouteChooserDialog שמוגדר כברירת מחדל, המצב של אפס מכשירים כבר מטופל.
השלבים הבאים
בשלב הזה סיימנו להוסיף את התכונות לאפליקציית השולט ל-Android. עכשיו אפשר ליצור אפליקציית שולט לפלטפורמה אחרת (iOS או אינטרנט), או ליצור אפליקציית מקלט לאינטרנט.