From e6b9abb3ad06d32e76a07e733e0a6554479fbfa4 Mon Sep 17 00:00:00 2001 From: Joe Fernandez Date: Sun, 5 Oct 2014 12:44:04 -0700 Subject: [PATCH] docs: migrate Android TV content discovery Change-Id: I35fe1e7f4f60409a0f7c5cd5bfc8ccfede4d6c20 --- docs/html/preview/tv/ui/in-app-search.jd | 111 ---------------- docs/html/training/training_toc.cs | 19 +++ docs/html/training/tv/discovery/in-app-search.jd | 145 +++++++++++++++++++++ docs/html/training/tv/discovery/index.jd | 48 +++++++ .../tv/discovery}/recommendations.jd | 96 +++++++++----- 5 files changed, 276 insertions(+), 143 deletions(-) delete mode 100644 docs/html/preview/tv/ui/in-app-search.jd create mode 100644 docs/html/training/tv/discovery/in-app-search.jd create mode 100644 docs/html/training/tv/discovery/index.jd rename docs/html/{preview/tv/ui => training/tv/discovery}/recommendations.jd (66%) diff --git a/docs/html/preview/tv/ui/in-app-search.jd b/docs/html/preview/tv/ui/in-app-search.jd deleted file mode 100644 index 3dbfcd293d15..000000000000 --- a/docs/html/preview/tv/ui/in-app-search.jd +++ /dev/null @@ -1,111 +0,0 @@ -page.title=Adding Search to TV Apps - -@jd:body - -
-
-

In this document

-
    -
  1. Add Search User Interface
  2. -
- -
-
- - -

Users frequently have specific content in mind when using a media app. A search interface can - help your users get to the content they want faster than browsing. The Leanback library provides a - set of classes to enable a standard search interface within your app that is consistent with other - search functions on TV and provides features such as voice input.

- -

Add Search User Interface

-

When you use the BrowseFragment class for your media browsing interface, you can enable the - search icon by setting an OnClickListener to the BrowseFragment object. The following sample code - demonstrates this technique.

- -
-@Override
-public void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-    setContentView(R.layout.browse_activity);
-
-    mBrowseFragment = (BrowseFragment)
-            getFragmentManager().findFragmentById(R.id.browse_fragment);
-
-    ...
-
-    mBrowseFragment.setOnSearchClickedListener(new View.OnClickListener() {
-        @Override
-        public void onClick(View view) {
-            Intent intent = new Intent(BrowseActivity.this, SearchActivity.class);
-            startActivity(intent);
-        }
-    });
-
-    mBrowseFragment.setAdapter(buildAdapter());
-}
-
- -

- Note: You can set the color of the search icon using the - {@code setSearchAffordanceColor()} method of {@code BrowseFragment}. -

- -

When a user selects the search icon, the system invokes a search activity via the defined - Intent. Your search activity should use a linear layout containing a SearchFragment. This fragment - must also implement the SearchFragment.SearchResultProvider interface in order to display the - results of a search. The following code sample shows how to extend the SearchFragment class to - provide a search interface and results:

- -
-public class MySearchFragment extends SearchFragment
-        implements SearchFragment.SearchResultProvider {
-
-    private static final int SEARCH_DELAY_MS = 300;
-    private ArrayObjectAdapter mRowsAdapter;
-    private Handler mHandler = new Handler();
-    private SearchRunnable mDelayedLoad;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
-        setSearchResultProvider(this);
-        setOnItemClickedListener(getDefaultItemClickedListener());
-        mDelayedLoad = new SearchRunnable();
-    }
-
-    @Override
-    public ObjectAdapter getResultsAdapter() {
-        return mRowsAdapter;
-    }
-
-    @Override
-    public boolean onQueryTextChange(String newQuery) {
-        mRowsAdapter.clear();
-        if (!TextUtils.isEmpty(newQuery)) {
-            mDelayedLoad.setSearchQuery(newQuery);
-            mHandler.removeCallbacks(mDelayedLoad);
-            mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
-        }
-        return true;
-    }
-
-    @Override
-    public boolean onQueryTextSubmit(String query) {
-        mRowsAdapter.clear();
-        if (!TextUtils.isEmpty(query)) {
-            mDelayedLoad.setSearchQuery(query);
-            mHandler.removeCallbacks(mDelayedLoad);
-            mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
-        }
-        return true;
-    }
-}
-
- -

