1. סקירה כללית
בקודלאב הזה תלמדו איך לשנות אפליקציית Android TV קיימת כך שתתמוך בהעברה (cast) ובתקשורת מאפליקציות Cast קיימות לשליחת תוכן.
מה זה Google Cast ו-Cast Connect?
מערכת Google Cast מאפשרת למשתמשים להעביר תוכן מטלפון נייד לטלוויזיה. סשן Google Cast אופייני מורכב משני רכיבים – אפליקציית שליחה ואפליקציית קבלה. אפליקציות של שולחים, כמו אפליקציה לנייד או אתר כמו Youtube.com, מתחילות את ההפעלה של אפליקציית מקלט העברה ומנהלות אותה. אפליקציות לאפליקציות Cast הן אפליקציות HTML 5 שפועלות במכשירי Chromecast ו-Android TV.
כמעט כל המצבים בסשן העברה (cast) מאוחסנים באפליקציית המכשיר המקבל. כשהמצב מתעדכן, למשל אם נטען פריט מדיה חדש, סטטוס המדיה מופץ לכל השולחים. השידורים האלה כוללים את המצב הנוכחי של סשן הפעלת Cast. אפליקציות של שולחים משתמשות בסטטוס המדיה הזה כדי להציג את פרטי ההפעלה בממשק המשתמש שלהן.
Cast Connect מבוסס על התשתית הזו, ואפליקציית Android TV פועלת כמקלט. ספריית Cast Connect מאפשרת לאפליקציה ל-Android TV לקבל הודעות ולשדר את סטטוס המדיה כאילו היא אפליקציית מקלט Cast.
מה אנחנו הולכים ליצור?
בסיום הקודלאב הזה, תוכלו להשתמש באפליקציות לשליחת תוכן ב-Cast כדי להעביר סרטונים לאפליקציה ל-Android TV. אפליקציית Android TV יכולה גם לתקשר עם אפליקציות לשליחת תוכן באמצעות פרוטוקול Cast.
מה תלמדו
- איך להוסיף את ספריית Cast Connect לאפליקציית ATV לדוגמה.
- איך מחברים מכשיר להעברת תוכן (cast) ומפעילים את אפליקציית 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 משתמשת בממשק המשתמש של Leanback ובנגן וידאו בסיסי. המשתמש יכול לבחור סרטון מרשימה שיופעל בטלוויזיה, אם הוא ייבחר. באמצעות אפליקציית השליחה לנייד, המשתמש יכול גם להעביר (cast) סרטון לאפליקציית Android TV.
רישום מכשירים למפתחים
כדי להפעיל את היכולות של Cast Connect לפיתוח אפליקציות, צריך לרשום את המספר הסידורי של ה-Chromecast המובנה במכשיר Android TV שבו אתם מתכוונים להשתמש במסוף הפיתוח של Cast. כדי למצוא את המספר הסידורי, עוברים אל הגדרות > העדפות המכשיר > Chromecast מובנה > מספר סידורי ב-Android TV. לתשומת ליבכם, זהו מספר שונה מהמספר הסידורי של המכשיר הפיזי, וצריך לקבל אותו בשיטה שמתוארת למעלה.
ללא רישום, Cast Connect יפעל רק באפליקציות שהותקנו מחנות Google Play, מטעמי אבטחה. אחרי 15 דקות מתחילת תהליך הרישום, מפעילים מחדש את המכשיר.
התקנת אפליקציית השליחה ל-Android
כדי לבדוק את שליחת הבקשות ממכשיר נייד, סיפקנו אפליקציית שליחה פשוטה בשם Cast Videos כקובץ mobile-sender-0629.apk
בהורדת קובץ ה-zip של קוד המקור. אנחנו נשתמש ב-ADB כדי להתקין את ה-APK. אם כבר התקנתם גרסה אחרת של Cast Videos, עליכם להסיר את הגרסה הזו מכל הפרופילים שנמצאים במכשיר לפני שתמשיכו.
- מפעילים את האפשרויות למפתחים ואת ניפוי הבאגים ב-USB בטלפון Android.
- מחברים כבל נתונים בחיבור USB כדי לחבר את טלפון Android למחשב הפיתוח.
- מתקינים את
mobile-sender-0629.apk
בטלפון Android.
- ניתן למצוא את אפליקציית השולח של הפעלת Cast של סרטונים בטלפון Android.
התקנת האפליקציה ל-Android TV
בהוראות הבאות מוסבר איך לפתוח ולהריץ את אפליקציית הדוגמה המושלמת ב-Android Studio:
- בוחרים באפשרות Import Project (ייבוא פרויקט) במסך הפתיחה או באפשרויות התפריט File > New > Import Project… (קובץ > חדש > ייבוא פרויקט…).
- בוחרים את הספרייה
app-done
מתיקיית הקוד לדוגמה ולוחצים על 'אישור'. - לוחצים על File (קובץ) > Sync Project with Gradle Files (סנכרון הפרויקט עם קובצי Gradle).
- מפעילים את האפשרויות למפתחים ואת ניפוי הבאגים ב-USB במכשיר Android TV.
- ADB connect עם מכשיר Android TV, המכשיר אמור להופיע ב-Android Studio.
- לוחצים על הלחצן Run (הפעלה). האפליקציה ל-ATV בשם Cast Connect Codelab אמורה להופיע אחרי כמה שניות.
רוצה להפעיל Cast Connect עם אפליקציית ATV?
- עוברים אל מסך הבית של Android TV.
- פותחים את אפליקציית השליחה של סרטוני Cast בטלפון Android. לוחצים על הלחצן להפעלת Cast ובוחרים את מכשיר ה-ATV.
- אפליקציית Cast Connect של Codelab ATV תופעל ב-ATV ולחצן הפעלת Cast אצל השולח יציין שהיא מחוברת .
- בוחרים סרטון מאפליקציית ATV והסרטון יתחיל לפעול ב-ATV.
- בטלפון הנייד שלכם ניתן לראות מיני-בקר בחלק התחתון של אפליקציית השולח. אפשר להשתמש בלחצן ההפעלה וההשהיה כדי לשלוט בהפעלה.
- בוחרים סרטון מהטלפון הנייד ומפעילים אותו. הסרטון יתחיל לפעול ב-ATV והשליטה המורחבת תוצג במכשיר השולח בנייד.
- נועלים את הטלפון. כשמבטלים את הנעילה, אמורה להופיע התראה במסך הנעילה כדי לשלוט בהפעלת המדיה או להפסיק את ההעברה (cast).
4. הכנת פרויקט ההתחלה
עכשיו, לאחר שאימתנו את שילוב Cast Connect של האפליקציה שהושלם, עלינו להוסיף תמיכה ב-Cast Connect לאפליקציית ההפעלה שהורדת. עכשיו אתם מוכנים לפתח את הפרויקט באמצעות Android Studio:
- בוחרים באפשרות ייבוא פרויקט במסך הפתיחה או באפשרויות התפריט קובץ > חדש > ייבוא פרויקט….
- בוחרים את הספרייה
app-start
מתיקיית הקוד לדוגמה ולוחצים על 'אישור'. - לוחצים על File (קובץ) > Sync Project with Gradle Files (סנכרון הפרויקט עם קובצי Gradle).
- בוחרים מכשיר ATV ולוחצים על הלחצן Run כדי להפעיל את האפליקציה ולעיין בממשק המשתמש.
עיצוב אפליקציות
האפליקציה מספקת רשימה של סרטונים שהמשתמשים יכולים לעיין בהם. המשתמשים יכולים לבחור סרטון להפעלה ב-Android TV. האפליקציה מורכבת משתי פעילויות עיקריות: MainActivity
ו-PlaybackActivity
.
MainActivity
פעילות זו מכילה מקטע (MainFragment
). רשימת הסרטונים והמטא-נתונים המשויכים אליהם מוגדרים במחלקה MovieList
וה-method setupMovies()
מופעלת ליצירת רשימה של Movie
אובייקטים.
אובייקט Movie
מייצג ישות של סרטון עם כותרת, תיאור, תמונות ממוזערות וכתובת URL של הסרטון. כל אובייקט Movie
מקושר ל-CardPresenter
כדי להציג את התמונה הממוזערת של הסרטון עם השם והאולפן, והוא מועבר אל ArrayObjectAdapter
.
כשנבחר פריט, אובייקט ה-Movie
התואם מועבר ל-PlaybackActivity
.
PlaybackActivity
הפעילות הזו מכילה מקטע (PlaybackVideoFragment
) שמארח VideoView
עם ExoPlayer
, פקדי מדיה מסוימים ואזור טקסט להצגת התיאור של הסרטון שנבחר ומאפשר למשתמש להפעיל את הסרטון ב-Android TV. המשתמש יכול להשתמש בשלט הרחוק כדי להפעיל או להשהות סרטונים או לדלג בהפעלתם.
דרישות מוקדמות ל-Cast Connect
התכונה Cast Connect משתמשת בגרסאות חדשות של Google Play Services, שמחייבות שהאפליקציה ל-ATV תתעדכן כך שתשתמש במרחב השמות AndroidX.
כדי לתמוך ב-Cast Connect באפליקציה ל-Android TV, עליכם ליצור אירועים ולתמוך בהם מסשן מדיה. הספרייה 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 לתיאום כל האינטראקציות של Cast. צריך להטמיע את הממשק 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
הוא מאפיין של היחידה היחידה (singleton) 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, צריך להוסיף את מסנן ה-Intent המוגדר מראש הבא באפליקציה ל-Android TV. בקובץ 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
עכשיו, אחרי שהפעילות מוגדרת לקבל את הכוונה הזו שמכילה בקשת טעינה, נצטרך לטפל בה.
האפליקציה קוראת לשיטה פרטית בשם processIntent
כשהפעילות מתחילה. השיטה הזו מכילה את הלוגיקה לעיבוד כוונות נכנסות. כדי לטפל בבקשת טעינה, נשנה את השיטה הזו ונשלח את הכוונה לעיבוד נוסף באמצעות קריאה לשיטה onNewIntent
של המופע MediaManager
. אם MediaManager
מזהה שהכוונה היא בקשת טעינה, הוא מחלץ את האובייקט MediaLoadRequestData
מה-Intent ומפעיל את MediaLoadCommandCallback.onLoad()
. משנים את השיטה processIntent
בקובץ PlaybackVideoFragment.kt
כדי לטפל בכוונה העסקית שמכילה את בקשת הטעינה:
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())
}
}
}
מפעילים את האפליקציה לדוגמה
לוחצים על הלחצן Run כדי לפרוס את האפליקציה במכשיר ה-ATV. במכשיר השולח, לוחצים על לחצן ההעברה (cast) ובוחרים את מכשיר ה-ATV. אפליקציית ATV תושק במכשיר ATV. בוחרים סרטון בנייד, והסרטון יתחיל לפעול ב-ATV. בודקים אם מופיעה התראה בטלפון עם אמצעי הבקרה של ההפעלה. מנסים להשתמש בפקדים כמו השהיה. הסרטון במכשיר ה-ATV אמור להשהות.
7. תמיכה בפקודות של Cast Control
הגרסה הנוכחית של האפליקציה תומכת עכשיו בפקודות בסיסיות שתואמות לסשן מדיה, כמו הפעלה, השהיה וסריקה. עם זאת, יש כמה פקודות מהשליטה בהפעלת Cast שלא זמינות בסשן מדיה. כדי לתמוך בפקודות הבקרה האלה של העברה (cast), צריך לרשום MediaCommandCallback
.
מוסיפים את MyMediaCommandCallback
למכונה של MediaManager
באמצעות setMediaCommandCallback
כשהנגן מופעל:
private fun initializePlayer() {
...
castReceiverContext = CastReceiverContext.getInstance()
if (castReceiverContext != null) {
val mediaManager = castReceiverContext!!.mediaManager
...
mediaManager.setMediaCommandCallback(MyMediaCommandCallback())
}
}
יוצרים את הכיתה MyMediaCommandCallback
כדי לשנות את שיטות ברירת המחדל, כמו onQueueUpdate()
, כדי לתמוך בפקודות הבקרה הבאות של Cast:
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
})
}
}
תיעוד סטטוס המדיה לפני השליחה
בדומה ל-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.