توصیه هایی در Android N و نسخه های قبلی

هنگام تعامل با تلویزیون‌ها، کاربران معمولاً ترجیح می‌دهند قبل از تماشای محتوا، حداقل اطلاعات را ارائه دهند. یک سناریوی ایده‌آل برای بسیاری از کاربران تلویزیون این است: بنشینید، تلویزیون را روشن کنید و تماشا کنید. کمترین مراحل برای رساندن کاربران به محتوایی که از آن لذت می‌برند، عموماً مسیری است که آنها ترجیح می‌دهند.

توجه: از APIهای شرح داده شده در اینجا فقط برای ارائه توصیه در برنامه‌هایی که در نسخه‌های اندروید تا اندروید ۷.۱ (سطح API ۲۵) اجرا می‌شوند، استفاده کنید. برای ارائه توصیه برای برنامه‌هایی که در اندروید ۸.۰ (سطح API ۲۶) و بالاتر اجرا می‌شوند، برنامه شما باید از کانال‌های توصیه استفاده کند.

چارچوب اندروید با ارائه یک ردیف پیشنهاد در صفحه اصلی، به تعامل با حداقل ورودی کمک می‌کند. پیشنهادهای محتوا پس از اولین استفاده از دستگاه، در اولین ردیف صفحه اصلی تلویزیون ظاهر می‌شوند. ارائه پیشنهادها از فهرست محتوای برنامه شما می‌تواند به بازگشت کاربران به برنامه شما کمک کند.

نمونه‌ای از ردیف پیشنهادات در صفحه اصلی تلویزیون اندروید
شکل ۱. نمونه‌ای از ردیف توصیه‌ها.

این راهنما به شما آموزش می‌دهد که چگونه توصیه‌هایی ایجاد کنید و آنها را در چارچوب اندروید ارائه دهید تا کاربران بتوانند محتوای برنامه شما را کشف کرده و از آن لذت ببرند. همچنین به نمونه پیاده‌سازی در برنامه نمونه Leanback مراجعه کنید.

بهترین شیوه‌ها برای توصیه‌ها

توصیه‌ها به کاربران کمک می‌کنند تا به سرعت محتوا و برنامه‌های مورد علاقه خود را پیدا کنند. ایجاد توصیه‌هایی که با کیفیت بالا و مرتبط با کاربران باشند، عامل مهمی در ایجاد یک تجربه کاربری عالی با برنامه تلویزیونی شما است. به همین دلیل، باید به دقت بررسی کنید که چه توصیه‌هایی را به کاربر ارائه می‌دهید و آنها را از نزدیک مدیریت کنید.

انواع توصیه‌ها

وقتی توصیه‌هایی ایجاد می‌کنید، باید کاربران را به فعالیت‌های مشاهده‌ی ناقص پیوند دهید یا فعالیت‌هایی را پیشنهاد دهید که آن را به محتوای مرتبط گسترش می‌دهند. در اینجا چند نوع خاص از توصیه‌ها وجود دارد که باید در نظر بگیرید:

  • پیشنهادهای ادامه محتوا برای قسمت بعدی برای کاربران تا بتوانند تماشای یک سریال را از سر بگیرند. یا از پیشنهادهای ادامه برای فیلم‌ها، برنامه‌های تلویزیونی یا پادکست‌های متوقف‌شده استفاده کنید تا کاربران بتوانند تنها با چند کلیک به تماشای محتوای متوقف‌شده بازگردند.
  • توصیه‌های محتوای جدید ، مانند یک قسمت جدید برای اولین بار، در صورتی که کاربر تماشای سریال دیگری را تمام کرده باشد. همچنین، اگر برنامه شما به کاربران اجازه می‌دهد در محتوا مشترک شوند، آن را دنبال کنند یا آن را پیگیری کنند، از توصیه‌های محتوای جدید برای موارد تماشا نشده در فهرست محتوای پیگیری شده آنها استفاده کنید.
  • توصیه‌های محتوای مرتبط بر اساس سابقه‌ی مشاهده‌ی کاربران.

