Saat berinteraksi dengan TV, pengguna umumnya lebih suka memberikan input minimal sebelum menonton saat ini. Skenario ideal untuk sebagian besar pengguna TV adalah: duduk, menyalakan TV, dan menontonnya. Langkah paling sedikit membuat pengguna mendapatkan konten yang mereka sukai, umumnya adalah jalur yang mereka sukai.
Catatan: Gunakan API yang dijelaskan di sini untuk membuat rekomendasi di aplikasi yang berjalan di versi Android hingga dan termasuk Android 7.1 (API level 25) saja. Untuk memasok rekomendasi untuk aplikasi yang berjalan di Android 8.0 (API level 26) dan yang lebih baru, aplikasi harus menggunakan saluran rekomendasi.
Framework Android membantu interaksi dengan input minimum dengan memberikan baris rekomendasi di layar beranda. Rekomendasi konten muncul sebagai baris pertama layar utama TV setelah perangkat tersebut digunakan untuk pertama kalinya. Memberikan rekomendasi dari katalog konten aplikasi Anda dapat membantu membawa pengguna kembali ke aplikasi Anda.
Panduan ini mengajarkan cara membuat rekomendasi dan memberikannya ke framework Android agar pengguna dapat dengan mudah menemukan dan menikmati konten aplikasi Anda. Lihat juga contoh implementasi di tindakan Aplikasi contoh Leanback kami.
Praktik terbaik untuk rekomendasi
Rekomendasi membantu pengguna menemukan konten dan aplikasi yang mereka nikmati dengan cepat. Membuat rekomendasi yang berkualitas tinggi dan relevan bagi pengguna merupakan faktor penting dalam menciptakan pengalaman pengguna yang hebat dengan aplikasi TV Anda. Untuk alasan ini, Anda harus mempertimbangkan dengan cermat rekomendasi yang Anda berikan kepada pengguna dan mengelolanya dengan cermat.
Jenis rekomendasi
Saat membuat rekomendasi, Anda harus menautkan pengguna kembali ke aktivitas menonton yang belum selesai atau menyarankan aktivitas yang memperluasnya ke konten terkait. Berikut adalah beberapa jenis rekomendasi yang harus Anda pertimbangkan:
- Rekomendasi konten lanjutan untuk episode berikutnya yang dapat dilanjutkan oleh pengguna menonton serial. Atau, gunakan rekomendasi lanjutan untuk film, acara TV, atau podcast yang dijeda sehingga pengguna dapat kembali menonton konten yang dijeda hanya dengan beberapa klik.
- Rekomendasi konten baru, seperti untuk episode yang diputar pertama kali, jika pengguna selesai menonton serial lainnya. Selain itu, jika aplikasi Anda memungkinkan pengguna berlangganan, mengikuti, atau melacak menggunakan rekomendasi konten baru untuk item yang belum ditonton dalam daftar konten yang dilacak.
- Rekomendasi konten terkait berdasarkan perilaku historis yang dilihat pengguna.
Untuk informasi selengkapnya tentang cara mendesain kartu rekomendasi untuk pengalaman pengguna terbaik, lihat Baris Rekomendasi di Spesifikasi Desain Android TV.
Memuat ulang rekomendasi
Saat memperbarui rekomendasi, jangan hanya menghapus dan memposting ulang, karena hal itu akan menyebabkan rekomendasi agar muncul di akhir baris rekomendasi. Setelah item konten, seperti film, telah diputar, menghapusnya dari rekomendasi.
Menyesuaikan rekomendasi
Anda dapat menyesuaikan kartu rekomendasi untuk menyampaikan informasi branding, dengan menyetel antarmuka pengguna elemen seperti gambar latar depan dan latar belakang, warna, ikon aplikasi, judul, dan subjudul kartu. Untuk mempelajari lebih lanjut, lihat Baris Rekomendasi di Spesifikasi Desain Android TV.
Mengelompokkan rekomendasi
Anda dapat secara opsional mengelompokkan rekomendasi berdasarkan sumber rekomendasi. Misalnya, aplikasi Anda mungkin memberikan dua kelompok rekomendasi: rekomendasi untuk konten yang di-subscribe pengguna, dan rekomendasi konten trending baru yang mungkin tidak diketahui pengguna.
Sistem memberi peringkat dan mengurutkan rekomendasi untuk setiap grup secara terpisah saat membuat atau memperbarui baris rekomendasi. Dengan menyediakan informasi grup untuk rekomendasi, Anda dapat memastikan bahwa rekomendasi Anda tidak diurutkan di bawah rekomendasi yang tidak terkait.
Gunakan
NotificationCompat.Builder.setGroup()
untuk menetapkan string kunci grup dari rekomendasi. Sebagai
misalnya, untuk menandai rekomendasi sebagai milik grup yang berisi konten trending baru,
Anda mungkin memanggil setGroup("trending")
.
Membuat layanan rekomendasi
Rekomendasi konten dibuat dengan pemrosesan latar belakang. Agar aplikasi Anda berkontribusi pada rekomendasi, buat layanan yang secara berkala menambahkan listingan dari katalog aplikasi ke daftar rekomendasi sistem.
Contoh kode berikut mengilustrasikan cara memperluas IntentService
ke
buat layanan rekomendasi untuk aplikasi Anda:
Kotlin
class UpdateRecommendationsService : IntentService("RecommendationService") { override protected fun onHandleIntent(intent: Intent) { Log.d(TAG, "Updating recommendation cards") val recommendations = VideoProvider.getMovieList() if (recommendations == null) return var count = 0 try { val builder = RecommendationBuilder() .setContext(applicationContext) .setSmallIcon(R.drawable.videos_by_google_icon) for (entry in recommendations.entrySet()) { for (movie in entry.getValue()) { Log.d(TAG, "Recommendation - " + movie.getTitle()) builder.setBackground(movie.getCardImageUrl()) .setId(count + 1) .setPriority(MAX_RECOMMENDATIONS - count) .setTitle(movie.getTitle()) .setDescription(getString(R.string.popular_header)) .setImage(movie.getCardImageUrl()) .setIntent(buildPendingIntent(movie)) .build() if (++count >= MAX_RECOMMENDATIONS) { break } } if (++count >= MAX_RECOMMENDATIONS) { break } } } catch (e: IOException) { Log.e(TAG, "Unable to update recommendation", e) } } private fun buildPendingIntent(movie: Movie): PendingIntent { val detailsIntent = Intent(this, DetailsActivity::class.java) detailsIntent.putExtra("Movie", movie) val stackBuilder = TaskStackBuilder.create(this) stackBuilder.addParentStack(DetailsActivity::class.java) stackBuilder.addNextIntent(detailsIntent) // Ensure a unique PendingIntents, otherwise all // recommendations end up with the same PendingIntent detailsIntent.setAction(movie.getId().toString()) val intent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT) return intent } companion object { private val TAG = "UpdateRecommendationsService" private val MAX_RECOMMENDATIONS = 3 } }
Java
public class UpdateRecommendationsService extends IntentService { private static final String TAG = "UpdateRecommendationsService"; private static final int MAX_RECOMMENDATIONS = 3; public UpdateRecommendationsService() { super("RecommendationService"); } @Override protected void onHandleIntent(Intent intent) { Log.d(TAG, "Updating recommendation cards"); HashMap<String, List<Movie>> recommendations = VideoProvider.getMovieList(); if (recommendations == null) return; int count = 0; try { RecommendationBuilder builder = new RecommendationBuilder() .setContext(getApplicationContext()) .setSmallIcon(R.drawable.videos_by_google_icon); for (Map.Entry<String, List<Movie>> entry : recommendations.entrySet()) { for (Movie movie : entry.getValue()) { Log.d(TAG, "Recommendation - " + movie.getTitle()); builder.setBackground(movie.getCardImageUrl()) .setId(count + 1) .setPriority(MAX_RECOMMENDATIONS - count) .setTitle(movie.getTitle()) .setDescription(getString(R.string.popular_header)) .setImage(movie.getCardImageUrl()) .setIntent(buildPendingIntent(movie)) .build(); if (++count >= MAX_RECOMMENDATIONS) { break; } } if (++count >= MAX_RECOMMENDATIONS) { break; } } } catch (IOException e) { Log.e(TAG, "Unable to update recommendation", e); } } private PendingIntent buildPendingIntent(Movie movie) { Intent detailsIntent = new Intent(this, DetailsActivity.class); detailsIntent.putExtra("Movie", movie); TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); stackBuilder.addParentStack(DetailsActivity.class); stackBuilder.addNextIntent(detailsIntent); // Ensure a unique PendingIntents, otherwise all // recommendations end up with the same PendingIntent detailsIntent.setAction(Long.toString(movie.getId())); PendingIntent intent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); return intent; } }
Agar layanan ini dikenali oleh sistem dan dijalankan, daftarkan layanan menggunakan manifes aplikasi. Cuplikan kode berikut mengilustrasikan cara mendeklarasikan class ini sebagai layanan:
<manifest ... > <application ... > ... <service android:name="com.example.android.tvleanback.UpdateRecommendationsService" android:enabled="true" /> </application> </manifest>
Membuat rekomendasi
Setelah layanan rekomendasi Anda mulai berjalan, layanan tersebut harus membuat rekomendasi dan meneruskannya ke
framework Android. Framework ini menerima rekomendasi sebagai objek Notification
yang menggunakan template spesifik dan ditandai dengan
kategori.
Menyetel nilai
Untuk menyetel nilai elemen UI bagi kartu rekomendasi, Anda membuat class builder yang mengikuti pola builder yang dijelaskan sebagai berikut. Pertama, Anda menetapkan nilai kartu rekomendasi yang kurang penting.
Kotlin
class RecommendationBuilder { ... fun setTitle(title: String): RecommendationBuilder { this.title = title return this } fun setDescription(description: String): RecommendationBuilder { this.description = description return this } fun setImage(uri: String): RecommendationBuilder { imageUri = uri return this } fun setBackground(uri: String): RecommendationBuilder { backgroundUri = uri return this } ...
Java
public class RecommendationBuilder { ... public RecommendationBuilder setTitle(String title) { this.title = title; return this; } public RecommendationBuilder setDescription(String description) { this.description = description; return this; } public RecommendationBuilder setImage(String uri) { imageUri = uri; return this; } public RecommendationBuilder setBackground(String uri) { backgroundUri = uri; return this; } ...
Membuat notifikasi
Setelah menetapkan nilai, Anda kemudian akan membuat notifikasi, menetapkan nilai dari builder
ke notifikasi, dan memanggil NotificationCompat.Builder.build()
.
Juga, pastikan untuk memanggil
setLocalOnly()
jadi notifikasi NotificationCompat.BigPictureStyle
tidak akan muncul
di perangkat lain.
Contoh kode berikut menunjukkan cara membuat rekomendasi.
Kotlin
class RecommendationBuilder { ... @Throws(IOException::class) fun build(): Notification { ... val notification = NotificationCompat.BigPictureStyle( NotificationCompat.Builder(context) .setContentTitle(title) .setContentText(description) .setPriority(priority) .setLocalOnly(true) .setOngoing(true) .setColor(context.resources.getColor(R.color.fastlane_background)) .setCategory(Notification.CATEGORY_RECOMMENDATION) .setLargeIcon(image) .setSmallIcon(smallIcon) .setContentIntent(intent) .setExtras(extras)) .build() return notification } }
Java
public class RecommendationBuilder { ... public Notification build() throws IOException { ... Notification notification = new NotificationCompat.BigPictureStyle( new NotificationCompat.Builder(context) .setContentTitle(title) .setContentText(description) .setPriority(priority) .setLocalOnly(true) .setOngoing(true) .setColor(context.getResources().getColor(R.color.fastlane_background)) .setCategory(Notification.CATEGORY_RECOMMENDATION) .setLargeIcon(image) .setSmallIcon(smallIcon) .setContentIntent(intent) .setExtras(extras)) .build(); return notification; } }
Menjalankan layanan rekomendasi
Layanan rekomendasi aplikasi Anda harus berjalan secara berkala untuk membuat
rekomendasi. Untuk menjalankan layanan, buat class yang menjalankan timer dan memanggil
secara berkala. Contoh kode berikut memperluas class BroadcastReceiver
untuk memulai eksekusi layanan rekomendasi secara berkala
setiap setengah jam:
Kotlin
class BootupActivity : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { Log.d(TAG, "BootupActivity initiated") if (intent.action.endsWith(Intent.ACTION_BOOT_COMPLETED)) { scheduleRecommendationUpdate(context) } } private fun scheduleRecommendationUpdate(context: Context) { Log.d(TAG, "Scheduling recommendations update") val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager val recommendationIntent = Intent(context, UpdateRecommendationsService::class.java) val alarmIntent = PendingIntent.getService(context, 0, recommendationIntent, 0) alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, INITIAL_DELAY, AlarmManager.INTERVAL_HALF_HOUR, alarmIntent ) } companion object { private val TAG = "BootupActivity" private val INITIAL_DELAY:Long = 5000 } }
Java
public class BootupActivity extends BroadcastReceiver { private static final String TAG = "BootupActivity"; private static final long INITIAL_DELAY = 5000; @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "BootupActivity initiated"); if (intent.getAction().endsWith(Intent.ACTION_BOOT_COMPLETED)) { scheduleRecommendationUpdate(context); } } private void scheduleRecommendationUpdate(Context context) { Log.d(TAG, "Scheduling recommendations update"); AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Intent recommendationIntent = new Intent(context, UpdateRecommendationsService.class); PendingIntent alarmIntent = PendingIntent.getService(context, 0, recommendationIntent, 0); alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, INITIAL_DELAY, AlarmManager.INTERVAL_HALF_HOUR, alarmIntent); } }
Implementasi class BroadcastReceiver
ini harus berjalan setelah dimulai
di perangkat TV tempat penginstalan. Untuk melakukannya, daftarkan class ini di aplikasi Anda
manifes dengan filter intent yang memproses penyelesaian proses {i>booting<i} perangkat. Tujuan
kode contoh berikut menunjukkan cara menambahkan konfigurasi ini ke manifes:
<manifest ... > <application ... > <receiver android:name="com.example.android.tvleanback.BootupActivity" android:enabled="true" android:exported="false"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver> </application> </manifest>
Penting: Penerimaan notifikasi proses booting selesai mengharuskan aplikasi Anda
meminta izin RECEIVE_BOOT_COMPLETED
.
Untuk informasi selengkapnya, lihat ACTION_BOOT_COMPLETED
.
Di class layanan rekomendasi Anda onHandleIntent()
, posting rekomendasi ke manajer sebagai berikut:
Kotlin
val notification = notificationBuilder.build() notificationManager.notify(id, notification)
Java
Notification notification = notificationBuilder.build(); notificationManager.notify(id, notification);