کانال ها در صفحه اصلی

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

صفحه اصلی تلویزیون اندروید
صفحه اصلی تلویزیون اندروید

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

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

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

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

کانال واچ نکست

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

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

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

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

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

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

پیش‌نیازها

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

<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() مربوط به activity، کد وضعیت 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 استفاده کنید. آیکون لوگو باید 80dp x 80dp باشد و باید مات باشد. این آیکون زیر یک ماسک دایره‌ای نمایش داده می‌شود:

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

    کاتلین

    // 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);

برنامه‌ها

برنامه‌ها، کارت‌های محتوای جداگانه‌ای هستند که در یک کانال نمایش داده می‌شوند. می‌توانید برنامه‌ها را هم در کانال‌های سفارشی برنامه خود و هم در کانال Watch Next که توسط سیستم مدیریت می‌شود، منتشر کنید.

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

یک 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);

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

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

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

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

از 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 خود ( Activity.RESULT_CANCELED یا Activity.RESULT_OK ) مدیریت کنید.

رویدادهای صفحه اصلی اندروید تی‌وی

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

  • صفحه اصلی، 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 که صفحه اصلی برای تعاملات کاربر ارسال می‌کند، فیلترهای intent ایجاد کرده‌اید؛ برای مثال:

<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
                      }
                  }
              }
  • برای همه تصاویر (لوگوها، آیکون‌ها، تصاویر محتوا) از Uris منحصر به فرد استفاده کنید. هنگام به‌روزرسانی یک تصویر، حتماً از Uri متفاوتی استفاده کنید. همه تصاویر در حافظه پنهان (cache) ذخیره می‌شوند. اگر هنگام تغییر تصویر، Uri را تغییر ندهید، تصویر قدیمی همچنان ظاهر خواهد شد.

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

ویژگی‌ها

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

ویژگی‌های کانال

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

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

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

  • شناسه ارائه دهنده داخلی
  • داده‌های ارائه‌دهنده داخلی
  • پرچم_ارائه_دهنده_داخلی1
  • پرچم_ارائه_دهنده_داخلی2
  • پرچم داخلی ارائه دهنده
  • پرچم_ارائه_دهنده_داخلی4

ویژگی‌های برنامه

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

کد نمونه

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