برای اطلاعات بیشتر در مورد نحوه طراحی کارت‌های توصیه برای بهترین تجربه کاربری، به ردیف توصیه‌ها در مشخصات طراحی تلویزیون اندروید مراجعه کنید.

توصیه‌های تازه

هنگام به‌روزرسانی توصیه‌ها، آنها را صرفاً حذف و دوباره ارسال نکنید، زیرا انجام این کار باعث می‌شود توصیه‌ها در انتهای ردیف توصیه‌ها ظاهر شوند. پس از پخش یک آیتم محتوا، مانند یک فیلم، آن را از توصیه‌ها حذف کنید .

سفارشی‌سازی توصیه‌ها

شما می‌توانید کارت‌های توصیه را برای انتقال اطلاعات برندسازی، با تنظیم عناصر رابط کاربری مانند تصویر پیش‌زمینه و پس‌زمینه کارت، رنگ، آیکون برنامه، عنوان و زیرنویس، سفارشی کنید. برای کسب اطلاعات بیشتر، به ردیف توصیه‌ها در مشخصات طراحی تلویزیون اندروید مراجعه کنید.

توصیه‌های گروهی

شما می‌توانید به صورت اختیاری توصیه‌ها را بر اساس منبع توصیه گروه‌بندی کنید. به عنوان مثال، برنامه شما ممکن است دو گروه توصیه ارائه دهد: توصیه‌هایی برای محتوایی که کاربر در آن مشترک شده است، و توصیه‌هایی برای محتوای پرطرفدار جدیدی که کاربر ممکن است از آن آگاه نباشد.

سیستم هنگام ایجاد یا به‌روزرسانی ردیف توصیه‌ها، توصیه‌ها را برای هر گروه به‌طور جداگانه رتبه‌بندی و مرتب می‌کند. با ارائه اطلاعات گروه برای توصیه‌های خود، می‌توانید اطمینان حاصل کنید که توصیه‌های شما تحت توصیه‌های نامرتبط مرتب نمی‌شوند.

از NotificationCompat.Builder.setGroup() برای تنظیم رشته کلید گروه یک توصیه استفاده کنید. برای مثال، برای علامت‌گذاری یک توصیه به عنوان متعلق به گروهی که حاوی محتوای پرطرفدار جدید است، می‌توانید setGroup("trending") را فراخوانی کنید.

ایجاد سرویس توصیه‌ها

توصیه‌های محتوا با پردازش پس‌زمینه ایجاد می‌شوند. برای اینکه برنامه شما در ارائه توصیه‌ها مشارکت داشته باشد، سرویسی ایجاد کنید که به صورت دوره‌ای فهرست‌هایی از کاتالوگ برنامه شما را به فهرست توصیه‌های سیستم اضافه کند.

مثال کد زیر نحوه‌ی گسترش IntentService برای ایجاد یک سرویس توصیه برای برنامه‌ی شما را نشان می‌دهد:

کاتلین

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
    }
}

جاوا

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

برای اینکه این سرویس توسط سیستم شناسایی و اجرا شود، آن را با استفاده از مانیفست برنامه خود ثبت کنید. قطعه کد زیر نحوه اعلام این کلاس به عنوان یک سرویس را نشان می‌دهد:

<manifest ... >
  <application ... >
    ...

    <service
            android:name="com.example.android.tvleanback.UpdateRecommendationsService"
            android:enabled="true" />
  </application>
</manifest>

توصیه‌ها را بسازید

به محض اینکه سرویس توصیه شما شروع به اجرا می‌کند، باید توصیه‌هایی ایجاد کرده و آنها را به چارچوب اندروید ارسال کند. چارچوب، توصیه‌ها را به عنوان اشیاء Notification دریافت می‌کند که از یک الگوی خاص استفاده می‌کنند و با یک دسته خاص علامت‌گذاری شده‌اند.

