Kullanıcılar TV'lerle etkileşim kurarken genellikle içerik izlemeden önce minimum giriş yapmayı tercih eder. Birçok TV kullanıcısı için ideal senaryo şudur: Otur, aç ve izle. Kullanıcıları keyif aldıkları içeriğe ulaştırmak için gereken en az adım genellikle tercih ettikleri yoldur.
Not: Yalnızca Android 7.1 (API düzeyi 25) dahil olmak üzere bu sürümlerde çalışan uygulamalarda öneri sunmak için burada açıklanan API'leri kullanın. Android 8.0 (API düzeyi 26) ve sonraki sürümlerde çalışan uygulamalar için öneriler sunmak istiyorsanız uygulamanız öneri kanallarını kullanmalıdır.
Android çerçevesi, ana ekranda bir öneri satırı sağlayarak minimum girişli etkileşime yardımcı olur. İçerik önerileri, cihaz ilk kez kullanıldıktan sonra TV'nin ana ekranının ilk satırında gösterilir. Uygulamanızın içerik kataloğundan öneriler sunmak, kullanıcıları uygulamanıza geri çekmenize yardımcı olabilir.
Bu kılavuzda, kullanıcıların uygulama içeriğinizi keşfedip keyifle kullanabilmesi için nasıl öneriler oluşturacağınız ve bunları Android çerçevesine nasıl sağlayacağınız açıklanmaktadır. Ayrıca Leanback örnek uygulamasındaki örnek uygulamaya da göz atın.
Önerilerle ilgili en iyi uygulamalar
Öneriler, kullanıcıların beğendikleri içerikleri ve uygulamaları hızlıca bulmalarına yardımcı olur. Yüksek kaliteli ve kullanıcılarla alakalı öneriler oluşturmak, TV uygulamanızla harika bir kullanıcı deneyimi oluşturmanın önemli bir faktörüdür. Bu nedenle, kullanıcıya sunduğunuz önerileri dikkatlice değerlendirmeniz ve yakından yönetmeniz gerekir.
Öneri türleri
Öneriler oluştururken kullanıcıları tamamlanmamış izleme etkinliklerine geri yönlendirmeli veya bu etkinlikleri ilgili içeriklerle genişleten etkinlikler önermelisiniz. Dikkate almanız gereken bazı öneri türleri şunlardır:
- Kullanıcıların bir diziyi izlemeye devam etmesi için sonraki bölümle ilgili devam niteliğindeki içerik önerileri Alternatif olarak, duraklatılmış filmler, TV programları veya podcast'ler için devam ettirme önerilerini kullanabilirsiniz. Böylece kullanıcılar, duraklatılmış içerikleri birkaç tıklamayla izlemeye devam edebilir.
- Kullanıcı başka bir diziyi bitirdiyse yeni içerik önerileri (ör. ilk gösterimdeki yeni bir bölüm) Ayrıca, uygulamanız kullanıcıların içeriğe abone olmasına, takip etmesine veya içeriği izlemesine olanak tanıyorsa, izlenen içerik listesindeki izlenmemiş öğeler için yeni içerik önerileri kullanın.
- Kullanıcıların geçmiş görüntüleme davranışlarına dayalı ilgili içerik önerileri.
En iyi kullanıcı deneyimi için öneri kartlarını nasıl tasarlayacağınız hakkında daha fazla bilgi edinmek isterseniz Android TV Tasarım Spesifikasyonu'ndaki Öneri Satırı bölümüne bakın.
Önerileri yenile
Önerileri yenilerken bunları yalnızca kaldırıp yeniden yayınlamayın. Aksi takdirde öneriler, öneri satırının sonunda görünür. Bir içerik öğesi (ör. film) oynatıldıktan sonra önerilerden kaldırılır.
Önerileri özelleştir
Kartın ön ve arka plan resmi, rengi, uygulama simgesi, başlığı ve alt başlığı gibi kullanıcı arayüzü öğelerini ayarlayarak öneri kartlarını markalama bilgilerini iletecek şekilde özelleştirebilirsiniz. Daha fazla bilgi edinmek için Android TV Tasarım Spesifikasyonu'ndaki Öneri Satırı bölümüne bakın.
Grup önerileri
İsteğe bağlı olarak önerileri öneri kaynağına göre gruplandırabilirsiniz. Örneğin, uygulamanız iki grup öneri sunabilir: kullanıcının abone olduğu içeriklerle ilgili öneriler ve kullanıcının farkında olmayabileceği yeni trend olan içeriklerle ilgili öneriler.
Sistem, öneri satırını oluştururken veya güncellerken her grup için önerileri ayrı ayrı sıralar ve düzenler. Önerileriniz için grup bilgileri sağlayarak önerilerinizin alakasız öneriler altında sıralanmamasını sağlayabilirsiniz.
Bir önerinin grup anahtarı dizesini ayarlamak için NotificationCompat.Builder.setGroup() kullanın. Örneğin, bir öneriyi yeni trend olan içeriklerin bulunduğu bir gruba ait olarak işaretlemek için setGroup("trending") işlevini çağırabilirsiniz.
Bir öneri hizmeti oluşturun
İçerik önerileri arka planda işlenerek oluşturulur. Uygulamanızın önerilere katkıda bulunabilmesi için uygulamanızın kataloğundaki listelemeleri düzenli olarak sistemin öneri listesine ekleyen bir hizmet oluşturun.
Aşağıdaki kod örneğinde, uygulamanız için bir öneri hizmeti oluşturmak üzere IntentService'nın nasıl genişletileceği gösterilmektedir:
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; } }
Bu servisin sistem tarafından tanınması ve çalıştırılması için, uygulama manifestinizi kullanarak kaydınızı yaptırın. Aşağıdaki kod parçası, bu sınıfı bir hizmet olarak nasıl tanımlayacağınızı göstermektedir:
<manifest ... > <application ... > ... <service android:name="com.example.android.tvleanback.UpdateRecommendationsService" android:enabled="true" /> </application> </manifest>
Öneriler oluşturun
Öneri servisiniz çalışmaya başladıktan sonra, öneriler oluşturmalı ve bunları Android çerçevesine iletmelidir. Çerçeve, önerileri belirli bir şablon kullanan ve belirli bir kategoriyle işaretlenmiş Notification nesneler olarak alır.
Değerlerin ayarlanması
Öneri kartı için kullanıcı arayüzü öğesi değerlerini ayarlamak için, aşağıdaki gibi açıklanan oluşturucu desenini izleyen bir oluşturucu sınıfı oluşturursunuz. Öncelikle, öneri kartı öğelerinin değerlerini ayarlarsınız.
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; } ...
Bildirimi oluştur
Değerleri ayarladıktan sonra, oluşturucu sınıftan gelen değerleri bildirime atayarak ve NotificationCompat.Builder.build()'ı çağırarak bildirimi oluşturursunuz.
Ayrıca, NotificationCompat.BigPictureStyle bildiriminin diğer cihazlarda görünmemesi için setLocalOnly()'ı çağırdığınızdan emin olun.
Aşağıdaki kod örneği, bir öneri sisteminin nasıl oluşturulacağını göstermektedir.
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; } }
Öneri hizmetini çalıştırın.
Uygulamanızın öneri servisi, güncel öneriler oluşturmak için düzenli aralıklarla çalışmalıdır. Servisinizi çalıştırmak için, bir zamanlayıcı çalıştıran ve bunu düzenli aralıklarla çağıran bir sınıf oluşturun. Aşağıdaki kod örneği, öneri hizmetinin her yarım saatte bir periyodik olarak çalıştırılmasını başlatmak için BroadcastReceiver sınıfını genişletir:
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); } }
BroadcastReceiver sınıfının bu uygulaması, yüklendiği TV cihazının başlatılmasından sonra çalıştırılmalıdır. Bunu yapmak için bu sınıfı, cihaz başlatma işleminin tamamlanmasını dinleyen bir intent filtresiyle uygulama manifestinize kaydedin. Aşağıdaki örnek kod, bu yapılandırmanın manifest dosyasına nasıl ekleneceğini göstermektedir:
<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>
Önemli: Önyükleme tamamlandı bildirimini almak için uygulamanızın RECEIVE_BOOT_COMPLETED iznini istemesi gerekir.
Daha fazla bilgi için ACTION_BOOT_COMPLETED sayfasına bakın.
Öneri hizmeti sınıfınızın onHandleIntent()
yönteminde, öneriyi yöneticiye aşağıdaki şekilde gönderin:
Kotlin
val notification = notificationBuilder.build() notificationManager.notify(id, notification)
Java
Notification notification = notificationBuilder.build(); notificationManager.notify(id, notification);