1. סקירה כללית
בשיעור הזה תלמדו איך לשנות אפליקציה קיימת ל-Android TV כדי לתמוך בהעברה (cast) ובתקשורת מהאפליקציות הקיימות של שולחי Cast.
מה זה Google Cast ו-Cast Connect?
Google Cast מאפשר למשתמשים להעביר (cast) תוכן ממכשיר נייד לטלוויזיה. סשן טיפוסי של Google Cast כולל שני רכיבים – אפליקציה של שולח ואפליקציה של המקבל. אפליקציות של השולחים, כמו אפליקציה לנייד או אתר כמו youtube.com, יכולות להפעיל אפליקציה של מקלט Cast ולשלוט בה. אפליקציות של מקלט Cast הן אפליקציות HTML 5 שפועלות במכשירי Chromecast ו-Android TV.
כמעט כל המצב של סשן ההעברה מאוחסן באפליקציה המקבלת. כשהמצב מתעדכן, לדוגמה אם נטען פריט מדיה חדש, סטטוס מדיה משודר לכל השולחים. השידורים האלה כוללים את המצב הנוכחי של סשן ההעברה. אפליקציות שולח משתמשות בסטטוס מדיה זה כדי להציג פרטי הפעלה בממשק המשתמש שלהן.
התכונה Cast Connect מתבססת על התשתית הזו, ואפליקציית Android TV משמשת כמקלטת. ספריית Cast Connect מאפשרת לאפליקציית Android TV לקבל הודעות ולשדר סטטוס מדיה כאילו היא אפליקציית cast.
מה אנחנו מתכוונים לבנות?
בסיום ה-Codelab, תהיה לך אפשרות להשתמש באפליקציות של שולחי Cast כדי להעביר (cast) סרטונים לאפליקציה Android TV. האפליקציה ל-Android TV יכולה גם לתקשר עם אפליקציות של שולחים באמצעות פרוטוקול Cast.
מה תלמדו
- איך להוסיף את הספרייה של Cast Connect לאפליקציה לדוגמה של ATV.
- איך לחבר שולח העברה ולהפעיל את אפליקציית ATV
- איך להפעיל מדיה באפליקציית ATV דרך אפליקציית שולח Cast.
- איך לשלוח סטטוס מדיה מאפליקציית ATV לאפליקציות שולח של Cast.
מה הדרישות כדי להצטרף לתוכנית?
- Android SDK העדכני ביותר.
- הגרסה העדכנית ביותר של Android Studio. באופן ספציפי, יש
Chipmunk | 2021.2.1
גרסאות ואילך. - מכשיר Android TV שהופעל בו אפשרויות למפתחים וניפוי באגים ב-USB.
- טלפון Android שהופעל בו אפשרויות למפתחים וניפוי באגים ב-USB.
- כבל נתונים בחיבור USB לצורך חיבור טלפון Android ומכשירי Android TV למחשב הפיתוח.
- ידע בסיסי בפיתוח אפליקציות Android באמצעות Kotlin.
2. לקבלת הקוד לדוגמה
אפשר להוריד את כל הקוד לדוגמה למחשב...
ופורקים את קובץ ה-ZIP שהורד.
3. הפעלת האפליקציה לדוגמה
קודם נראה איך נראית האפליקציה לדוגמה שהושלמה. אפליקציית Android TV משתמשת בממשק המשתמש של Terraform ובנגן וידאו בסיסי. המשתמש יכול לבחור סרטון מרשימה שתופעל בטלוויזיה לאחר הבחירה באפשרות הזו. באמצעות אפליקציית השולח הנלווית לנייד, משתמש יכול גם להעביר סרטון לאפליקציית Android TV.
רישום מכשירים למפתחים
כדי להפעיל יכולות של Cast Connect לפיתוח אפליקציות, עליך לרשום את המספר הסידורי של ה-Chromecast המובנה של מכשיר ה-Android TV שבו בכוונתך להשתמש ב-Cast Developer Console. ניתן למצוא את המספר הסידורי על ידי מעבר אל הגדרות > העדפות מכשיר > Chromecast Built-In > מספר סידורי ב-Android TV. לתשומת ליבכם, המספר הזה שונה מהמספר הסידורי של המכשיר הפיזי. צריך לקבל אותו בשיטה המתוארת למעלה.
ללא רישום, Cast Connect יפעל רק באפליקציות שהותקנו מחנות Google Play מטעמי אבטחה. אחרי 15 דקות מתחילת תהליך הרישום, צריך להפעיל מחדש את המכשיר.
התקנת אפליקציית השולח ב-Android
כדי לבדוק בקשות שליחה ממכשיר נייד, סיפקנו אפליקציית שולח פשוטה שנקראת "cast סרטונים" בתור קובץ 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.
- בטלפון Android, פותחים את אפליקציית השולח של העברת סרטונים. לוחצים על לחצן הפעלת Cast ובוחרים את מכשיר ה-ATV.
- אפליקציית ה-ATV של Cast Connect Codelab תופעל ב-ATV, ולחצן הפעלת Cast בשולח יציין שהוא מחובר .
- בוחרים סרטון מאפליקציית ATV והסרטון יתחיל לפעול ב-ATV.
- בטלפון הנייד, מיני שלט רחוק גלוי עכשיו בחלק התחתון של אפליקציית השולח. אפשר להשתמש בלחצן 'הפעלה/השהיה' כדי לשלוט בהפעלה.
- בוחרים סרטון מהטלפון הנייד ומפעילים אותו. הסרטון יתחיל לפעול ב-ATV והבקר המורחב יוצג בנייד.
- נועלים את הטלפון וכשמבטלים את הנעילה, אמורה להופיע התראה במסך הנעילה כדי לשלוט בהפעלה של מדיה או להפסיק את ההעברה.
4. הכנת הפרויקט להתחלה
לאחר אימות השילוב של Cast Connect עם האפליקציה, עלינו להוסיף תמיכה ב-Cast Connect לאפליקציית ההתחלה שהורדת. עכשיו אתם מוכנים להשתמש ב-Android Studio כדי להוסיף ולבנות פרויקטים חדשים באמצעות Android Studio:
- בוחרים באפשרות ייבוא פרויקט במסך הפתיחה או באפשרויות התפריט קובץ > חדש > ייבוא פרויקט....
- בוחרים את הספרייה
app-start
מתיקיית הקוד לדוגמה ולוחצים על 'אישור'. - לוחצים על קובץ > סנכרון פרויקט עם קובצי Gradle.
- בוחרים מכשיר ATV ולוחצים על הלחצן Run (הפעלה) כדי להפעיל את האפליקציה ולחקור את ממשק המשתמש.
עיצוב אפליקציות
האפליקציה מספקת רשימה של סרטונים שהמשתמש יכול לעיין בהם. המשתמשים יכולים לבחור סרטון להפעלה ב-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 Services, שכדי להשתמש בהן במרחב השמות AndroidX, צריך לעדכן את אפליקציית ה-ATV.
כדי לתמוך ב-Cast Connect באפליקציית Android TV, עליך ליצור אירועים מתוך סשן מדיה ולתמוך בהם. ספריית Cast Connect יוצרת סטטוס מדיה על סמך הסטטוס של הסשן במדיה. ספריית Cast Connect משמשת גם את ספריית Cast Connect כדי לאותת מתי התקבלו הודעות מסוימות משולח, למשל, השהיה.
5. הגדרת התמיכה ב-Cast
יחסי תלות
צריך לעדכן את קובץ האפליקציה 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'
}
צריך לסנכרן את הפרויקט כדי לאשר את גרסאות ה-build של הפרויקט ללא שגיאות.
אתחול
CastReceiverContext
הוא אובייקט singleton לתיאום כל האינטראקציות של ההעברה. עליך ליישם את הממשק 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 משולח ההעברה, בוחרים פעילות שרוצים להפעיל. ב-Codelab הזה, נפעיל את 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>
מחזור החיים של הקשר מקלט העברה (cast)
צריך להפעיל את CastReceiverContext
כשהאפליקציה מופעלת ולהפסיק את CastReceiverContext
כשהאפליקציה מועברת לרקע. מומלץ להשתמש ב-LifecycleObserver
מספריית androidx.lifecycle כדי לנהל את השיחות אל CastReceiverContext.start()
ואל CastReceiverContext.stop()
פותחים את הקובץ MyApplication.kt
, מפעילים את ההקשר להעברה (cast) על ידי קריאה ל-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
בגלל הפעלה לא פעילה, צריך להגדיר אסימון null ב-MediaManager
:
private fun releasePlayer() {
mMediaSession?.release()
castReceiverContext?.mediaManager?.setSessionCompatToken(null)
...
}
שנפעיל את האפליקציה לדוגמה?
לוחצים על הלחצן הפעלה כדי לפרוס את האפליקציה במכשיר ה-ATV, לסגור אותה ולחזור למסך הבית של ATV. מהשולח, לוחצים על לחצן הפעלת Cast ובוחרים את מכשיר ה-ATV שלכם. תוכלו לראות שאפליקציית ATV מופעלת במכשיר ה-ATV ומצב לחצן הפעלת Cast מחובר.
6. המדיה בטעינה
פקודת הטעינה נשלחת באמצעות Intent עם שם החבילה שהגדרתם ב-Play Console. צריך להוסיף לאפליקציה ל-Android TV את מסנן Intent שהוגדר מראש, כדי לציין את פעילות היעד שמקבלת את ה-Intent הזה. בקובץ AndroidManifest.xml
, יש להוסיף את מסנן Intent הטעינה אל 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
כשהפעילות מתחילה. השיטה הזו כוללת את הלוגיקה לעיבוד אובייקטים נכנסים. כדי לטפל בבקשת טעינה, נשנה את השיטה הזו ונשלח את הכוונה להמשך עיבוד על ידי קריאה לשיטת 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. מהשולח, לוחצים על לחצן הפעלת Cast ובוחרים את מכשיר ה-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
כשמופעלת קריאה חוזרת (callback) של 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. מזל טוב
עכשיו אתה יודע איך להפעיל העברה (cast) לאפליקציה ל-Android TV באמצעות ספריית Cast Connect.
לפרטים נוספים, כדאי לעיין במדריך למפתחים: /cast/docs/android_tv_receiver.