کانال‌های صفحه اصلی

صفحه اصلی Android TV واسط کاربری‌ای ارائه می‌دهد که محتوای توصیه‌شده را به‌صورت جدولی از کانال‌ها و برنامه‌ها نمایش می‌دهد. هر ردیف یک کانال است. کانال حاوی کارت‌هایی برای هر برنامه موجود در آن کانال است:

صفحه اصلی Android TV
صفحه اصلی Android TV

این سند نشان می‌دهد که چگونه کانال‌ها و برنامه‌ها را به صفحه اصلی اضافه کنید، محتوا را به‌روز کنید، کنش‌های کاربر را مدیریت کنید، و بهترین تجربه را برای کاربرانتان فراهم کنید. (اگر می‌خواهید عمیق‌تر در API کاوش کنید، کارگاه کدنویسی صفحه اصلی را امتحان کنید و جلسه Android TV در I/O 2017 را تماشا کنید)

رابط کاربری صفحه اصلی

برنامه‌ها می‌توانند کانال‌های جدید ایجاد کنند، برنامه‌ها را در کانال اضافه، حذف، و به‌روزرسانی کنند، و ترتیب برنامه‌ها را در کانال کنترل کنند. برای مثال، برنامه‌ای می‌تواند کانالی به‌نام «تازه‌ها» ایجاد کند و کارت‌هایی برای برنامه‌های جدیداً دردسترس نشان دهد.

برنامه‌ها نمی‌توانند ترتیب نمایش کانال‌ها را در صفحه اصلی کنترل کنند. وقتی برنامه‌تان کانال جدیدی ایجاد می‌کند، صفحه اصلی آن را به پایین فهرست کانال اضافه می‌کند. کاربر می‌تواند ترتیب کانال‌ها را تغییر دهد، آن‌ها را پنهان کند، و نمایش دهد.

کانال «تماشای بعدی»

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

کانال‌های برنامه

کانال‌هایی که برنامه‌تان ایجاد می‌کند همگی از این چرخه حیات پیروی می‌کنند:

  1. کاربر کانالی را در برنامه شما پیدا می‌کند و درخواست می‌کند آن را به صفحه اصلی اضافه کند.
  2. برنامه کانال را ایجاد می‌کند و آن را به TvProvider اضافه می‌کند (در این مرحله کانال قابل‌مشاهده نیست).
  3. برنامه از سیستم می‌خواهد کانال را نمایش دهد.
  4. سیستم از کاربر می‌خواهد کانال جدید را تأیید کند.
  5. کانال جدید در آخرین ردیف صفحه اصلی نشان داده می‌شود.

کانال پیش‌فرض

برنامه شما می‌تواند هر تعداد کانال را برای افزودن کاربر به صفحه اصلی ارائه دهد. کاربر معمولاً باید هر کانال را قبل‌از اینکه در صفحه اصلی ظاهر شود انتخاب و تأیید کند. هر برنامه گزینه ایجاد یک کانال پیش‌فرض را دارد. کانال پیش‌فرض ویژه است زیرا به‌طور خودکار در صفحه اصلی ظاهر می‌شود؛ کاربر مجبور نیست به‌طور صریح آن را درخواست کند.

پیش‌نیازها

صفحه اصلی Android TV از میاناهای برنامه‌سازی کاربردی TvProvider Android برای مدیریت کانال‌ها و برنامه‌هایی که برنامه شما ایجاد می‌کند استفاده می‌کند. برای دسترسی به داده‌های ارائه‌دهنده، اجازه زیر را به مانیفست برنامه‌تان اضافه کنید:

<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />

کتابخانه پشتیبانی TvProvider استفاده از ارائه‌دهنده را آسان‌تر می‌کند. آن را به وابستگی‌ها در فایل build.gradle خود اضافه کنید:

شیک

implementation 'androidx.tvprovider:tvprovider:1.0.0'

کاتلین

implementation("androidx.tvprovider:tvprovider:1.0.0")