This example code shown above is meant to be used with a separate {@code SearchRunnable} - class that runs the search query on a separate thread. This technique keeps potentially - slow-running queries from blocking the main user interface thread.

- diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs index d33372b460a7..44e31d73314c 100644 --- a/docs/html/training/training_toc.cs +++ b/docs/html/training/training_toc.cs @@ -851,6 +851,7 @@ include the action bar on devices running Android 2.1 or higher." + + diff --git a/docs/html/training/tv/discovery/in-app-search.jd b/docs/html/training/tv/discovery/in-app-search.jd new file mode 100644 index 000000000000..28c7a35ce8fa --- /dev/null +++ b/docs/html/training/tv/discovery/in-app-search.jd @@ -0,0 +1,145 @@ +page.title=Searching within TV Apps +page.tags="leanback" + +trainingnavtop=true + +@jd:body + +
+
+

This lesson teaches you to

+
    +
  1. Add a Search Action
  2. +
  3. Add Search Input and Results
  4. +
+ +
+
+ + +

+ Users frequently have specific content in mind when using a media app on TV. If your app contains + a large catalog of content, browsing for a specific title may not be the most efficient way for + users to find what they are looking for. A search interface can help your users get to the + content they want faster than browsing. +

+ +

+ The Leanback support + library provides a set of classes to enable a standard search interface within your app that + is consistent with other search functions on TV and provides features such as voice input. +

+ +

+ This lesson discusses how to provide a search interface in your app using Leanback support + library classes. +

+ + +

Add a Search Action

+ +

+ When you use the {@link android.support.v17.leanback.app.BrowseFragment} class for a media + browsing interface, you can enable a search interface as a standard part of the user + interface. The search interface is an icon that appears in the layout when you set {@link + android.view.View.OnClickListener} on the {@link android.support.v17.leanback.app.BrowseFragment} + object. The following sample code demonstrates this technique. +

+ +
+@Override
+public void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+    setContentView(R.layout.browse_activity);
+
+    mBrowseFragment = (BrowseFragment)
+            getFragmentManager().findFragmentById(R.id.browse_fragment);
+
+    ...
+
+    mBrowseFragment.setOnSearchClickedListener(new View.OnClickListener() {
+        @Override
+        public void onClick(View view) {
+            Intent intent = new Intent(BrowseActivity.this, SearchActivity.class);
+            startActivity(intent);
+        }
+    });
+
+    mBrowseFragment.setAdapter(buildAdapter());
+}
+
+ +

