یک سرویس ورودی تلویزیون ایجاد کنید

یک سرویس ورودی تلویزیون نشان دهنده یک منبع جریان رسانه است و به شما امکان می دهد محتوای رسانه ای خود را به صورت خطی و پخش تلویزیونی به عنوان کانال و برنامه ارائه دهید. با سرویس ورودی تلویزیون، می‌توانید کنترل‌های والدین، اطلاعات راهنمای برنامه و رتبه‌بندی محتوا را ارائه دهید. سرویس ورودی تلویزیون با برنامه تلویزیون سیستم اندروید کار می کند. این برنامه در نهایت محتوای کانال را در تلویزیون کنترل و ارائه می کند. برنامه تلویزیون سیستم به طور خاص برای دستگاه توسعه یافته است و توسط برنامه های شخص ثالث غیر قابل تغییر است. برای اطلاعات بیشتر در مورد معماری چارچوب ورودی تلویزیون (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 برای برنامه تلویزیون سیستم ارائه می دهد و تعامل با ورودی ها و برنامه های تلویزیون را مدیریت می کند.

همچنین باید موارد زیر را انجام دهید:

  1. سرویس ورودی تلویزیون خود را در مانیفست اعلام کنید، همانطور که در اعلام سرویس ورودی تلویزیون در مانیفست توضیح داده شده است.
  2. فایل فراداده سرویس را ایجاد کنید.
  3. اطلاعات کانال و برنامه خود را ایجاد و ثبت کنید.
  4. فعالیت راه اندازی خود را ایجاد کنید.

سرویس ورودی تلویزیون خود را تعریف کنید

برای خدمات خود، کلاس 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);
}

شکل 1. چرخه عمر TvInputService.

برای اطلاعات بیشتر در مورد کار با محتوای مسدود شده و ارائه کنترل والدین به کنترل محتوا مراجعه کنید. برای اقدامات بیشتر مبتنی بر سیستم که ممکن است بخواهید در سرویس ورودی تلویزیون خود انجام دهید، TvInputManager ببینید.

TvInputService یک TvInputService.Session ایجاد می کند که Handler.Callback را برای مدیریت تغییرات وضعیت پخش کننده پیاده سازی می کند. با onSetSurface() ، TvInputService.Session Surface با محتوای ویدیویی تنظیم می کند. برای اطلاعات بیشتر در مورد کار با Surface برای رندر کردن ویدیو، به ادغام پخش کننده با سطح مراجعه کنید.

TvInputService.Session رویداد onTune() را هنگامی که کاربر یک کانال را انتخاب می کند مدیریت می کند و برنامه تلویزیون سیستم را برای تغییرات در محتوا و فراداده محتوا مطلع می کند. این متدهای notify() در Control Content و Handle track انتخاب بیشتر در این آموزش توضیح داده شده است.

فعالیت راه اندازی خود را تعریف کنید

برنامه تلویزیون سیستم با فعالیت راه اندازی که برای ورودی تلویزیون خود تعریف کرده اید کار می کند. فعالیت راه اندازی مورد نیاز است و باید حداقل یک رکورد کانال برای پایگاه داده سیستم ارائه کند. برنامه تلویزیون سیستم زمانی که نمی تواند کانالی برای ورودی تلویزیون پیدا کند، فعالیت راه اندازی را فراخوانی می کند.

فعالیت راه‌اندازی، کانال‌هایی را که از طریق ورودی تلویزیون در دسترس قرار گرفته‌اند، در برنامه تلویزیون سیستم توضیح می‌دهد، همانطور که در درس بعدی، ایجاد و به‌روزرسانی داده‌های کانال نشان داده شد.

مراجع اضافی