تنظیم مقادیر

برای تنظیم مقادیر عناصر رابط کاربری برای کارت توصیه، یک کلاس سازنده ایجاد می‌کنید که از الگوی سازنده‌ای که در ادامه توضیح داده شده است، پیروی می‌کند. ابتدا، مقادیر عناصر کارت توصیه را تنظیم می‌کنید.

کاتلین

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
    }

...

جاوا

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;
        }
...

اعلان را ایجاد کنید

پس از تنظیم مقادیر، اعلان را می‌سازید، مقادیر را از کلاس سازنده به اعلان اختصاص می‌دهید و NotificationCompat.Builder.build() را فراخوانی می‌کنید.

همچنین، حتماً تابع setLocalOnly() را فراخوانی کنید تا اعلان NotificationCompat.BigPictureStyle در دستگاه‌های دیگر نمایش داده نشود.

مثال کد زیر نحوه ساخت یک توصیه را نشان می‌دهد.

کاتلین

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
    }
}

جاوا

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

اجرای سرویس توصیه‌ها

سرویس توصیه برنامه شما باید به صورت دوره‌ای اجرا شود تا توصیه‌های فعلی را ایجاد کند. برای اجرای سرویس خود، کلاسی ایجاد کنید که یک تایمر را اجرا کند و آن را در فواصل منظم فراخوانی کند. مثال کد زیر کلاس BroadcastReceiver را برای شروع اجرای دوره‌ای یک سرویس توصیه هر نیم ساعت یکبار، بسط می‌دهد:

کاتلین

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
    }
}

جاوا

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 باید پس از راه‌اندازی دستگاه تلویزیونی که در آن نصب شده است، اجرا شود. برای انجام این کار، این کلاس را در مانیفست برنامه خود با یک فیلتر intent که منتظر تکمیل فرآیند بوت دستگاه است، ثبت کنید. کد نمونه زیر نحوه اضافه کردن این پیکربندی به مانیفست را نشان می‌دهد:

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

مهم: دریافت اعلان اتمام بوت مستلزم آن است که برنامه شما مجوز RECEIVE_BOOT_COMPLETED را درخواست کند. برای اطلاعات بیشتر، به ACTION_BOOT_COMPLETED مراجعه کنید.

در متد onHandleIntent() از کلاس سرویس توصیه، توصیه را به صورت زیر برای مدیر ارسال کنید:

کاتلین

val notification = notificationBuilder.build()
notificationManager.notify(id, notification)

جاوا

Notification notification = notificationBuilder.build();
notificationManager.notify(id, notification);
،

هنگام تعامل با تلویزیون‌ها، کاربران معمولاً ترجیح می‌دهند قبل از تماشای محتوا، حداقل اطلاعات را ارائه دهند. یک سناریوی ایده‌آل برای بسیاری از کاربران تلویزیون این است: بنشینید، تلویزیون را روشن کنید و تماشا کنید. کمترین مراحل برای رساندن کاربران به محتوایی که از آن لذت می‌برند، عموماً مسیری است که آنها ترجیح می‌دهند.

توجه: از APIهای شرح داده شده در اینجا فقط برای ارائه توصیه در برنامه‌هایی که در نسخه‌های اندروید تا اندروید ۷.۱ (سطح API ۲۵) اجرا می‌شوند، استفاده کنید. برای ارائه توصیه برای برنامه‌هایی که در اندروید ۸.۰ (سطح API ۲۶) و بالاتر اجرا می‌شوند، برنامه شما باید از کانال‌های توصیه استفاده کند.

چارچوب اندروید با ارائه یک ردیف پیشنهاد در صفحه اصلی، به تعامل با حداقل ورودی کمک می‌کند. پیشنهادهای محتوا پس از اولین استفاده از دستگاه، در اولین ردیف صفحه اصلی تلویزیون ظاهر می‌شوند. ارائه پیشنهادها از فهرست محتوای برنامه شما می‌تواند به بازگشت کاربران به برنامه شما کمک کند.