برای کار با کانال‌ها و برنامه‌ها، حتماً این واردات کتابخانه پشتیبانی را در برنامه خود بگنجانید:

کاتلین

import android.support.media.tv.Channel
import android.support.media.tv.TvContractCompat
import android.support.media.tv.ChannelLogoUtils
import android.support.media.tv.PreviewProgram
import android.support.media.tv.WatchNextProgram

جاوا

import android.support.media.tv.Channel;
import android.support.media.tv.TvContractCompat;
import android.support.media.tv.ChannelLogoUtils;
import android.support.media.tv.PreviewProgram;
import android.support.media.tv.WatchNextProgram;

کانال‌ها

اولین کانالی که برنامه‌تان ایجاد می‌کند کانال پیش‌فرض آن می‌شود. کانال پیش‌فرض به‌طور خودکار در صفحه اصلی نشان داده می‌شود. همه کانال‌های دیگری که ایجاد می‌کنید باید توسط کاربر انتخاب و پذیرفته شوند تا بتوانند در صفحه اصلی نشان داده شوند.

ایجاد کردن کانال

برنامه شما باید از سیستم بخواهد کانال‌های جدیداً اضافه‌شده را فقط زمانی نشان دهد که در پیش‌زمینه اجرا می‌شود. این کار مانع از نمایش کادر گفتگویی می‌شود که در آن برنامه‌تان درخواست تأیید برای افزودن کانال شما را دارد، درحالی‌که کاربر درحال اجرای برنامه دیگری است. اگر سعی کنید کانالی را درحین اجرا در پس‌زمینه اضافه کنید، روش onActivityResult() فعالیت کد وضعیت RESULT_CANCELED را برمی‌گرداند.

برای ایجاد کانال، این مراحل را دنبال کنید:

  1. سازنده کانال ایجاد کنید و ویژگی‌های آن را تنظیم کنید. توجه داشته باشید که نوع کانال باید TYPE_PREVIEW باشد. مشخصه‌های بیشتری را درصورت نیاز اضافه کنید.

    کاتلین

    val builder = Channel.Builder()
    // Every channel you create must have the type `TYPE_PREVIEW`
    builder.setType(TvContractCompat.Channels.TYPE_PREVIEW)
            .setDisplayName("Channel Name")
            .setAppLinkIntentUri(uri)
    

    جاوا

    Channel.Builder builder = new Channel.Builder();
    // Every channel you create must have the type `TYPE_PREVIEW`
    builder.setType(TvContractCompat.Channels.TYPE_PREVIEW)
            .setDisplayName("Channel Name")
            .setAppLinkIntentUri(uri);
    
  2. کانال را در ارائه‌دهنده وارد کنید:

    کاتلین

    var channelUri = context.contentResolver.insert(
            TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues())
    

    جاوا

    Uri channelUri = context.getContentResolver().insert(
            TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues());
    
  3. برای اینکه بتوانید بعداً به کانال برنامه اضافه کنید، باید شناسه کانال را ذخیره کنید. شناسه کانال را از URI برگردانده‌شده استخراج کنید:

    کاتلین

    var channelId = ContentUris.parseId(channelUri)
    

    جاوا

    long channelId = ContentUris.parseId(channelUri);
    
  4. باید برای کانالتان نشان‌واره اضافه کنید. از Uri یا Bitmap استفاده کنید. نماد نشان‌واره باید ۸۰ دی‌پی در ۸۰ دی‌پی باشد و باید مات باشد. این نماد زیر ماسک دایره‌ای نمایش داده می‌شود:

    ماسک نماد صفحه اصلی تلویزیون

    کاتلین

    // Choose one or the other
    storeChannelLogo(context: Context, channelId: Long, logoUri: Uri) // also works if logoUri is a URL
    storeChannelLogo(context: Context, channelId: Long, logo: Bitmap)
    

    جاوا

    // Choose one or the other
    storeChannelLogo(Context context, long channelId, Uri logoUri); // also works if logoUri is a URL
    storeChannelLogo(Context context, long channelId, Bitmap logo);
    
  5. ایجاد کانال پیش‌فرض (اختیاری): وقتی برنامه‌تان اولین کانال خود را ایجاد می‌کند، می‌توانید آن را به کانال پیش‌فرض تبدیل کنید تا بلافاصله بدون هیچ اقدامی ازسوی کاربر در صفحه اصلی ظاهر شود. هر کانال دیگری که ایجاد می‌کنید تا زمانی که کاربر صریحاً آن‌ها را انتخاب نکند، قابل‌مشاهده نیست.

    کاتلین

    TvContractCompat.requestChannelBrowsable(context, channelId)
    

    جاوا

    TvContractCompat.requestChannelBrowsable(context, channelId);
    
  6. کاری کنید که کانال پیش‌فرضتان قبل‌از باز شدن برنامه‌تان نشان داده شود. می‌توانید با افزودن BroadcastReceiver که به کنش android.media.tv.action.INITIALIZE_PROGRAMS گوش می‌دهد، این رفتار را ایجاد کنید. صفحه اصلی این کنش را پس‌از نصب برنامه ارسال می‌کند:

    <receiver
      android:name=".RunOnInstallReceiver"
      android:exported="true">
        <intent-filter>
          <action android:name="android.media.tv.action.INITIALIZE_PROGRAMS" />
          <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>
    

    هنگام بارگذاری جانبی برنامه‌تان درطول توسعه، می‌توانید این مرحله را با راه‌اندازی هدف ازطریق adb آزمایش کنید، که در آن your.package.name/.YourReceiverName BroadcastReceiver برنامه‌تان است:

    adb shell am broadcast -a android.media.tv.action.INITIALIZE_PROGRAMS -n \
        your.package.name/.YourReceiverName
    

    در موارد نادر، ممکن است برنامه‌تان هم‌زمان با شروع برنامه توسط کاربر، رویداد ثبت‌شده را دریافت کند. مطمئن شوید کدتان سعی نمی‌کند کانال پیش‌فرض را بیش‌از یک بار اضافه کند.

