Rekomendacje na Androidzie N i starszych

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.

Rysunek 1. Przykład wiersza rekomendacji.

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);