نمونه‌ای از ردیف پیشنهادات در صفحه اصلی تلویزیون اندروید
شکل ۱. نمونه‌ای از ردیف توصیه‌ها.

این راهنما به شما آموزش می‌دهد که چگونه توصیه‌هایی ایجاد کنید و آنها را در چارچوب اندروید ارائه دهید تا کاربران بتوانند محتوای برنامه شما را کشف کرده و از آن لذت ببرند. همچنین به نمونه پیاده‌سازی در برنامه نمونه Leanback مراجعه کنید.

بهترین شیوه‌ها برای توصیه‌ها

توصیه‌ها به کاربران کمک می‌کنند تا به سرعت محتوا و برنامه‌های مورد علاقه خود را پیدا کنند. ایجاد توصیه‌هایی که با کیفیت بالا و مرتبط با کاربران باشند، عامل مهمی در ایجاد یک تجربه کاربری عالی با برنامه تلویزیونی شما است. به همین دلیل، باید به دقت بررسی کنید که چه توصیه‌هایی را به کاربر ارائه می‌دهید و آنها را از نزدیک مدیریت کنید.

انواع توصیه‌ها

وقتی توصیه‌هایی ایجاد می‌کنید، باید کاربران را به فعالیت‌های مشاهده‌ی ناقص پیوند دهید یا فعالیت‌هایی را پیشنهاد دهید که آن را به محتوای مرتبط گسترش می‌دهند. در اینجا چند نوع خاص از توصیه‌ها وجود دارد که باید در نظر بگیرید:

  • پیشنهادهای ادامه محتوا برای قسمت بعدی برای کاربران تا بتوانند تماشای یک سریال را از سر بگیرند. یا از پیشنهادهای ادامه برای فیلم‌ها، برنامه‌های تلویزیونی یا پادکست‌های متوقف‌شده استفاده کنید تا کاربران بتوانند تنها با چند کلیک به تماشای محتوای متوقف‌شده بازگردند.
  • توصیه‌های محتوای جدید ، مانند یک قسمت جدید برای اولین بار، در صورتی که کاربر تماشای سریال دیگری را تمام کرده باشد. همچنین، اگر برنامه شما به کاربران اجازه می‌دهد در محتوا مشترک شوند، آن را دنبال کنند یا آن را پیگیری کنند، از توصیه‌های محتوای جدید برای موارد تماشا نشده در فهرست محتوای پیگیری شده آنها استفاده کنید.
  • توصیه‌های محتوای مرتبط بر اساس سابقه‌ی مشاهده‌ی کاربران.

برای اطلاعات بیشتر در مورد نحوه طراحی کارت‌های توصیه برای بهترین تجربه کاربری، به ردیف توصیه‌ها در مشخصات طراحی تلویزیون اندروید مراجعه کنید.

توصیه‌های تازه

هنگام به‌روزرسانی توصیه‌ها، آنها را صرفاً حذف و دوباره ارسال نکنید، زیرا انجام این کار باعث می‌شود توصیه‌ها در انتهای ردیف توصیه‌ها ظاهر شوند. پس از پخش یک آیتم محتوا، مانند یک فیلم، آن را از توصیه‌ها حذف کنید .

سفارشی‌سازی توصیه‌ها

شما می‌توانید کارت‌های توصیه را برای انتقال اطلاعات برندسازی، با تنظیم عناصر رابط کاربری مانند تصویر پیش‌زمینه و پس‌زمینه کارت، رنگ، آیکون برنامه، عنوان و زیرنویس، سفارشی کنید. برای کسب اطلاعات بیشتر، به ردیف توصیه‌ها در مشخصات طراحی تلویزیون اندروید مراجعه کنید.

توصیه‌های گروهی