به‌روزرسانی کانال

به‌روزرسانی کانال‌ها بسیار شبیه به ایجاد آن‌ها است.

از Channel.Builder دیگری برای تنظیم مشخصه‌هایی که باید تغییر کنند استفاده کنید.

از ContentResolver برای به‌روزرسانی کانال استفاده کنید. از شناسه کانالی استفاده کنید که هنگام اضافه شدن کانال ذخیره کرده‌اید:

کاتلین

context.contentResolver.update(
        TvContractCompat.buildChannelUri(channelId),
        builder.build().toContentValues(),
        null,
        null
)

جاوا

context.getContentResolver().update(TvContractCompat.buildChannelUri(channelId),
    builder.build().toContentValues(), null, null);

برای به‌روزرسانی نشان‌واره کانال، از storeChannelLogo() استفاده کنید.

حذف کانال

کاتلین

context.contentResolver.delete(TvContractCompat.buildChannelUri(channelId), null, null)

جاوا

context.getContentResolver().delete(TvContractCompat.buildChannelUri(channelId), null, null);

برنامه‌ها

برنامه‌ها کارت‌های محتوای تکی هستند که در کانال نمایش داده می‌شوند. می‌توانید برنامه‌ها را هم در کانال‌های سفارشی برنامه‌تان و هم در کانال «تماشای بعدی» که توسط سیستم مدیریت می‌شود منتشر کنید.

افزودن برنامه‌ها به کانال برنامه

PreviewProgram.Builder ایجاد کنید و مشخصه‌های آن را تنظیم کنید:

کاتلین

val builder = PreviewProgram.Builder()
builder.setChannelId(channelId)
        .setType(TvContractCompat.PreviewPrograms.TYPE_CLIP)
        .setTitle("Title")
        .setDescription("Program description")
        .setPosterArtUri(uri)
        .setIntentUri(uri)
        .setInternalProviderId(appProgramId)

