یک سرویس ورودی تلویزیون نشان دهنده یک منبع جریان رسانه است و به شما امکان می دهد محتوای رسانه ای خود را به صورت خطی و پخش تلویزیونی به عنوان کانال و برنامه ارائه دهید. با سرویس ورودی تلویزیون، میتوانید کنترلهای والدین، اطلاعات راهنمای برنامه و رتبهبندی محتوا را ارائه دهید. سرویس ورودی تلویزیون با برنامه تلویزیون سیستم اندروید کار می کند. این برنامه در نهایت محتوای کانال را در تلویزیون کنترل و ارائه می کند. برنامه تلویزیون سیستم به طور خاص برای دستگاه توسعه یافته است و توسط برنامه های شخص ثالث غیر قابل تغییر است. برای اطلاعات بیشتر در مورد معماری چارچوب ورودی تلویزیون (TIF) و اجزای آن، به چارچوب ورودی تلویزیون مراجعه کنید.
با استفاده از TIF Companion Library یک سرویس ورودی تلویزیون ایجاد کنید
TIF Companion Library چارچوبی است که پیاده سازی های قابل توسعه ای از ویژگی های مشترک سرویس ورودی تلویزیون را ارائه می دهد. در نظر گرفته شده است که توسط OEMها برای ساخت کانال برای Android 5.0 (سطح API 21) تا Android 7.1 (سطح API 25) استفاده شود.
پروژه خود را به روز کنید
TIF Companion Library برای استفاده قدیمی توسط OEMها در مخزن androidtv-sample-inputs در دسترس است. برای مثالی از نحوه گنجاندن کتابخانه در یک برنامه، آن مخزن را ببینید.
سرویس ورودی تلویزیون خود را در مانیفست اعلام کنید
برنامه شما باید یک سرویس سازگار با TvInputService
ارائه کند که سیستم از آن برای دسترسی به برنامه شما استفاده می کند. TIF Companion Library کلاس BaseTvInputService
را ارائه می دهد که اجرای پیش فرض TvInputService
را ارائه می دهد که می توانید آن را سفارشی کنید. یک زیر کلاس از BaseTvInputService
ایجاد کنید و زیر کلاس را در مانیفست خود به عنوان یک سرویس اعلام کنید.
در اعلامیه مانیفست، مجوز BIND_TV_INPUT
را مشخص کنید تا به سرویس اجازه دهد ورودی تلویزیون را به سیستم متصل کند. یک سرویس سیستم اتصال را انجام می دهد و مجوز BIND_TV_INPUT
را دارد. برنامه تلویزیون سیستم درخواست ها را از طریق رابط TvInputManager
به سرویس های ورودی تلویزیون ارسال می کند.
در اعلامیه سرویس خود، یک فیلتر هدف قرار دهید که TvInputService
به عنوان عملی که باید با هدف انجام شود مشخص می کند. همچنین فراداده سرویس را به عنوان یک منبع XML جداگانه اعلام کنید. اعلان سرویس، فیلتر قصد، و اعلان فراداده سرویس در مثال زیر نشان داده شده است:
<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" />
در نهایت یک اکتیویتی راه اندازی ایجاد کنید. فعالیت راهاندازی شما باید راهی برای همگامسازی دادههای کانال و برنامه ارائه دهد. یکی از راه های انجام این کار این است که کاربر این کار را از طریق UI در اکتیویتی انجام دهد. همچنین ممکن است از برنامه بخواهید این کار را به طور خودکار با شروع فعالیت انجام دهد. وقتی فعالیت راهاندازی نیاز به همگامسازی اطلاعات کانال و برنامه دارد، برنامه باید سرویس کار را راهاندازی کند:
کاتلین
val inputId = getActivity().intent.getStringExtra(TvInputInfo.EXTRA_INPUT_ID) EpgSyncJobService.cancelAllSyncRequests(getActivity()) EpgSyncJobService.requestImmediateSync( getActivity(), inputId, ComponentName(getActivity(), SampleJobService::class.java) )
جاوا
String inputId = getActivity().getIntent().getStringExtra(TvInputInfo.EXTRA_INPUT_ID); EpgSyncJobService.cancelAllSyncRequests(getActivity()); EpgSyncJobService.requestImmediateSync(getActivity(), inputId, new ComponentName(getActivity(), SampleJobService.class));
از متد requestImmediateSync()
برای همگام سازی سرویس job استفاده کنید. کاربر باید منتظر بماند تا همگام سازی تمام شود، بنابراین باید دوره درخواست خود را نسبتاً کوتاه نگه دارید.
از متد setUpPeriodicSync()
استفاده کنید تا سرویس job به صورت دورهای دادههای کانال و برنامه را در پسزمینه همگامسازی کند:
کاتلین
EpgSyncJobService.setUpPeriodicSync( context, inputId, ComponentName(context, SampleJobService::class.java) )
جاوا
EpgSyncJobService.setUpPeriodicSync(context, inputId, new ComponentName(context, SampleJobService.class));
TIF Companion Library یک روش اضافه بار اضافی از requestImmediateSync()
ارائه می دهد که به شما امکان می دهد مدت زمان همگام سازی داده های کانال را در میلی ثانیه مشخص کنید. روش پیشفرض دادههای یک ساعته کانال را همگامسازی میکند.
TIF Companion Library همچنین یک روش اضافه بار اضافی از setUpPeriodicSync()
ارائه میکند که به شما امکان میدهد مدت زمان همگامسازی دادههای کانال و اینکه هر چند وقت یکبار همگامسازی دورهای باید انجام شود را مشخص کنید. روش پیشفرض 48 ساعت داده کانال را هر 12 ساعت همگامسازی میکند.
برای جزئیات بیشتر در مورد داده های کانال و EPG، به کار با داده های کانال مراجعه کنید.
رسیدگی به درخواست های تنظیم و پخش رسانه
وقتی کاربر کانال خاصی را انتخاب میکند، برنامه تلویزیون سیستم از Session
ساخته شده توسط برنامه شما برای تنظیم کانال درخواستی و پخش محتوا استفاده میکند. TIF Companion Library چندین کلاس را ارائه می دهد که می توانید آنها را برای رسیدگی به تماس های کانال و جلسه از سیستم گسترش دهید.
زیرکلاس BaseTvInputService
شما جلساتی را ایجاد می کند که درخواست های تنظیم را انجام می دهد. روش onCreateSession()
را لغو کنید، یک جلسه توسعه یافته از کلاس BaseTvInputService.Session
ایجاد کنید و با جلسه جدید خود super.sessionCreated()
را فراخوانی کنید. در مثال زیر، onCreateSession()
یک شی RichTvInputSessionImpl
را برمی گرداند که BaseTvInputService.Session
گسترش می دهد:
کاتلین
override fun onCreateSession(inputId: String): Session = RichTvInputSessionImpl(this, inputId).apply { setOverlayViewEnabled(true) }
جاوا
@Override public final Session onCreateSession(String inputId) { RichTvInputSessionImpl session = new RichTvInputSessionImpl(this, inputId); session.setOverlayViewEnabled(true); return session; }
هنگامی که کاربر از برنامه تلویزیون سیستم برای شروع مشاهده یکی از کانال های شما استفاده می کند، سیستم متد onPlayChannel()
جلسه شما را فراخوانی می کند. اگر قبل از شروع پخش برنامه نیاز به مقداردهی اولیه کانال خاصی دارید، این روش را لغو کنید.
سپس سیستم برنامه زمانبندیشده فعلی را دریافت میکند و متد onPlayProgram()
جلسه شما را فراخوانی میکند و اطلاعات برنامه و زمان شروع را بر حسب میلیثانیه مشخص میکند. برای شروع پخش برنامه از رابط TvPlayer
استفاده کنید.
کد پخش کننده رسانه شما باید TvPlayer
برای مدیریت رویدادهای پخش خاص پیاده سازی کند. کلاس TvPlayer
ویژگی هایی مانند کنترل های تغییر زمان را بدون افزودن پیچیدگی به پیاده سازی BaseTvInputService
کنترل می کند.
در روش getTvPlayer()
جلسه، پخش کننده رسانه خود را که TvPlayer
را پیاده سازی می کند، برگردانید. برنامه نمونه سرویس ورودی تلویزیون یک پخش کننده رسانه را اجرا می کند که از ExoPlayer استفاده می کند.
با استفاده از چارچوب ورودی تلویزیون، یک سرویس ورودی تلویزیون ایجاد کنید
اگر سرویس ورودی تلویزیون شما نمی تواند از TIF Companion Library استفاده کند، باید اجزای زیر را پیاده سازی کنید:
-
TvInputService
دسترسی طولانی مدت و پسزمینه ورودی تلویزیون را فراهم میکند -
TvInputService.Session
وضعیت ورودی تلویزیون را حفظ می کند و با برنامه میزبانی ارتباط برقرار می کند -
TvContract
کانال ها و برنامه های موجود برای ورودی تلویزیون را توصیف می کند -
TvContract.Channels
اطلاعات یک کانال تلویزیونی را نشان می دهد -
TvContract.Programs
یک برنامه تلویزیونی را با داده هایی مانند عنوان برنامه و زمان شروع توصیف می کند -
TvTrackInfo
یک آهنگ صوتی، تصویری یا زیرنویس را نشان می دهد -
TvContentRating
یک رتبه بندی محتوا را توصیف می کند، به طرح های رتبه بندی محتوای سفارشی اجازه می دهد -
TvInputManager
یک API برای برنامه تلویزیون سیستم ارائه می دهد و تعامل با ورودی ها و برنامه های تلویزیون را مدیریت می کند.
همچنین باید موارد زیر را انجام دهید:
- سرویس ورودی تلویزیون خود را در مانیفست اعلام کنید، همانطور که در اعلام سرویس ورودی تلویزیون در مانیفست توضیح داده شده است.
- فایل فراداده سرویس را ایجاد کنید.
- اطلاعات کانال و برنامه خود را ایجاد و ثبت کنید.
- فعالیت راه اندازی خود را ایجاد کنید.
سرویس ورودی تلویزیون خود را تعریف کنید
برای خدمات خود، کلاس TvInputService
گسترش می دهید. پیاده سازی TvInputService
یک سرویس محدود است که در آن سرویس سیستم مشتری است که به آن متصل می شود. روش های چرخه عمر خدماتی که باید پیاده سازی کنید در شکل 1 نشان داده شده است.
متد onCreate()
مقداردهی اولیه میکند و HandlerThread
را راهاندازی میکند که یک رشته پردازشی جدا از رشته UI برای مدیریت اقدامات مبتنی بر سیستم فراهم میکند. در مثال زیر، متد onCreate()
CaptioningManager
را مقداردهی اولیه می کند و برای مدیریت اقدامات ACTION_BLOCKED_RATINGS_CHANGED
و ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED
آماده می شود. این کنشها اهداف سیستم را توصیف میکنند که وقتی کاربر تنظیمات کنترل والدین را تغییر میدهد و زمانی که تغییری در لیست رتبهبندیهای مسدود شده وجود دارد، اجرا میشوند.
کاتلین
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) }
جاوا
@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); }
برای اطلاعات بیشتر در مورد کار با محتوای مسدود شده و ارائه کنترل والدین به کنترل محتوا مراجعه کنید. برای اقدامات بیشتر مبتنی بر سیستم که ممکن است بخواهید در سرویس ورودی تلویزیون خود انجام دهید، TvInputManager
ببینید.
TvInputService
یک TvInputService.Session
ایجاد می کند که Handler.Callback
را برای مدیریت تغییرات وضعیت پخش کننده پیاده سازی می کند. با onSetSurface()
، TvInputService.Session
Surface
با محتوای ویدیویی تنظیم می کند. برای اطلاعات بیشتر در مورد کار با Surface
برای رندر کردن ویدیو، به ادغام پخش کننده با سطح مراجعه کنید.
TvInputService.Session
رویداد onTune()
را هنگامی که کاربر یک کانال را انتخاب می کند مدیریت می کند و برنامه تلویزیون سیستم را برای تغییرات در محتوا و فراداده محتوا مطلع می کند. این متدهای notify()
در Control Content و Handle track انتخاب بیشتر در این آموزش توضیح داده شده است.
فعالیت راه اندازی خود را تعریف کنید
برنامه تلویزیون سیستم با فعالیت راه اندازی که برای ورودی تلویزیون خود تعریف کرده اید کار می کند. فعالیت راه اندازی مورد نیاز است و باید حداقل یک رکورد کانال برای پایگاه داده سیستم ارائه کند. برنامه تلویزیون سیستم زمانی که نمی تواند کانالی برای ورودی تلویزیون پیدا کند، فعالیت راه اندازی را فراخوانی می کند.
فعالیت راهاندازی، کانالهایی را که از طریق ورودی تلویزیون در دسترس قرار گرفتهاند، در برنامه تلویزیون سیستم توضیح میدهد، همانطور که در درس بعدی، ایجاد و بهروزرسانی دادههای کانال نشان داده شد.