شما می‌توانید به صورت اختیاری توصیه‌ها را بر اساس منبع توصیه گروه‌بندی کنید. به عنوان مثال، برنامه شما ممکن است دو گروه توصیه ارائه دهد: توصیه‌هایی برای محتوایی که کاربر در آن مشترک شده است، و توصیه‌هایی برای محتوای پرطرفدار جدیدی که کاربر ممکن است از آن آگاه نباشد.

سیستم هنگام ایجاد یا به‌روزرسانی ردیف توصیه‌ها، توصیه‌ها را برای هر گروه به‌طور جداگانه رتبه‌بندی و مرتب می‌کند. با ارائه اطلاعات گروه برای توصیه‌های خود، می‌توانید اطمینان حاصل کنید که توصیه‌های شما تحت توصیه‌های نامرتبط مرتب نمی‌شوند.

از NotificationCompat.Builder.setGroup() برای تنظیم رشته کلید گروه یک توصیه استفاده کنید. برای مثال، برای علامت‌گذاری یک توصیه به عنوان متعلق به گروهی که حاوی محتوای پرطرفدار جدید است، می‌توانید setGroup("trending") را فراخوانی کنید.

ایجاد سرویس توصیه‌ها

توصیه‌های محتوا با پردازش پس‌زمینه ایجاد می‌شوند. برای اینکه برنامه شما در ارائه توصیه‌ها مشارکت داشته باشد، سرویسی ایجاد کنید که به صورت دوره‌ای فهرست‌هایی از کاتالوگ برنامه شما را به فهرست توصیه‌های سیستم اضافه کند.

مثال کد زیر نحوه‌ی گسترش IntentService برای ایجاد یک سرویس توصیه برای برنامه‌ی شما را نشان می‌دهد:

کاتلین

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
    }
}

جاوا

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

برای اینکه این سرویس توسط سیستم شناسایی و اجرا شود، آن را با استفاده از مانیفست برنامه خود ثبت کنید. قطعه کد زیر نحوه اعلام این کلاس به عنوان یک سرویس را نشان می‌دهد:

<manifest ... >
  <application ... >
    ...

    <service
            android:name="com.example.android.tvleanback.UpdateRecommendationsService"
            android:enabled="true" />
  </application>
</manifest>

توصیه‌ها را بسازید

به محض اینکه سرویس توصیه شما شروع به اجرا می‌کند، باید توصیه‌هایی ایجاد کرده و آنها را به چارچوب اندروید ارسال کند. چارچوب، توصیه‌ها را به عنوان اشیاء Notification دریافت می‌کند که از یک الگوی خاص استفاده می‌کنند و با یک دسته خاص علامت‌گذاری شده‌اند.

تنظیم مقادیر

برای تنظیم مقادیر عناصر رابط کاربری برای کارت توصیه، یک کلاس سازنده ایجاد می‌کنید که از الگوی سازنده‌ای که در ادامه توضیح داده شده است، پیروی می‌کند. ابتدا، مقادیر عناصر کارت توصیه را تنظیم می‌کنید.

کاتلین

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
    }

...

جاوا

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;
        }
...

اعلان را ایجاد کنید

پس از تنظیم مقادیر، اعلان را می‌سازید، مقادیر را از کلاس سازنده به اعلان اختصاص می‌دهید و NotificationCompat.Builder.build() را فراخوانی می‌کنید.

همچنین، حتماً تابع setLocalOnly() را فراخوانی کنید تا اعلان NotificationCompat.BigPictureStyle در دستگاه‌های دیگر نمایش داده نشود.

مثال کد زیر نحوه ساخت یک توصیه را نشان می‌دهد.

کاتلین

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
    }
}

جاوا

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

اجرای سرویس توصیه‌ها