جاوا

PreviewProgram.Builder builder = new PreviewProgram.Builder();
builder.setChannelId(channelId)
        .setType(TvContractCompat.PreviewPrograms.TYPE_CLIP)
        .setTitle("Title")
        .setDescription("Program description")
        .setPosterArtUri(uri)
        .setIntentUri(uri)
        .setInternalProviderId(appProgramId);

بسته به نوع برنامه، مشخصه‌های بیشتری اضافه کنید. (برای دیدن مشخصه‌های موجود برای هر نوع برنامه، به جدول‌های زیر مراجعه کنید.)

برنامه را در ارائه‌دهنده درج کنید:

کاتلین

var programUri = context.contentResolver.insert(TvContractCompat.PreviewPrograms.CONTENT_URI,
        builder.build().toContentValues())

جاوا

Uri programUri = context.getContentResolver().insert(TvContractCompat.PreviewPrograms.CONTENT_URI,
      builder.build().toContentValues());

شناسه برنامه را برای ارجاع بعدی بازیابی کنید:

کاتلین

val programId = ContentUris.parseId(programUri)

جاوا

long programId = ContentUris.parseId(programUri);

افزودن برنامه‌ها به کانال «صف پخش»

برای درج برنامه‌ها در کانال «بعدی برای تماشا»، به افزودن برنامه‌ها به کانال «بعدی برای تماشا» مراجعه کنید.

درحال به‌روزرسانی برنامه

می‌توانید اطلاعات برنامه را تغییر دهید. برای مثال، ممکن است بخواهید قیمت اجاره فیلمی را به‌روز کنید، یا نوار پیشرفتی را به‌روز کنید که نشان می‌دهد کاربر چه مقدار از برنامه را تماشا کرده است.

از PreviewProgram.Builder برای تنظیم مشخصه‌هایی که باید تغییر دهید استفاده کنید، سپس getContentResolver().update را برای به‌روزرسانی برنامه فراخوانی کنید. شناسه برنامه‌ای را که هنگام افزودن اولیه برنامه ذخیره کرده‌اید مشخص کنید:

کاتلین

context.contentResolver.update(
        TvContractCompat.buildPreviewProgramUri(programId),
                builder.build().toContentValues(), null, null
)

جاوا

context.getContentResolver().update(TvContractCompat.buildPreviewProgramUri(programId),
    builder.build().toContentValues(), null, null);

درحال حذف برنامه

کاتلین

context.contentResolver
        .delete(TvContractCompat.buildPreviewProgramUri(programId), null, null)

جاوا

context.getContentResolver().delete(TvContractCompat.buildPreviewProgramUri(programId), null, null);

رسیدگی به کنش‌های کاربر

برنامه شما می‌تواند با ارائه واسط کاربری برای نمایش و افزودن کانال‌ها، به کاربران کمک کند محتوا را کاوش کنند. برنامه شما باید تعامل با کانال‌هایتان را پس‌از ظاهر شدن در صفحه اصلی نیز مدیریت کند.

کاوش و افزودن کانال‌ها

برنامه شما می‌تواند عنصر میانای کاربری ارائه دهد که به کاربر اجازه می‌دهد کانال‌های آن را انتخاب و اضافه کند (برای مثال، دکمه‌ای که درخواست می‌کند کانال اضافه شود).

پس‌از اینکه کاربر کانال خاصی را درخواست کرد، این کد را اجرا کنید تا اجازه کاربر را برای افزودن آن به میانای کاربر صفحه اصلی دریافت کنید:

کاتلین

val intent = Intent(TvContractCompat.ACTION_REQUEST_CHANNEL_BROWSABLE)
intent.putExtra(TvContractCompat.EXTRA_CHANNEL_ID, channelId)
try {
  activity.startActivityForResult(intent, 0)
} catch (e: ActivityNotFoundException) {
  // handle error
}

جاوا

