W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
編寫:awong1900 - 原文:http://developer.android.com/training/tv/discovery/recommendations.html
當操作TV時,用戶通常喜歡使用最少的輸入操作來找內(nèi)容。許多用戶的理想場景是,坐下,打開TV然后觀看。用最少的步驟讓用戶觀看他們的喜歡的內(nèi)容是最好的方式。
Android framework為了實現(xiàn)較少交互而提供了主屏幕推薦欄。在設備第一次使用時候,內(nèi)容推薦出現(xiàn)在TV主屏幕的第一欄。應用程序的內(nèi)容目錄提供推薦建議可以把用戶帶回到我們的應用。
圖1. 一個推薦欄的例子
這節(jié)課教我們?nèi)绾蝿?chuàng)建推薦和提供他們到Android framework,這樣用戶能容易的發(fā)現(xiàn)和使用我們的應用內(nèi)容。這個討論描述了一些代碼,在Android Leanback示例代碼。
內(nèi)容推薦是被后臺處理創(chuàng)建。為了把我們的應用提供到內(nèi)容推薦,創(chuàng)建一個周期性添加列表服務,從應用目錄到系統(tǒng)推薦列表。
接下來的代碼描繪了如何擴展IntentService為我們的應用創(chuàng)建推薦服務:
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;
}
}
使服務被系統(tǒng)意識和運行,在應用manifest中注冊它,接下來的代碼片段展示了如何定義這個類做為服務:
<manifest ... >
<application ... >
...
<service
android:name="com.example.android.tvleanback.UpdateRecommendationsService"
android:enabled="true" />
</application>
</manifest>
基于用戶的行為和數(shù)據(jù)來推薦,例如播放列表,喜愛列表和相關內(nèi)容。當刷新推薦時,不僅僅是刪除和重新加載他們,因為這樣會導致推薦出現(xiàn)在推薦欄的結(jié)尾。一旦一個內(nèi)容項被播放,如一個影片,從推薦中刪除它。
應用的推薦順序被保存依據(jù)應用提供他們的順序。framework interleave應用推薦基于推薦質(zhì)量,用戶習慣的收集。最好的推薦應是推薦最合適的出現(xiàn)在列表前面。
一旦我們的推薦服務開始運行,它必須創(chuàng)建推薦和推送他們到Android framework。Framework收到推薦作為通知對象。它用特定的模板并且標記為特定的目錄。
去設置推薦卡片的UI元素,創(chuàng)建一個builder類用接下來的builder樣式描述。首先,設置推薦卡片元素的值。
public class RecommendationBuilder {
...
public RecommendationBuilder setTitle(String title) {
mTitle = title;
return this;
}
public RecommendationBuilder setDescription(String description) {
mDescription = description;
return this;
}
public RecommendationBuilder setImage(String uri) {
mImageUri = uri;
return this;
}
public RecommendationBuilder setBackground(String uri) {
mBackgroundUri = uri;
return this;
}
...
一旦我們設置了值,然后去創(chuàng)建通知,從builder類分配值到通知,并且調(diào)用NotificationCompat.Builder.build)。
并且,確信調(diào)用setLocalOnly()),這樣NotificationCompat.BigPictureStyle通知不將顯示在另一個設備。
接下來的代碼示例展示了如何創(chuàng)建推薦。
public class RecommendationBuilder {
...
public Notification build() throws IOException {
...
Notification notification = new NotificationCompat.BigPictureStyle(
new NotificationCompat.Builder(mContext)
.setContentTitle(mTitle)
.setContentText(mDescription)
.setPriority(mPriority)
.setLocalOnly(true)
.setOngoing(true)
.setColor(mContext.getResources().getColor(R.color.fastlane_background))
.setCategory(Notification.CATEGORY_RECOMMENDATION)
.setLargeIcon(image)
.setSmallIcon(mSmallIcon)
.setContentIntent(mIntent)
.setExtras(extras))
.build();
return notification;
}
}
我們的應用推薦服務必須周期性運行確保創(chuàng)建當前的推薦。去運行我們的服務,創(chuàng)建一個類運行計時器和在周期間隔關聯(lián)它。接下來的代碼例子擴展了BroadcastReceiver類去開始每半小時的推薦服務的周期性執(zhí)行:
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類的實現(xiàn)必須運行在TV設備啟動后。 為了完成這個,注冊這個類在應用manifest的intet filter中,它監(jiān)聽設備啟動完成。接下來的代碼展示了如何添加這個配置到manifest。
<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>
Important: 接收一個啟動完成通知需要我們的應用有RECEIVE_BOOT_COMPLETED權限。更多信息,查看ACTION_BOOT_COMPLETED。
在推薦服務類的onHandleIntent())方法中,用以下代碼提交推薦到管理器:
Notification notification = notificationBuilder.build();
mNotificationManager.notify(id, notification);
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: