am f0acbc15: am e6b9abb3: docs: migrate Android TV content discovery

* commit 'f0acbc154d1b31240ea8a4b21186667c7dcbf897':
  docs: migrate Android TV content discovery
This commit is contained in:
Joe Fernandez
2014-10-13 04:01:02 +00:00
committed by Android Git Automerger
5 changed files with 276 additions and 143 deletions

View File

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

View File

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

View File

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

View File

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

View File

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