Intent intent = new Intent(TvContractCompat.ACTION_REQUEST_CHANNEL_BROWSABLE);
intent.putExtra(TvContractCompat.EXTRA_CHANNEL_ID, channelId);
try {
   activity.startActivityForResult(intent, 0);
} catch (ActivityNotFoundException e) {
  // handle error
}

سیستم کادر گفتگویی را نمایش می‌دهد که از کاربر می‌خواهد کانال را تأیید کند. نتیجه درخواست را در روش onActivityResult فعالیتتان (Activity.RESULT_CANCELED یا Activity.RESULT_OK) مدیریت کنید.

رویدادهای صفحه اصلی Android TV

وقتی کاربر با برنامه‌ها و کانال‌های منتشرشده توسط برنامه تعامل برقرار می‌کند، صفحه اصلی هدف‌هایی را به برنامه ارسال می‌کند:

  • وقتی کاربر نشان‌واره کانال را انتخاب می‌کند، صفحه اصلی Uri ذخیره‌شده در مشخصه APP_LINK_INTENT_URI کانال را به برنامه ارسال می‌کند. برنامه باید فقط میانای کاربر اصلی یا نمای مربوط به کانال انتخاب‌شده را راه‌اندازی کند.
  • وقتی کاربر برنامه‌ای را انتخاب می‌کند، صفحه اصلی Uri ذخیره‌شده در مشخصه INTENT_URI برنامه را به برنامه ارسال می‌کند. برنامه باید محتوای انتخاب‌شده را پخش کند.
  • کاربر می‌تواند نشان دهد که دیگر به برنامه‌ای علاقه ندارد و می‌خواهد آن را از واسط کاربر صفحه اصلی بردارد. سیستم برنامه را از واسط کاربر برمی‌دارد و قصدی (android.media.tv.ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED یا android.media.tv.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED) با شناسه برنامه به برنامه‌ای که مالک برنامه است ارسال می‌کند. برنامه باید برنامه را از ارائه‌دهنده بردارد و نباید آن را دوباره درج کند.

مطمئن شوید که فیلترهای قصد را برای همه Uris که صفحه اصلی برای تعاملات کاربر ارسال می‌کند ایجاد کنید؛ برای مثال:

<receiver
   android:name=".WatchNextProgramRemoved"
   android:enabled="true"
   android:exported="true">
   <intent-filter>
       <action android:name="android.media.tv.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED" />
   </intent-filter>
</receiver>

سایر ملاحظات

  • بسیاری از برنامه‌های تلویزیون از کاربران می‌خواهند به سیستم وارد شوند. در این مورد، BroadcastReceiver که به android.media.tv.action.INITIALIZE_PROGRAMS گوش می‌دهد باید محتوای کانال را برای کاربران تأییدنشده پیشنهاد دهد. برای مثال، برنامه‌تان می‌تواند در ابتدا بهترین محتوا یا محتوای پرطرفدار فعلی را نشان دهد. پس‌از اینکه کاربر به سیستم وارد شد، می‌تواند محتوای شخصی‌سازی‌شده را نشان دهد. این فرصت خوبی برای برنامه‌ها است تا قبل‌از ورود کاربران به سیستم، فروش ویژه داشته باشند.
  • وقتی برنامه‌تان در پیش‌نما نیست و باید کانال یا برنامه‌ای را به‌روز کنید، از JobScheduler برای زمان‌بندی کار استفاده کنید (JobScheduler و JobService را ببینید).
  • اگر برنامه‌تان رفتار نادرستی داشته باشد (برای مثال، به‌طور مداوم داده‌های هرزنامه به ارائه‌دهنده ارسال کند)، سیستم می‌تواند اجازه‌های ارائه‌دهنده برنامه‌تان را لغو کند. مطمئن شوید که کد دسترسی به ارائه‌دهنده را با بندهای try-catch بپوشانید تا استثناهای امنیتی را مدیریت کنید.
  • قبل‌از به‌روزرسانی برنامه‌ها و کانال‌ها، داده‌هایی را که باید به‌روزرسانی و تطبیق دهید از ارائه‌دهنده درخواست کنید. برای مثال، نیازی نیست برنامه‌ای را که کاربر می‌خواهد از میانای کاربری برداشته شود به‌روز کنید. از کار پس‌زمینه‌ای استفاده کنید که داده‌هایتان را پس‌از جستجوی داده‌های موجود و سپس درخواست تأیید برای کانال‌هایتان، در ارائه‌دهنده درج یا به‌روزرسانی کند. می‌توانید این کار را هنگام شروع برنامه و هر زمان که برنامه نیاز به به‌روزرسانی داده‌هایش دارد اجرا کنید.

