שירות קלט טלוויזיה מייצג מקור זרם מדיה ומאפשר לכם להציג את תוכן המדיה אופנה לינארית משודרת בטלוויזיה כערוצים ותוכניות. באמצעות שירות קלט של טלוויזיה, ניתן לספק אמצעי בקרת הורים, מידע על לוח השידורים וסיווגי תוכן. שירות הקלט של הטלוויזיה פועל עם אפליקציית מערכת ההפעלה Android TV. האפליקציה הזו שולטת בתוכן של הערוץ ומציגה אותו בסופו של דבר בטלוויזיה. אפליקציית המערכת לטלוויזיה פותחה במיוחד למכשיר ולא ניתנת לשינוי באמצעות אפליקציות של צד שלישי. למידע נוסף על מסגרת קלט הטלוויזיה (TIF) של הארכיטקטורה והרכיבים שלה, מסגרת קלט לטלוויזיה.
יצירת שירות קלט לטלוויזיה באמצעות הספרייה הנלווית של TIF
הספרייה הנלווית של TIF היא מסגרת שמאפשרת הרחבה של תכונות נפוצות של שירות קלט טלוויזיה. היא מיועדת לשימוש של יצרני ציוד מקורי (OEM) כדי ליצור ערוצים ל-Android 5.0 (רמת API 21) עד Android 7.1 (רמת API 25) בלבד.
עדכון הפרויקט
הספרייה הנלווית של TIF זמינה לשימוש של יצרני ציוד מקורי (OEM) מדור קודם קלט android-sample-input של מאגר הנתונים. במאגר הזה תוכלו לראות דוגמה לאופן שבו אפשר לכלול את הספרייה באפליקציה.
הצהרה על שירות הקלט של הטלוויזיה במניפסט
באפליקציה צריך לספק מספר תואם ל-TvInputService
השירות שבו המערכת משתמשת כדי לגשת לאפליקציה. ה-TIF
הספרייה הנלווית מספקת את המחלקה BaseTvInputService
,
מספק יישום ברירת מחדל של TvInputService
שאפשר להתאים אישית. יוצרים מחלקה משנית של BaseTvInputService
,
ולהצהיר על המחלקה המשנית במניפסט כשירות.
בהצהרת המניפסט, מציינים את
הרשאה מסוג BIND_TV_INPUT
כדי לאפשר
שירות לחיבור קלט הטלוויזיה למערכת. שירות מערכת
מבצע את הקישור, ויש לו
ההרשאה BIND_TV_INPUT
.
אפליקציית המערכת של הטלוויזיה שולחת בקשות לשירותי קלט של טלוויזיה
דרך הממשק של TvInputManager
.
בהצהרת השירות, צריך לכלול מסנן Intent שמציין
TvInputService
כפעולה שיש לבצע עם
בכוונה טובה. בנוסף, מצהירים על המטא-נתונים של השירות כמשאב XML נפרד.
מוצגים הצהרת שירות, מסנן Intent והצהרת מטא-נתונים של שירות
בדוגמה הבאה:
<service android:name=".rich.RichTvInputService" android:label="@string/rich_input_label" android:permission="android.permission.BIND_TV_INPUT"> <!-- Required filter used by the system to launch our account service. --> <intent-filter> <action android:name="android.media.tv.TvInputService" /> </intent-filter> <!-- An XML file which describes this input. This provides pointers to the RichTvInputSetupActivity to the system/TV app. --> <meta-data android:name="android.media.tv.input" android:resource="@xml/richtvinputservice" /> </service>
מגדירים את המטא-נתונים של השירות בקובץ XML נפרד. השירות קובץ ה-XML של המטא-נתונים חייב לכלול ממשק הגדרה שמתאר את הקלט של הטלוויזיה הגדרה ראשונית וסריקת ערוצים. קובץ המטא-נתונים צריך להכיל גם סימון שמציין אם המשתמשים יכולים להקליט תוכן. לקבלת מידע נוסף לקבלת מידע על תמיכה בהקלטת תוכן באפליקציה שלך, הקלטת תוכן לתמיכה.
קובץ המטא-נתונים של השירות נמצא בספריית משאבי ה-XML
של האפליקציה, והערך שלו חייב להיות זהה לשם המשאב שעליו הצהרת
. על סמך ערכי המניפסט מהדוגמה הקודמת,
ליצור את קובץ ה-XML ב-res/xml/richtvinputservice.xml
, עם המאפיין
פריטי התוכן הבאים:
<?xml version="1.0" encoding="utf-8"?> <tv-input xmlns:android="http://schemas.android.com/apk/res/android" android:canRecord="true" android:setupActivity="com.example.android.sampletvinput.rich.RichTvInputSetupActivity" />
הגדרת ערוצים ויצירת פעילות הגדרה
שירות הקלט של הטלוויזיה חייב להגדיר לפחות ערוץ אחד שמשתמשים גישה דרך אפליקציית המערכת של טלוויזיה. עליך לרשום את הערוצים שלך במסד הנתונים של המערכת, ותספק פעילות הגדרה שהמערכת מופעל כשלא ניתן למצוא ערוץ לאפליקציה.
ראשית, צריך לאפשר לאפליקציה לקרוא ולכתוב במערכת אלקטרוניקה של המערכת מדריך תכנות (EPG), שהנתונים שלו כוללים ערוצים ותוכניות זמינים למשתמש. כדי לאפשר לאפליקציה לבצע את הפעולות האלה, צריך לסנכרן עם EPG אחרי הפעלה מחדש של המכשיר, מוסיפים את הרכיבים הבאים לקובץ המניפסט של האפליקציה:
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED "/>
צריך להוסיף את הרכיב הבא כדי לוודא שהאפליקציה מופיעה חנות Google Play כאפליקציה שמספקת ערוצי תוכן ב-Android TV:
<uses-feature android:name="android.software.live_tv" android:required="true" />
בשלב הבא יוצרים כיתה שמרחיבה את EpgSyncJobService
בכיתה. שיעור מופשט זה מאפשר ליצור בקלות שירות משימות
יוצר ומעדכן ערוצים במסד הנתונים של המערכת.
במחלקה המשנית, יצירה והחזרה של רשימת הערוצים המלאה ב-
getChannels()
אם הערוצים מגיעים מקובץ XMLTV,
להשתמש במחלקה XmlTvParser
. אחרת,
ערוצים באופן פרוגרמטי באמצעות המחלקה Channel.Builder
.
המערכת קוראת לכל ערוץ getProgramsForChannel()
כשנדרשת רשימה של תוכניות שניתן לצפות בהן במסגרת חלון זמן נתון
בערוץ. החזרת רשימה של Program
אובייקטים עבור
. להשתמש בכיתה XmlTvParser
כדי לקבל תוכניות מ
XMLTV, או ליצור אותם באופן פרוגרמטי באמצעות
כיתה אחת (Program.Builder
).
לכל אובייקט Program
משתמשים
InternalProviderData
כדי להגדיר פרטי תוכנית, כמו
סוג הסרטון של התוכנה. אם יש לך רק מספר מוגבל של תוכניות
אני רוצה שהערוץ יחזור על עצמו בלולאה, השתמשו
השיטה InternalProviderData.setRepeatable()
עם ערך של
true
כשמגדירים את המידע על התוכנית.
אחרי שמטמיעים את שירות המשימה, מוסיפים אותו לקובץ המניפסט של האפליקציה:
<service android:name=".sync.SampleJobService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true" />
לבסוף, יוצרים פעילות הגדרה. פעילות ההגדרה אמורה לספק אפשרות כדי לסנכרן את נתוני הערוץ והתוכנה. אחת מהדרכים לעשות זאת היא על ידי המשתמש דרך ממשק המשתמש בפעילות. יכול להיות שגם האפליקציה תבצע את הפעולה הזו באופן אוטומטי כשהפעילות מתחילה. כאשר פעילות ההגדרה צריכה לסנכרן את הערוץ פרטי תוכנית, האפליקציה צריכה להתחיל את שירות העבודה:
Kotlin
val inputId = getActivity().intent.getStringExtra(TvInputInfo.EXTRA_INPUT_ID) EpgSyncJobService.cancelAllSyncRequests(getActivity()) EpgSyncJobService.requestImmediateSync( getActivity(), inputId, ComponentName(getActivity(), SampleJobService::class.java) )
Java
String inputId = getActivity().getIntent().getStringExtra(TvInputInfo.EXTRA_INPUT_ID); EpgSyncJobService.cancelAllSyncRequests(getActivity()); EpgSyncJobService.requestImmediateSync(getActivity(), inputId, new ComponentName(getActivity(), SampleJobService.class));
שימוש בשיטה requestImmediateSync()
כדי לסנכרן
את שירות העבודה. המשתמש צריך להמתין לסיום הסנכרון, לכן עליך
שתקופת הבקשה תהיה קצרה יחסית.
משתמשים בשיטה setUpPeriodicSync()
כדי לקבל את שירות המשימה
לסנכרן מדי פעם את נתוני הערוץ והתוכנית ברקע:
Kotlin
EpgSyncJobService.setUpPeriodicSync( context, inputId, ComponentName(context, SampleJobService::class.java) )
Java
EpgSyncJobService.setUpPeriodicSync(context, inputId, new ComponentName(context, SampleJobService.class));
הספרייה הנלווית של TIF מספקת שיטה נוספת של עומס יתר
requestImmediateSync()
שמאפשר לציין את משך הזמן של
כדי לסנכרן אותם באלפיות השנייה. שיטת ברירת המחדל מסנכרנת
הערך של נתוני הערוץ.
הספרייה הנלווית של TIF מספקת גם שיטה של עומס יתר
setUpPeriodicSync()
שמאפשר לציין את משך הזמן של
של נתוני הערוץ לסנכרון, ובאיזו תדירות אמור להתבצע הסנכרון התקופתי.
שיטת ברירת המחדל מסנכרנת 48 שעות של נתוני הערוץ כל 12 שעות.
למידע נוסף על נתוני הערוץ ועל EPG: עבודה עם נתוני הערוץ.
טיפול בבקשות כוונון ובהפעלת מדיה
כשמשתמש בוחר ערוץ ספציפי, אפליקציית המערכת של YouTube TV משתמשת
Session
, שנוצרה על ידי האפליקציה שלך, כדי לכוון לערוץ המבוקש
ולהפעיל את התוכן. בספרייה הנלווית של TIF יש כמה
שיעורים שניתן להרחיב כדי לטפל בשיחות בערוצים ובסשנים מהמערכת.
תת-המחלקה BaseTvInputService
יוצרת סשנים שמטפלים
לבקשות כוונון. לשנות את
השיטה onCreateSession()
, יצירת סשן מורחב מ-
את הכיתה BaseTvInputService.Session
,
super.sessionCreated()
עם הסשן החדש שלך. בתוך
לדוגמה, הפונקציה onCreateSession()
מחזירה
אובייקט RichTvInputSessionImpl
מורחב
BaseTvInputService.Session
:
Kotlin
override fun onCreateSession(inputId: String): Session = RichTvInputSessionImpl(this, inputId).apply { setOverlayViewEnabled(true) }
Java
@Override public final Session onCreateSession(String inputId) { RichTvInputSessionImpl session = new RichTvInputSessionImpl(this, inputId); session.setOverlayViewEnabled(true); return session; }
כשהמשתמש משתמש באפליקציית המערכת לטלוויזיה כדי להתחיל לצפות באחד מהערוצים,
המערכת קוראת ל-method onPlayChannel()
של הסשן. שינוי מברירת המחדל
בשיטה הזאת אם צריך לבצע אתחול ערוץ מיוחד לפני
מתחילה לפעול.
לאחר מכן המערכת מקבלת את התוכנית המתוזמנת הנוכחית ומתקשרת
השיטה onPlayProgram()
של הסשן, מציין את התוכנה
ושעת ההתחלה באלפיות השנייה. משתמשים ב
ממשק TvPlayer
כדי להתחיל להפעיל את התוכנה.
קוד נגן המדיה שלך צריך להטמיע TvPlayer
כדי לטפל
אירועי הפעלה ספציפיים. הכיתה TvPlayer
מטפלת בתכונות
כמו פקדי להזזת זמן בלי להוסיף מורכבות
הטמעת BaseTvInputService
.
בשיטה getTvPlayer()
של הסשן, חוזרים
נגן המדיה שבו מוטמע TvPlayer
.
באפליקציה לדוגמה של TV Credentials Service מיושמת נגן מדיה שמשתמש
ExoPlayer.
יצירת שירות קלט של טלוויזיה באמצעות מסגרת הקלט של הטלוויזיה
אם שירות הקלט של הטלוויזיה לא יכול להשתמש בספרייה הנלווית של TIF, תצטרכו כדי להטמיע את הרכיבים הבאים:
TvInputService
מספק זמינות לטווח ארוך וזמינות ברקע את קלט הטלוויזיהTvInputService.Session
שומר על מצב הקלט של הטלוויזיה ומתקשר עם אפליקציית האירוח- ב
TvContract
מתוארים הערוצים והתוכניות שזמינים בטלוויזיה קלט TvContract.Channels
מייצג מידע על ערוץ טלוויזיה- ב
TvContract.Programs
מתואר תוכנית טלוויזיה עם נתונים כמו תוכנית שם ושעת התחלה TvTrackInfo
מייצג טראק של אודיו, וידאו או כתוביותTvContentRating
מתאר סיווג תוכן, מאפשר תוכן מותאם אישית הונאות דירוגTvInputManager
מספק API לאפליקציית המערכת לטלוויזיה ומנהל האינטראקציה עם אפליקציות הקלט והטלוויזיה
צריך לבצע גם את הפעולות הבאות:
- להצהיר על שירות הקלט של הטלוויזיה במניפסט, כפי שמתואר במאמר להצהיר על שירות הקלט של הטלוויזיה מניפסט.
- יוצרים את קובץ המטא-נתונים של השירות.
- יוצרים ורושמים את פרטי הערוץ והתוכנית.
- יוצרים את פעילות ההגדרה.
הגדרת שירות הקלט של הטלוויזיה
כדי להשתמש בשירות שלך, עליך להרחיב את הכיתה TvInputService
. א'
ההטמעה של TvInputService
שירות כריכה שבו שירות המערכת
הוא הלקוח שמקושר אליו. שיטות למחזור החיים של השירות
שצריך ליישם, אפשר לראות באיור 1.
ה-method onCreate()
מאתחלת ומפעילה את
HandlerThread
, מספק שרשור תהליך נפרד מה-thread של ממשק המשתמש
טיפול בפעולות שמונעות על ידי המערכת. בדוגמה הבאה, הפרמטר onCreate()
ה-method מאתחלת את CaptioningManager
ומתכוננת לטפל
ACTION_BLOCKED_RATINGS_CHANGED
ו-ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED
פעולות. האלה
הפעולות מתארות את כוונות המערכת שהופעלו כשהמשתמש משנה את ההגדרות של אמצעי בקרת ההורים, ומתי
יש שינוי ברשימת הדירוגים החסומים.
Kotlin
override fun onCreate() { super.onCreate() handlerThread = HandlerThread(javaClass.simpleName).apply { start() } dbHandler = Handler(handlerThread.looper) handler = Handler() captioningManager = getSystemService(Context.CAPTIONING_SERVICE) as CaptioningManager setTheme(android.R.style.Theme_Holo_Light_NoActionBar) sessions = mutableListOf<BaseTvInputSessionImpl>() val intentFilter = IntentFilter().apply { addAction(TvInputManager.ACTION_BLOCKED_RATINGS_CHANGED) addAction(TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED) } registerReceiver(broadcastReceiver, intentFilter) }
Java
@Override public void onCreate() { super.onCreate(); handlerThread = new HandlerThread(getClass() .getSimpleName()); handlerThread.start(); dbHandler = new Handler(handlerThread.getLooper()); handler = new Handler(); captioningManager = (CaptioningManager) getSystemService(Context.CAPTIONING_SERVICE); setTheme(android.R.style.Theme_Holo_Light_NoActionBar); sessions = new ArrayList<BaseTvInputSessionImpl>(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(TvInputManager .ACTION_BLOCKED_RATINGS_CHANGED); intentFilter.addAction(TvInputManager .ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED); registerReceiver(broadcastReceiver, intentFilter); }
![](https://developer.android.google.cn/static/images/tv/tvinput-life.png?authuser=0000&hl=he)
איור 1.מחזור החיים של TVInputService.
ראו
לשלוט בתוכן כדי לקבל מידע נוסף על עבודה עם תוכן חסום
בקרת הורים. ראו TvInputManager
לגבי פעולות נוספות שמבוססות על המערכת
ייתכן שכדאי לטפל בו בשירות הקלט של הטלוויזיה.
השדה TvInputService
יוצר
TvInputService.Session
שבו מוטמע Handler.Callback
כדי לטפל בשינויים במצב הנגן. ב-
onSetSurface()
,
TvInputService.Session
מגדיר את Surface
עם
תוכן וידאו. למידע נוסף, ראו שילוב הנגן עם הפלטפורמה
למידע נוסף על עבודה עם Surface
כדי לעבד את הסרטון.
TvInputService.Session
מטפל
onTune()
כשמשתמש בוחר ערוץ ומודיע לאפליקציית המערכת על שינויים בתוכן
המטא-נתונים של התוכן. השיטות האלה של notify()
מתוארות ב
שליטה בתוכן וניהול הטראקים
בהכשרה הזאת.
הגדרת פעילות ההגדרה
אפליקציית המערכת של הטלוויזיה פועלת עם פעילות ההגדרה שהגדרת לקלט הטלוויזיה. ההגדרה נדרשת, ועלינו לספק לפחות רשומת ערוץ אחת עבור מסד הנתונים של המערכת. אפליקציית מערכת TV מפעילה את פעילות ההגדרה כשהיא לא מוצאת ערוץ לקלט הטלוויזיה.
פעילות ההגדרה מתארת לאפליקציית המערכת לטלוויזיה שבה הערוצים הופכים לזמינים דרך הטלוויזיה את הקלט, כמו שמודגם בשיעור הבא, צרו ולעדכן את נתוני הערוץ.