سرویس توصیه برنامه شما باید به صورت دوره‌ای اجرا شود تا توصیه‌های فعلی را ایجاد کند. برای اجرای سرویس خود، کلاسی ایجاد کنید که یک تایمر را اجرا کند و آن را در فواصل منظم فراخوانی کند. مثال کد زیر کلاس BroadcastReceiver را برای شروع اجرای دوره‌ای یک سرویس توصیه هر نیم ساعت یکبار، بسط می‌دهد:

کاتلین

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
    }
}

جاوا

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 باید پس از راه‌اندازی دستگاه تلویزیونی که در آن نصب شده است، اجرا شود. برای انجام این کار، این کلاس را در مانیفست برنامه خود با یک فیلتر intent که منتظر تکمیل فرآیند بوت دستگاه است، ثبت کنید. کد نمونه زیر نحوه اضافه کردن این پیکربندی به مانیفست را نشان می‌دهد:

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

مهم: دریافت اعلان اتمام بوت مستلزم آن است که برنامه شما مجوز RECEIVE_BOOT_COMPLETED را درخواست کند. برای اطلاعات بیشتر، به ACTION_BOOT_COMPLETED مراجعه کنید.

در متد onHandleIntent() از کلاس سرویس توصیه، توصیه را به صورت زیر برای مدیر ارسال کنید:

کاتلین

val notification = notificationBuilder.build()
notificationManager.notify(id, notification)

جاوا

Notification notification = notificationBuilder.build();
notificationManager.notify(id, notification);
،

هنگام تعامل با تلویزیون‌ها، کاربران معمولاً ترجیح می‌دهند قبل از تماشای محتوا، حداقل اطلاعات را ارائه دهند. یک سناریوی ایده‌آل برای بسیاری از کاربران تلویزیون این است: بنشینید، تلویزیون را روشن کنید و تماشا کنید. کمترین مراحل برای رساندن کاربران به محتوایی که از آن لذت می‌برند، عموماً مسیری است که آنها ترجیح می‌دهند.

توجه: از APIهای شرح داده شده در اینجا فقط برای ارائه توصیه در برنامه‌هایی که در نسخه‌های اندروید تا اندروید ۷.۱ (سطح API ۲۵) اجرا می‌شوند، استفاده کنید. برای ارائه توصیه برای برنامه‌هایی که در اندروید ۸.۰ (سطح API ۲۶) و بالاتر اجرا می‌شوند، برنامه شما باید از کانال‌های توصیه استفاده کند.

چارچوب اندروید با ارائه یک ردیف پیشنهاد در صفحه اصلی، به تعامل با حداقل ورودی کمک می‌کند. پیشنهادهای محتوا پس از اولین استفاده از دستگاه، در اولین ردیف صفحه اصلی تلویزیون ظاهر می‌شوند. ارائه پیشنهادها از فهرست محتوای برنامه شما می‌تواند به بازگشت کاربران به برنامه شما کمک کند.

نمونه‌ای از ردیف پیشنهادات در صفحه اصلی تلویزیون اندروید
شکل ۱. نمونه‌ای از ردیف توصیه‌ها.

این راهنما به شما آموزش می‌دهد که چگونه توصیه‌هایی ایجاد کنید و آنها را در چارچوب اندروید ارائه دهید تا کاربران بتوانند محتوای برنامه شما را کشف کرده و از آن لذت ببرند. همچنین به نمونه پیاده‌سازی در برنامه نمونه Leanback مراجعه کنید.

بهترین شیوه‌ها برای توصیه‌ها

توصیه‌ها به کاربران کمک می‌کنند تا به سرعت محتوا و برنامه‌های مورد علاقه خود را پیدا کنند. ایجاد توصیه‌هایی که با کیفیت بالا و مرتبط با کاربران باشند، عامل مهمی در ایجاد یک تجربه کاربری عالی با برنامه تلویزیونی شما است. به همین دلیل، باید به دقت بررسی کنید که چه توصیه‌هایی را به کاربر ارائه می‌دهید و آنها را از نزدیک مدیریت کنید.

انواع توصیه‌ها