کاتلین

context.contentResolver
      .query(
          TvContractCompat.buildChannelUri(channelId),
              null, null, null, null).use({
                  cursor-> if (cursor != null and cursor.moveToNext()) {
                                val channel = Channel.fromCursor(cursor)
                                if (channel.isBrowsable()) {
                                    //update channel's programs
                                }
                            }
              })

جاوا

try (Cursor cursor = context.getContentResolver()
          .query(
              TvContractCompat.buildChannelUri(channelId),
              null,
              null,
              null,
              null)) {
                  if (cursor != null &amp;&amp; cursor.moveToNext()) {
                      Channel channel = Channel.fromCursor(cursor);
                      if (channel.isBrowsable()) {
                          //update channel's programs
                      }
                  }
              }
  • از شناسه منبع یکسان منحصربه‌فرد برای همه تصاویر (نشان‌واره‌ها، نمادها، تصاویر محتوا) استفاده کنید. حتماً هنگام به‌روزرسانی تصویر از Uri دیگری استفاده کنید. همه تصاویر در حافظه نهان ذخیره شده‌اند. اگر هنگام تغییر تصویر، Uri را تغییر ندهید، تصویر قدیمی همچنان نمایش داده خواهد شد.

  • به‌یاد داشته باشید که عبارت‌های WHERE مجاز نیستند و تماس با ارائه‌دهندگان با عبارت‌های WHERE استثنای امنیتی ایجاد می‌کند.

مشخصه‌ها

این بخش مشخصه‌های کانال و برنامه را به‌طور جداگانه شرح می‌دهد.

مشخصه‌های کانال

باید این مشخصه‌ها را برای هر کانال مشخص کنید:

مشخصه یادداشت‌ها
نوع روی TYPE_PREVIEW تنظیم شده است.
DISPLAY_NAME به نام کانال تنظیم شده است.
APP_LINK_INTENT_URI وقتی کاربر نشان‌واره کانال را انتخاب می‌کند، سیستم قصدی را برای شروع فعالیتی ارسال می‌کند که محتوای مربوط به کانال را ارائه می‌دهد. این مشخصه را روی Uri استفاده‌شده در فیلتر هدف برای آن فعالیت تنظیم کنید.

علاوه‌براین، هر کانال شش فیلد هم دارد که برای استفاده داخلی برنامه رزرو شده است. از این فیلدها می‌توان برای ذخیره کلیدها یا مقادیر دیگری استفاده کرد که می‌توانند به برنامه کمک کنند کانال را به ساختار داده‌های داخلی خود نگاشت کند:

  • INTERNAL_PROVIDER_ID
  • INTERNAL_PROVIDER_DATA
  • INTERNAL_PROVIDER_FLAG1
  • INTERNAL_PROVIDER_FLAG2
  • INTERNAL_PROVIDER_FLAG3
  • INTERNAL_PROVIDER_FLAG4

مشخصه‌های برنامه

برای دیدن مشخصه‌های هر نوع برنامه، به صفحه‌های جداگانه مراجعه کنید:

کد نمونه

برای کسب اطلاعات بیشتر درباره ساخت برنامه‌هایی که با صفحه اصلی تعامل دارند و افزودن کانال‌ها و برنامه‌ها به صفحه اصلی Android TV، به codelab صفحه اصلی ما مراجعه کنید.