summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Fernandez <joefernandez@google.com>2014-10-05 12:44:04 -0700
committerJoe Fernandez <joefernandez@google.com>2014-10-12 20:45:47 -0700
commite6b9abb3ad06d32e76a07e733e0a6554479fbfa4 (patch)
tree96f7538393c34f4796cfeaec62179b1517719705
parentf666355b2d9dbffffa640aff7731a8ba8309eaaa (diff)
downloadframeworks_base-e6b9abb3ad06d32e76a07e733e0a6554479fbfa4.zip
frameworks_base-e6b9abb3ad06d32e76a07e733e0a6554479fbfa4.tar.gz
frameworks_base-e6b9abb3ad06d32e76a07e733e0a6554479fbfa4.tar.bz2
docs: migrate Android TV content discovery
Change-Id: I35fe1e7f4f60409a0f7c5cd5bfc8ccfede4d6c20
-rw-r--r--docs/html/preview/tv/ui/in-app-search.jd111
-rw-r--r--docs/html/training/training_toc.cs19
-rw-r--r--docs/html/training/tv/discovery/in-app-search.jd145
-rw-r--r--docs/html/training/tv/discovery/index.jd48
-rw-r--r--docs/html/training/tv/discovery/recommendations.jd (renamed from docs/html/preview/tv/ui/recommendations.jd)96
5 files changed, 276 insertions, 143 deletions
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 3dbfcd2..0000000
--- 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
-
-<div id="qv-wrapper">
-<div id="qv">
- <h2>In this document</h2>
- <ol>
- <li><a href="#add-search-ui">Add Search User Interface</a></li>
- </ol>
-
-</div>
-</div>
-
-
-<p>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.</p>
-
-<h2 id="add-search-ui">Add Search User Interface</h2>
-<p>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.</p>
-
-<pre>
-&#64;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() {
- &#64;Override
- public void onClick(View view) {
- Intent intent = new Intent(BrowseActivity.this, SearchActivity.class);
- startActivity(intent);
- }
- });
-
- mBrowseFragment.setAdapter(buildAdapter());
-}
-</pre>
-
-<p class="note">
- <strong>Note:</strong> You can set the color of the search icon using the
- {@code setSearchAffordanceColor()} method of {@code BrowseFragment}.
-</p>
-
-<p>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:</p>
-
-<pre>
-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;
-
- &#64;Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
- setSearchResultProvider(this);
- setOnItemClickedListener(getDefaultItemClickedListener());
- mDelayedLoad = new SearchRunnable();
- }
-
- &#64;Override
- public ObjectAdapter getResultsAdapter() {
- return mRowsAdapter;
- }
-
- &#64;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;
- }
-
- &#64;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;
- }
-}
-</pre>
-
-<p>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.</p>
-
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index d33372b..44e31d7 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."
<li class="nav-section">
<div class="nav-section-header">
+
<a href="<?cs var:toroot ?>training/tv/start/index.html"
description="How to start building TV apps or extend your existing app to run on TV
devices.">
@@ -894,6 +895,24 @@ include the action bar on devices running Android 2.1 or higher."
</ul>
</li>
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/tv/discovery/index.html"
+ description="How to help users discovery content from your app.">
+ Helping Users Find Content on TV</a>
+ </div>
+ <ul>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/discovery/recommendations.html">
+ Recommending TV Content</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/discovery/in-app-search.html">
+ Searching within TV Apps</a>
+ </li>
+ </ul>
+ </li>
+
</ul>
</li>
<!-- End: Building for TV -->
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 0000000..28c7a35
--- /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
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#add-search-action">Add a Search Action</a></li>
+ <li><a href="#add-search-ui">Add Search Input and Results</a></li>
+ </ol>
+
+</div>
+</div>
+
+
+<p>
+ 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.
+</p>
+
+<p>
+ The <a href="{@docRoot}tools/support-library/features.html#v17-leanback">Leanback support
+ library</a> 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.
+</p>
+
+<p>
+ This lesson discusses how to provide a search interface in your app using Leanback support
+ library classes.
+</p>
+
+
+<h2 id="add-search-action">Add a Search Action</h2>
+
+<p>
+ 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.
+</p>
+
+<pre>
+&#64;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() {
+ &#64;Override
+ public void onClick(View view) {
+ Intent intent = new Intent(BrowseActivity.this, SearchActivity.class);
+ startActivity(intent);
+ }
+ });
+
+ mBrowseFragment.setAdapter(buildAdapter());
+}
+</pre>
+
+<p class="note">
+ <strong>Note:</strong> You can set the color of the search icon using the
+ {@link android.support.v17.leanback.app.BrowseFragment#setSearchAffordanceColor}.
+</p>
+
+
+<h2 id="add-search-ui">Add a Search Input and Results</h2>
+
+<p>
+ 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.
+</p>
+
+<p>
+ The following code sample shows how to extend the {@link
+ android.support.v17.leanback.app.SearchFragment} class to provide a search interface and results:
+</p>
+
+<pre>
+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;
+
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+ setSearchResultProvider(this);
+ setOnItemClickedListener(getDefaultItemClickedListener());
+ mDelayedLoad = new SearchRunnable();
+ }
+
+ &#64;Override
+ public ObjectAdapter getResultsAdapter() {
+ return mRowsAdapter;
+ }
+
+ &#64;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;
+ }
+
+ &#64;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;
+ }
+}
+</pre>
+
+<p>
+ 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.
+</p>
diff --git a/docs/html/training/tv/discovery/index.jd b/docs/html/training/tv/discovery/index.jd
new file mode 100644
index 0000000..fbc8c9f
--- /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
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>Dependencies and Prerequisites</h2>
+ <ul>
+ <li>Android 5.0 (API level 21) or higher</li>
+ </ul>
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}design/tv/index.html">
+ Design for TV</a></li>
+ </ul>
+</div>
+</div>
+
+<p>
+ 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.
+</p>
+
+<p>
+ 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.
+</p>
+
+<p>
+ This class shows you how to help users discover your app's content through recommendations and
+ in-app searching.
+</p>
+
+
+<h2>Topics</h2>
+
+<dl>
+ <dt><b><a href="recommendations.html">Recommending TV Content</a></b></dt>
+ <dd>Learn how to recommend content for users so that it appears in the recommendations row
+ on the home screen of a TV device.</dd>
+
+ <dt><b><a href="in-app-search.html">Searching within TV Apps</a></b></dt>
+ <dd>Learn how to use a built-for-TV user interface for searching within your app.</dd>
+</dl>
diff --git a/docs/html/preview/tv/ui/recommendations.jd b/docs/html/training/tv/discovery/recommendations.jd
index a2ff55c..048b649 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
-<div id="qv-wrapper">
-<div id="qv">
- <h2>In this document</h2>
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you to</h2>
<ol>
<li><a href="#service">Create a Recommendations Service</a></li>
<li><a href="#build">Build Recommendations</a></li>
<li><a href="#run-service">Run Recommendations Service</a></li>
</ol>
-
</div>
</div>
+<p>
+ 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.
+</p>
-<p>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.</p>
-
+<p>
+ 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.
+</p>
<img src="{@docRoot}preview/tv/images/home-recommendations.png" alt="" id="figure1" />
<p class="img-caption">
<strong>Figure 1.</strong> An example of the recommendations row.
</p>
+<p>
+ 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.
+</p>
+
<h2 id="service">Create a Recommendations Service</h2>
-<p>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.</p>
+<p>
+ 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.
+</p>
-<p>The following code example illustrates how to extend the {@link android.app.IntentService} to
- create a recommendation service for your application.</p>
+<p>
+ The following code example illustrates how to extend {@link android.app.IntentService} to
+ create a recommendation service for your application:
+</p>
<pre>
public class RecommendationsService extends IntentService {
@@ -66,9 +84,10 @@ public class RecommendationsService extends IntentService {
}
</pre>
-<p>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:</p>
+<p>
+ 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:
+</p>
<pre>
&lt;manifest ... &gt;
@@ -81,14 +100,20 @@ public class RecommendationsService extends IntentService {
&lt;/manifest&gt;
</pre>
+
<h2 id="build">Build Recommendations</h2>
-<p>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.</p>
+<p>
+ 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.
+</p>
-<p>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:</p>
+<p>
+ 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:
+</p>
<pre>
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 {
<h3 id="run-service">Run Recommendations Service</h3>
-<p>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
+<p>
+ 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:</p>
+ every 12 hours:
+</p>
<pre>
public class BootupReceiver extends BroadcastReceiver {
@@ -183,10 +213,12 @@ public class BootupReceiver extends BroadcastReceiver {
}
</pre>
-<p>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:</p>
+<p>
+ 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:
+</p>
<pre>
&lt;manifest ... &gt;
@@ -203,6 +235,6 @@ public class BootupReceiver extends BroadcastReceiver {
<p class="important">
<strong>Important:</strong> 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}.
</p>