docs: Android TV App Dev Basic Training

Change-Id: Iede448652efba25c3d0b6c26d49ea6548008515e
This commit is contained in:
Joe Fernandez
2014-09-11 09:52:07 -07:00
parent bbbeafa9bf
commit d86a2f5b34
14 changed files with 1165 additions and 1540 deletions

View File

@@ -1,183 +0,0 @@
page.title=Hardware Features on TV
page.tags="unsupported"
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li><a href="#unsupported-features">Unsupported Hardware Features</a></li>
<li><a href="#workaround-features">Handling Unsupported Features</a></li>
<li><a href="#check-features">Checking Available Features</a>
<ol>
<li><a href="#no-touchscreen">Touch screen</a></li>
<li><a href="#no-camera">Camera</a></li>
<li><a href="#no-gps">GPS</a></li>
</ol>
</li>
</ol>
</div>
</div>
<p>TVs do not have some of the hardware features found on other Android devices.
Touch screens, cameras, and GPS receivers are some of the most commonly used hardware features
which are typically not available on a TV. When you build an app for TV, you must carefully
consider if your app can handle not having these features and, if necessary, work around them.</p>
<p>This guide discusses the hardware features not available on TV devices and shows you how to
work around those limitations in your app. For more information on filtering and declaring
features in the manifest, see the
<a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">uses-feature</a> guide.</p>
<h2 id="unsupported-features">Unsupported Hardware Features</h2>
<p>TVs have a different purpose from other devices, and so they do not have hardware
features that other Android-powered devices often have. For this reason, the Android system
does not support the following features for a TV device:
<table>
<tr>
<th>Hardware</th>
<th>Android feature descriptor</th>
</tr>
<tr>
<td>Camera</td>
<td>android.hardware.camera</td>
</tr>
<tr>
<td>GPS</td>
<td>android.hardware.location.gps</td>
</tr>
<tr>
<td>Microphone</td>
<td>android.hardware.microphone</td>
</tr>
<tr>
<td>Near Field Communications (NFC)</td>
<td>android.hardware.nfc</td>
</tr>
<tr>
<td>Telephony</td>
<td>android.hardware.telephony</td>
</tr>
<tr>
<td>Touchscreen</td>
<td>android.hardware.touchscreen</td>
</tr>
</table>
</p>
<h2 id="check-features">Checking Available Features</h2>
<p>To check if a feature is available at runtime, call {@link
android.content.pm.PackageManager#hasSystemFeature(String)}. This method takes a single string
argument that specifies the feature you want to check. For example, to check for a touch screen,
use {@link android.content.pm.PackageManager#hasSystemFeature(String)} with the argument
{@link android.content.pm.PackageManager#FEATURE_TOUCHSCREEN}.</p>
<p>The following code example demonstrates how to detect the availability of a hardware features
at runtime:</p>
<pre>
// Check if the telephony hardware feature is available.
if (getPackageManager().hasSystemFeature("android.hardware.telephony")) {
Log.d("Mobile Test", "Running on phone");
// Check if android.hardware.touchscreen feature is available.
} else if (getPackageManager().hasSystemFeature("android.hardware.touchscreen")) {
Log.d("Tablet Test", "Running on devices that don't support telephony but "+
"do have a touch screen.");
} else {
Log.d("TV Test", "Running on a TV!");
}
</pre>
<p class="note">
<strong>Note:</strong> You can also use the {@link android.app.UiModeManager#getCurrentModeType
UiModeManager.getCurrentModeType()} method to detect the current platform type. For TV devices,
this method returns a value of {@link android.content.res.Configuration#UI_MODE_TYPE_TELEVISION
Configuration.UI_MODE_TYPE_TELEVISION}.
</p>
<h2 id="workaround-features">Handling Unsupported Features</h2>
<p>Depending on the design and functionality of your app, you may be able to work around certain
hardware features being unavailable. This section discusses how to work around specific hardware
features.</p>
<h3 id="no-touchscreen">Touch screen</h3>
<p>Android doesn't support touch screen interaction for TV devices, since most TVs don't have touch
screens, and using a touch screen is not consistent with a viewing environment where the user is
seated 10 feet away from the display.</p>
<p>On TV devices, you should work around this limitation by supporting navigation using a directional
pad (D-pad) on TV remote control. For more information on properly supporting navigation using
TV-friendly controls, see <a href="{@docRoot}preview/tv/ui/navigation.html">Navigation for
TV</a>.</p>
<p>You can explicitly declare if your application requires (or does not require) a touch screen
by including the following entry in your manifest:</p>
<pre>
&lt;uses-feature android:name="android.hardware.touchscreen"
android:required="false"/&gt;
</pre>
<h3 id="no-camera">Camera</h3>
<p>Although a TV typically does not have a camera, you can still provide a photography-related
application on a TV. For example, if you have an app that takes, views and edits photos, you can
disable its picture-taking functionality for TVs and still allow users to view and even edit
photos. If you decide that you want to enable your camera-related application to work on a
TV device without a camera, you can add an attribute to your app manifest declaring that
a camera is not required by your app:</p>
<pre>
&lt;uses-feature android:name="android.hardware.camera" android:required="false" /&gt;
</pre>
<p>If you enable your application to run without a camera, you should add code to your application
that detects if the camera feature is available and makes adjustments to the operation of your app.
The following code example demonstrates how to detect the presence of a camera:</p>
<pre>
// Check if the camera hardware feature is available.
if (getPackageManager().hasSystemFeature("android.hardware.camera")) {
Log.d("Camera test", "Camera available!");
} else {
Log.d("Camera test", "No camera available. View and edit features only.");
}
</pre>
<h3 id="no-gps">GPS</h3>
<p>TVs are stationary, indoor devices, and do not have built-in global positioning system (GPS)
receivers. If your application uses location information, you can still allow users to search
for a location, or use a static location provider such as a zip code configured during the
TV device setup.</p>
<pre>
LocationManager locationManager = (LocationManager) this.getSystemService(
Context.LOCATION_SERVICE);
Location location = locationManager.getLastKnownLocation("static");
Geocoder geocoder = new Geocoder(this);
Address address = null;
try {
address = geocoder.getFromLocation(location.getLatitude(),
location.getLongitude(), 1).get(0);
Log.d("Zip code", address.getPostalCode());
} catch (IOException e) {
Log.e(TAG, "Geocoder error", e);
}
</pre>

View File

@@ -1,237 +0,0 @@
page.title=Get Started with TV Apps
page.tags="leanback","recyclerview","launcher"
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#dev-project">Setup a TV Project</a>
<ul>
<li><a href="#tv-activity">Create a TV Activity</a></li>
<li><a href="#tv-libraries">Add TV Support Libraries</a></li>
</ul>
</li>
<li><a href="#build-it">Build TV Apps</a></li>
<li><a href="#run">Run TV Apps</a></li>
</ol>
</div>
</div>
<p>This guide describes how to prepare your development environment and projects for building
TV apps, including updating your existing app to run on TV devices.</p>
<p class="note">
<strong>Important:</strong> There are specific requirements your app must meet in order to
qualify as an Android TV app on Google Play. For more information, see the requirements listed
in <a href="{@docRoot}preview/tv/publish/index.html">Publishing TV Apps</a>.
</p>
<h2 id="prerequisites">Prerequisites</h2>
<p>Before you begin setting up to build apps for TV, you must:</p>
<ul>
<li><strong><a href="{@docRoot}preview/setup-sdk.html">
Set up the Preview SDK</a></strong>
<br>
The preview SDK provides the developer tools needed to build and test apps for TV.
</li>
<li><strong><a href="{@docRoot}preview/setup-sdk.html#project">
Create a Preview SDK Project</a></strong>
<br>
In order to access new APIs for TV devices, you must create a project that targets the preview
release level or modify an existing project to target the preview release.
</li>
</ul>
<h2 id="dev-project">Set up a TV Project</h2>
<p>TV apps use the same structure as those for phones and tablets. This means you can modify
your existing apps to also run on TV devices or create new apps based on what you already know
about building apps for Android. This section discusses how to modify an existing app, or create a
new one, to run on TV devices.</p>
<p>These are the main steps to creating an app that runs on TV devices. Only the first
is required:</p>
<ul>
<li><strong>Activity for TV</strong> - (Required) In your application manifest, you must
declare an activity that is intended to run on TV devices.</li>
<li><strong>TV Support Libraries</strong> - (Optional) There are several Support Libraries
available for TV devices that provide widgets for building user interfaces.</li>
</ul>
<h3 id="tv-activity">Create a TV Activity</h3>
<p>An application intended to run on TV devices must declare a launcher activity for TV
in its manifest using a {@code android.intent.category.LEANBACK_LAUNCHER} intent filter.
This filter identifies your app as being built for TV, enabling it to be displayed in the
Google Play store app running on TV devices. Declaring this intent also identifies which activity
in your app should be launched when a user selects its icon on the TV home screen.</p>
<p class="caution">
<strong>Caution:</strong> If you do not include the {@code LEANBACK_LAUNCHER} intent filter in
your app, it is not visible to users running the Google Play store on TV devices. Also, if your
app does not have this filter when you load it onto a TV device using developer tools, the app
does not appear in the TV user interface.
</p>
<p>The following code snippet shows how to include this intent filter in your manifest:</p>
<pre>
&lt;application&gt;
...
&lt;activity
android:name=&quot;com.example.android.MainActivity&quot;
android:label=&quot;@string/app_name&quot; &gt;
&lt;intent-filter&gt;
&lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
&lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;
&lt;/intent-filter&gt;
&lt;/activity&gt;
&lt;activity
android:name=&quot;com.example.android.<strong>TvActivity</strong>&quot;
android:label=&quot;&#64;string/app_name&quot;
android:theme=&quot;&#64;style/Theme.Leanback&quot;&gt;
&lt;intent-filter&gt;
&lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
&lt;category android:name="<strong>android.intent.category.LEANBACK_LAUNCHER</strong>" /&gt;
&lt;/intent-filter&gt;
&lt;/activity&gt;
&lt;/application&gt;
</pre>
<p>The second activity manifest entry in the example above specifies that activity as
the main one when your app launches on an TV device.</p>
<p>If you have an existing app that you are modifying for TV use, your app should not use the same
activity layout for TV that it does for phones and tablets. The user interface of your TV app (or
TV portion of your existing app) should provide a simpler interface that can be easily navigated
using a remote control from a couch. For guidelines on designing an app for TV, see the
<a href="{@docRoot}design/tv/index.html">TV Design</a> guide. For more instructions on
developing a user interface appropriate to TV, see the
<a href="{@docRoot}preview/tv/ui/index.html">TV User Interface</a> guide.
</p>
<h3 id="tv-libraries">Add TV Support Libraries</h3>
<p>The Preview SDK includes support libraries that are intended for use with TV apps. These
libraries provide APIs and user interface widgets for use on TV devices. The libraries are
located in the {@code &lt;sdk&gt;/extras/android/support/} directory where you installed the
Preview SDK. Here is a list of the libraries and their general purpose:</p>
<ul>
<li><strong>v17 leanback library</strong> - Provides user interface widgets for TV, including
{@code BrowseFragment}, {@code DetailsFragment}, and {@code SearchFragment}.
<ul>
<li>SDK location: {@code &lt;sdk&gt;/extras/android/support/v17/leanback}</li>
<li>Gradle dependency: {@code com.android.support:leanback-v17:20.0.+}</li>
<li>Contains resources: Yes</li>
</ul>
</li>
<li><strong>v7 recyclerview library</strong> - Provides classes for managing display of long
lists in a memory efficient manner. Several classes in the v17 leanback library depend on the
classes in this library.
<ul>
<li>SDK location: {@code &lt;sdk&gt;/extras/android/support/v7/recyclerview}</li>
<li>Gradle dependency: {@code com.android.support:recyclerview-v7:20.0.+}</li>
<li>Contains resources: No</li>
</ul>
</li>
</ul>
<p class="note">
<strong>Note:</strong> You are not required to use these support libraries for your TV app.
However, we strongly recommend using them, particularly for apps that provide a media catalog
browsing interface.
</p>
<p>If you decide to use the v17 leanback library for your app, you should note that it is
dependent on the
<a href="{@docRoot}tools/support-library/features.html#v4">v4 support library</a>. This means
that apps that use the leanback support library should include all of these support
libraries:</p>
<ul>
<li>v17 leanback support library</li>
<li>v7 recyclerview support library</li>
<li>v4 support library</li>
</ul>
<p>The v17 leanback library contain resources, which requires
you to take specific steps to include it in app projects. For instructions on
importing a support library with resources, see
<a href="http://developer.android.com/tools/support-library/setup.html#libs-with-res">
Support Library Setup</a>.
</p>
<h2 id="build-it">Build TV Apps</h2>
<p>After you have completed the steps described above, it's time to start building apps for
the big screen! Check out these additional topics to help you build your app for TV:
<ul>
<li><a href="{@docRoot}preview/tv/ui/index.html">User Interface</a> - The user interface of
TV devices is different from those of other Android devices. See this topic to find out how
to build TV user interfaces and to learn about the widgets provided to simplify that task.
</li>
<li><a href="{@docRoot}preview/tv/games/index.html">Games for TV</a> - TV devices are great
platforms for games. See this topic for information on building great game experiences for
TV.</li>
<li><a href="{@docRoot}preview/tv/start/hardware-features.html">Hardware features</a> - TV
devices do not contain hardware features normally found on other Android devices. See this
topic for information on unsupported hardware features and what to do about them.
</li>
</ul>
<h2 id="run">Run TV Apps</h2>
<p>Running your app is an important part of the development process. The AVD Manager in the
Android SDK provides the device definitions that allows you to create virtual TV devices for
running and testing your applications.</p>
<p>To create an virtual TV device:</p>
<ol>
<li>Start the AVD Manager. For more information, see the
<a href="{@docRoot}tools/help/avd-manager.html">AVD Manager</a> help.</li>
<li>In the AVD Manager dialog, click the <strong>Device Definitions</strong> tab.</li>
<li>Select one of the Android TV device definitions, such as
<strong>Large Android TV</strong>, and click <strong>Create AVD</strong>.</li>
<li>Select the emulator options and click <strong>OK</strong> to create the AVD.
<p class="note">
<strong>Note:</strong> For best performance of the TV emulator device, enable the <strong>Use
Host GPU</strong> option and CPU platform image that supports hardware acceleration. For
more information on hardware acceleration of the emulator, see
<a href="{@docRoot}tools/devices/emulator.html#acceleration">Using the Emulator</a>.
</p>
</li>
</ol>
<p>To test your application on the virtual TV device:</p>
<ol>
<li>Compile your TV application in your development environment.</li>
<li>Run the application from your development environment and choose the TV virtual device as
the target.</li>
</ol>
<p>For more information about using emulators see, <a href="{@docRoot}tools/devices/emulator.html">
Using the Emulator</a>. For more information about deploying apps to emulators from
Eclipse with ADT, see <a href="{@docRoot}http://developer.android.com/tools/building/building-eclipse.html">
Building and Running from Eclipse with ADT</a>.</p>

View File

@@ -1,298 +0,0 @@
page.title=Layouts for TV
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li><a href="#themes">Themes</a>
<ol>
<li><a href="#leanback-theme">Leanback Theme</a></li>
<li><a href="#notitle-theme">NoTitleBar Theme</a></li>
</ol>
</li>
<li><a href="#structure">Layout Structure</a>
<ol>
<li><a href="#overscan">Overscan</a></li>
</ol>
</li>
<li><a href="#visibility">Text and Controls Visibility</a></li>
<li><a href="#density-resources">Screen Density and Image Resources</a></li>
<li><a href="#anti-patterns">Layout Anti-Patterns</a></li>
<li><a href="#large-bitmaps">Handling Large Bitmaps</a></li>
</ol>
</div>
</div>
<p>
A TV screen is typically viewed from about 10 feet away, and while it is much larger than most
other Android device displays, this type of screen does not provide the same level of precise
detail and color as a smaller device. These factors require that you create app layouts with
TV devices in mind in order to create a useful and enjoyable user experience.</p>
<p>This guide provides direction and implementation details for building effective layouts inN
TV apps.</p>
<h2 id="themes">Themes</h2>
<p>Android <a href="{@docRoot}guide/topics/ui/themes.html">Themes</a> can provide a basis for
layouts in your TV apps. You should use a theme to modify the display of your app activities
that are meant to run on a TV device. This section explains which themes you should use.</p>
<h3 id="leanback-theme">Leanback Theme</h3>
<p>The Leanback library provides a standard theme for TV activities, called {@code
Theme.Leanback}, which establishes a consistent visual style for TV apps. Use of this theme is
recommended for most apps. This theme is recommended for any TV app that uses the Leanback
library classes. The following code sample shows how to apply this theme to a given
activity within an app:</p>
<pre>
&lt;activity
android:name="com.example.android.TvActivity"
android:label="&#64;string/app_name"
<strong>android:theme="&#64;style/Theme.Leanback"</strong>&gt;
</pre>
<h3 id="notitle-theme">NoTitleBar Theme</h3>
<p>The title bar is a standard user interface element for Android apps on phones and tablets,
but it is not appropriate for TV apps. If you are not using the Leanback library classes,
you should apply this theme to your TV activities. The following code example from a TV app
manifest demonstrates how to apply this theme to remove the display of a title bar:
</p>
<pre>
&lt;application&gt;
...
&lt;activity
android:name="com.example.android.TvActivity"
android:label="&#64;string/app_name"
<strong>android:theme="&#64;android:style/Theme.NoTitleBar"</strong>&gt;
...
&lt;/activity&gt;
&lt;/application&gt;
</pre>
<h2 id="structure">Layout Structure</h2>
<p>Layouts for TV devices should follow some basic guidelines to ensure they are usable and
effective on large screens. Follow these tips to build landscape layouts optimized for TV screens:
</p>
<ul>
<li>Build layouts with a landscape orientation. TV screens always display in landscape.</li>
<li>Put on-screen navigation controls on the left or right side of the screen and save the
vertical space for content.</li>
<li>Create UIs that are divided into sections, using <a
href="{@docRoot}guide/components/fragments.html"
>Fragments</a>, and use view groups like {@link android.widget.GridView} instead of {@link
android.widget.ListView} to make better use of the horizontal screen space.
</li>
<li>Use view groups such as {@link android.widget.RelativeLayout} or {@link
android.widget.LinearLayout} to arrange views. This approach allows the system to adjust the
position of the views to the size, alignment, aspect ratio, and pixel density of a TV screen.</li>
<li>Add sufficient margins between layout controls to avoid a cluttered UI.</li>
</ul>
<h3 id="overscan">Overscan</h3>
<p>Layouts for TV have some unique requirements due to the evolution of TV standards and the
desire to always present a full screen picture to viewers. For this reason, TV devices may
clip the outside edge of an app layout in order to ensure that the entire display is filled.
This behavior is generally referred to as Overscan.</p>
<p>In order to account for the impact of overscan and make sure that all the user interface
elements you place in a layout are actually shown on screen, you should incorporate a 10% margin
on all sides of your layout. This translates into a 27dp margin on the left and right edges and
a 48dp margin on the top and bottom of your base layouts for activities. The following
example layout demonstrates how to set these margins in the root layout for a TV app:
</p>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/base_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginTop="27dp"
android:layout_marginLeft="48dp"
android:layout_marginRight="48dp"
android:layout_marginBottom="27dp" &gt;
&lt;/LinearLayout&gt;
</pre>
<p class="caution">
<strong>Caution:</strong> Do not apply overscan margins to your layout if you are using the
Leanback Support Library {@code BrowseFragment} or related widgets, as those layouts already
incorporate overscan-safe margins.
</p>
<h2 id="visibility">Text and Controls Visibility</h2>
<p>
The text and controls in a TV app layout should be easily visible and navigable from a distance.
Follow these tips to make them easier to see from a distance :
</p>
<ul>
<li>Break text into small chunks that users can quickly scan.</li>
<li>Use light text on a dark background. This style is easier to read on a TV.</li>
<li>Avoid lightweight fonts or fonts that have both very narrow and very broad strokes.
Use simple sans-serif fonts and anti-aliasing to increase readability.</li>
<li>Use Android's standard font sizes:
<pre>
&lt;TextView
android:id="@+id/atext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"/&gt;
</pre>
</li>
<li>Ensure that all your view widgets are large enough to be clearly visible to someone
sitting 10 feet away from the screen (this distance is greater for very large screens). The
best way to do this is to use layout-relative sizing rather than absolute sizing, and
density-independent pixel units instead of absolute pixel units. For example, to set the
width of a widget, use wrap_content instead of a pixel measurement, and to set the margin
for a widget, use dip instead of px values.</li>
</ul>
<h2 id="density-resources">Screen Density and Image Resources</h2>
<p>The common high-definition TV display resolutions are 720p, 1080i, and 1080p.
Your TV layout should target a screen size of 1920 x 1080 pixels, and then allow the Android
system to downscale your layout elements to 720p if necessary. In general, downscaling
(removing pixels) does not degrade your layout presentation quality. However, upscaling can
cause display artifacts that degrade the quality of your layout and have a negative impact on
the user experience of your app.</p>
<p>
To get the best scaling results for images, provide them as
<a href="{@docRoot}tools/help/draw9patch.html">9-patch image</a> elements if possible. If you
provide low quality or small images in your layouts, they will appear pixelated, fuzzy, or
grainy. This is not a good experience for the user. Instead, use high-quality images.
</p>
<p>
For more information on optimizing layouts and resources for large screens see
<a href="{@docRoot}training/multiscreen/index.html">Designing for multiple screens</a>.
</p>
<h2 id="anti-patterns">Layout Anti-Patterns</h2>
<p>There are a few approaches to building layouts for TV that you should avoid because they do not
work well and lead to bad user experiences. Here are some user interface approaches you
should specifically <em>not</em> use when developing a layout for TV.
</p>
<ul>
<li><strong>Re-using phone or tablet layouts</strong> - Do not reuse layouts from a phone or
tablet app without modification. Layouts built for other Android device form factors are not
well suited for TV devices and should be simplified for operation on a TV.</li>
<li><strong>ActionBar</strong> - While this user interface convention is recommended for use
on phones and tablets, it is not appropriate for a TV interface. In particular, using an
action bar options menu (or any pull-down menu for that matter) is strongly discouraged, due
to the difficulty in navigating such a menu with a remote control.</li>
<li><strong>ViewPager</strong> - Sliding between screens can work great on a phone or tablet,
but don't try this on a TV!</li>
</ul>
<p>For more information on designing layouts that are appropriate to TV, see the
<a href="{@docRoot}design/tv/index.html">TV Design</a> guide.</p>
<h2 id="large-bitmaps">Handling Large Bitmaps</h2>
<p>TV devices, like any other Android device, have a limited amount of memory. If you build your
app layout with very high-resolution images or use many high-resolution images in the operation
of your app, it can quickly run into memory limits and cause out of memory errors.
To avoid these types of problems, follow these tips:</p>
<ul>
<li>Load images only when they're displayed on the screen. For example, when displaying multiple images in
a {@link android.widget.GridView} or
{@link android.widget.Gallery}, only load an image when
{@link android.widget.Adapter#getView(int, View, ViewGroup) getView()}
is called on the View's {@link android.widget.Adapter}.
</li>
<li>Call {@link android.graphics.Bitmap#recycle()} on
{@link android.graphics.Bitmap} views that are no longer needed.
</li>
<li>Use {@link java.lang.ref.WeakReference} for storing references
to {@link android.graphics.Bitmap} objects in an in-memory
{@link java.util.Collection}.</li>
<li>If you fetch images from the network, use {@link android.os.AsyncTask}
to fetch and store them on the device for faster access.
Never do network transactions on the application's UI thread.
</li>
<li>Scale down large images to a more appropriate size as you download them;
otherwise, downloading the image itself may cause an out of memory exception.
The following sample code demonstrates how to scale down images while downloading:
<pre>
// Get the source image's dimensions
BitmapFactory.Options options = new BitmapFactory.Options();
// This does not download the actual image, just downloads headers.
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(IMAGE_FILE_URL, options);
// The actual width of the image.
int srcWidth = options.outWidth;
// The actual height of the image.
int srcHeight = options.outHeight;
// Only scale if the source is bigger than the width of the destination view.
if(desiredWidth > srcWidth)
desiredWidth = srcWidth;
// Calculate the correct inSampleSize/scale value. This approach helps reduce
// memory use. This value should be a power of 2.
int inSampleSize = 1;
while(srcWidth / 2 > desiredWidth){
srcWidth /= 2;
srcHeight /= 2;
inSampleSize *= 2;
}
float desiredScale = (float) desiredWidth / srcWidth;
// Decode with inSampleSize
options.inJustDecodeBounds = false;
options.inDither = false;
options.inSampleSize = inSampleSize;
options.inScaled = false;
// Ensures the image stays as a 32-bit ARGB_8888 image.
// This preserves image quality.
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap sampledSrcBitmap = BitmapFactory.decodeFile(IMAGE_FILE_URL, options);
// Resize
Matrix matrix = new Matrix();
matrix.postScale(desiredScale, desiredScale);
Bitmap scaledBitmap = Bitmap.createBitmap(sampledSrcBitmap, 0, 0,
sampledSrcBitmap.getWidth(), sampledSrcBitmap.getHeight(), matrix, true);
sampledSrcBitmap = null;
// Save
FileOutputStream out = new FileOutputStream(LOCAL_PATH_TO_STORE_IMAGE);
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
scaledBitmap = null;
</pre>
</li>
</ul>

View File

@@ -1,136 +0,0 @@
page.title=Navigation for TV
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li><a href="#d-pad-navigation">D-pad Navigation</a></li>
<li><a href="#focus-selection">Focus and Selection</a></li>
</ol>
</div>
</div>
<p>TV devices provide a limited set of navigation controls for apps. Creating an effective
navigation scheme for your TV app depends on understanding these limited controls and the limits
of users' perception while operating your app. As you build your Android app for TVs,
you should pay special attention to how the user actually navigates around your app
when using remote control buttons instead of a touch screen.</p>
<p>This guide shows you how to build an effective navigation scheme for your TV app.</p>
<h2 id="d-pad-navigation">D-pad Navigation</h2>
<p>On a TV device, users navigate with controls on a remote control device, using either a
directional pad (D-pad) or arrow keys. This type of control limits movement to up, down, left,
and right. To build a great TV-optimized app, you must provide a navigation scheme where
the user can quickly learn how to navigate your app using these limited controls.</p>
<p>Follow these guidelines to build a navigation system that works well with a D-pad on a TV device:
</p>
<ul>
<li>Ensure that the D-pad can navigate to all the visible controls on the screen.</li>
<li>For scrolling lists with focus, D-pad up/down keys scroll the list, and the Enter key selects
an item in the list. Ensure that users can select an element in the list and that the list still
scrolls when an element is selected.</li>
<li>Ensure that movement between controls is straightforward and predictable.</li>
</ul>
<p>The Android framework handles directional navigation between layout elements automatically, so
you typically do not need to do anything extra for your app. However, you should thoroughly test
navigation with a D-pad control to discover any navigation problems. If you discover that your
screen layout makes navigation difficult, or if you want users to move through the layout in a
specific way, you can set up explicit directional navigation for your controls. The following
code sample shows how to define the next control to receive focus for a
{@link android.widget.TextView} layout object:</p>
<pre>
&lt;TextView android:id="&#64;+id/Category1"
android:nextFocusDown="&#64;+id/Category2"\&gt;
</pre>
<p>The following table lists all of the available navigation attributes for Android user interface
widgets:</p>
<table>
<tr>
<th>Attribute</th>
<th>Function</th>
</tr>
<tr>
<td>{@link android.R.attr#nextFocusDown}</td>
<td>Defines the next view to receive focus when the user navigates down.</td>
</tr>
<tr>
<td>{@link android.R.attr#nextFocusLeft}</td>
<td>Defines the next view to receive focus when the user navigates left.</td>
</tr>
<tr>
<td>{@link android.R.attr#nextFocusRight}</td>
<td>Defines the next view to receive focus when the user navigates right.</td>
</tr>
<tr>
<td>{@link android.R.attr#nextFocusUp}</td>
<td>Defines the next view to receive focus when the user navigates up.</td>
</tr>
</table>
<p>To use one of these explicit navigation attributes, set the value to the ID ({@code android:id}
value) of another widget in the layout. You should set up the navigation order as a loop, so that
the last control directs focus back to the first one.</p>
<p class="note">
<strong>Note:</strong> You should only use these attributes to modify the navigation order if the
default order that the system applies does not work well.
</p>
<h2 id="focus-selection">Focus and Selection</h2>
<p>The success of a navigation scheme on TV devices is strongly dependent on how easy it is for a
user to determine what user interface element is in focus on screen. If you do not provide clear
indications of what is in focus on screen (and therefore what item they can take action on),
users can quickly become frustrated and exit your app. By the same token, it is important
to always have an item in focus that a user can take action on immediately after your app starts,
and any time your app is not playing content.</p>
<p>Your app layout and implementation should use color, size, animation, or a combination of
these attributes to help users easily determine what actions they can take next. Use a uniform
scheme for indicating focus across your application.</p>
<p>Android provides <a href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">
Drawable State List Resources</a> to implement highlights for selected and focused controls. The
following code example demonstrates how to indicate selection of a button object:
</p>
<pre>
&lt;!-- res/drawable/button.xml --&gt;
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;selector xmlns:android="http://schemas.android.com/apk/res/android"&gt;
&lt;item android:state_pressed="true"
android:drawable="@drawable/button_pressed" /&gt; &lt;!-- pressed --&gt;
&lt;item android:state_focused="true"
android:drawable="@drawable/button_focused" /&gt; &lt;!-- focused --&gt;
&lt;item android:state_hovered="true"
android:drawable="@drawable/button_focused" /&gt; &lt;!-- hovered --&gt;
&lt;item android:drawable="@drawable/button_normal" /&gt; &lt;!-- default --&gt;
&lt;/selector&gt;
</pre>
<p>
This layout XML applies the above state list drawable to a {@link android.widget.Button}:
</p>
<pre>
&lt;Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:background="@drawable/button" /&gt;
</pre>
<p>Make sure to provide sufficient padding within the focusable and selectable controls so that
the highlights around them are clearly visible.</p>

View File

@@ -839,6 +839,48 @@ include the action bar on devices running Android 2.1 or higher."
<!-- End Building for wearables -->
<!-- Start: Building for TV -->
<li class="nav-section">
<div class="nav-section-header">
<a href="<?cs var:toroot ?>training/tv/index.html">
<span class="small">Building Apps for</span><br/>
TV
</a>
</div>
<ul>
<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.">
Building TV Apps</a>
</div>
<ul>
<li>
<a href="<?cs var:toroot ?>training/tv/start/start.html">
Getting Started with TV Apps</a>
</li>
<li>
<a href="<?cs var:toroot ?>training/tv/start/hardware.html">
Handling TV Hardware</a>
</li>
<li>
<a href="<?cs var:toroot ?>training/tv/start/layouts.html">
Building TV Layouts</a>
</li>
<li>
<a href="<?cs var:toroot ?>training/tv/start/navigation.html">
Creating TV Navigation</a>
</li>
</ul>
</li>
</ul>
</li>
<!-- End: Building for TV -->
<li class="nav-section">
<div class="nav-section-header">
<a href="<?cs var:toroot ?>training/best-ux.html">
@@ -1045,29 +1087,6 @@ results."
</ul>
</li>
<li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot ?>training/tv/index.html"
description=
"How to optimize your app's user interface and user input for
the &quot;ten foot experience&quot; of a TV screen."
>Designing for TV</a>
</div>
<ul>
<li><a href="<?cs var:toroot ?>training/tv/optimizing-layouts-tv.html">
Optimizing Layouts for TV
</a>
</li>
<li><a href="<?cs var:toroot ?>training/tv/optimizing-navigation-tv.html">
Optimizing Navigation for TV
</a>
</li>
<li><a href="<?cs var:toroot ?>training/tv/unsupported-features-tv.html">
Handling Features Not Supported on TV
</a>
</li>
</ul>
</li>
<li class="nav-section">
<div class="nav-section-header">
<a href="<?cs var:toroot ?>training/custom-views/index.html"

View File

@@ -1,59 +1,8 @@
page.title=Designing for TV
page.tags="input","screens"
trainingnavtop=true
startpage=true
page.title=Building Apps for TV
page.trainingcourse=true
@jd:body
<div id="tb-wrapper">
<div id="tb">
<!-- Required platform, tools, add-ons, devices, knowledge, etc. -->
<h2>Dependencies and prerequisites</h2>
<ul>
<li>Android 2.0 (API Level 5) or higher</li>
</ul>
</div>
</div>
<a class="notice-developers-video wide" href="http://www.youtube.com/watch?v=zsRnRLh-O34">
<div>
<h3>Video</h3>
<p>DevBytes: Design for Large Displays - Part 1</p>
</div>
</a>
<p>
Smart TVs powered by Android bring your favorite Android apps to the best screen in your house.
Thousands of apps in the Google Play Store are already optimized for TVs. This class shows how
you can optimize your Android app for TVs, including how to build a layout that
works great when the user is ten feet away and navigating with a remote control.
</p>
<h2>Lessons</h2>
<dl>
<dt><b><a href="optimizing-layouts-tv.html">Optimizing Layouts for TV</a></b></dt>
<dd>Shows you how to optimize app layouts for TV screens, which have some unique characteristics such as:
<ul>
<li>permanent "landscape" mode</li>
<li>high-resolution displays</li>
<li>"10 foot UI" environment.</li>
</ul>
</dd>
<dt><b><a href="optimizing-navigation-tv.html">Optimizing Navigation for TV</a></b></dt>
<dd>Shows you how to design navigation for TVs, including:
<ul>
<li>handling D-pad navigation</li>
<li>providing navigational feedback</li>
<li>providing easily-accessible controls on the screen.</li>
</ul>
</dd>
<dt><b><a href="unsupported-features-tv.html">Handling features not supported on TV</a></b></dt>
<dd>Lists the hardware features that are usually not available on TVs. This lesson also shows you how to
provide alternatives for missing features or check for missing features and disable code at run time.</dd>
</dl>
<p>These classes teach you how to build apps for TV devices.</p>

View File

@@ -1,246 +0,0 @@
page.title=Optimizing Layouts for TV
parent.title=Designing for TV
parent.link=index.html
trainingnavtop=true
next.title=Optimizing Navigation for TV
next.link=optimizing-navigation-tv.html
@jd:body
<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you to</h2>
<ol>
<li><a href="#DesignLandscapeLayouts">Design Landscape Layouts</a></li>
<li><a href="#MakeTextControlsEasyToSee">Make Text and Controls Easy to See</a></li>
<li><a href="#DesignForLargeScreens">Design for High-Density Large Screens</a></li>
<li><a href="#HandleLargeBitmaps">Design to Handle Large Bitmaps</a></li>
</ol>
<h2>You should also read</h2>
<ul>
<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a></li>
</ul>
</div>
</div>
<p>
When your application is running on a television set, you should assume that the user is sitting about
ten feet away from the screen. This user environment is referred to as the
<a href="http://en.wikipedia.org/wiki/10-foot_user_interface">10-foot UI</a>. To provide your
users with a usable and enjoyable experience, you should style and lay out your UI accordingly..
</p>
<p>
This lesson shows you how to optimize layouts for TV by:
</p>
<ul>
<li>Providing appropriate layout resources for landscape mode.</li>
<li>Ensuring that text and controls are large enough to be visible from a distance.</li>
<li>Providing high resolution bitmaps and icons for HD TV screens.</li>
</ul>
<h2 id="DesignLandscapeLayouts">Design Landscape Layouts</h2>
<p>
TV screens are always in landscape orientation. Follow these tips to build landscape layouts optimized for TV screens:
</p>
<ul>
<li>Put on-screen navigational controls on the left or right side of the screen and save the
vertical space for content.</li>
<li>Create UIs that are divided into sections, by using <a href="{@docRoot}guide/components/fragments.html">Fragments</a>
and use view groups like {@link android.widget.GridView} instead
of {@link android.widget.ListView} to make better use of the
horizontal screen space.</li>
<li>Use view groups such as {@link android.widget.RelativeLayout}
or {@link android.widget.LinearLayout} to arrange views.
This allows the Android system to adjust the position of the views to the size, alignment,
aspect ratio, and pixel density of the TV screen.</li>
<li>Add sufficient margins between layout controls to avoid a cluttered UI.</li>
</ul>
<p>
For example, the following layout is optimized for TV:
</p>
<img src="{@docRoot}images/training/panoramio-grid.png" />
<p>
In this layout, the controls are on the lefthand side. The UI is displayed within a
{@link android.widget.GridView}, which is well-suited to landscape orientation.
In this layout both GridView and Fragment have the width and height set
dynamically, so they can adjust to the screen resolution. Controls are added to the left side Fragment programatically at runtime.
The layout file for this UI is {@code res/layout-land-large/photogrid_tv.xml}.
(This layout file is placed in {@code layout-land-large} because TVs have large screens with landscape orientation. For details refer to
<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>.)</p>
res/layout-land-large/photogrid_tv.xml
<pre>
&lt;RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" &gt;
&lt;fragment
android:id="@+id/leftsidecontrols"
android:layout_width="0dip"
android:layout_marginLeft="5dip"
android:layout_height="match_parent" /&gt;
&lt;GridView
android:id="@+id/gridview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /&gt;
&lt;/RelativeLayout>
</pre>
<p>
To set up action bar items on the left side of the screen, you can also include the <a
href="http://code.google.com/p/googletv-android-samples/source/browse/#git%2FLeftNavBarLibrary">
Left navigation bar library</a> in your application to set up action items on the left side
of the screen, instead of creating a custom Fragment to add controls:
</p>
<pre>
LeftNavBar bar = (LeftNavBarService.instance()).getLeftNavBar(this);
</pre>
<p>
When you have an activity in which the content scrolls vertically, always use a left navigation bar;
otherwise, your users have to scroll to the top of the content to switch between the content view and
the ActionBar. Look at the
<a href="http://code.google.com/p/googletv-android-samples/source/browse/#git%2FLeftNavBarDemo">
Left navigation bar sample app</a> to see how to simple it is to include the left navigation bar in your app.
</p>
<h2 id="MakeTextControlsEasyToSee">Make Text and Controls Easy to See</h2>
<p>
The text and controls in a TV application's UI should be easily visible and navigable from a distance.
Follow these tips to make them easier to see from a distance :
</p>
<ul>
<li>Break text into small chunks that users can quickly scan.</li>
<li>Use light text on a dark background. This style is easier to read on a TV.</li>
<li>Avoid lightweight fonts or fonts that have both very narrow and very broad strokes. Use simple sans-serif
fonts and use anti-aliasing to increase readability.</li>
<li>Use Android's standard font sizes:
<pre>
&lt;TextView
android:id="@+id/atext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"/&gt;
</pre></li>
<li>Ensure that all your view widgets are large enough to be clearly visible to someone sitting 10 feet away
from the screen (this distance is greater for very large screens). The best way to do this is to use
layout-relative sizing rather than absolute sizing, and density-independent pixel units instead of absolute
pixel units. For example, to set the width of a widget, use wrap_content instead of a pixel measurement,
and to set the margin for a widget, use dip instead of px values.
</li>
</ul>
<p>
</p>
<h2 id="DesignForLargeScreens">Design for High-Density Large Screens</h2>
<p>
The common HDTV display resolutions are 720p, 1080i, and 1080p. Design your UI for 1080p, and then
allow the Android system to downscale your UI to 720p if necessary. In general, downscaling (removing pixels)
does not degrade the UI (Notice that the converse is not true; you should avoid upscaling because it degrades
UI quality).
</p>
<p>
To get the best scaling results for images, provide them as <a href="{@docRoot}tools/help/draw9patch.html">
9-patch image</a> elements if possible.
If you provide low quality or small images in your layouts, they will appear pixelated, fuzzy, or grainy. This
is not a good experience for the user. Instead, use high-quality images.
</p>
<p>
For more information on optimizing apps for large screens see <a href="{@docRoot}training/multiscreen/index.html">
Designing for multiple screens</a>.
</p>
<h2 id="HandleLargeBitmaps">Design to Handle Large Bitmaps</h2>
<p>
The Android system has a limited amount of memory, so downloading and storing high-resolution images can often
cause out-of-memory errors in your app. To avoid this, follow these tips:
</p>
<ul>
<li>Load images only when they're displayed on the screen. For example, when displaying multiple images in
a {@link android.widget.GridView} or
{@link android.widget.Gallery}, only load an image when
{@link android.widget.Adapter#getView(int, View, ViewGroup) getView()}
is called on the View's {@link android.widget.Adapter}.
</li>
<li>Call {@link android.graphics.Bitmap#recycle()} on
{@link android.graphics.Bitmap} views that are no longer needed.
</li>
<li>Use {@link java.lang.ref.WeakReference} for storing references
to {@link android.graphics.Bitmap} objects in an in-memory
{@link java.util.Collection}.</li>
<li>If you fetch images from the network, use {@link android.os.AsyncTask}
to fetch them and store them on the SD card for faster access.
Never do network transactions on the application's UI thread.
</li>
<li>Scale down really large images to a more appropriate size as you download them; otherwise, downloading the image
itself may cause an "Out of Memory" exception. Here is sample code that scales down images while downloading:
<pre>
// Get the source image's dimensions
BitmapFactory.Options options = new BitmapFactory.Options();
// This does not download the actual image, just downloads headers.
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(IMAGE_FILE_URL, options);
// The actual width of the image.
int srcWidth = options.outWidth;
// The actual height of the image.
int srcHeight = options.outHeight;
// Only scale if the source is bigger than the width of the destination view.
if(desiredWidth > srcWidth)
desiredWidth = srcWidth;
// Calculate the correct inSampleSize/scale value. This helps reduce memory use. It should be a power of 2.
int inSampleSize = 1;
while(srcWidth / 2 > desiredWidth){
srcWidth /= 2;
srcHeight /= 2;
inSampleSize *= 2;
}
float desiredScale = (float) desiredWidth / srcWidth;
// Decode with inSampleSize
options.inJustDecodeBounds = false;
options.inDither = false;
options.inSampleSize = inSampleSize;
options.inScaled = false;
// Ensures the image stays as a 32-bit ARGB_8888 image.
// This preserves image quality.
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap sampledSrcBitmap = BitmapFactory.decodeFile(IMAGE_FILE_URL, options);
// Resize
Matrix matrix = new Matrix();
matrix.postScale(desiredScale, desiredScale);
Bitmap scaledBitmap = Bitmap.createBitmap(sampledSrcBitmap, 0, 0,
sampledSrcBitmap.getWidth(), sampledSrcBitmap.getHeight(), matrix, true);
sampledSrcBitmap = null;
// Save
FileOutputStream out = new FileOutputStream(LOCAL_PATH_TO_STORE_IMAGE);
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
scaledBitmap = null;
</pre>
</li> </ul>

View File

@@ -1,206 +0,0 @@
page.title=Optimizing Navigation for TV
parent.title=Designing for TV
parent.link=index.html
trainingnavtop=true
previous.title=Optimizing Layouts for TV
previous.link=optimizing-layouts-tv.html
next.title=Handling Features Not Supported on TV
next.link=unsupported-features-tv.html
@jd:body
<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you to</h2>
<ol>
<li><a href="#HandleDpadNavigation">Handle D-pad Navigation</a></li>
<li><a href="#HandleFocusSelection">Provide Clear Visual Indication for Focus and Selection</a></li>
<li><a href="#DesignForEasyNavigation">Design for Easy Navigation</a></li>
</ol>
<h2>You should also read</h2>
<ul>
<li><a href="{@docRoot}training/design-navigation/index.html">Designing Effective Navigation</a></li>
</ul>
</div>
</div>
<p>
An important aspect of the user experience when operating a TV is the direct human interface: a remote control.
As you optimize your Android application for TVs, you should pay special attention to how the user actually navigates
around your application when using a remote control instead of a touchscreen.
</p>
<p>
This lesson shows you how to optimize navigation for TV by:
</p>
<ul>
<li>Ensuring all layout controls are D-pad navigable.</li>
<li>Providing highly obvious feedback for UI navigation.</li>
<li>Placing layout controls for easy access.</li>
</ul>
<h2 id="HandleDpadNavigation">Handle D-pad Navigation</h2>
<p>
On a TV, users navigate with controls on a TV remote, using either a D-pad or arrow keys.
This limits movement to up, down, left, and right.
To build a great TV-optimized app, you must provide a navigation scheme in which the user can
quickly learn how to navigate your app using the remote.
</p>
<p>
When you design navigation for D-pad, follow these guidelines:
</p>
<ul>
<li>Ensure that the D-pad can navigate to all the visible controls on the screen.</li>
<li>For scrolling lists with focus, D-pad up/down keys scroll the list and Enter key selects an item in the list. Ensure that users can
select an element in the list and that the list still scrolls when an element is selected.</li>
<li>Ensure that movement between controls is straightforward and predictable.</li>
</ul>
<p>
Android usually handles navigation order between layout elements automatically, so you don't need to do anything extra. If the screen layout
makes navigation difficult, or if you want users to move through the layout in a specific way, you can set up explicit navigation for your
controls.
For example, for an {@code android.widget.EditText}, to define the next control to receive focus, use:
<pre>
&lt;EditText android:id="@+id/LastNameField" android:nextFocusDown="@+id/FirstNameField"\&gt;
</pre>
The following table lists all of the available navigation attributes:
</p>
<table>
<tr>
<th>Attribute</th>
<th>Function</th>
</tr>
<tr>
<td>{@link android.R.attr#nextFocusDown}</td>
<td>Defines the next view to receive focus when the user navigates down.</td>
</tr>
<tr>
<td>{@link android.R.attr#nextFocusLeft}</td>
<td>Defines the next view to receive focus when the user navigates left.</td>
</tr>
<tr>
<td>{@link android.R.attr#nextFocusRight}</td>
<td>Defines the next view to receive focus when the user navigates right.</td>
</tr>
<tr>
<td>{@link android.R.attr#nextFocusUp}</td>
<td>Defines the next view to receive focus when the user navigates up.</td>
</tr>
</table>
<p>
To use one of these explicit navigation attributes, set the value to the ID (android:id value) of another widget in the layout. You should set
up the navigation order as a loop, so that the last control directs focus back to the first one.
</p>
<p>
Note: You should only use these attributes to modify the navigation order if the default order that the system applies does not work well.
</p>
<h2 id="HandleFocusSelection">Provide Clear Visual Indication for Focus and Selection</h2>
<p>
Use appropriate color highlights for all navigable and selectable elements in the UI. This makes it easy for users to know whether the control
is currently focused or selected when they navigate with a D-pad. Also, use uniform highlight scheme across your application.
</p>
<p>
Android provides <a href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">Drawable State List Resources</a> to implement highlights
for selected and focused controls. For example:
</p>
res/drawable/button.xml:
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;selector xmlns:android="http://schemas.android.com/apk/res/android"&gt;
&lt;item android:state_pressed="true"
android:drawable="@drawable/button_pressed" /&gt; &lt;!-- pressed --&gt;
&lt;item android:state_focused="true"
android:drawable="@drawable/button_focused" /&gt; &lt;!-- focused --&gt;
&lt;item android:state_hovered="true"
android:drawable="@drawable/button_focused" /&gt; &lt;!-- hovered --&gt;
&lt;item android:drawable="@drawable/button_normal" /&gt; &lt;!-- default --&gt;
&lt;/selector&gt;
</pre>
<p>
This layout XML applies the above state list drawable to a {@link android.widget.Button}:
</p>
<pre>
&lt;Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:background="@drawable/button" /&gt;
</pre>
<p>
Provide sufficient padding within the focusable and selectable controls so that the highlights around them are clearly visible.
</p>
<h2 id="DesignForEasyNavigation">Design for Easy Navigation</h2>
<p>
Users should be able to navigate to any UI control with a couple of D-pad clicks. Navigation should be easy and intuitive to
understand. For any non-intuitive actions, provide users with written help, using a dialog triggered by a help button or action bar icon.
</p>
<p>
Predict the next screen that the user will want to navigate to and provide one click navigation to it. If the current screen UI is very sparse,
consider making it a multi pane screen. Use fragments for making multi-pane screens. For example, consider the multi-pane UI below with continent names
on the left and list of cool places in each continent on the right.
</p>
<img src="{@docRoot}images/training/cool-places.png" alt="" />
<p>
The above UI consists of three Fragments - <code>left_side_action_controls</code>, <code>continents</code> and
<code>places</code> - as shown in its layout
xml file below. Such multi-pane UIs make D-pad navigation easier and make good use of the horizontal screen space for
TVs.
</p>
res/layout/cool_places.xml
<pre>
&lt;LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
&gt;
&lt;fragment
android:id="@+id/left_side_action_controls"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_marginLeft="10dip"
android:layout_weight="0.2"/&gt;
&lt;fragment
android:id="@+id/continents"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_marginLeft="10dip"
android:layout_weight="0.2"/&gt;
&lt;fragment
android:id="@+id/places"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_marginLeft="10dip"
android:layout_weight="0.6"/&gt;
&lt;/LinearLayout&gt;
</pre>
<p>
Also, notice in the UI layout above action controls are on the left hand side of a vertically scrolling list to make
them easily accessible using D-pad.
In general, for layouts with horizontally scrolling components, place action controls on left or right hand side and
vice versa for vertically scrolling components.
</p>

View File

@@ -0,0 +1,361 @@
page.title=Handling TV Hardware
page.tags="unsupported"
trainingnavtop=true
@jd:body
<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you how to</h2>
<ol>
<li><a href="#runtime-check">Check for a TV Device</a>
<li><a href="#handle-features">Handle Unsupported Hardware Features</a></li>
<li><a href="#controllers">Manage Hardware Controllers</a>
</li>
</ol>
</div>
</div>
<p>
TV hardware is substantially different from other Android devices. TVs do not
include some of the hardware features found on other Android devices, such as touch screens,
cameras, and GPS receivers. TVs are also completely dependent on secondary hardware devices.
In order for users to interact with TV apps, they must use a remote control or game pad. When
you build an app for TV, you must carefully consider the hardware limitations and requirements of
operating on TV hardware.
</p>
<p>
This lesson discusses how to check if your app is running on a TV, how to handle unsupported
hardware features, and discusses the requirements for handling controllers for TV devices.
</p>
<h2 id="runtime-check">Check for a TV Device</h2>
<p>
If you are building an app that operates both on TV devices and other devices, you may need to
check what kind of device your app is running on and adjust the operation of your app. For
instance, if you have an app that can be started through an {@link android.content.Intent}, your
application should check the device properties to determine if it should start a TV-oriented
activity or a phone activity.
</p>
<p>
The recommended way to determine if your app is running on a TV device is to use the {@link
android.app.UiModeManager#getCurrentModeType UiModeManager.getCurrentModeType()} method to check
if the device is running in television mode. The following example code shows you how to check if
your app is running on a TV device:
</p>
<pre>
public static final String TAG = "DeviceTypeRuntimeCheck";
UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE);
if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) {
Log.d(TAG, "Running on a TV Device")
} else {
Log.d(TAG, "Running on a non-TV Device")
}
</pre>
<h2 id="handle-features">Handle Unsupported Hardware Features</h2>
<p>
Depending on the design and functionality of your app, you may be able to work around certain
hardware features being unavailable. This section discusses what hardware features are typically
not available for TV, how to detect missing hardware features, and suggests alternatives to
using these features.
</p>
<h3 id="unsupported-features">Unsupported TV hardware features</h3>
<p>
TVs have a different purpose from other devices, and so they do not have hardware features that
other Android-powered devices often have. For this reason, the Android system does not support
the following features for a TV device:
</p>
<table>
<tr>
<th>Hardware</th>
<th>Android feature descriptor</th>
</tr>
<tr>
<td>Touchscreen</td>
<td>android.hardware.touchscreen</td>
</tr>
<tr>
<td>Telephony</td>
<td>android.hardware.telephony</td>
</tr>
<tr>
<td>Camera</td>
<td>android.hardware.camera</td>
</tr>
<tr>
<td>Near Field Communications (NFC)</td>
<td>android.hardware.nfc</td>
</tr>
<tr>
<td>GPS</td>
<td>android.hardware.location.gps</td>
</tr>
<tr>
<td>Microphone</td>
<td>android.hardware.microphone</td>
</tr>
</table>
<h3 id="declare-hardware-requirements">Declaring hardware requirements for TV</h3>
<p>
Android apps can declare hardware feature requirements in the app manifest to ensure that they do
not get installed on devices that do not provide those features. If you are extending an existing
app for use on TV, closely review your app's manifest for any hardware requirement
declarations that might prevent it from being installed on a TV device.
</p>
<p>
If your app uses hardware features (such as a touchscreen or camera) that are not available on
TV, but can operate without the use of those features, modify your app's manifest to
indicate that these features are not required by your app. The following manifest code snippet
demonstrates how to declare that your app does not require hardware features which are unavailable
on TV devices, even though your app may use these features on non-TV devices:
</p>
<pre>
&lt;uses-feature android:name="android.hardware.touchscreen"
android:required="false"/&gt;
&lt;uses-feature android:name="android.hardware.telephony"
android:required="false"/&gt;
&lt;uses-feature android:name="android.hardware.camera"
android:required="false"/&gt;
&lt;uses-feature android:name="android.hardware.nfc"
android:required="false"/&gt;
&lt;uses-feature android:name="android.hardware.gps"
android:required="false"/&gt;
&lt;uses-feature android:name="android.hardware.microphone"
android:required="false"/&gt;
</pre>
<p class="caution">
<strong>Caution:</strong> Declaring an unavailable hardware feature as required by setting its
value to {@code true} in your app manifest prevents your app from being installed on TV
devices or appearing in the Android TV home screen launcher.
</p>
<p class="caution">
<strong>Caution:</strong> Some <a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">{@code uses-permission}</a> manifest declarations <em>imply hardware use</em>, which can also
prevent your app from being installed and used on TV devices. For example, requesting the
{@link android.Manifest.permission#RECORD_AUDIO} permission in your app implies the
{@code android.hardware.microphone} hardware feature requirement. In which case, you must declare
the microphone feature as not required ({@code android:required="false"}) in your app manifest.
For a list of permission requests that imply a hardware feature requirement, see <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html#permissions-features">
{@code uses-feature}</a> guide.
</p>
<p>
Once you decide to make hardware features optional for your app, you must check for the
availability of those features at runtime and then adjust your app's behavior. The next section
discusses how to check for hardware features and suggests some approaches for changing the
behavior of your app.
</p>
<p>
For more information on filtering and declaring features in the manifest, see the
<a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code uses-feature}</a>
guide.
</p>
<h3 id="check-features">Checking for hardware features</h2>
<p>
The Android framework can tell you if hardware features are not available on the device where
your app is running. Use the {@link android.content.pm.PackageManager#hasSystemFeature(String)}
method to check for specific features at runtime. This method takes a single string argument that
specifies the feature you want to check.
</p>
<p>The following code example demonstrates how to detect the availability of hardware features
at runtime:</p>
<pre>
// Check if the telephony hardware feature is available.
if (getPackageManager().hasSystemFeature("android.hardware.telephony")) {
Log.d("HardwareFeatureTest", "Device can make phone calls");
}
// Check if android.hardware.touchscreen feature is available.
if (getPackageManager().hasSystemFeature("android.hardware.touchscreen")) {
Log.d("HardwareFeatureTest", "Device has a touch screen.");
}
</pre>
<h4 id="no-touchscreen">Touch screen</h4>
<p>
Since most TVs do not have touch screens, Android does not support touch screen interaction for
TV devices. Furthermore, using a touch screen is not consistent with a viewing environment where
the user is seated 10 feet away from the display.
</p>
<p>
On TV devices, you should design your app to work with this interaction model by supporting
navigation using a directional pad (D-pad) on a TV remote control. For more information on
properly supporting navigation using TV-friendly controls, see
<a href="{@docRoot}training/tv/start/navigation.html">Creating TV Navigation</a>.
</p>
<h4 id="no-camera">Camera</h4>
<p>
Although a TV typically does not have a camera, you can still provide a photography-related
app on a TV. For example, if you have an app that takes, views, and edits photos, you can
disable its picture-taking functionality for TVs and still allow users to view and even edit
photos. If you decide to enable your camera-related app to work on a TV, add the
following feature declaration your app manifest:
</p>
<pre>
&lt;uses-feature android:name="android.hardware.camera" android:required="false" /&gt;
</pre>
<p>
If you enable your app to run without a camera, add code to your app
that detects if the camera feature is available and makes adjustments to the operation of your
app. The following code example demonstrates how to detect the presence of a camera:
</p>
<pre>
// Check if the camera hardware feature is available.
if (getPackageManager().hasSystemFeature("android.hardware.camera")) {
Log.d("Camera test", "Camera available!");
} else {
Log.d("Camera test", "No camera available. View and edit features only.");
}
</pre>
<h4 id="no-gps">GPS</h4>
<p>
TVs are stationary, indoor devices, and do not have built-in global positioning system (GPS)
receivers. If your app uses location information, you can still allow users to search for
a location, or use a static location provider such as a zip code configured during the TV device
setup.
</p>
<pre>
// Request a static location from the location manager
LocationManager locationManager = (LocationManager) this.getSystemService(
Context.LOCATION_SERVICE);
Location location = locationManager.getLastKnownLocation("static");
// Attempt to get postal or zip code from the static location object
Geocoder geocoder = new Geocoder(this);
Address address = null;
try {
address = geocoder.getFromLocation(location.getLatitude(),
location.getLongitude(), 1).get(0);
Log.d("Zip code", address.getPostalCode());
} catch (IOException e) {
Log.e(TAG, "Geocoder error", e);
}
</pre>
<h2 id="controllers">Handling Controllers</h2>
<p>
TV devices require a secondary hardware device for interacting with apps, in the form of a basic
remote controller or game controller. This means that your app must support D-pad input. It also
means that your app may need to handle controllers going offline and input from more than one
type of controller.
</p>
<h3 id="d-pad-minimum">D-pad minimum controls</h3>
<p>
The default controller for a TV device is a D-pad. In general, your app should be operable from a
remote controller that only has up, down, left, right, select, Back, and Home buttons. If your app
is a game that typically requires a game controller with additional controls, your app should
attempt to allow gameplay with these D-pad controls. In this case, your app should also warn the
user that
a controller is required and allow them to exit your game gracefully using the D-pad controller.
For more information about handling navigation with D-pad controller for TV devices, see
<a href="{@docRoot}training/tv/start/navigation.html">Creating TV Navigation</a>.
</p>
<h3 id="controller-disconnects">Handle controller disconnects</h3>
<p>
Controllers for TV are frequently Bluetooth devices which may attempt to save power by periodically
going into sleep mode and disconnecting from the TV device. This means that an app might be
interrupted or restarted if it is not configured to handle these reconnect events. These events
can happen in any of the following circumstances:
</p>
<ul>
<li>While watching a video which is several minutes long, a D-Pad or game controller goes into
sleep mode, disconnects from the TV device and then reconnects later on.
</li>
<li>During gameplay, a new player joins the game using a game controller that is not currently
connected.
</li>
<li>During gameplay, a player leaves the game and disconnects a game controller.
</li>
</ul>
<p>
Any TV app activity that is subject to disconnect and reconnect events must be configured to
handle reconnection events in the app manifest. The following code sample demonstrates how to
enable an activity to handle configuration changes, including a keyboard or navigation device
connecting, disconnecting, or reconnecting:
</p>
<pre>
&lt;activity
android:name=&quot;com.example.android.TvActivity&quot;
android:label=&quot;&#64;string/app_name&quot;
<strong>android:configChanges="keyboard|keyboardHidden|navigation"</strong>
android:theme=&quot;&#64;style/Theme.Leanback&quot;&gt;
&lt;intent-filter&gt;
&lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
&lt;category android:name="android.intent.category.LEANBACK_LAUNCHER" /&gt;
&lt;/intent-filter&gt;
...
&lt;/activity&gt;
</pre>
<p>
This configuration change allows the app to continue running through a reconnection event, rather
than being restarted by the Android framework, which is not a good user experience.
</p>
<h3 id="d-pad-variants">Handle D-pad input variations</h3>
<p>
TV device users may have more than one type of controller that they use with their TV. For
example, a user might have both a basic D-pad controller and a game controller. The key codes
provided by a game controller when it is being used for D-pad functions may vary from the key
codes sent by a physical D-pad.
</p>
<p>
Your app should handle the variations of D-pad input from a game controller, so the user does not
have to physically switch controllers to operate your app. For more information on handling these
input variations, see <a href="{@docRoot}training/game-controllers/controller-input.html#dpad">
Handling Controller Actions</a>.
</p>

View File

@@ -0,0 +1,63 @@
page.title=Building TV Apps
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>
<li>Android Studio 0.8 or later and Gradle 0.12 or later</li>
</ul>
</div>
</div>
<p>
Android offers a rich user experience that's optimized for apps running on large screen devices,
such as high-definition televisions. Apps on TV offer new opportunities to delight your users
from the comfort of their couch.
</p>
<p>
TV apps use the same structure as those for phones and tablets. This approach means you can
create new TV apps based on what you already know about building apps for Android, or extend your
existing apps to also run on TV devices. However, the user interaction model for TV is
substantially different from phone and tablet devices. In order to make your app successful on TV
devices, you must design new layouts that can be easily understood from 10 feet away, and provide
navigation that works with just a directional pad and a select button.
</p>
<p>
This class describes how to start building apps for TV, including setting up your development
environment, basic requirements for layouts and navigation, as well as guidance on how to handle
hardware features that are not typically available on TV devices.
</p>
<p class="note">
<strong>Note:</strong> You are encouraged to use <a href=
"{@docRoot}sdk/installing/studio.html">Android Studio</a> for building TV apps, because it
provides project setup, library inclusion, and packaging conveniences. This training assumes you
are using Android Studio.
</p>
<h2>Lessons</h2>
<dl>
<dt><a href="{@docRoot}training/tv/start/start.html">
Getting Started with TV Apps</a></dt>
<dd>Learn how to create a new Android Studio project for TV apps or modify your existing
app project to run on TV devices.</dd>
<dt><a href="{@docRoot}training/tv/start/layouts.html">
Building TV Layouts</a></dt>
<dd>Learn the minimum requirements for TV layouts and how to implement them.</dd>
<dt><a href="{@docRoot}training/tv/start/navigation.html">
Creating TV Navigation</a></dt>
<dd>Learn the requirements for TV navigation and how to implement TV-compatible
navigation.</dd>
<dt><a href="{@docRoot}training/tv/start/hardware.html">
Handling TV Hardware</a></dt>
<dd>Learn how to check if your app is running on TV hardware, handle unsupported hardware
features, and manage controller devices.</dd>
</dl>

View File

@@ -0,0 +1,257 @@
page.title=Building Layouts for TV
trainingnavtop=true
@jd:body
<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you how to</h2>
<ol>
<li><a href="#themes">Use Layout Themes for TV</a></li>
<li><a href="#structure">Build Basic TV Layouts</a></li>
<li><a href="#visibility">Build Useable Text and Controls</a></li>
<li><a href="#density-resources">Manage Layout Resources for TV</a></li>
<li><a href="#anti-patterns">Avoid Layout Anti-Patterns</a></li>
<li><a href="#large-bitmaps">Handle Large Bitmaps</a></li>
</ol>
<h2>You should also read</h2>
<ol>
<li><a href="{@docRoot}design/tv/index.html">Android TV Design</a></li>
</ol>
</div>
</div>
<p>
A TV screen is typically viewed from about 10 feet away, and while it is much larger than most
other Android device displays, this type of screen does not provide the same level of precise
detail and color as a smaller device. These factors require you to create app layouts with TV
devices in mind in order to create a useful and enjoyable user experience.
</p>
<p>
This lesson describes the minimum requirements and implementation details for building effective
layouts in TV apps.
</p>
<h2 id="themes">Use Layout Themes for TV</h2>
<p>
Android <a href="{@docRoot}guide/topics/ui/themes.html">Themes</a> can provide a basis for
layouts in your TV apps. You should use a theme to modify the display of your app activities that
are meant to run on a TV device. This section explains which themes you should use.
</p>
<h3 id="leanback-theme">Leanback theme</h3>
<p>
A support library for TV user interfaces called the <a href=
"{@docRoot}tools/support-library/features.html#v17-leanback">v17 leanback library</a> provides a
standard theme for TV activities, called {@code Theme.Leanback}. This theme establishes a
consistent visual style for TV apps. Use of this theme is recommended for most TV apps. This
theme is strongly recommended for any TV app that uses v17 leanback classes. The following code
sample shows how to apply this theme to a given activity within an app:
</p>
<pre>
&lt;activity
android:name="com.example.android.TvActivity"
android:label="&#64;string/app_name"
<strong>android:theme="&#64;style/Theme.Leanback"</strong>&gt;
</pre>
<h3 id="notitle-theme">NoTitleBar theme</h3>
<p>
The title bar is a standard user interface element for Android apps on phones and tablets, but it
is not appropriate for TV apps. If you are not using v17 leanback classes, you should apply this
theme to your TV activities to suppress the display of a title bar. The following code example
from a TV app manifest demonstrates how to apply this theme to remove the display of a title bar:
</p>
<pre>
&lt;application&gt;
...
&lt;activity
android:name="com.example.android.TvActivity"
android:label="&#64;string/app_name"
<strong>android:theme="&#64;android:style/Theme.NoTitleBar"</strong>&gt;
...
&lt;/activity&gt;
&lt;/application&gt;
</pre>
<h2 id="structure">Build Basic TV Layouts</h2>
<p>Layouts for TV devices should follow some basic guidelines to ensure they are usable and
effective on large screens. Follow these tips to build landscape layouts optimized for TV screens:
</p>
<ul>
<li>Build layouts with a landscape orientation. TV screens always display in landscape mode.</li>
<li>Put on-screen navigation controls on the left or right side of the screen and save the
vertical space for content.</li>
<li>Create UIs that are divided into sections, using <a href="{@docRoot}guide/components/fragments.html"
>Fragments</a>, and use view groups like {@link android.widget.GridView} instead of {@link
android.widget.ListView} to make better use of the horizontal screen space.
</li>
<li>Use view groups such as {@link android.widget.RelativeLayout} or {@link
android.widget.LinearLayout} to arrange views. This approach allows the system to adjust the
position of the views to the size, alignment, aspect ratio, and pixel density of a TV screen.</li>
<li>Add sufficient margins between layout controls to avoid a cluttered UI.</li>
</ul>
<h3 id="overscan">Overscan</h3>
<p>Layouts for TV have some unique requirements due to the evolution of TV standards and the
desire to always present a full screen picture to viewers. For this reason, TV devices may
clip the outside edge of an app layout in order to ensure that the entire display is filled.
This behavior is generally referred to as <em>overscan</em>.
</p>
<p>
Avoid screen elements being clipped due to overscan and by incorporating a 10% margin
on all sides of your layout. This translates into a 27dp margin on the left and right edges and
a 48dp margin on the top and bottom of your base layouts for activities. The following
example layout demonstrates how to set these margins in the root layout for a TV app:
</p>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/base_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginTop="27dp"
android:layout_marginLeft="48dp"
android:layout_marginRight="48dp"
android:layout_marginBottom="27dp" &gt;
&lt;/LinearLayout&gt;
</pre>
<p class="caution">
<strong>Caution:</strong> Do not apply overscan margins to your layout if you are using the
v17 leanback classes, such as {@link android.support.v17.leanback.app.BrowseFragment} or related
widgets, as those layouts already incorporate overscan-safe margins.
</p>
<h2 id="visibility">Build Useable Text and Controls</h2>
<p>
The text and controls in a TV app layout should be easily visible and navigable from a distance.
Follow these tips to make your user interface elements easier to see from a distance:
</p>
<ul>
<li>Break text into small chunks that users can quickly scan.</li>
<li>Use light text on a dark background. This style is easier to read on a TV.</li>
<li>Avoid lightweight fonts or fonts that have both very narrow and very broad strokes.
Use simple sans-serif fonts and anti-aliasing to increase readability.</li>
<li>Use Android's standard font sizes:
<pre>
&lt;TextView
android:id="@+id/atext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:singleLine="true"
<strong>android:textAppearance="?android:attr/textAppearanceMedium"/&gt;</strong>
</pre>
</li>
<li>Ensure that all your view widgets are large enough to be clearly visible to someone
sitting 10 feet away from the screen (this distance is greater for very large screens). The
best way to do this is to use layout-relative sizing rather than absolute sizing, and
density-independent pixel (dip) units instead of absolute pixel units. For example, to set the
width of a widget, use {@code wrap_content} instead of a pixel measurement, and to set the
margin for a widget, use dip values instead of px values.</li>
</ul>
<p>
For more information about density-independent pixels and building layouts to handle larger
screen sizes, see <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
Screens</a>.
</p>
<h2 id="density-resources">Manage Layout Resources for TV</h2>
<p>The common high-definition TV display resolutions are 720p, 1080i, and 1080p.
Your TV layout should target a screen size of 1920 x 1080 pixels, and then allow the Android
system to downscale your layout elements to 720p if necessary. In general, downscaling
(removing pixels) does not degrade your layout presentation quality. However, upscaling can
cause display artifacts that degrade the quality of your layout and have a negative impact on
the user experience of your app.</p>
<p>
To get the best scaling results for images, provide them as
<a href="{@docRoot}tools/help/draw9patch.html">9-patch image</a> elements if possible. If you
provide low quality or small images in your layouts, they will appear pixelated, fuzzy, or
grainy, which is not a good experience for the user. Use high-quality images instead.
</p>
<p>
For more information on optimizing layouts and resources for large screens see
<a href="{@docRoot}training/multiscreen/index.html">Designing for multiple screens</a>.
</p>
<h2 id="anti-patterns">Avoid Layout Anti-Patterns</h2>
<p>
There are a few approaches to building layouts that you should avoid because they do not work
well on TV devices and lead to bad user experiences. Here are some user interface approaches you
should specifically <em>not</em> use when developing a layout for TV.
</p>
<ul>
<li><strong>Re-using phone or tablet layouts</strong> - Do not reuse layouts from a phone or
tablet app without modification. Layouts built for other Android device form factors are not
well suited for TV devices and should be simplified for operation on a TV.</li>
<li><strong>ActionBar</strong> - While this user interface convention is recommended for use
on phones and tablets, it is not appropriate for a TV interface. In particular, using an
action bar options menu (or any pull-down menu for that matter) is strongly discouraged, due
to the difficulty in navigating such a menu with a remote control.</li>
<li><strong>ViewPager</strong> - Sliding between screens can work great on a phone or tablet,
but don't try this on a TV!</li>
</ul>
<p>For more information on designing layouts that are appropriate to TV, see the
<a href="{@docRoot}design/tv/index.html">TV Design</a> guide.</p>
<h2 id="large-bitmaps">Handle Large Bitmaps</h2>
<p>TV devices, like any other Android device, have a limited amount of memory. If you build your
app layout with very high-resolution images or use many high-resolution images in the operation
of your app, it can quickly run into memory limits and cause out of memory errors.
To avoid these types of problems, follow these tips:</p>
<ul>
<li>Load images only when they are displayed on the screen. For example, when displaying multiple
images in a {@link android.widget.GridView} or {@link android.widget.Gallery}, only load an image
when {@link android.widget.Adapter#getView getView()} is called on the
view's {@link android.widget.Adapter}.
</li>
<li>Call {@link android.graphics.Bitmap#recycle()} on {@link android.graphics.Bitmap} views that
are no longer needed.
</li>
<li>Use {@link java.lang.ref.WeakReference} for storing references to {@link
android.graphics.Bitmap} objects in an in-memory {@link java.util.Collection}.
</li>
<li>If you fetch images from the network, use {@link android.os.AsyncTask} to fetch and store
them on the device for faster access. Never do network transactions on the application's main
user interface thread.
</li>
<li>Scale down large images to a more appropriate size as you download them; otherwise,
downloading the image itself may cause an out of memory exception.
</li>
</ul>
<p>
For more information on getting the best performance when working with images, see
<a href="{@docRoot}training/displaying-bitmaps/index.html">Displaying Bitmaps Efficiently</a>.
</p>

View File

@@ -0,0 +1,180 @@
page.title=Creating TV Navigation
page.tags="focus","selection","d-pad"
trainingnavtop=true
@jd:body
<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you how to</h2>
<ol>
<li><a href="#d-pad-navigation">Enable D-pad Navigation</a></li>
<li><a href="#focus-selection">Provide Clear Focus and Selection</a></li>
</ol>
</div>
</div>
<p>
TV devices provide a limited set of navigation controls for apps. Creating an effective
navigation scheme for your TV app depends on understanding these limited controls and the limits
of users' perception while operating your app. As you build your Android app for TVs,
pay special attention to how the user actually navigates around your app when using remote
control buttons instead of a touch screen.
</p>
<p>
This lesson explains the minimum requirements for creating effective TV app navigation scheme and
how to apply those requirements to your app.
</p>
<h2 id="d-pad-navigation">Enable D-pad Navigation</h2>
<p>
On a TV device, users navigate with controls on a remote control device, using either a
directional pad (D-pad) or arrow keys. This type of control limits movement to up, down, left,
and right. To build a great TV-optimized app, you must provide a navigation scheme where the user
can quickly learn how to navigate your app using these limited controls.
</p>
<p>
The Android framework handles directional navigation between layout elements automatically, so
you typically do not need to do anything extra for your app. However, you should thoroughly test
navigation with a D-pad controller to discover any navigation problems. Follow these guidelines to
test that your app's navigation system works well with a D-pad on a TV device:
</p>
<ul>
<li>Ensure that a user with a D-pad controller can navigate to all visible controls on the
screen.
</li>
<li>For scrolling lists with focus, make sure that the D-pad up and down keys scroll the list,
and the Enter key selects an item in the list. Verify that users can select an element in the
list and that the list still scrolls when an element is selected.
</li>
<li>Ensure that switching between controls between controls is straightforward and predictable.
</li>
</ul>
<h3 id="modify-d-pad-nav">Modifying directional navigation</h3>
<p>
The Android framework automatically applies a directional navigation scheme based on the
relative position of focusable elements in your layouts. You should test the generated
navigation scheme in your app using a D-pad controller. After testing, if you decide you want
users to move through your layouts in a specific way, you can set up explicit directional
navigation for your controls.
</p>
<p class="note">
<strong>Note:</strong> You should only use these attributes to modify the navigation order if the
default order that the system applies does not work well.
</p>
<p>
The following code sample shows how to define the next control to receive focus for a {@link
android.widget.TextView} layout object:
</p>
<pre>
&lt;TextView android:id="&#64;+id/Category1"
android:nextFocusDown="&#64;+id/Category2"\&gt;
</pre>
<p>
The following table lists all of the available navigation attributes for Android user interface
widgets:
</p>
<table>
<tr>
<th>Attribute</th>
<th>Function</th>
</tr>
<tr>
<td>{@link android.R.attr#nextFocusDown}</td>
<td>Defines the next view to receive focus when the user navigates down.</td>
</tr>
<tr>
<td>{@link android.R.attr#nextFocusLeft}</td>
<td>Defines the next view to receive focus when the user navigates left.</td>
</tr>
<tr>
<td>{@link android.R.attr#nextFocusRight}</td>
<td>Defines the next view to receive focus when the user navigates right.</td>
</tr>
<tr>
<td>{@link android.R.attr#nextFocusUp}</td>
<td>Defines the next view to receive focus when the user navigates up.</td>
</tr>
</table>
<p>
To use one of these explicit navigation attributes, set the value to the ID ({@code android:id}
value) of another widget in the layout. You should set up the navigation order as a loop, so that
the last control directs focus back to the first one.
</p>
<h2 id="focus-selection">Provide Clear Focus and Selection</h2>
<p>
The success of an app's navigation scheme on TV devices is depends on how easy it is for
a user to determine what user interface element is in focus on screen. If you do not provide
clear indications of focused items (and therefore what item a user can take action on), they can
quickly become frustrated and exit your app. For the same reason, it is important to always have
an item in focus that a user can take action on immediately after your app starts, or any time
it is idle.
</p>
<p>
Your app layout and implementation should use color, size, animation, or a combination of these
attributes to help users easily determine what actions they can take next. Use a uniform scheme
for indicating focus across your application.
</p>
<p>
Android provides <a href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">
Drawable State List Resources</a> to implement highlights for focused and selected controls. The
following code example demonstrates how to enable visual behavior for a button to indicate that a
user has navigated to the control and then selected it:
</p>
<pre>
&lt;!-- res/drawable/button.xml --&gt;
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;selector xmlns:android="http://schemas.android.com/apk/res/android"&gt;
&lt;item android:state_pressed="true"
android:drawable="@drawable/button_pressed" /&gt; &lt;!-- pressed --&gt;
&lt;item android:state_focused="true"
android:drawable="@drawable/button_focused" /&gt; &lt;!-- focused --&gt;
&lt;item android:state_hovered="true"
android:drawable="@drawable/button_focused" /&gt; &lt;!-- hovered --&gt;
&lt;item android:drawable="@drawable/button_normal" /&gt; &lt;!-- default --&gt;
&lt;/selector&gt;
</pre>
<p>
The following layout XML sample code applies the previous state list drawable to a
{@link android.widget.Button}:
</p>
<pre>
&lt;Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:background="@drawable/button" /&gt;
</pre>
<p>
Make sure to provide sufficient padding within the focusable and selectable controls so that the
highlights around them are clearly visible.
</p>
<p>
For more recommendations on designing effective selection and focus for your TV app, see
<a href="{@docRoot}design/tv/patterns.html">Patterns for TV</a>.
</p>

View File

@@ -0,0 +1,259 @@
page.title=Get Started with TV Apps
page.tags="leanback","recyclerview","launcher"
trainingnavtop=true
startpage=true
@jd:body
<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you how to</h2>
<ol>
<li><a href="#dev-project">Setup a TV Project</a></li>
<li><a href="#build-it">Build TV Apps</a></li>
<li><a href="#run">Run TV Apps</a></li>
</ol>
<h2>You should also read</h2>
<ol>
<li><a href="{@docRoot}design/tv/index.html">
TV Design</a></li>
<li><a href="{@docRoot}training/tv/start/layouts.html">
Building TV Layouts</a></li>
</ol>
</div>
</div>
<p>
TV apps use the same structure as those for phones and tablets. This similarity means you can
modify your existing apps to also run on TV devices or create new apps based on what you already
know about building apps for Android.
</p>
<p class="note">
<strong>Important:</strong> There are specific requirements your app must meet in order to
qualify as an Android TV app on Google Play. For more information, see the requirements listed
in <a href="{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a>.
</p>
<p>
This lesson describes how to prepare your development environment for building TV apps, and the
minimum required changes to enable an app to run on TV devices.
</p>
<h2 id="dev-project">Set up a TV Project</h2>
<p>
This section discusses how to modify an existing app to run on TV devices, or create a new one.
These are the main components you must use to create an app that runs on TV devices:
</p>
<ul>
<li><strong>Activity for TV</strong> (Required) - In your application manifest,
declare an activity that is intended to run on TV devices.</li>
<li><strong>TV Support Libraries</strong> (Optional) - There are several
<a href="#tv-libraries">Support Libraries</a>
available for TV devices that provide widgets for building user interfaces.</li>
</ul>
<h3 id="prerequisites">Prerequisites</h3>
<p>Before you begin building apps for TV, you must:</p>
<ul>
<li><strong><a href="{@docRoot}sdk/installing/adding-packages.html#GetTools">
Update your SDK tools to version 24.0.0 or higher</a></strong>
<br>
The updated SDK tools enable you to build and test apps for TV.
</li>
<li><strong><a href="{@docRoot}sdk/installing/adding-packages.html#GetTools">
Update your SDK with Android 5.0 (API 21) or higher</a></strong>
<br>
The updated platform version provides new APIs for TV apps.
</li>
<li><strong><a href="{@docRoot}sdk/installing/create-project.html">
Create or update your app project</a></strong>
<br>
In order to access new APIs for TV devices, you must create a project or modify an existing
project that targets Android 5.0 (API level 21) or higher.
</li>
</ul>
<h3 id="tv-activity">Declare a TV Activity</h3>
<p>An application intended to run on TV devices must declare a launcher activity for TV
in its manifest using a {@link android.content.Intent#CATEGORY_LEANBACK_LAUNCHER} intent filter.
This filter identifies your app as being enabled for TV, allowing it to be considered a TV app
in Google Play. Declaring this intent also identifies which activity
in your app to launch when a user selects its icon on the TV home screen.</p>
<p class="caution">
<strong>Caution:</strong> If you do not include the {@link android.content.Intent#CATEGORY_LEANBACK_LAUNCHER} intent filter in
your app, it is not visible to users running the Google Play store on TV devices. Also, if your
app does not have this filter when you load it onto a TV device using developer tools, the app
does not appear in the TV user interface.
</p>
<p>The following code snippet shows how to include this intent filter in your manifest:</p>
<pre>
&lt;application&gt;
...
&lt;activity
android:name=&quot;com.example.android.MainActivity&quot;
android:label=&quot;@string/app_name&quot; &gt;
&lt;intent-filter&gt;
&lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
&lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;
&lt;/intent-filter&gt;
&lt;/activity&gt;
&lt;activity
android:name=&quot;com.example.android.<strong>TvActivity</strong>&quot;
android:label=&quot;&#64;string/app_name&quot;
android:theme=&quot;&#64;style/Theme.Leanback&quot;&gt;
&lt;intent-filter&gt;
&lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
&lt;category android:name="<strong>android.intent.category.LEANBACK_LAUNCHER</strong>" /&gt;
&lt;/intent-filter&gt;
&lt;/activity&gt;
&lt;/application&gt;
</pre>
<p>
The second activity manifest entry in this example specifies that activity as the one to
launch on a TV device.
</p>
<p>
If you are modifying an existing app for use on TV, your app should not use the same
activity layout for TV that it does for phones and tablets. The user interface of your TV app (or
TV portion of your existing app) should provide a simpler interface that can be easily navigated
using a remote control from a couch. For guidelines on designing an app for TV, see the <a href=
"{@docRoot}design/tv/index.html">TV Design</a> guide. For more information on the minimum
implementation requirements for interface layouts on TV, see <a href=
"{@docRoot}training/tv/start/layouts.html">Building TV Layouts</a>.
</p>
<h3 id="tv-libraries">Add TV support libraries</h3>
<p>
The Android SDK includes support libraries that are intended for use with TV apps. These
libraries provide APIs and user interface widgets for use on TV devices. The libraries are
located in the {@code &lt;sdk&gt;/extras/android/support/} directory. Here is a list of the
libraries and their general purpose:
</p>
<ul>
<li><a href="{@docRoot}tools/support-library/features.html#v17-leanback">
<strong>v17 leanback library</strong></a> - Provides user interface widgets for TV apps,
particularly for apps that do media playback.
</li>
<li><a href="{@docRoot}tools/support-library/features.html#v7-recyclerview">
<strong>v7 recyclerview library</strong></a> - Provides classes for managing display of long
lists in a memory efficient manner. Several classes in the v17 leanback library depend on the
classes in this library.
</li>
<li><a href="{@docRoot}tools/support-library/features.html#v7-cardview">
<strong>v7 cardview library</strong></a> - Provides user interface widgets for displaying
information cards, such as media item pictures and descriptions.
</li>
</ul>
<p class="note">
<strong>Note:</strong> You are not required to use these support libraries for your TV app.
However, we strongly recommend using them, particularly for apps that provide a media catalog
browsing interface.
</p>
<p>
If you decide to use the v17 leanback library for your app, you should note that it is dependent
on the <a href="{@docRoot}tools/support-library/features.html#v4">v4 support library</a>. This
means that apps that use the leanback support library should include all of these support
libraries:
</p>
<ul>
<li>v4 support library</li>
<li>v7 recyclerview support library</li>
<li>v17 leanback support library</li>
</ul>
<p>
The v17 leanback library contains resources, which require you to take specific steps to include
it in app projects. For instructions on importing a support library with resources, see
<a href="{@docRoot}tools/support-library/setup.html#libs-with-res">Support Library Setup</a>.
</p>
<h2 id="build-it">Build TV Apps</h2>
<p>After you have completed the steps described above, it's time to start building apps for
the big screen! Check out these additional topics to help you build your app for TV:
<ul>
<li>
<a href="{@docRoot}training/tv/playback/index.html">Building TV Playback Apps</a> - TVs are
built to entertain, so Android provides a set of user interface tools and widgets for building
TV apps that play videos and music, and let users browse for the content they want.
</li>
<li>
<a href="{@docRoot}training/tv/search/index.html">Surfacing Content on TV</a> - With all the
content choices at users' fingertips, helping them find content they enjoy is almost as important
as providing that content. This training discusses how to surface your content on TV devices.
</li>
<li>
<a href="{@docRoot}training/tv/games/index.html">Games for TV</a> - TV devices are a great
platform for games. See this topic for information on building great game experiences for TV.
</li>
</ul>
<h2 id="run">Run TV Apps</h2>
<p>
Running your app is an important part of the development process. The AVD Manager in the Android
SDK provides the device definitions that allow you to create virtual TV devices for running and
testing your applications.
</p>
<p>To create an virtual TV device:</p>
<ol>
<li>Start the AVD Manager. For more information, see the
<a href="{@docRoot}tools/help/avd-manager.html">AVD Manager</a> help.</li>
<li>In the AVD Manager dialog, click the <strong>Device Definitions</strong> tab.</li>
<li>Select one of the Android TV device definitions and click <strong>Create AVD</strong>.</li>
<li>Select the emulator options and click <strong>OK</strong> to create the AVD.
<p class="note">
<strong>Note:</strong> For best performance of the TV emulator device, enable the <strong>Use
Host GPU</strong> option and, where supported, use virtual device acceleration. For
more information on hardware acceleration of the emulator, see
<a href="{@docRoot}tools/devices/emulator.html#acceleration">Using the Emulator</a>.
</p>
</li>
</ol>
<p>To test your application on the virtual TV device:</p>
<ol>
<li>Compile your TV application in your development environment.</li>
<li>Run the application from your development environment and choose the TV virtual device as
the target.</li>
</ol>
<p>
For more information about using emulators see, <a href="{@docRoot}tools/devices/emulator.html">
Using the Emulator</a>. For more information on deploying apps from Android Studio to virtual
devices, see <a href="{@docRoot}sdk/installing/studio-debug.html">Debugging with Android
Studio</a>. For more information about deploying apps to emulators from Eclipse with ADT, see
<a href="{@docRoot}tools/building/building-eclipse.html">Building and Running from Eclipse with
ADT</a>.
</p>

View File

@@ -1,157 +0,0 @@
page.title=Handling Features Not Supported on TV
parent.title=Designing for TV
parent.link=index.html
trainingnavtop=true
previous.title=Optimizing Navigation for TV
previous.link=optimizing-navigation-tv.html
@jd:body
<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you to</h2>
<ol>
<li><a href="#WorkaroundUnsupportedFeatures">Work Around Features Not Supported on TV</a></li>
<li><a href="#CheckAvailableFeatures">Check for Available Features at Runtime</a></li>
</ol>
</div>
</div>
<p>
TVs are much different from other Android-powered devices:
</p>
<ul>
<li>They're not mobile.</li>
<li>Out of habit, people use them for watching media with little or no interaction.</li>
<li>People interact with them from a distance.</li>
</ul>
<p>
Because TVs have a different purpose from other devices, they usually don't have hardware features
that other Android-powered devices often have. For this reason, the Android system does not
support the following features for a TV device:
<table>
<tr>
<th>Hardware</th>
<th>Android feature descriptor</th>
</tr>
<tr>
<td>Camera</td>
<td>android.hardware.camera</td>
</tr>
<tr>
<td>GPS</td>
<td>android.hardware.location.gps</td>
</tr>
<tr>
<td>Microphone</td>
<td>android.hardware.microphone</td>
</tr>
<tr>
<td>Near Field Communications (NFC)</td>
<td>android.hardware.nfc</td>
</tr>
<tr>
<td>Telephony</td>
<td>android.hardware.telephony</td>
</tr>
<tr>
<td>Touchscreen</td>
<td>android.hardware.touchscreen</td>
</tr>
</table>
</p>
<p>
This lesson shows you how to work around features that are not available on TV by:
<ul>
<li>Providing work arounds for some non-supported features.</li>
<li>Checking for available features at runtime and conditionally activating/deactivating certain code
paths based on availability of those features.</li>
</ul>
</p>
<h2 id="WorkaroundUnsupportedFeatures">Work Around Features Not Supported on TV</h2>
<p>
Android doesn't support touchscreen interaction for TV devices, most TVs don't have touch screens,
and interacting with a TV using a touchscreen is not consistent with the 10 foot environment. For
these reasons, users interact with Android-powered TVs using a remote. In consideration of this,
ensure that every control in your app can be accessed with the D-pad. Refer back to the previous two lessons
<a href="{@docRoot}training/tv/optimizing-layouts-tv.html">Optimizing Layouts for TV</a> and
<a href="{@docRoot}training/tv/optimizing-navigation-tv.html">Optimize Navigation for TV</a> for
more details
on this topic. The Android system assumes that a device has a touchscreen, so if you want your application
to run on a TV, you must <strong>explicitly</strong> disable the touchscreen requirement in your manifest file:
<pre>
&lt;uses-feature android:name="android.hardware.touchscreen" android:required="false"/&gt;
</pre>
</p>
<p>
Although a TV doesn't have a camera, you can still provide a photography-related application on a TV.
For example, if you have an app that takes, views and edits photos, you can disable its picture-taking
functionality for TVs and still allow users to view and even edit photos. The next section talks about how to
deactivate or activate specific functions in the application based on runtime device type detection.
</p>
<p>
Because TVs are stationary, indoor devices, they don't have built-in GPS. If your application uses location
information, allow users to search for a location or use a "static" location provider to get
a location from the zip code configured during the TV setup.
<pre>
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
Location location = locationManager.getLastKnownLocation("static");
Geocoder geocoder = new Geocoder(this);
Address address = null;
try {
address = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1).get(0);
Log.d("Zip code", address.getPostalCode());
} catch (IOException e) {
Log.e(TAG, "Geocoder error", e);
}
</pre>
</p>
<p>
TVs usually don't support microphones, but if you have an application that uses voice control,
you can create a mobile device app that takes voice input and then acts as a remote control for a TV.
</p>
<h2 id="CheckAvailableFeatures">Check for Available Features at Runtime</h2>
<p>
To check if a feature is available at runtime, call
{@link android.content.pm.PackageManager#hasSystemFeature(String)}.
This method takes a single argument : a string corresponding to the
feature you want to check. For example, to check for touchscreen, use
{@link android.content.pm.PackageManager#hasSystemFeature(String)} with the argument
{@link android.content.pm.PackageManager#FEATURE_TOUCHSCREEN}.
</p>
<p>
The following code snippet demonstrates how to detect device type at runtime based on supported features:
<pre>
// Check if android.hardware.telephony feature is available.
if (getPackageManager().hasSystemFeature("android.hardware.telephony")) {
Log.d("Mobile Test", "Running on phone");
// Check if android.hardware.touchscreen feature is available.
} else if (getPackageManager().hasSystemFeature("android.hardware.touchscreen")) {
Log.d("Tablet Test", "Running on devices that don't support telphony but have a touchscreen.");
} else {
Log.d("TV Test", "Running on a TV!");
}
</pre>
</p>
<p>
This is just one example of using runtime checks to deactivate app functionality that depends on features
that aren't available on TVs.
</p>