وقتی توصیه‌هایی ایجاد می‌کنید، باید کاربران را به فعالیت‌های مشاهده‌ی ناقص پیوند دهید یا فعالیت‌هایی را پیشنهاد دهید که آن را به محتوای مرتبط گسترش می‌دهند. در اینجا چند نوع خاص از توصیه‌ها وجود دارد که باید در نظر بگیرید:

  • پیشنهادهای ادامه محتوا برای قسمت بعدی برای کاربران تا بتوانند تماشای یک سریال را از سر بگیرند. یا از پیشنهادهای ادامه برای فیلم‌ها، برنامه‌های تلویزیونی یا پادکست‌های متوقف‌شده استفاده کنید تا کاربران بتوانند تنها با چند کلیک به تماشای محتوای متوقف‌شده بازگردند.
  • توصیه‌های محتوای جدید ، مانند یک قسمت جدید برای اولین بار، در صورتی که کاربر تماشای سریال دیگری را تمام کرده باشد. همچنین، اگر برنامه شما به کاربران اجازه می‌دهد در محتوا مشترک شوند، آن را دنبال کنند یا آن را پیگیری کنند، از توصیه‌های محتوای جدید برای موارد تماشا نشده در فهرست محتوای پیگیری شده آنها استفاده کنید.
  • توصیه‌های محتوای مرتبط بر اساس سابقه‌ی مشاهده‌ی کاربران.

برای اطلاعات بیشتر در مورد نحوه طراحی کارت‌های توصیه برای بهترین تجربه کاربری، به ردیف توصیه‌ها در مشخصات طراحی تلویزیون اندروید مراجعه کنید.

توصیه‌های تازه

هنگام به‌روزرسانی توصیه‌ها، آنها را صرفاً حذف و دوباره ارسال نکنید، زیرا انجام این کار باعث می‌شود توصیه‌ها در انتهای ردیف توصیه‌ها ظاهر شوند. پس از پخش یک آیتم محتوا، مانند یک فیلم، آن را از توصیه‌ها حذف کنید .

سفارشی‌سازی توصیه‌ها

شما می‌توانید کارت‌های توصیه را برای انتقال اطلاعات برندسازی، با تنظیم عناصر رابط کاربری مانند تصویر پیش‌زمینه و پس‌زمینه کارت، رنگ، آیکون برنامه، عنوان و زیرنویس، سفارشی کنید. برای کسب اطلاعات بیشتر، به ردیف توصیه‌ها در مشخصات طراحی تلویزیون اندروید مراجعه کنید.

توصیه‌های گروهی

شما می‌توانید به صورت اختیاری توصیه‌ها را بر اساس منبع توصیه گروه‌بندی کنید. به عنوان مثال، برنامه شما ممکن است دو گروه توصیه ارائه دهد: توصیه‌هایی برای محتوایی که کاربر در آن مشترک شده است، و توصیه‌هایی برای محتوای پرطرفدار جدیدی که کاربر ممکن است از آن آگاه نباشد.

سیستم هنگام ایجاد یا به‌روزرسانی ردیف توصیه‌ها، توصیه‌ها را برای هر گروه به‌طور جداگانه رتبه‌بندی و مرتب می‌کند. با ارائه اطلاعات گروه برای توصیه‌های خود، می‌توانید اطمینان حاصل کنید که توصیه‌های شما تحت توصیه‌های نامرتبط مرتب نمی‌شوند.

از NotificationCompat.Builder.setGroup() برای تنظیم رشته کلید گروه یک توصیه استفاده کنید. برای مثال، برای علامت‌گذاری یک توصیه به عنوان متعلق به گروهی که حاوی محتوای پرطرفدار جدید است، می‌توانید setGroup("trending") را فراخوانی کنید.

ایجاد سرویس توصیه‌ها