+ Note: You can set the color of the search icon using the + {@link android.support.v17.leanback.app.BrowseFragment#setSearchAffordanceColor}. +

+ + +

Add a Search Input and Results

+ +

+ When a user selects the search icon, the system invokes a search activity via the defined intent. + Your search activity should use a linear layout containing a {@link + android.support.v17.leanback.app.SearchFragment}. This fragment must also implement the {@link + android.support.v17.leanback.app.SearchFragment.SearchResultProvider} interface in order to + display the results of a search. +

+ +

+ The following code sample shows how to extend the {@link + android.support.v17.leanback.app.SearchFragment} class to provide a search interface and results: +

+ +
+public class MySearchFragment extends SearchFragment
+        implements SearchFragment.SearchResultProvider {
+
+    private static final int SEARCH_DELAY_MS = 300;
+    private ArrayObjectAdapter mRowsAdapter;
+    private Handler mHandler = new Handler();
+    private SearchRunnable mDelayedLoad;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+        setSearchResultProvider(this);
+        setOnItemClickedListener(getDefaultItemClickedListener());
+        mDelayedLoad = new SearchRunnable();
+    }
+
+    @Override
+    public ObjectAdapter getResultsAdapter() {
+        return mRowsAdapter;
+    }
+
+    @Override
+    public boolean onQueryTextChange(String newQuery) {
+        mRowsAdapter.clear();
+        if (!TextUtils.isEmpty(newQuery)) {
+            mDelayedLoad.setSearchQuery(newQuery);
+            mHandler.removeCallbacks(mDelayedLoad);
+            mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean onQueryTextSubmit(String query) {
+        mRowsAdapter.clear();
+        if (!TextUtils.isEmpty(query)) {
+            mDelayedLoad.setSearchQuery(query);
+            mHandler.removeCallbacks(mDelayedLoad);
+            mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
+        }
+        return true;
+    }
+}
+
+ +

+ The example code shown above is meant to be used with a separate {@code SearchRunnable} class + that runs the search query on a separate thread. This technique keeps potentially slow-running + queries from blocking the main user interface thread. +

diff --git a/docs/html/training/tv/discovery/index.jd b/docs/html/training/tv/discovery/index.jd new file mode 100644 index 000000000000..fbc8c9f96eac --- /dev/null +++ b/docs/html/training/tv/discovery/index.jd @@ -0,0 +1,48 @@ +page.title=Helping Users Find Content on TV + +startpage=true + +@jd:body + +
+
+

Dependencies and Prerequisites

+
    +
  • Android 5.0 (API level 21) or higher
  • +
+

You should also read

+ +
+
+ +

+ TV devices offer many entertainment options for users. They have thousands of content options + from apps and related content services. At the same time, most users prefer to use TVs with the + least amount of input possible. With the amount of choice available to users, it is important for + app developers to provide quick and easy paths for users to discover and enjoy your content. +

+ +

+ The Android framework helps you provide a number of paths for users to discover your content, + including recommendations on the home screen and searching within your app's content catalog. +

+ +

+ This class shows you how to help users discover your app's content through recommendations and + in-app searching. +

+ + +

Topics

+ +
+
Recommending TV Content
+
Learn how to recommend content for users so that it appears in the recommendations row + on the home screen of a TV device.
+ +
Searching within TV Apps
+
Learn how to use a built-for-TV user interface for searching within your app.
+
diff --git a/docs/html/preview/tv/ui/recommendations.jd b/docs/html/training/tv/discovery/recommendations.jd similarity index 66% rename from docs/html/preview/tv/ui/recommendations.jd rename to docs/html/training/tv/discovery/recommendations.jd index a2ff55ca8ea6..048b649daa99 100644 --- a/docs/html/preview/tv/ui/recommendations.jd +++ b/docs/html/training/tv/discovery/recommendations.jd @@ -1,39 +1,57 @@ -page.title=Making Recommendations +page.title=Recommending TV Content +page.tags="recommendation","recommend" + +trainingnavtop=true @jd:body -
-
-

In this document

+ +

+ When interacting with TVs, users generally prefer to give minimal input before watching + content. An ideal scenario for many TV users is: sit down, turn on, and watch. The fewest steps + to get users to content they enjoy is generally the path they prefer. +

-

Content recommendations appear as the first row of the TV launch screen after the first use - of the device. This row is intended to help users quickly find content they enjoy. Contributing - recommendations from your apps content catalog can help bring users back to your app.

- +

+ The Android framework assists with minimum-input interaction by providing a recommendations row + on the home screen. Content recommendations appear as the first row of the TV launch screen after + the first use of the device. Contributing recommendations from your app's content catalog can help + bring users back to your app. +

Figure 1. An example of the recommendations row.

+

+ This lesson teaches you how to create recommendations and provide them to the Android framework + so your app content can be easily discovered and enjoyed by users. +

+

Create a Recommendations Service

-

Content recommendations are created with background processing. In order for your application - to contribute to recommendations, you create a service that periodically adds listings from your - app's catalog to the system list of recommendations.

+

+ Content recommendations are created with background processing. In order for your application to + contribute to recommendations, create a service that periodically adds listings from your + app's catalog to the system list of recommendations. +

-

The following code example illustrates how to extend the {@link android.app.IntentService} to - create a recommendation service for your application.

+

+ The following code example illustrates how to extend {@link android.app.IntentService} to + create a recommendation service for your application: +

 public class RecommendationsService extends IntentService {
@@ -66,9 +84,10 @@ public class RecommendationsService extends IntentService {
 }
 
-

In order for this class to be recognized and run as a service, you must register this service - using your app manifest. The following code snippet illustrates how to add this class as a - service:

+

+ In order for this service to be recognized by the system and run, register it using your + app manifest. The following code snippet illustrates how to declare this class as a service: +

 <manifest ... >
@@ -81,14 +100,20 @@ public class RecommendationsService extends IntentService {
 </manifest>
 
+

Build Recommendations

-

Once it starts running, your service must create recommendations and pass them to the Android - framework. The framework receives the recommendations as {@link android.app.Notification} objects - that use a specific style and are marked with a specific category.

+

+ Once your recommendation server starts running, it must create recommendations and pass them to + the Android framework. The framework receives the recommendations as {@link + android.app.Notification} objects that use a specific template and are marked with a specific + category. +

-

The following code example demonstrates how to get an instance of the {@link - android.app.NotificationManager}, build a recommendation, and post it to the manager:

+

+ The following code example demonstrates how to get an instance of the {@link + android.app.NotificationManager}, build a recommendation, and post it to the manager: +

 public class RecommendationsService extends IntentService {
@@ -113,8 +138,11 @@ public class RecommendationsService extends IntentService {
                 new NotificationCompat.Builder(context)
                         .setContentTitle(movie.getTitle())
                         .setContentText(movie.getDescription())
+                        .setContentInfo(APP_NAME)
+                        .setGroup("ActionMovies")
+                        .setSortKey("0.8")
                         .setPriority(movie.getPriority())
-                        .setOngoing(true)
+                        .setColor(#FFFF2020)
                         .setCategory("recommendation")
                         .setLargeIcon(movie.getImage())
                         .setSmallIcon(movie.getSmallIcon())
@@ -148,11 +176,13 @@ public class RecommendationsService extends IntentService {
 
 

Run Recommendations Service

-

Your app's recommendation service must run periodically in order to create current - recommendations. In order to run your service, you should create a class that runs a timer and - invokes it at regular intervals. The following code example extends the {@link +

+ Your app's recommendation service must run periodically in order to create current + recommendations. To run your service, create a class that runs a timer and invokes + it at regular intervals. The following code example extends the {@link android.content.BroadcastReceiver} class to start periodic execution of a recommendation service - every 12 hours:

+ every 12 hours: +

 public class BootupReceiver extends BroadcastReceiver {
@@ -183,10 +213,12 @@ public class BootupReceiver extends BroadcastReceiver {
 }
 
-

In order for the {@link android.content.BroadcastReceiver} class to execute after a TV - device starts up, you must register this class in your app manifest and attach an intent filter - in order for the device boot process to complete. This sample code demonstrates how to add this - configuration to the manifest:

+

+ This implementation of the {@link android.content.BroadcastReceiver} class must run after start + up of the TV device where it is installed. To accomplish this, register this class in your app + manifest with an intent filter that listens for the completion of the device boot process. The + following sample code demonstrates how to add this configuration to the manifest: +

 <manifest ... >
@@ -203,6 +235,6 @@ public class BootupReceiver extends BroadcastReceiver {
 
 

Important: Receiving a boot completed notification requires that your app - request the {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED} permission. + requests the {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED} permission. For more information, see {@link android.content.Intent#ACTION_BOOT_COMPLETED}.

-- 2.11.0