Saat berinteraksi dengan TV, pengguna umumnya lebih suka memberikan input seminimal mungkin sebelum menonton konten. Skenario ideal untuk sebagian besar pengguna TV adalah: duduk, menyalakan TV, dan menontonnya. Jalur dengan langkah paling sedikit untuk mengarahkan pengguna ke konten yang mereka sukai umumnya adalah jalur yang lebih mereka sukai.
Catatan: Gunakan API yang dijelaskan di sini hanya untuk membuat rekomendasi di aplikasi yang berjalan di versi Android hingga Android 7.1 (API level 25). Untuk memberikan rekomendasi untuk aplikasi yang berjalan di Android 8.0 (API level 26) dan yang lebih baru, aplikasi Anda harus menggunakan saluran rekomendasi.
Kerangka kerja Android membantu interaksi dengan input minimal dengan menyediakan baris rekomendasi di layar beranda. Rekomendasi konten muncul sebagai baris pertama layar beranda TV setelah penggunaan pertama perangkat. Memberikan rekomendasi dari katalog konten aplikasi Anda dapat membantu menarik pengguna kembali ke aplikasi Anda.
Panduan ini mengajarkan Anda cara membuat rekomendasi dan menyediakannya ke kerangka kerja Android agar pengguna dapat menemukan dan menikmati konten aplikasi Anda. Lihat juga contoh implementasi di aplikasi contoh Leanback .
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. Karena alasan ini, Anda harus mempertimbangkan dengan cermat rekomendasi apa yang Anda sajikan kepada pengguna dan mengelolanya dengan saksama.
Jenis rekomendasi
Saat membuat rekomendasi, Anda harus menautkan pengguna kembali ke aktivitas menonton yang belum selesai atau menyarankan aktivitas yang memperluas aktivitas tersebut ke konten terkait. Berikut beberapa jenis rekomendasi spesifik yang perlu Anda pertimbangkan:
- Konten lanjutan rekomendasi untuk episode berikutnya agar pengguna dapat melanjutkan menonton serial tersebut. Atau, gunakan rekomendasi kelanjutan untuk film, acara TV, atau podcast yang dijeda sehingga pengguna dapat kembali menonton konten yang dijeda hanya dalam beberapa klik.
- Konten baru rekomendasi, seperti episode perdana yang baru ditayangkan, jika pengguna telah selesai menonton serial lain. Selain itu, jika aplikasi Anda memungkinkan pengguna untuk berlangganan, mengikuti, atau melacak konten, gunakan rekomendasi konten baru untuk item yang belum ditonton dalam daftar konten yang mereka lacak.
- Rekomendasi konten terkait berdasarkan perilaku historis yang dilihat pengguna.
Untuk informasi lebih lanjut 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 melakukan hal itu menyebabkan rekomendasi muncul di bagian akhir baris rekomendasi. Setelah sebuah konten, seperti film, diputar, hapus konten tersebut dari rekomendasi.
Sesuaikan rekomendasi
Anda dapat menyesuaikan kartu rekomendasi untuk menyampaikan informasi merek, dengan mengatur elemen antarmuka pengguna seperti gambar latar depan dan belakang kartu, warna, ikon aplikasi, judul, dan subjudul. Untuk mempelajari lebih lanjut, lihat Baris Rekomendasi di Spesifikasi Desain Android TV.
Mengelompokkan rekomendasi
Anda dapat secara opsional mengelompokkan rekomendasi berdasarkan sumber rekomendasi. Sebagai contoh, aplikasi Anda mungkin menyediakan dua kelompok rekomendasi: rekomendasi untuk konten yang telah dilanggan pengguna, dan rekomendasi untuk konten tren baru yang mungkin belum diketahui pengguna.
Sistem ini memberi peringkat dan mengurutkan rekomendasi untuk setiap grup secara terpisah saat membuat atau memperbarui baris rekomendasi. Dengan memberikan informasi grup untuk rekomendasi Anda, Anda dapat memastikan bahwa rekomendasi Anda tidak diurutkan di bawah rekomendasi yang tidak terkait.
Gunakan NotificationCompat.Builder.setGroup() untuk mengatur string kunci grup dari sebuah rekomendasi. Misalnya, untuk menandai rekomendasi sebagai bagian dari grup yang berisi konten trending baru, Anda dapat memanggil setGroup("trending").
Membuat layanan rekomendasi
Rekomendasi konten dibuat dengan pemrosesan latar belakang. Agar aplikasi Anda dapat berkontribusi pada rekomendasi, buatlah layanan yang secara berkala menambahkan daftar dari katalog aplikasi Anda ke daftar rekomendasi sistem.
Contoh kode berikut mengilustrasikan cara memperluas IntentService untuk membuat 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 dapat dikenali oleh sistem dan dijalankan, daftarkan layanan tersebut menggunakan manifes aplikasi Anda. Cuplikan kode berikut mengilustrasikan cara mendeklarasikan kelas 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 kerangka kerja Android. Kerangka kerja menerima rekomendasi sebagai objek Notification yang menggunakan templat tertentu dan ditandai dengan kategori tertentu.
Menyetel nilai
Untuk mengatur nilai elemen UI untuk kartu rekomendasi, Anda membuat kelas pembangun yang mengikuti pola pembangun yang dijelaskan sebagai berikut. Pertama, Anda mengatur nilai elemen kartu rekomendasi.
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 Anda menetapkan nilai-nilai tersebut, Anda kemudian membuat notifikasi, menetapkan nilai-nilai dari kelas pembangun ke notifikasi, dan memanggil NotificationCompat.Builder.build().
Selain itu, pastikan untuk memanggil setLocalOnly() agar notifikasi NotificationCompat.BigPictureStyle tidak 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 agar dapat membuat rekomendasi terkini. Untuk menjalankan layanan Anda, buatlah sebuah kelas yang menjalankan timer dan memanggilnya secara berkala. Contoh kode berikut memperluas kelas BroadcastReceiver untuk memulai eksekusi periodik layanan rekomendasi 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 kelas BroadcastReceiver ini harus dijalankan setelah perangkat TV tempat kelas ini diinstal dinyalakan. Untuk melakukan hal ini, daftarkan kelas ini di manifes aplikasi Anda dengan filter intent yang mendengarkan selesainya proses booting perangkat. Kode contoh berikut menunjukkan cara menambahkan konfigurasi ini ke manifest:
<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: Menerima notifikasi booting selesai mengharuskan aplikasi Anda meminta izin RECEIVE_BOOT_COMPLETED.
Untuk informasi selengkapnya, lihat ACTION_BOOT_COMPLETED.
Di dalam metode onHandleIntent() kelas layanan rekomendasi Anda, kirimkan rekomendasi ke manajer sebagai berikut:
Kotlin
val notification = notificationBuilder.build() notificationManager.notify(id, notification)
Java
Notification notification = notificationBuilder.build(); notificationManager.notify(id, notification);