Podczas interakcji z telewizorami użytkownicy wolą nie podejmować żadnych działań przed obejrzeniem filmu. Idealny scenariusz dla wielu użytkowników telewizji to: usiądź, włącz się i oglądaj. Aby zachęcić użytkowników do obejrzenia treści, które im się podobają, zwykle stosuje się preferowaną przez nich ścieżkę.
Uwaga: opisane tutaj interfejsy API pozwalają tworzyć rekomendacje tylko w aplikacjach działających na urządzeniach z Androidem w wersji do 7.1 (poziom interfejsu API 25) włącznie. Aby udostępniać rekomendacje aplikacji działających w Androidzie 8.0 (poziom interfejsu API 26) i nowszych, aplikacja musi używać kanałów rekomendacji.
Platforma Android ułatwia interakcję z minimalną ilością danych, wyświetlając wiersz rekomendacji na ekranie głównym. Rekomendacje treści pojawiają się jako pierwszy wiersz na ekranie głównym telewizora po pierwszym użyciu urządzenia. Rekomendacje z katalogu treści aplikacji mogą pomóc użytkownikom wrócić do Twojej aplikacji.
Z tego przewodnika dowiesz się, jak tworzyć rekomendacje i udostępniać je w ramach platformy Androida, aby użytkownicy mogli łatwo odkrywać i korzystać z treści Twojej aplikacji. Zobacz też przykładową implementację w przykładowej aplikacji funkcji TalkBack.
Sprawdzone metody dotyczące rekomendacji
Rekomendacje pomagają użytkownikom szybko znajdować interesujące ich treści i aplikacje. Tworzenie rekomendacji wysokiej jakości, które są przydatne dla użytkowników, ma duże znaczenie dla zapewnienia użytkownikom wygody korzystania z aplikacji na telewizorze. Dlatego należy dokładnie przemyśleć, jakie rekomendacje przekazujesz użytkownikowi, i dokładnie nimi zarządzać.
Typy rekomendacji
Tworząc rekomendacje, odsyłaj użytkowników do niezakończonych działań związanych z oglądaniem lub sugeruj działania, które mogą rozszerzyć o powiązane treści. Oto kilka konkretnych rekomendacji, które warto wziąć pod uwagę:
- Rekomendacje dotyczące dalszych treści dotyczące następnego odcinka, aby użytkownicy mogli wznowić oglądanie serii. Możesz też użyć rekomendacji kontynuacji w przypadku wstrzymanych filmów, seriali i podcastów, aby użytkownicy mogli za pomocą kilku kliknięć wrócić do wstrzymanych treści.
- rekomendacje nowych treści (np. nowego odcinka serialu), jeśli użytkownik zakończył oglądanie innego serialu. Jeśli Twoja aplikacja umożliwia użytkownikom subskrybowanie, obserwowanie lub śledzenie treści, możesz też korzystać z rekomendacji nowych treści dotyczących nieobejrzanych elementów na ich liście śledzonych treści.
- Rekomendacje podobnych treści oparte na wcześniejszych zachowaniach użytkowników.
Więcej informacji o projektowaniu kart rekomendacji, które zapewniają użytkownikom najlepsze wrażenia, znajdziesz w wierszu rekomendacji w specyfikacji projektu Androida TV.
Odśwież rekomendacje
Przy odświeżaniu rekomendacji nie tylko nie usuwaj ich i publikuj ponownie, ponieważ dzięki temu rekomendacje pojawiają się na końcu wiersza rekomendacji. Po odtworzeniu elementu treści, na przykład filmu, usuń go z rekomendacji.
Dostosuj rekomendacje
Możesz dostosować karty rekomendacji, aby przekazywały informacje o marce, ustawiając elementy interfejsu, takie jak obraz na pierwszym planie i w tle, kolor, ikona aplikacji, tytuł i podtytuł. Więcej informacji znajdziesz w sekcji Wiersz rekomendacji w specyfikacji projektu Androida TV.
Rekomendacje dotyczące grupy
Opcjonalnie możesz grupować rekomendacje na podstawie źródła rekomendacji. Aplikacja może na przykład przedstawiać 2 grupy rekomendacji: rekomendacje dotyczące treści, które subskrybuje, oraz rekomendacje dotyczące nowych treści zyskujących popularność, których użytkownik może nie znać.
System klasyfikuje i sortuje rekomendacje dla każdej grupy oddzielnie podczas tworzenia lub aktualizowania wiersza rekomendacji. Podając informacje o grupach na potrzeby rekomendacji, możesz zadbać o to, aby rekomendacje nie były uporządkowane poniżej niepowiązanych rekomendacji.
Użyj operatora NotificationCompat.Builder.setGroup()
, aby ustawić ciąg klucza grupy rekomendacji. Aby na przykład oznaczyć rekomendację jako należącą do grupy zawierającej nowe treści zyskujące popularność, możesz wywołać setGroup("trending")
.
Tworzenie usługi rekomendacji
Rekomendacje treści są tworzone podczas przetwarzania w tle. Aby aplikacja mogła brać udział w rekomendacjach, utwórz usługę, która okresowo dodaje informacje z katalogu aplikacji do listy rekomendacji systemu.
Poniższy przykładowy kod ilustruje, jak rozszerzyć IntentService
, aby utworzyć usługę rekomendacji dla Twojej aplikacji:
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; } }
Aby system rozpoznał i uruchomił tę usługę, zarejestruj ją za pomocą pliku manifestu aplikacji. Ten fragment kodu pokazuje, jak zadeklarować tę klasę jako usługę:
<manifest ... > <application ... > ... <service android:name="com.example.android.tvleanback.UpdateRecommendationsService" android:enabled="true" /> </application> </manifest>
Rekomendacje dotyczące kompilacji
Po uruchomieniu usługi rekomendacji musi ona tworzyć rekomendacje i przekazywać je do platformy Androida. Platforma otrzymuje rekomendacje jako obiekty Notification
, które korzystają z określonego szablonu i są oznaczone konkretną kategorią.
Ustawianie wartości
Aby ustawić wartości elementów interfejsu na karcie rekomendacji, utwórz klasę konstruktora zgodną z wzorcem konstruktora opisanym poniżej. Najpierw ustaw wartości elementów karty rekomendacji.
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; } ...
Tworzenie powiadomienia
Po ustawieniu wartości utwórz powiadomienie, przypisując do niego wartości z klasy konstruktora i wywołując NotificationCompat.Builder.build()
.
Zadzwoń też pod numer setLocalOnly()
, aby powiadomienie z aplikacji NotificationCompat.BigPictureStyle
nie pojawiło się na innych urządzeniach.
Poniższy przykładowy kod pokazuje, jak utworzyć rekomendację.
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; } }
Uruchom usługę rekomendacji
Usługa rekomendacji aplikacji musi działać okresowo, aby utworzyć bieżące rekomendacje. Aby uruchomić usługę, utwórz klasę, która uruchamia licznik czasu i wywołuje go w regularnych odstępach czasu. Ten przykładowy kod rozszerza klasę BroadcastReceiver
tak, aby co pół godziny uruchamiać okresowe wykonywanie usługi rekomendacji:
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); } }
Ta implementacja klasy BroadcastReceiver
musi być uruchomiona po uruchomieniu urządzenia telewizyjnego, na którym jest zainstalowana. Aby to zrobić, zarejestruj tę klasę w pliku manifestu aplikacji za pomocą filtra intencji, który nasłuchuje ukończenia procesu uruchamiania urządzenia. Ten przykładowy kod pokazuje, jak dodać tę konfigurację do pliku manifestu:
<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>
Ważne: aby otrzymać powiadomienie o zakończeniu uruchamiania, aplikacja musi poprosić o uprawnienie RECEIVE_BOOT_COMPLETED
.
Więcej informacji: ACTION_BOOT_COMPLETED
.
Opublikuj rekomendację dla menedżera w metodzie onHandleIntent()
klasy usługi rekomendacji w ten sposób:
Kotlin
val notification = notificationBuilder.build() notificationManager.notify(id, notification)
Java
Notification notification = notificationBuilder.build(); notificationManager.notify(id, notification);