توصیه‌های محتوا با پردازش پس‌زمینه ایجاد می‌شوند. برای اینکه برنامه شما در ارائه توصیه‌ها مشارکت داشته باشد، سرویسی ایجاد کنید که به صورت دوره‌ای فهرست‌هایی از کاتالوگ برنامه شما را به فهرست توصیه‌های سیستم اضافه کند.

مثال کد زیر نحوه‌ی گسترش IntentService برای ایجاد یک سرویس توصیه برای برنامه‌ی شما را نشان می‌دهد:

کاتلین

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
    }
}

جاوا

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

برای اینکه این سرویس توسط سیستم شناسایی و اجرا شود، آن را با استفاده از مانیفست برنامه خود ثبت کنید. قطعه کد زیر نحوه اعلام این کلاس به عنوان یک سرویس را نشان می‌دهد:

<manifest ... >
  <application ... >
    ...

    <service
            android:name="com.example.android.tvleanback.UpdateRecommendationsService"
            android:enabled="true" />
  </application>
</manifest>

توصیه‌ها را بسازید

به محض اینکه سرویس توصیه شما شروع به اجرا می‌کند، باید توصیه‌هایی ایجاد کرده و آنها را به چارچوب اندروید ارسال کند. چارچوب، توصیه‌ها را به عنوان اشیاء Notification دریافت می‌کند که از یک الگوی خاص استفاده می‌کنند و با یک دسته خاص علامت‌گذاری شده‌اند.

تنظیم مقادیر

برای تنظیم مقادیر عناصر رابط کاربری برای کارت توصیه، یک کلاس سازنده ایجاد می‌کنید که از الگوی سازنده‌ای که در ادامه توضیح داده شده است، پیروی می‌کند. ابتدا، مقادیر عناصر کارت توصیه را تنظیم می‌کنید.

کاتلین

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
    }

...

جاوا

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;
        }
...

اعلان را ایجاد کنید

پس از تنظیم مقادیر، اعلان را می‌سازید، مقادیر را از کلاس سازنده به اعلان اختصاص می‌دهید و NotificationCompat.Builder.build() را فراخوانی می‌کنید.

همچنین، حتماً تابع setLocalOnly() را فراخوانی کنید تا اعلان NotificationCompat.BigPictureStyle در دستگاه‌های دیگر نمایش داده نشود.

مثال کد زیر نحوه ساخت یک توصیه را نشان می‌دهد.

کاتلین

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
    }
}

جاوا

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

اجرای سرویس توصیه‌ها

سرویس توصیه برنامه شما باید به صورت دوره‌ای اجرا شود تا توصیه‌های فعلی را ایجاد کند. برای اجرای سرویس خود، کلاسی ایجاد کنید که یک تایمر را اجرا کند و آن را در فواصل منظم فراخوانی کند. مثال کد زیر کلاس BroadcastReceiver را برای شروع اجرای دوره‌ای یک سرویس توصیه هر نیم ساعت یکبار، بسط می‌دهد:

کاتلین

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
    }
}

جاوا

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 باید پس از راه‌اندازی دستگاه تلویزیونی که در آن نصب شده است، اجرا شود. برای انجام این کار، این کلاس را در مانیفست برنامه خود با یک فیلتر intent که منتظر تکمیل فرآیند بوت دستگاه است، ثبت کنید. کد نمونه زیر نحوه اضافه کردن این پیکربندی به مانیفست را نشان می‌دهد:

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

مهم: دریافت اعلان اتمام بوت مستلزم آن است که برنامه شما مجوز RECEIVE_BOOT_COMPLETED را درخواست کند. برای اطلاعات بیشتر، به ACTION_BOOT_COMPLETED مراجعه کنید.

در متد onHandleIntent() از کلاس سرویس توصیه، توصیه را به صورت زیر برای مدیر ارسال کنید:

کاتلین

val notification = notificationBuilder.build()
notificationManager.notify(id, notification)

جاوا

Notification notification = notificationBuilder.build();
notificationManager.notify(id, notification);