Podczas interakcji z telewizorem użytkownicy zazwyczaj wolą ograniczać się do minimum przed rozpoczęciem oglądania. treści. Idealny scenariusz dla wielu użytkowników telewizora to siadanie, włączanie i oglądanie. Jak najmniej kroków kierowanie użytkowników do treści, które lubią, jest zwykle metodą wybraną przez nich.
Uwaga: do tworzenia rekomendacji używaj opisanych tu interfejsów API w aplikacjach na urządzeniach z Androidem do wersji 7.1 (poziom interfejsu API 25) włącznie. Aby dostarczyć zaleceń dotyczących aplikacji działających w Androidzie 8.0 (poziom interfejsu API 26) lub nowszym, aplikacja musi używać kanałów rekomendacji.
Platforma Androida wspiera minimalną interakcję z danymi wejściowymi, wyświetlając wiersz rekomendacji na ekranie głównym. Rekomendacje treści wyświetlają się w pierwszym wierszu ekranu głównego telewizora po przy pierwszym użyciu urządzenia. Rekomendacje z katalogu treści aplikacji mogą pomóc aby zachęcić użytkowników do powrotu do Twojej aplikacji.
Z tego przewodnika dowiesz się, jak tworzyć rekomendacje i przekazywać je do platformy Androida dzięki czemu użytkownicy mogą łatwo odkrywać treści w aplikacji i z nich korzystać. Zobacz też przykładową implementację w Przykładowa aplikacja Leanback ,
Sprawdzone metody tworzenia rekomendacji
Rekomendacje pomagają użytkownikom szybko znajdować treści i aplikacje, które im się podobają. Tworzę trafne i wysokiej jakości rekomendacje to ważny czynnik i zwiększa wygodę użytkowników aplikacji TV. Z tego powodu należy dokładnie przemyśleć, rekomendacje przedstawiane użytkownikowi i ściśle zarządzaj nimi.
Typy rekomendacji
Tworząc rekomendacje, odsyłaj użytkowników do niepełnych aktywności lub proponują działania, które obejmują pokrewne treści. Oto niektóre z nich które warto wziąć pod uwagę:
- Rekomendacje treści kontynuacji następnego odcinka, które użytkownicy mogą wznowić podczas oglądania serialu. Możesz też korzystać z rekomendacji dotyczących kontynuacji w przypadku wstrzymanych filmów, programów telewizyjnych lub podcastów aby użytkownicy mogli wrócić do oglądania wstrzymanych treści kilkoma kliknięciami.
- rekomendacje związane z nowymi treściami, np. w przypadku pierwszego odcinka, jeśli użytkownik którzy obejrzeli już inny serial. Jeśli aplikacja pozwala użytkownikom subskrybować, obserwować lub śledzić rekomendować nowe treści w przypadku nieobejrzanych elementów na liście śledzonych treści.
- Rekomendacje powiązanych treści wybrane na podstawie opinii użytkowników historycznego sposobu oglądania.
Więcej informacji o tym, jak zaprojektować karty z rekomendacjami, aby zadbać o wygodę użytkowników, znajdziesz w artykule Wiersz rekomendacji w specyfikacji projektowej Androida TV.
Odśwież rekomendacje
Odświeżając rekomendacje, nie ograniczaj się do ich usuwania i publikowania ponownie, ponieważ rekomendacje pojawią się na końcu wiersza „Rekomendacje”. Gdy element treści, taki jak film, odtwarzany, i usuń ją z rekomendacji.
Dostosuj rekomendacje
Możesz dostosować karty rekomendacji, tak aby przekazywały informacje o marce, konfigurując interfejs takie jak pierwszy plan i obraz tła, kolor, ikona aplikacji, tytuł oraz podtytuł karty. Więcej informacji: Wiersz rekomendacji w specyfikacji projektowej Androida TV.
Rekomendacje dotyczące grup
Opcjonalnie możesz grupować rekomendacje na podstawie źródła rekomendacji. Na przykład aplikacja mogą wyświetlić 2 grupy rekomendacji: rekomendacje dotyczące treści subskrybowanych przez użytkownika, i rekomendacje treści zyskujących popularność, których użytkownik może nie znać.
Podczas tworzenia lub aktualizowania rekomendacji w przypadku każdej grupy system osobno ustala ich pozycje w rankingu i zamawia je w wierszu rekomendacji. Podając informacje o grupie na potrzeby rekomendacji, masz pewność, aby rekomendacje nie były uporządkowane pod niepowiązanymi rekomendacjami.
Używaj
NotificationCompat.Builder.setGroup()
, aby ustawić ciąg klucza grupy rekomendacji. Dla:
aby oznaczyć rekomendację jako należącą do grupy zawierającej nowe treści zyskujące popularność,
możesz zadzwonić pod numer setGroup("trending")
.
Utwórz usługę rekomendacji
Rekomendacje treści są tworzone w trakcie przetwarzania w tle. Aby aplikacja przyczyniają się do rekomendacji, utwórz usługę, która będzie okresowo dodawać informacje o do katalogu aplikacji do systemowej listy rekomendacji.
Poniższy przykładowy kod ilustruje, jak rozszerzyć IntentService
do
utwórz usługę rekomendacji dla swojej 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 usługa została rozpoznana i uruchomiona przez system, zarejestruj ją przy użyciu manifestu aplikacji. Fragment kodu poniżej pokazuje, jak zadeklarować tę klasę jako usługę:
<manifest ... > <application ... > ... <service android:name="com.example.android.tvleanback.UpdateRecommendationsService" android:enabled="true" /> </application> </manifest>
Tworzenie rekomendacji
Po uruchomieniu usługi rekomendacji musi ona tworzyć rekomendacje i przekazywać je do
platformy Android. Platforma odbiera rekomendacje jako obiekty Notification
, które używają określonego szablonu i są oznaczone konkretnym szablonem
.
Ustawianie wartości
Aby ustawić wartości elementów interfejsu na karcie rekomendacji, utwórz klasę konstruktora, która postępuje zgodnie z zgodnie z poniższym wzorcem narzędzia. Najpierw ustawiasz wartości na karcie 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; } ...
Utwórz powiadomienie
Po ustawieniu wartości utwórz powiadomienie, przypisując wartości z konstruktora
do powiadomienia i wywołaj NotificationCompat.Builder.build()
.
Pamiętaj też, by zadzwonić
setLocalOnly()
więc powiadomienie z aplikacji NotificationCompat.BigPictureStyle
się nie pojawi
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; } }
Uruchamianie usługi rekomendacji
Usługa rekomendacji aplikacji musi być co jakiś czas uruchamiana, aby mogła być
o zaleceniach. Aby uruchomić usługę, utwórz klasę, która uruchamia licznik czasu i wywołuje
w regularnych odstępach czasu. Ten przykładowy kod rozszerza klasę BroadcastReceiver
, aby rozpocząć okresowe wykonywanie usługi rekomendacji
co pół godziny:
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ć uruchamiana po rozpoczęciu
urządzenia, na którym jest zainstalowane. Aby to zrobić, zarejestruj te zajęcia w aplikacji
plik manifestu z filtrem intencji, który nasłuchuje na zakończenie procesu rozruchu 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: otrzymanie powiadomienia o ukończeniu uruchamiania wymaga, aby aplikacja
prosi o uprawnienie RECEIVE_BOOT_COMPLETED
.
Więcej informacji: ACTION_BOOT_COMPLETED
.
W klasie usługi rekomendacji onHandleIntent()
prześlij rekomendację do menedżera w następujący sposób:
Kotlin
val notification = notificationBuilder.build() notificationManager.notify(id, notification)
Java
Notification notification = notificationBuilder.build(); notificationManager.notify(id, notification);