توفِّر شاشة Android TV الرئيسية أو الشاشة الرئيسية واجهة مستخدم المحتوى المُقترَح كجدول للقنوات والبرامج. يمثل كل صف قناة. تحتوي القناة على بطاقات لكل برنامج متاح على هذه القناة:
يوضح هذا المستند كيفية إضافة قنوات وبرامج إلى الشاشة الرئيسية، وتحديث المحتوى، والتعامل مع إجراءات المستخدمين، وتقديم أفضل تجربة للمستخدمين. (إذا كنت تريد التعمق في واجهة برمجة التطبيقات، فحاول درس تطبيقي حول ترميز الشاشة الرئيسية ومشاهدة جلسة مؤتمر I/O لعام 2017 على Android TV.)
ملاحظة: لا تتوفّر قنوات الاقتراحات إلا في Android 8.0 (المستوى 26 من واجهة برمجة التطبيقات) والإصدارات الأحدث يجب استخدامها لتقديم اقتراحات للتطبيقات التي تعمل بنظام التشغيل Android 8.0 (المستوى 26 لواجهة برمجة التطبيقات) والإصدارات الأحدث. إلى سيقدم توصيات للتطبيقات التي تعمل على إصدارات سابقة من Android، أو تطبيقك استخدام صف الاقتراحات بدلاً من ذلك.
واجهة مستخدم الشاشة الرئيسية
يمكن للتطبيقات إنشاء قنوات جديدة وإضافة برامج وإزالتها وتعديلها في القناة والتحكّم في ترتيب البرامج في القناة. على سبيل المثال، يمكن لتطبيق إنشاء قناة باسم "الميزات الجديدة" وإظهار بطاقات للبرامج المتاحة حديثًا
لا يمكن للتطبيقات التحكّم في ترتيب ظهور القنوات في الشاشة الرئيسية. عندما ينشئ تطبيقك قناة جديدة، تضيفها الشاشة الرئيسية إلى أسفل قائمة القنوات. يمكن للمستخدم إعادة ترتيب القنوات وإخفائها وإظهارها.
قناة "اقتراحات أخرى"
قناة "اقتراحات أخرى" هي الصف الثاني الذي يظهر في الشاشة الرئيسية، بعد صف التطبيقات. ينشئ النظام هذه القناة ويحافظ عليها. يمكن لتطبيقك إضافة البرامج على قناة "اقتراحات أخرى". لمزيد من المعلومات، يُرجى الاطّلاع على المقالة إضافة برامج إلى قناة "المشاهدة تاليًا"
قنوات التطبيقات
تتبع القنوات التي ينشئها تطبيقك دورة الحياة التالية:
- يكتشف المستخدم قناة في تطبيقك ويطلب إضافتها إلى الشاشة الرئيسية.
- ينشئ التطبيق القناة ويضيفها إلى
TvProvider
(تكون القناة غير مرئية في هذه المرحلة). - يطلب التطبيق من النظام عرض القناة.
- يطلب النظام من المستخدم الموافقة على القناة الجديدة.
- تظهر القناة الجديدة في الصف الأخير من الشاشة الرئيسية.
القناة التلقائية
يمكن أن يقدم تطبيقك أي عدد من القنوات للمستخدم لإضافته إلى الشاشة الرئيسية. يضطر المستخدم عادةً إلى تحديد كل قناة والموافقة عليها قبل ظهورها في الشاشة الرئيسية. يمكن لكل تطبيق إنشاء قناة تلقائية واحدة. القناة الافتراضية خاصة لأنها تظهر تلقائيًا في الشاشة الرئيسية؛ لا يضطر المستخدم إلى تطلبها صراحةً.
المتطلّبات الأساسية
تستخدم شاشة Android TV الرئيسية واجهات TvProvider
API في Android لإدارة القنوات والبرامج التي ينشئها تطبيقك.
للوصول إلى بيانات موفِّر التطبيق، أضِف الإذن التالي إلى ملف بيان تطبيقك:
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
تسهّل مكتبة الدعم في "TvProvider
" استخدام مقدّم الخدمة. أضِفها إلى العناصر التابعة في ملف build.gradle
:
Groovy
implementation 'androidx.tvprovider:tvprovider:1.0.0'
Kotlin
implementation("androidx.tvprovider:tvprovider:1.0.0")
للعمل مع القنوات والبرامج، يجب تضمين عمليات استيراد مكتبة الدعم التالية في برنامجك:
Kotlin
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
Java
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
.
لإنشاء قناة، يُرجى اتّباع الخطوات التالية:
أنشئ أداة إنشاء القنوات واضبط سماتها. لاحظ أن يجب أن يكون نوع القناة
TYPE_PREVIEW
. إضافة المزيد السمات على النحو المطلوب.Kotlin
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)Java
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);أدخِل القناة في مقدّم الخدمة:
Kotlin
var channelUri = context.contentResolver.insert( TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues())
Java
Uri channelUri = context.getContentResolver().insert( TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues());
-
يجب حفظ معرّف القناة لإضافة برامج إلى القناة. لاحقًا. استخرِج معرّف القناة من معرّف الموارد المنتظم (URI) الذي تم عرضه:
Kotlin
var channelId = ContentUris.parseId(channelUri)
Java
long channelId = ContentUris.parseId(channelUri);
يجب إضافة شعار لقناتك. يُرجى استخدام
Uri
أوBitmap
. الشعار يجب أن يكون حجم الرمز 80 بكسل مستقل الكثافة × 80 بكسل مستقل الكثافة (dp)، ويجب أن يكون معتمًا. يتم عرضها ضمن قناع دائري:Kotlin
// 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)
Java
// 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);
إنشاء القناة التلقائية (اختياري): عند إنشاء التطبيق لأول مرة على قناتك، فيمكنك جعلها القناة التلقائية كي تظهر في الصفحة الرئيسية الشاشة على الفور دون أي إجراء من جانب المستخدم. وأي قنوات أخرى تنشئها لا تكون مرئية إلى أن ينقر المستخدم بشكل صريح يحددها.
Kotlin
TvContractCompat.requestChannelBrowsable(context, channelId)
Java
TvContractCompat.requestChannelBrowsable(context, channelId);
- اجعل قناتك التلقائية تظهر قبل فتح تطبيقك. يمكنك
أن يحدث هذا السلوك من خلال إضافة
BroadcastReceiver
التي تستمع إلى الإجراءandroid.media.tv.action.INITIALIZE_PROGRAMS
، الذي تصل إليه الشاشة الرئيسية يرسله بعد تثبيت التطبيق: عند تثبيت تطبيقك من مصدر غير معروف أثناء تطويره، يمكنك اختبار هذه الخطوة يؤدي إلى تفعيل intent من خلال adb، حيث يشير your.package.name/.YourReceiverName هو مستوى أداء تطبيقك<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>
BroadcastReceiver
:adb shell am broadcast -a android.media.tv.action.INITIALIZE_PROGRAMS -n \ your.package.name/.YourReceiverName
في حالات نادرة، قد يتلقى تطبيقك البث في الوقت نفسه الذي يستخدمه المستخدم. لبدء تشغيل تطبيقك. تأكّد من أنّ الرمز لا يحاول إضافة القناة التلقائية. أكثر من مرة.
تحديث قناة
إنّ تحديث القنوات يشبه إلى حد كبير إنشائها.
استخدِم سمة Channel.Builder
أخرى لضبط السمات التي تحتاج إلى تغييرها.
استخدِم "ContentResolver
" لتعديل القناة. استخدِم معرّف القناة الذي حفظته عند إضافة القناة في الأصل:
Kotlin
context.contentResolver.update( TvContractCompat.buildChannelUri(channelId), builder.build().toContentValues(), null, null )
Java
context.getContentResolver().update(TvContractCompat.buildChannelUri(channelId), builder.build().toContentValues(), null, null);
ولتعديل شعار القناة، استخدِم storeChannelLogo()
.
حذف قناة
Kotlin
context.contentResolver.delete(TvContractCompat.buildChannelUri(channelId), null, null)
Java
context.getContentResolver().delete(TvContractCompat.buildChannelUri(channelId), null, null);
البرامج
إضافة برامج إلى قناة التطبيق
أنشئ PreviewProgram.Builder
واضبط سماته:
Kotlin
val builder = PreviewProgram.Builder() builder.setChannelId(channelId) .setType(TvContractCompat.PreviewPrograms.TYPE_CLIP) .setTitle("Title") .setDescription("Program description") .setPosterArtUri(uri) .setIntentUri(uri) .setInternalProviderId(appProgramId)
Java
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);
ويمكنك إضافة المزيد من السمات حسب نوع البرنامج. (لعرض السمات لكل نوع من البرامج، راجِع الجداول الواردة أدناه.)
إدراج البرنامج في المزوِّد:
Kotlin
var programUri = context.contentResolver.insert(TvContractCompat.PreviewPrograms.CONTENT_URI, builder.build().toContentValues())
Java
Uri programUri = context.getContentResolver().insert(TvContractCompat.PreviewPrograms.CONTENT_URI, builder.build().toContentValues());
استرجع رقم تعريف البرنامج للرجوع إليه لاحقًا:
Kotlin
val programId = ContentUris.parseId(programUri)
Java
long programId = ContentUris.parseId(programUri);
إضافة برامج إلى قناة "اقتراحات أخرى"
لإدراج برامج في قناة "اقتراحات أخرى"، راجِع القسم إضافة برامج إلى قائمة "اقتراحات". القناة التالية:
تحديث برنامج
يمكنك تغيير معلومات البرنامج. على سبيل المثال، يمكنك تعديل سعر استئجار فيلم أو شريط تقدّم يعرض المدة التي شاهدها المستخدم من البرنامج.
استخدِم PreviewProgram.Builder
لضبط السمات التي تريد تغييرها.
ثم اتصل بـ getContentResolver().update
لتحديث البرنامج. حدِّد رقم تعريف البرنامج الذي حفظته عند إضافة البرنامج في الأصل:
Kotlin
context.contentResolver.update( TvContractCompat.buildPreviewProgramUri(programId), builder.build().toContentValues(), null, null )
Java
context.getContentResolver().update(TvContractCompat.buildPreviewProgramUri(programId), builder.build().toContentValues(), null, null);
حذف برنامج
Kotlin
context.contentResolver .delete(TvContractCompat.buildPreviewProgramUri(programId), null, null)
Java
context.getContentResolver().delete(TvContractCompat.buildPreviewProgramUri(programId), null, null);
معالجة إجراءات المستخدم
يمكن أن يساعد تطبيقك المستخدمين في استكشاف المحتوى من خلال توفير واجهة مستخدم لعرض القنوات وإضافتها. ومن المفترض أن يعالج تطبيقك أيضًا التفاعلات مع قنواتك بعد ظهورها على الشاشة الرئيسية.
اكتشاف القنوات وإضافتها
يمكن أن يوفّر تطبيقك عنصر واجهة مستخدم يتيح للمستخدم اختيار القنوات وإضافتها (على سبيل المثال، زر يطلب إضافة القناة).
بعد أن يطلب المستخدم قناة معيّنة، نفِّذ هذا الرمز للحصول على إذن المستخدم بإضافتها إلى واجهة مستخدم الشاشة الرئيسية:
Kotlin
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 }
Java
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 لأحد البرامج، وذلك عندما يختار المستخدم أحد البرامج. من المفترض أن يشغّل التطبيق المحتوى الذي اخترته. - يمكن للمستخدم الإشارة إلى أنه لم يعد مهتمًا ببرنامج ويريد إزالته من واجهة مستخدم الشاشة الرئيسية. يزيل النظام البرنامج من واجهة المستخدم ويرسل رسالة intent إلى التطبيق الذي يملك البرنامج (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>
أفضل الممارسات
- تتطلّب العديد من تطبيقات TV من المستخدمين تسجيل الدخول. وهو في هذه الحالة
BroadcastReceiver
التي تستجيب لـandroid.media.tv.action.INITIALIZE_PROGRAMS
يجب أن تقترح محتوى القناة للمستخدمين الذين لم تتم مصادقتهم.على سبيل المثال، يمكن لتطبيقك أن تعرض أفضل محتوى أو محتوى رائج حاليًا. بعد أن يقوم المستخدم بتسجيل الدخول، عرض محتوى مخصّص هذه فرصة رائعة لزيادة مبيعات التطبيقات. للمستخدمين قبل تسجيل دخولهم. - عندما لا يكون تطبيقك يعمل في المقدّمة وتحتاج إلى تحديث قناة أو
البرنامج، استخدِم
JobScheduler
لجدولة العمل (يُرجى الاطّلاع على: أداة جدولة المهام وJobService). - يمكن للنظام إبطال أذونات موفّر التطبيق في حال حدوث خلل في أداء التطبيق. (على سبيل المثال، إرسال بيانات غير مرغوب فيها باستمرار إلى المزوِّد). تأكد من يجب إحاطة الرمز البرمجي الذي يصل إلى الموفر بعبارات Try-catch للتعامل معها. استثناءات الأمان.
قبل تحديث البرامج والقنوات، اطلب من مقدم الخدمة البحث عن البيانات تحتاج إلى تحديث البيانات وتوفيقها. على سبيل المثال، لا حاجة إلى تحديث برنامج يريد المستخدم إزالته من واجهة المستخدم. استخدم وظيفة في الخلفية إدراج/تحديث بياناتك في المزود بعد الاستعلام عن البيانات ثم طلب الموافقة على إنشاء قنواتك. يمكنك تشغيل هذه المهمة عندما عند بدء تشغيل التطبيق وعندما يحتاج التطبيق إلى تحديث بياناته.
Kotlin
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 } } })
Java
try (Cursor cursor = context.getContentResolver() .query( TvContractCompat.buildChannelUri(channelId), null, null, null, null)) { if (cursor != null && cursor.moveToNext()) { Channel channel = Channel.fromCursor(cursor); if (channel.isBrowsable()) { //update channel's programs } } }
استخدم Uris الفريد لجميع الصور (الشعارات والرموز وصور المحتوى). احرص على استخدام معرّف موارد منتظم (URI) مختلف عند تعديل الصورة. تم تخزين جميع الصور مؤقتًا. إذا لم تُغير معرف الموارد المنتظم (URI) عند تغيير الصورة، فستستمر الصورة القديمة في الظهور.
تذكر أن عبارات WHERE غير مسموح بها وأن الاتصالات المقدمة إلى الموفرين باستخدام عبارات WHERE ستؤدي إلى استثناء أمان.
السمات
يصف هذا القسم سمتَي القناة والبرنامج بشكل منفصل.
سمات القناة
عليك تحديد السمات التالية لكل قناة:
السمة | ملاحظات |
---|---|
النوع | تم الضبط على TYPE_PREVIEW |
DISPLAY_NAME | على اسم القناة |
APP_LINK_INTENT_URI | عندما يختار المستخدم شعار القناة، يرسل النظام نيةً لبدء نشاط يعرض محتوًى ذا صلة بالقناة. اضبط هذه السمة على معرّف الموارد المنتظم (URI) المستخدَم في فلتر الأهداف لهذا النشاط. |
بالإضافة إلى ذلك، تتضمّن القناة ستة حقول مخصّصة لاستخدام التطبيقات الداخلية. ويمكن استخدام هذه الحقول لتخزين المفاتيح أو القيم الأخرى التي يمكن أن تساعد التطبيق في ربط القناة ببنية البيانات الداخلية:
- INTERNAL_provider_ID
- البيانات الداخلية
- INTERNAL_provider_FLAG1
- INTERNAL_provider_FLAG2
- INTERNAL_provider_FLAG3
- INTERNAL_provider_FLAG4
سمات البرنامج
اطّلِع على الصفحات الفردية لسمات كل نوع من أنواع البرامج:
نموذج التعليمات البرمجية
لمزيد من المعلومات حول إنشاء تطبيقات تتفاعل مع الشاشة الرئيسية وتضيف قنوات وبرامج إلى شاشة Android TV الرئيسية، يمكنك الاطّلاع على الدرس التطبيقي حول الترميز على الشاشة الرئيسية.