delete tv

Change-Id: I22058850b4186951e69ada51959ef9f86054b1b1
This commit is contained in:
Robert Ly
2014-06-16 16:10:42 -07:00
parent 208eb3e84a
commit d458e3f4d8
17 changed files with 0 additions and 2111 deletions

View File

@@ -1,319 +0,0 @@
page.title=ADT-1 Developer Kit
page.tags="emote","e-mote","adt"
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li><a href="#faq">ADT-1 Frequently Asked Questions</a></li>
<li><a href="#regulatory">Regulatory Disclosures</a></li>
<li><a href="#safety">Important Safety Instructions</a></li>
</ol>
</div>
</div>
<p class="note">
<strong>!FIX: FOR REVIEW ONLY:</strong> link to <a href="request.html">ADT-1 Request</a> page.
</p>
<p>The ADT-1 Developer Kit is streaming media player and game controller designed for running
and testing app built for Android TV. The kit is provided to a limited number of developers
who are interested in building new apps or extending their existing apps to run on the Android TV
platform.</p>
<p class="note">
<strong>Note:</strong> The ADT-1 kit <em>is not required</em> for building and testing apps
for Android TV. You can build apps for TV and test them using an emulator for TV devices. The
L-Preview SDK includes all the software needed to build TV apps and an emulator for running and
testing them. For more information, see the
<a href="{@docRoot}preview/tv/start/index.html">Get Started</a> guide for TV apps.
</p>
<h2 id="faq">ADT-1 Frequently Asked Questions</h2>
<p>
<strong>How do I put the gamepad that came with my ADT-1 into pairing mode?</strong>
</p>
<p>Press and hold the Back and Home buttons together for about three seconds, until all four
blue LEDs flash together. When the LEDs are flashing, the gamepad is in pairing mode.</p>
<p>
<strong>How do I use the gamepad with the on-screen keyboard?</strong>
</p>
<p>Use the D-pad or left joystick to move the cursor, and press A to select. Press X to delete a
character, and press Y to insert a space. Also, you can press the right joystick to toggle caps
lock, and press the left joystick to show additional symbols.</p>
<p>
<strong>How do I perform a hard reset of ADT-1?</strong>
</p>
<p>Unplug the power cable from the back of ADT-1. Press and hold the small, round button on the
back of ADT-1 as you re-insert the power cable, and continue to hold the small round button. The
LED will begin flashing red for a few seconds, then change to multi-color cycle. When the LED
starts the multi-color cycle, release the small, round button, and ADT-1 will boot. Note: this is
a factory data reset, thus all downloaded apps, system and app data, and account settings will be
lost.</p>
<p>
<strong>How do I do a soft reset?</strong>
</p>
<p>Go to Settings - Device - Factory data reset, and select Reset device. Note: this is a
factory data reset, thus all downloaded apps, system and app data, and account settings will be
lost.</p>
<p>
<strong>How do I turn my device on?</strong>
</p>
<p>Plug in the included power cable into the back of ADT-1. There is no on/off switch.</p>
<p>
<strong>How do I completely turn my device off? </strong>
</p>
<p>Unplug in the included power cable from the back of ADT-1. There is no on/off switch.
However, ADT-1 will begin sleeping (daydream) based on user settings in Display -&gt; Daydream.</p>
<p>
<strong>How do I connect to the network?</strong>
</p>
<p>ADT-1 has both Wi-Fi and Ethernet for connecting to your network. To change your Wi-Fi
network, go to Settings -&gt; Wi-Fi. To use an Ethernet network connection, simply plug in an
Ethernet cable (that is connected to your network) into the port on the back of ADT-1.</p>
<p>
<strong>How do I use the developer cable?</strong>
</p>
<p>The developer cable has three connectors: a small, male power connector that plugs into the
power port on the back of ADT-1, a standard male USB-A connector that connects your PC, and a
small, female power connector that the included power supply plugs into.</p>
<p>
<strong>Is there an app for phone and tablet that I can use to control ADT-1?</strong>
</p>
<p>Yes, you can download the remote control app from Android phones and tablets here.</p>
<p>
<strong>Can I connect a USB keyboard/mouse to ADT-1?</strong>
</p>
<p>Yes, you can connect a USB keyboard/mouse to the USB port on the back of ADT-1. Note: not all
manufacturers/models are guaranteed to work.</p>
<hr />
<p>
Press the small, round button on the back of ADT-1 to make it search for Bluetooth devices in
pairing mode. If multiple accessories are found, press the small, round button to select the
device you want to pair. Pairing will happen automatically after a few seconds. To pair Bluetooth
devices to ADT-1 from the UI, go to <strong>Settings &gt; Remote &amp; Accessories &gt;
Add accessory</strong>.
</p>
<h2 id="regulatory">Regulatory Disclosures</h2>
<p>Model: W2</p>
<p>FCC ID: A4R-W2</p>
<p>IC: 10395A-W2</p>
<p>U.S. Federal Communications Commission Notices</p>
<p>To satisfy FCC and IC exposure requirements, a separation distance of at least 20 cm should
be maintained between the antenna of this device and persons during device operation. Operations
at closer than this distance are not recommended.</p>
<p>The antenna used for this transmitter must not be co-located in conjunction with any other
antenna or transmitter.</p>
<p>This equipment has been tested and found to comply with the limits for a Class B digital
device, pursuant to part 15 of the FCC Rules. These limits are designed to provide reasonable
protection against harmful interference in a residential installation. This equipment generates,
uses and can radiate radio frequency energy and, if not installed and used in accordance with the
instructions, may cause harmful interference to radio communications. However, there is no
guarantee that interference will not occur in a particular installation. If this equipment does
cause harmful interference to radio or television reception, which can be determined by turning
the equipment off and on, the user is encouraged to try to correct the interference by one or more
of the following measures:</p>
<p>—Reorient or relocate the receiving antenna.</p>
<p>—Increase the separation between the equipment and receiver.</p>
<p>—Connect the equipment into an outlet on a circuit different from that to which the receiver
is connected.</p>
<p>—Consult the dealer or an experienced radio/ TV technician for help.</p>
<p>This device complies with part 15 of the FCC Rules. Operation is subject to the following two
conditions: (1) This device may not cause harmful interference, and (2) this device must accept
any interference received, including interference that may cause undesired operation.</p>
<p>Changes or modifications not expressly approved by Google Inc. could void the user's
authority to operate the equipment.</p>
<p>Industry Canada Notices</p>
<p>This device complies with Industry Canada licence-exempt RSS standard(s). Operation is
subject to the following two conditions: (1) this device may not cause interference, and (2) this
device must accept any interference, including interference that may cause undesired operation of
the device.</p>
<p>Under Industry Canada regulations, this radio transmitter may only operate using an antenna
of a type and maximum (or lesser) gain approved for the transmitter by Industry Canada. To reduce
potential radio interference to other users, the antenna type and its gain should be so chosen
that the equivalent isotropically radiated power (e.i.r.p.) is not more than that necessary for
successful communication.</p>
<p>The radiated output power of the Wireless Device is below the Industry Canada (IC) radio
frequency exposure limits. The Wireless Device should be used in such a manner such that the
potential for human contact during normal operation is minimized.</p>
<hr />
<p>CAN ICES-3 (B)/NMB-3(B)</p>
<p>
<u>Avis d<em>Industrie Canada</em></u>
</p>
<p>
Le présent appareil est conforme aux <em>CNR</em> d'Industrie Canada applicables aux appareils
radio exempts de licence. L'exploitation est autorisée aux deux conditions suivantes : (1)
l'appareil ne doit pas produire de brouillage, et (2) l'appareil doit accepter tout brouillage
radioélectrique subi, même si le brouillage est susceptible d'en compromettre le fonctionnement.
</p>
<p>
En vertu de la règlementation d<em>Industrie Canada</em>, cet émetteur radio peut
fonctionner avec une antenne d'un type et d'un gain maximal (ou inférieur) approuvé pour
l'émetteur par <em>Industrie Canada</em>. Dans le but de réduire les risques de brouillage
radioélectrique à l'intention des autres utilisateurs, il faut choisir le type d'antenne et son
gain de sorte que la puissance isotrope rayonnée équivalente (p.i.r.e.) ne dépasse pas l'intensité
nécessaire à l'établissement d'une communication satisfaisante.
</p>
<p>
La puissance rayonnée en sortie de l'appareil sans fil est inférieure aux limites fixées par
<em>Industrie Canada</em> en matière d'exposition aux radiofréquences. L'appareil sans fil
doit être utilisé de sorte que la possibilité d'un contact humain pendant le fonctionnement
normal soit limitée.
</p>
<h2 id="safety">Important Safety Instructions</h2>
<p>
<strong>WARNING:</strong> Read all safety information below before using this device to avoid
injury.
</p>
<ul>
<li><p>Do not install near heat sources, such as heaters and other devices.</p></li>
<li><p>Use in a well-ventilated area and plug power adapter into an easily accessible
outlet. Only use this device with the provided power adapter.</p></li>
<li><p>The device has no on/off switch. To disconnect from power, you must unplug the
power adapter.</p></li>
<li><p>Only use indoors and do not expose to rain, liquid, moisture, excessive heat, or
naked flame.</p></li>
<li><p>Clean only with a dry cloth.</p></li>
</ul>
<p>
<strong>WARNING:</strong> Playing video games has been linked to injuries in some
users. Read all safety and health information below before using the gamepad to avoid possible
injury.
</p>
<p><u>Photosensitive Seizures</u></p>
<p>
A very small percentage of people may experience a seizure when exposed to certain visual images,
including flashing lights or patterns that may appear in some video games, even people who have no
history of seizures or epilepsy. These seizures have a variety of symptoms, including
lightheadedness, altered vision, disorientation, loss of awareness, involuntary movements, loss of
consciousness, or convulsions. If you experience any of these symptoms, <u>stop gaming
immediately and consult your doctor</u>.
</p>
<p><u>Ergonomics</u></p>
<p>Long periods of repetitive motion using incorrect body positioning may be associated with
physical discomfort and injuries to nerves, tendons, and muscles. If during or after gaming you
feel pain, numbness, weakness, swelling, burning, cramping, or stiffness,<u>stop gaming
and consult your doctor</u>.
<p>
<strong>Healthy Gaming</strong>
</p>
<p>To reduce risk of seizures or injury, take the following precautions:</p>
<ul>
<li><p>Sit as far away from the TV screen as possible.</p></li>
<li><p>Play in a well-lit room.</p></li>
<li><p>Do not play when you are drowsy or fatigued.</p></li>
<li><p>Take 10-15 minute breaks every hour if playing video games and avoid prolonged
gaming.</p></li>
</ul>
<p>
<strong>Do Not Attempt Repairs Yourself</strong>
</p>
<p>There are no user-serviceable parts inside. Do not attempt to open or disassemble.</p>
<p>Failure to follow these safety instructions could result in fire, electric shock, damage to
the device or other property, or personal injury.</p>
<hr />
<p>
<strong>Importantes instructions concernant la sécurité</strong>
</p>
<p>
<strong>ATTENTION:</strong> Veuillez lire toutes les informations de sécurité énoncées ci-bas
avant dutiliser lappareil pour éviter des blessures.
</p>
<ul>
<li><p>Ne pas installer à proximité dune source de chaleur telle une chaufferette ou un
autre appareil similaire.</p></li>
<li><p>Utiliser dans un endroit bien aéré et brancher ladaptateur électrique dans une
prise de courant facilement accessible.</p></li>
<li><p>Lappareil ne possède aucun interrupteur marché/arrêt. Pour mettre lappareil hors
tension, il faut débrancher lappareil de la prise de courant.</p></li>
<li><p>Utiliser lappareil uniquement à lintérieur et ne pas lexposer à la pluie, à des
substances liquides, à lhumidité, à la chaleur excessive ou à une flamme.</p></li>
<li><p>Nettoyer uniquement avec un linge sec.</p></li>
</ul>
<p>
<strong>ATTENTION:</strong> Le fait de jouer à des jeux vidéo a été relié à des blessures chez certains
utilisateurs. Afin déviter de possibles blessures, veuillez lire toutes les informations
concernant la sécurité et la santé énoncées ci-bas avant dutiliser la tablette de jeu.
</p>
<p><u>Épilepsie photosensible</u></p>
<p>Lexposition à certaines images visuelles, incluant les lumières ou motifs clignotants qui
peuvent apparaître dans certains jeux vidéo, peut provoquer chez un très faible pourcentage de
personnes une crise dépilepsie, et ce, même si ces personnes nont aucun historique de crises ou
dépilepsie. Ces crises comportent divers symptômes tels que des étourdissements, une vision
altérée, un sentiment de désorientation, la perte de conscience, des mouvements involontaires, la
perte de connaissance ou de conscience ou des convulsions. Si vous ressentez quelconque de ces
symptômes, <u>cessez de jouer immédiatement et consultez votre médecin</u>.</p>
<p><u>Ergonomie</u></p>
<p>Les longues périodes de mouvements répétitifs effectués dans une position corporelle
inadéquate peuvent mener à un inconfort physique et à des blessures aux nerfs, tendons et muscles.
Si durant ou après avoir joué à des jeux vidéo, vous ressentez de la douleur, de
lengourdissement, une faiblesse, de linflammation, une sensation de brûlure, des crampes ou de
la rigidité, <u>cessez de jouer immédiatement et consultez votre médecin</u>.</p>
<p>
<strong>Le jeu sécuritaire</strong>
</p>
<p>Afin de réduire les risques de crises dépilepsie ou de blessures, veuillez prendre les
précautions suivantes :</p>
<ul>
<li>Asseyez-vous aussi loin de lécran de télévision que possible.</li>
<li>Jouez dans une pièce munie dun éclairage adéquat.</li>
<li>Ne jouez pas lorsque vous êtes étourdi ou fatigué.</li>
<li>Prenez 10 à 15 minutes de pause après chaque heure de jeu et évitez les périodes de jeu
prolongées.</li>
</ul>
<p>
<strong>Ne pas tenter deffectuer des réparations par vous-même</strong>
</p>
<p>LAppareil ne contient aucune pièce pouvant être réparée par lutilisateur. Ne pas tenter
douvrir ou de désassembler lAppareil.</p>
<p>Le défaut de suivre ces instructions de sécurité pourrait provoquer un feu, un choc
électrique, un dommage à lAppareil ou à dautres objets ou des lésions corporelles.</p>

View File

@@ -1,47 +0,0 @@
page.title=Request ADT-1 Developer Kit
@jd:body
<p>The ADT-1 Developer Kit is streaming media player and game controller designed for running
and testing app built for Android TV. The kit is offered to developers who are interested in
building new apps or extending their existing apps to run on the Android TV platform before
the commercial release of Android TV devices. Supplies of the ADT-1 kit are limited and
requesting one not guarantee it will be delivered to you.</p>
<p class="note">
<strong>Note:</strong> The ADT-1 kit <em>is not required</em> for building and testing apps
for Android TV. You can build apps for TV and test them using an emulator for TV devices. The
L-Preview SDK includes all the software needed to build TV apps and an emulator for running and
testing them. For more information, see the
<a href="{@docRoot}preview/tv/start/index.html">Get Started</a> guide for TV apps.
For more information about the ADT-1 kit, see the
<a href="{@docRoot}preview/tv/adt-1/index.html">ADT-1 Developer Kit</a> information page.
</p>
<div class="sdk-terms" style="width:678px" onfocus="this.blur()">
<div class="sdk-terms-padding">
Android ADT-1 Developer Kit Request Agreement.
1. These are the terms.
2. You must agree to the terms.
3. Otherwise you have not agreed to the terms.
4. And then we don't want to talk to you.
</div>
</div>
<p class="caution">
<strong>Important:</strong> The email address your provide in this form is used to verify
you as an Android developer. Please provide a Google account email address that is associated
with the Google Play app you enter. We may also use your email address to provide you with
updates about the ADT-1 Developer Kit and Android TV.
</p>
<iframe src="https://docs.google.com/a/google.com/forms/d/1MLhC39rf3aAJw-KhZw9cyjT1dWuz_k3_iC5QXpC4Cbw/viewform?embedded=true"
width="100%" height="540" frameborder="0" marginheight="0" marginwidth="0"
id="signupform">Loading...</iframe>

View File

@@ -1,70 +0,0 @@
page.title=Games on TV
page.tags="controller"
@jd:body
<p>This section complements the [larger best-practices guidance for designing for Android TV](TODO, use formal name of referenced doc, and add link). It assumes that you have read that guidance, and seeks to minimize repetition.</p>
<h2>Overview</h2>
<p>Because of factors including its large size, its control scheme, and its nature as a shared display, the television screen presents a number of considerations that may be new to mobile developers. This document breaks these considerations down into five sections:</p>
<ul>
<li>Display</li>
<li>Control</li>
<li>Manifest</li>
<li>Google Play Game Services</li>
<li>Web</li>
</ul>
<h2>Display</h2>
<p>Large and centrally situated, the television screen imposes limitations, but also opens up new opportunities for immersive gameplay.</p>
<h3>A shared display</h3>
<p>A living-room TV poses design challenges for multiplayer games, in that all players can see everything. This issue is especially germane to games (such as card games or strategy games) that rely on each players possession of hidden information.</p>
<p>Some mechanisms you can implement to address the problem of one players “eavesdropping” on anothers information are:</p>
<ul>
<li>A player might place a "blinder" on the screen to help conceal information. For example, in a turn-based game like a word or card game, one player at a time might view the display. When the player finishes a move, the game allows him or her to cover the screen with a “blinder” that blocks anyone from viewing secret information. When the next player begins a turn, the blinder opens to reveal his or her own information.</li>
<li>A second screen, such as a handset or larger device, can enable a player to conceal information. For information on implementing second-screen support, see <a href="http://developer.android.com/reference/android/app/Presentation.html">Presentation</a> on the Android developer site.</li>
</ul>
<h3>No touch interface</h3>
<p>A television does not have a touch interface. Your game design, therefore, need not take into account the possibility that a players controlling fingers might block the on-screen action. You can assume constant visibility of the entire viewing area.</p>
<p>See the <a href=#control>Control</a> section in this document and in [Design for TV](TODO, use formal name of referenced doc, and add link) for more implications of the lack of touch interface.</p>
<h3>Landscape display</h3>
<p>In mobile-device terms, a TV is always “sideways.” You cant turn it, and there is no portrait orientation. You should always be designing your TV games to be displayed in landscape mode.</p>
<a id=control><h2>Control</h2>
<p>Without a touch interface, it's even more important than usual to get your controls right, so that players find them intuitive and fun to use. The separation of controller from device also introduces some other issues to pay attention to, like keeping track of multiple players' controllers, and handling disconnects gracefully.</p>
<h3>D-pad</h3>
<p>Because of the lack of touch interface, you should be planning your control scheme based on a D-pad. Some key points to keep in mind include:</p>
<p>The player needs to use the gamepad in all aspects of the game&ndash;not just controlling core gameplay, but also navigating menus and ads. For this reason, you should also ensure that your Android TV game does not refer to a touch interface: for example, an Android TV game cannot tell a player to "Tap to skip".</p>
<p>You can avoid unhappy surprises (and resulting low ratings) by using your Play Store description to communicate to the player any expectations about controllers. If a game is better suited to a gamepad with a joystick than one with only a D-pad, you should make this clear. A player who uses an ill-suited controller for a game is likely to have a subpar experience&ndash;and penalize your game in the ratings.</p>
<p>You can also help ensure a good player experience by ensuring that button mapping is intuitive and flexible. For example, you can adhere to accepted custom by using the A button to <code>Accept</code>, and the B button to <code>Cancel</code>. You can also offer flexibility in the form of remappability. For more information on button mapping, see <a href="http://developer.android.com/training/game-controllers/controller-input.html">Handling Controller Actions</a>.</p>
<p>Your game can also contribute to a good match between controller and game by querying the controller about its capabilities. For example, you may intend for a player to steer an object by waving the controller in the air. If a player's controller lacks accelerometer and gyroscope hardware, however, waving will not work. But when your game queries the controller and discovers that motion detection is not supported, it can switch over to an alternative, available control scheme.</p>
<p>For more information on querying controller capabilities, see <a href="http://developer.android.com/training/game-controllers/compatibility.html">Supporting Controllers Across Android Versions</a>.</p>
<h3>Back-button behavior</h3>
<p>The Back button should never act as a toggle. For example, do not use it to both open and close a menu. Its behavior should only be linear. For example: Game play &gt; Game pause screen &gt; Game main screen &gt; Android home screen.</p>
<p>With this principle of "linear navigation" in mind, you <b>may</b> use the back button to leave an in-game menu (opened by a different button) and return to gameplay.</p>
<h3>Handling multiple controllers</h3>
<p>When multiple players are playing a game, each with his or her own controller, it is important to map each player-controller pair. For information on how to implement controller-number identification, see <a href="http://developer.android.com/reference/android/view/InputDevice.html#getControllerNumber(">Input Devices</a>) on the Android developer site.</p>
<h3>Handling disconnects</h3>
<p>When a controller is disconnected in the middle of gameplay, the game should pause, and a dialog should appear prompting the disconnected player to reconnect his or her controller.</p>
<p>The dialog should also offer troubleshooting tips (e.g., "Check your Bluetooth connection").</p>
<h2>Manifest</h2>
<p>Games are displayed in a separate row from regular apps in the launcher. Android TV uses the <code>android:isGame</code> flag to differentiate games from non-game apps. You can assign it a value of either <code>true</code> or <code>false</code>. For example:</p>
<pre class="fragment">&lt;application&gt;
. . .
&lt;meta-data android:name="isGame" android:value=["true" | "false"]/&gt;
android:isGame=["true" | "false"] &gt;
. . .
&lt;/application&gt;
</pre><h2>Google Play Game Services</h2>
<p>If your game integrates Google Play Game Services, you should keep in mind a number of considerations pertaining to achievements, sign-on, saving games, and multiplayer play.</p>
<h3>Achievements</h3>
<p>Your game should include at least five (earnable) achievements. Only a user controlling gameplay from a supported input device should be able to earn achievements.</p>
<h3>Sign-on</h3>
<p>Your game should attempt to sign the user in on launch. If the player declines sign-in several times in a row, your game should stop asking.</p>
<h3>Saving</h3>
<p>We highly recommend using Play Services cloud save to store your game save. Your game should bind game saves to a specific Google account, so as to be uniquely identifiable even across devices: Whether the player is using a handset or a TV, the game should be able to pull the same game-save information from his or her account.</p>
<p>You should also provide an option in your game's UI to prompt the player to destroy save data. You might put the option in the game's <code>Settings</code> screen.</p>
<h3>Multiplayer experience</h3>
<p>A game offering a multiplayer experience must allow at least two players to enter a room.</p>
<h2>Web</h2>
<p>Android TV games do not support a full web browser. You should therefore avoid using generic URLs in your game.</p>
<p>Webviews will work for logins to services like Google+ and Facebook. </p>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 285 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

View File

@@ -1,22 +0,0 @@
page.title=Android TV Apps
@jd:body
<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>This guide helps you build apps for TV devices, including:</p>
<ul>
<li>How to set up your development environment</li>
<li>How to build user interfaces for TV</li>
<li>Guidelines for building games for TV</li>
</ul>
<p>Prepare your app for its big screen debut!</p>
<p>
<strong><a href="{@docRoot}preview/tv/start/index.html">Get Started &gt;</a></strong>
</p>

View File

@@ -1,174 +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.</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>
<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 workaround 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 workaround 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 make 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,193 +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>
</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>
<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">
Setup 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">Setup 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 app that runs on TV devices.</p>
<p>There are the main steps to creating an app that runs on TV devices, only the first of these
is required:</p>
<ul>
<li><strong>Activity for TV</strong> - (Required) Your application must have an activity that is
is declared to run on TV devices through an app manifest entry.</li>
<li><strong>TV Support Libraries</strong> - (Optional) There are several Support Libraries
available for TV devices that provide user interface widgets for building user interfaces
for use on TV.</li>
</ul>
<h3 id="tv-activity">Create a TV Activity</h3>
<p>Applications that are intended to run on TV devices must declare a launcher activity for TV
in their manifest using a the {@code android.intent.category.LEANBACK_LAUNCHER} intent filter.
This filter identifies your app as being built for TV, enabling your app to be displayed in the
Google Play app running on TV devices. Declaring this intent also identifies which activity in
your app should be launched when a user selects your app icon on a TV.</p>
<p class="caution">
<strong>Caution:</strong> If you do not include the LEANBACK_LAUNCHER intent filter in your app,
it will not be visible to users running the Google Play store on TV devices. If your load an app
without this intent filter 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;android:style/Theme.NoTitleBar&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 it should be used as
the main activity when your app launched 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 you do 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 that is 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 application, you should note that it is
dependent on the <a href="{@docRoot}tools/support-library/features.html#v7-appcompat">v7
appcompat library</a>, which is, in turn, 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>v7 appcompat support library</li>
<li>v4 support library</li>
</ul>
<p>Two of these libraries (v17 leanback and v7 appcompat) contain resources, which require
you to take specific steps to include them 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 the widgets provided to make it easier to build them.
</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>

View File

@@ -1,217 +0,0 @@
page.title=BrowseFragment
parent.title=User Interfaces for TV
parent.link=index.html
trainingnavtop=true
next.title=DetailsFragment
next.link=details.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li><a href="#layout">Media Browse Layout</a></li>
<li><a href="#lists">Displaying Media Lists</a></li>
<li><a href="#background">Updating the Background</a></li>
</ol>
</div>
</div>
<p>The <a href="{@docRoot}preview/tv/start/index.html#tv-libraries">Leanback support library</a>
provides several APIs for displaying and browsing media catalogs
on the TV devices. This guide discusses how to use the classes provided by this library to
implement a user interface for browsing music or videos from your app's media catalog.</p>
<h2 id="layout">Media Browse Layout</h2>
<p>The BrowseFragment class in the Leanback support library allows you to create a primary
layout for browsing categories and rows of media items with a minimum of code. The following
example layout shows how to create a layout that contains a BrowseFragment:</p>
<pre>
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;match_parent&quot;
android:orientation=&quot;vertical&quot;
&gt;
&lt;fragment
<strong>android:name="android.support.v17.leanback.app.BrowseFragment"</strong>
android:id=&quot;@+id/browse_fragment&quot;
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;match_parent&quot;
/&gt;
&lt;/LinearLayout&gt;
</pre>
<p>In order to work with this layout in an activity, retrieve the BrowseFragment element from
the layout. Use the BrowseFragment.Params class to set display parameters such as the icon, title
and whether category headers are enabled. The following code sample demonstrates how to set the
layout parameters for a BrowseFragment in a layout:</p>
<pre>
public class BrowseMediaActivity extends Activity {
public static final String TAG ="BrowseActivity";
protected BrowseFragment mBrowseFragment;
&#64;Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.browse_fragment);
final FragmentManager fragmentManager = getFragmentManager();
<strong>mBrowseFragment = (BrowseFragment) fragmentManager.findFragmentById(
R.id.browse_fragment);</strong>
// Set display parameters for the BrowseFragment
BrowseFragment.Params params = mBrowseFragment.getBrowseParams();
if (params == null) {
params = new BrowseFragment.Params();
}
params.setHeadersState(BrowseFragment.HEADERS_ENABLED);
params.setTitle(getString(R.string.app_name));
params.setBadgeImage(getResources().getDrawable(R.drawable.ic_launcher));
mBrowseFragment.setBrowseParams(params);
}
}
</pre>
<h2 id="lists">Displaying Media Lists</h2>
<p>The BrowseFragment allows you to define and display browseable media content categories and
media items from a media catalog using adapters and presenters. Adapters enable you to connect to
local or online data sources that contain your media catalog information. Presenter classes hold
data about media items and provide layout information for displaying an item on screen.</p>
<p>The following example code shows an implementation of a presenter for displaying string
data:</p>
<pre>
public class StringPresenter extends Presenter {
private static final String TAG = "StringPresenter";
public ViewHolder onCreateViewHolder(ViewGroup parent) {
TextView textView = new TextView(parent.getContext());
textView.setFocusable(true);
textView.setFocusableInTouchMode(true);
textView.setBackground(
parent.getContext().getResources().getDrawable(R.drawable.text_bg));
return new ViewHolder(textView);
}
public void onBindViewHolder(ViewHolder viewHolder, Object item) {
((TextView) viewHolder.view).setText(item.toString());
}
public void onUnbindViewHolder(ViewHolder viewHolder) {
Log.d(TAG, "onUnbindViewHolder");
}
}
</pre>
<p>Once you have constructed a presenter class for your media items, you can build and attach an
adapter to the BrowseFragment to display those items on screen for browsing by the user. The
following example code demonstrates how to construct an adapter to display categories and items
in those categories using the StringPresenter class shown in the previous code example:</p>
<pre>
private ArrayObjectAdapter mRowsAdapter;
private static final int NUM_ROWS = 4;
&#64;Override
protected void onCreate(Bundle savedInstanceState) {
...
buildRowsAdapter();
}
private void buildRowsAdapter() {
mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
for (int i = 0; i &lt; NUM_ROWS; ++i) {
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(
new StringPresenter());
listRowAdapter.add("Media Item 1");
listRowAdapter.add("Media Item 2");
listRowAdapter.add("Media Item 3");
HeaderItem header = new HeaderItem(i, "Category " + i, null);
mRowsAdapter.add(new ListRow(header, listRowAdapter));
}
mBrowseFragment.setAdapter(mRowsAdapter);
}
</pre>
<p>This example shows a static implementation of the adapters. A typical media browsing
application uses data from an online database or web service. For an example of a browsing
application that uses data retrieved from the web, see the <a href="">!FIX</a> code sample.</p>
<p>The following screenshot shows the output of this code on an Android TV device:</p>
<img src="{@docRoot}preview/tv/images/browsefragment.png" alt="" height="XXX" id="figure1" />
<p class="img-caption">
<strong>Figure 1.</strong> Display layout example based on the
{@link android.support.v17.leanback.app.BrowseFragment} and {@code StringPresenter}
classes.
</p>
<h2 id="background">Updating the Background</h2>
<p>In order to add visual interest to a media browsing app on TV, you can update the background
image as users browse through content. This technique can make interaction with your app feel more
cinematic and enjoyable for users.</p>
<p>The Leanback support library provides a {@link
android.support.v17.leanback.app.BackgroundManager} class for changing the background of your TV
app activity. The following example shows how to create a simple method for updating the
background:</p>
<pre>
protected void updateBackground(Drawable drawable) {
BackgroundManager.getInstance(this).setDrawable(drawable);
}
</pre>
<p>Many of the existing media browse apps automatically update the background as the user
navigates through media listings. In order to do this, you can set up a selection listener to
automatically update the background based on the user's current selection. The following example
shows you how to set up an {@link android.support.v17.leanback.widget.OnItemSelectedListener}
class to catch selection events and update the background:</p>
<pre>
protected void clearBackground() {
BackgroundManager.getInstance(this).setDrawable(mDefaultBackground);
}
protected OnItemSelectedListener getDefaultItemSelectedListener() {
return new OnItemSelectedListener() {
&#64;Override
public void onItemSelected(Object item, Row row) {
if (item instanceof Movie ) {
URI uri = ((Movie)item).getBackdropURI();
updateBackground(uri);
} else {
clearBackground();
}
}
};
}
</pre>
<p class="note">
<strong>Note:</strong> The implementation above is a simple example shown for purposes of
illustration. When creating this function in your own app, you should consider running the
background update action in a separate thread for better performance. In addition, if you are
planning on updating the background in response to user's scrolling through items, consider adding
a time to delay a background image update until the user settles on item, to avoid excessive
background image updates.
</p>

View File

@@ -1,230 +0,0 @@
page.title=DetailFragment
parent.title=User Interfaces for TV
parent.link=index.html
trainingnavtop=true
previous.title=BrowseFragment
previous.link=browse.html
next.title=Searching in TV Apps
next.link=in-app-search.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li><a href="#details-presenter">Build a Details Presenter</a></li>
<li><a href="#details-fragment">Extend the Details Fragment</a>
<li><a href="#activity">Creating a Details Activity</a></li>
<li><a href="#item-listener">Listener for Clicked Items</a></li>
</li>
</ol>
</div>
</div>
<p>The media browsing interface classes provided by the
<a href="{@docRoot}preview/tv/start/index.html#tv-libraries">Leanback support library</a>
include classes for displaying additional information about a media item, such as a description
or reviews, and taking action on that item, such as purchasing it or playing its content. This
section discusses how to create a presenter class for media item details and extend the
{@code DetailsFragment} class to implement a details view for a media item when it
is selected by a user.
</p>
<p class="note">
<strong>Note:</strong> The implementation example shown here uses an additional activity to
contain the {@code DetailsFragment}. However, it is possible to avoid creating a second activity
by replacing the current {@code BrowseFragment} with a {@code DetailsFragment} within the <em>same</em>
activity using fragment transactions. For more information on using fragment transactions, see the
<a href="{@docRoot}training/basics/fragments/fragment-ui.html#Replace">Building a Dynamic
UI with Fragments</a> training.
</p>
<h2 id="details-presenter">Build a Details Presenter</h2>
<p>In the media browsing framework provided for by the leanback support library, you use
presenter objects to control the display of data on screen, including media item details. The
framework provides the {@code AbstractDetailsDescriptionPresenter} class for this purpose, which
is a nearly complete implementation of the presenter for media item details. All you have to do is
implement the {@code onBindDescription()} method to bind the view fields to your data objects, as shown in
the following code sample:</p>
<pre>
public class DetailsDescriptionPresenter
extends AbstractDetailsDescriptionPresenter {
&#64;Override
protected void onBindDescription(ViewHolder viewHolder, Object itemData) {
MyMediaItemDetails details = (MyMediaItemDetails) itemData;
// In a production app, the itemData object contains the information
// needed to display details for the media item:
// viewHolder.getTitle().setText(details.getShortTitle());
// Here we provide static data for testing purposes:
viewHolder.getTitle().setText(itemData.toString());
viewHolder.getSubtitle().setText("2014 Drama TV-14");
viewHolder.getBody().setText("Lorem ipsum dolor sit amet, consectetur "
+ "adipisicing elit, sed do eiusmod tempor incididunt ut labore "
+ " et dolore magna aliqua. Ut enim ad minim veniam, quis "
+ "nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
+ "commodo consequat.");
}
}
</pre>
<h2 id="details-fragment">Extend the Details Fragment</h2>
<p>When you use the {@code DetailsFragment} class for displaying your media item details, you
extend that class to provide additional content such as a preview image and actions for the media
item. You can also provide additional content, such as a list of related media items.</p>
<p>The following example code demonstrates how to use the presenter class you created in the
previous section, add a preview image and actions for the media item being viewed. This example
also shows the addition of a related media items row, which appears below the details listing.</p>
<pre>
public class MediaItemDetailsFragment extends DetailsFragment {
private static final String TAG = "MediaItemDetailsFragment";
private ArrayObjectAdapter mRowsAdapter;
&#64;Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState);
buildDetails();
}
private void buildDetails() {
ClassPresenterSelector selector = new ClassPresenterSelector();
// Attach your media item details presenter to the row presenter:
DetailsOverviewRowPresenter rowPresenter =
new DetailsOverviewRowPresenter(new DetailsDescriptionPresenter());
selector.addClassPresenter(DetailsOverviewRow.class, rowPresenter);
selector.addClassPresenter(ListRow.class,
new ListRowPresenter());
mRowsAdapter = new ArrayObjectAdapter(selector);
Resources res = getActivity().getResources();
DetailsOverviewRow detailsOverview = new DetailsOverviewRow(
"Media Item Details");
// Add images and action buttons to the details view
detailsOverview.setImageDrawable(res.getDrawable(R.drawable.jelly_beans));
detailsOverview.addAction(new Action(1, "Buy $9.99"));
detailsOverview.addAction(new Action(2, "Rent $2.99"));
mRowsAdapter.add(detailsOverview);
// Add a Related items row
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(
new StringPresenter());
listRowAdapter.add("Media Item 1");
listRowAdapter.add("Media Item 2");
listRowAdapter.add("Media Item 3");
HeaderItem header = new HeaderItem(0, "Related Items", null);
mRowsAdapter.add(new ListRow(header, listRowAdapter));
setAdapter(mRowsAdapter);
}
}
</pre>
<p>The following screenshot shows the output of this code on a TV device:</p>
<img src="{@docRoot}preview/tv/images/detailsfragment.png" alt="" height="XXX" id="figure1" />
<p class="img-caption">
<strong>Figure 1.</strong> Display layout example based on {@code DetailsFragment}, using a
{@code DetailsOverviewRow} and a {@code ListRow} for related items.
</p>
<h3 id="activity">Creating a Details Activity</h3>
<p>Fragments such as the {@code DetailsFragment} must be contained within an activity in order
to be used for display. Creating an activity for your details view, separate from the browse
activity, enables you to invoke your details view using an Intent. This section explains how to
build an activity to contain your implementation of the detail view for your media items.</p>
<p>Start creating the details activity by building a layout that references your implementation
of the {@code DetailsFragment}:</p>
<pre>
&lt;!-- file: res/layout/details.xml --&gt;
&lt;fragment xmlns:android="http://schemas.android.com/apk/res/android"
<strong>android:name="com.example.android.mediabrowser.MediaItemDetailsFragment"</strong>
android:id="&#64;+id/details_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
/&gt;
</pre>
<p>Next, create an activity class that uses the layout shown in the previous code example:</p>
<pre>
public class DetailsActivity extends Activity
{
&#64;Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
<strong>setContentView(R.layout.details);</strong>
}
}
</pre>
<p>Finally, add this new activity to the manifest. Remember to apply the Leanback theme to
ensure that the user interface is consistent with the media browse activity:</p>
<pre>
&lt;application&gt;
...
&lt;activity android:name=".DetailsActivity"
android:exported="true"
<strong>android:theme="@style/Theme.Leanback"/&gt;</strong>
&lt;/application&gt;
</pre>
<h3 id="item-listener">Listener for Clicked Items</h3>
<p>After you have implemented the {@code DetailsFragment}, you must modify your main media
browsing view to move to your details view when a user clicks on a media item. In order to enable
this behavior, add an {@code OnItemClickedListener} object to the BrowseFragment that fires an
intent to start the item details activity.</p>
<p>The following example shows how to implement a listener to start the details view when a user
clicks a media item in the main media browsing activity:</p>
<pre>
public class BrowseMediaActivity extends Activity {
...
&#64;Override
protected void onCreate(Bundle savedInstanceState) {
...
// create the media item rows
buildRowsAdapter();
// add a listener for selected items
mBrowseFragment.setOnItemClickedListener(
new OnItemClickedListener() {
&#64;Override
public void onItemClicked(Object item, Row row) {
System.out.println("Media Item clicked: " + item.toString());
Intent intent = new Intent(BrowseMediaActivity.this,
DetailsActivity.class);
// pass the item information
intent.getExtras().putLong("id", item.getId());
startActivity(intent);
}
});
}
}
</pre>

View File

@@ -1,119 +0,0 @@
page.title=Searching in TV Apps
parent.title=User Interfaces for TV
parent.link=index.html
trainingnavtop=true
previous.title=DetailsFragment
previous.link=details.html
next.title=Recommendations
next.link=recommendations.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li><a href="#add-search-ui">Add Search User Interface</a></li>
</ol>
</div>
</div>
<p>Users frequently have specific content in mind when using a media app. A search interface can
help your users get to the content they want faster than browsing. The Leanback library provides a
set of classes to enable a standard search interface within your app that is consistent with other
search functions on TV and provides features such as voice input.</p>
<h2 id="add-search-ui">Add Search User Interface</h2>
<p>When you use the BrowseFragment class for your media browsing interface, you can enable the
search icon by setting an OnClickListener to the browse fragment object. The following sample code
demonstrates this technique.</p>
<pre>
&#64;Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.browse_activity);
mBrowseFragment = (BrowseFragment)
getFragmentManager().findFragmentById(R.id.browse_fragment);
...
mBrowseFragment.setOnSearchClickedListener(new View.OnClickListener() {
&#64;Override
public void onClick(View view) {
Intent intent = new Intent(BrowseActivity.this, SearchActivity.class);
startActivity(intent);
}
});
mBrowseFragment.setAdapter(buildAdapter());
}
</pre>
<p class="note">
<strong>Note:</strong> You can set the color of the search icon using the
{@code setSearchAffordanceColor()} method of {@code BrowseFragment}.
</p>
<p>When a user selects the search icon, the system invokes a search activity via the defined
Intent. Your search activity should use a linear layout containing a SearchFragment. This fragment
must also implement the SearchFragment.SearchResultProvider interface in order to display the
results of a search. The following code sample shows how to extend the SearchFragment class to
provide a search interface and results:</p>
<pre>
public class MySearchFragment extends SearchFragment
implements SearchFragment.SearchResultProvider {
private static final int SEARCH_DELAY_MS = 300;
private ArrayObjectAdapter mRowsAdapter;
private Handler mHandler = new Handler();
private SearchRunnable mDelayedLoad;
&#64;Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
setSearchResultProvider(this);
setOnItemClickedListener(getDefaultItemClickedListener());
mDelayedLoad = new SearchRunnable();
}
&#64;Override
public ObjectAdapter getResultsAdapter() {
return mRowsAdapter;
}
&#64;Override
public boolean onQueryTextChange(String newQuery) {
mRowsAdapter.clear();
if (!TextUtils.isEmpty(newQuery)) {
mDelayedLoad.setSearchQuery(newQuery);
mHandler.removeCallbacks(mDelayedLoad);
mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
}
return true;
}
&#64;Override
public boolean onQueryTextSubmit(String query) {
mRowsAdapter.clear();
if (!TextUtils.isEmpty(query)) {
mDelayedLoad.setSearchQuery(query);
mHandler.removeCallbacks(mDelayedLoad);
mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
}
return true;
}
}
</pre>
<p>This example code shown above is meant to be used with a separate SearchRunnable class, that
runs the search query on a separate thread. This technique keeps potentially slow-running queries
from interfering with the main user interface thread.</p>

View File

@@ -1,44 +0,0 @@
page.title=User Interfaces for TV
page.tags="input","screens"
trainingnavtop=true
startpage=true
@jd:body
<p>
Building an effective and engaging for TV devices requires a firm understanding what works well
in the context of a living room. Imagine a large screen that can be seen by many people at the
same time, controlled a few buttons by users with limited attention and you start to see the
challenges and opportunity of building an app for TV. Building apps for this environment
requires a different approach and different tools.</p>
<p>This section discusses how to build a living room experience with your app, including
implementation instructions and user interface widgets built for TV. Also check out the
<a href="{@docRoot}design/tv/index.html">Design for TV</a> for information and inspiration
on creating engaging user interfaces for TV devices.</p>
<h2>Topics</h2>
<dl>
<dt><b><a href="layouts.html">Layouts</a></b></dt>
<dd>Learn how to build app layouts for TV screens.</dd>
<dt><b><a href="navigation.html">Navigation</a></b></dt>
<dd>Learn how to build navigation for TV devices.</dd>
<dt><b><a href="browse.html">BrowseFragment</a></b></dt>
<dd>Learn how to use this fragment to build a browsing interface for media catalogs.</dd>
<dt><b><a href="details.html">DetailsFragment</a></b></dt>
<dd>Learn how to use this fragment to build a details page for media items.</dd>
<dt><b><a href="search.html">In-App Search</a></b></dt>
<dd>Learn how to use a built-for-TV user interface for searching within your app.</dd>
<dt><b><a href="recommendations.html">Recommendations</a></b></dt>
<dd>Learn how to contribute watch next suggestions and get your content noticed by users.</dd>
</dl>

View File

@@ -1,298 +0,0 @@
page.title=Layouts for TV
parent.title=User Interfaces for TV
parent.link=index.html
trainingnavtop=true
next.title=Navigation for TV
next.link=navigation.html
@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>
</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 guidance and implementation details for building effective layouts for
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 apps. On TV devices, you should use a theme to suppress the title bar from
your app activities that are meant for TV. The title bar is a standard user interface element
for Android apps on phones and tablets, but it is not appropriate for TV apps. The following
code example from TV app manifest demonstrates how to apply this theme:
</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>
<h3 id="leanback-theme">Leanback Theme</h3>
<p>The Android framework provides a standard theme for TV activities, called {@code
Leanback.Theme}, which establishes a consistent visual style for TV apps. Use of this theme is
recommended for most apps. 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;android:style/Theme.Leanback"</strong>&gt;
</pre>
<h2 id="structure">Layout Structure</h2>
<p>Layouts for TV devices should follow some basic guidelines to ensure they are useable 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 are always displayed in this
orientation.</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 a 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
antion 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-resolutions 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 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 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,144 +0,0 @@
page.title=Navigation for TV
parent.title=User Interfaces for TV
parent.link=index.html
trainingnavtop=true
previous.title=Layouts for TV
previous.link=layouts.html
next.title=BrowseFragment
next.link=browse.html
@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 application for TVs,
you should pay special attention to how the user actually navigates around your application
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 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 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 demonstates how to apply selection indication for 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

@@ -1,234 +0,0 @@
page.title=Making Recommendations
parent.title=User Interfaces for TV
parent.link=index.html
trainingnavtop=true
previous.title=Searching in TV Apps
previous.link=in-app-search.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li><a href="#service">Create a Recommendations Service</a></li>
<li><a href="#build">Build Recommendations</a></li>
<li><a href="#run-service">Run Recommendations Service</a></li>
<li><a href="#DesignLandscapeLayouts">Design Landscape Layouts</a></li>
</ol>
</div>
</div>
<p>Content recommendations appear as the first row of the TV launch screen after the first use
of the device. This row is intended to help users quickly find content they enjoy. Contributing
recommendations from your apps content catalog can help bring users back to your app.</p>
<img src="{@docRoot}preview/tv/images/home-recommendations.png" alt="" height="XXX" id="figure1" />
<p class="img-caption">
<strong>Figure 1.</strong> The first row after the search widget is the system-wide
recommendations.
</p>
<h2 id="service">Create a Recommendations Service</h2>
<p>Content recommendations are created with background processing. In order for your application
to contribute to recommendations, you create a service that periodically adds listings from your
app's catalog to the system list of recommendations.</p>
<p>The following code example illustrates how to extend the {@link android.app.IntentService} to
create a recommendation service for your application.</p>
<pre>
public class RecommendationsService extends IntentService {
...
public Notification buildRecommendation(Context context, Movie movie)
throws IOException {
if (mNotificationManager == null) {
mNotificationManager = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
}
Bundle extras = new Bundle();
if (mBackgroundUri != movie.getBackgroundUri()) {
extras.putString(EXTRA_BACKGROUND_IMAGE_URL, movie.getBackgroundUri());
}
// build the recommendation as a Notification object
Notification notification = new NotificationCompat.BigPictureStyle(
new NotificationCompat.Builder(context)
.setContentTitle(movie.getTitle())
.setContentText(movie.getDescription())
.setPriority(movie.getPriority())
.setOngoing(true)
.setCategory("recommendation")
.setLargeIcon(movie.getImage())
.setSmallIcon(movie.getSmallIcon())
.setContentIntent(buildPendingIntent(movie.getId()))
.setExtras(extras))
.build();
// post the recommendation to the NotificationManager
mNotificationManager.notify(movie.getId(), notification);
mNotificationManager = null;
return notification;
}
private PendingIntent buildPendingIntent(long id) {
Intent detailsIntent = new Intent(this, DetailsActivity.class);
detailsIntent.putExtra("id", id);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(DetailsActivity.class);
stackBuilder.addNextIntent(detailsIntent);
// Ensure each PendingIntent is unique
detailsIntent.setAction(Long.toString(id));
PendingIntent intent = stackBuilder.getPendingIntent(
0, PendingIntent.FLAG_UPDATE_CURRENT);
return intent;
}
}
</pre>
<p>In order for this class to be recognized and run as a service, you must register this service
using your app manifest. The following code snippet illustrates how to add this class as a
service:</p>
<pre>
&lt;manifest ... &gt;
&lt;application ... &gt;
...
&lt;service android:name=&quot;.UpdateRecommendationsService&quot;
android:enabled=&quot;true&quot; android:exported=&quot;true&quot;/&gt;
&lt;/application&gt;
&lt;/manifest&gt;
</pre>
<h2 id="build">Build Recommendations</h2>
<p>Once it starts running, your service must create recommendations and pass them to the Android
framework. The framework receives the recommendations as {@link android.app.Notification} objects
that use a specific style and are marked with a specific category.</p>
<p>The following code example demonstrates how to get an instance of the {@link
android.app.NotificationManager}, build a recommendation and post it to the manager:</p>
<pre>
public class RecommendationsService extends IntentService {
...
public Notification buildRecommendation(Context context, Movie movie)
throws IOException {
if (mNotificationManager == null) {
mNotificationManager = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
}
Bundle extras = new Bundle();
if (mBackgroundUri != movie.getBackgroundUri()) {
extras.putString(EXTRA_BACKGROUND_IMAGE_URL, movie.getBackgroundUri());
}
// build the recommendation as a Notification object
Notification notification = new NotificationCompat.BigPictureStyle(
new NotificationCompat.Builder(context)
.setContentTitle(movie.getTitle())
.setContentText(movie.getDescription())
.setPriority(movie.getPriority())
.setOngoing(true)
.setCategory("recommendation")
.setLargeIcon(movie.getImage())
.setSmallIcon(movie.getSmallIcon())
.setContentIntent(buildPendingIntent(movie.getId()))
.setExtras(extras))
.build();
// post the recommendation to the NotificationManager
mNotificationManager.notify(movie.getId(), notification);
mNotificationManager = null;
return notification;
}
private PendingIntent buildPendingIntent(long id) {
Intent detailsIntent = new Intent(this, DetailsActivity.class);
detailsIntent.putExtra("id", id);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(DetailsActivity.class);
stackBuilder.addNextIntent(detailsIntent);
// Ensure each PendingIntent is unique
detailsIntent.setAction(Long.toString(id));
PendingIntent intent = stackBuilder.getPendingIntent(
0, PendingIntent.FLAG_UPDATE_CURRENT);
return intent;
}
}
</pre>
<h3 id="run-service">Run Recommendations Service</h3>
<p>Your app's recommendation service must run periodically in order to create current
recommendations. In order to run your service, you should create a class that runs a timer and
invokes it at regular intervals. The following code example extends the {@link
android.content.BroadcastReceiver} class to start periodic execution of a recommendation service
every 30 minutes:</p>
<pre>
public class BootupActivity extends BroadcastReceiver {
private static final String TAG = "BootupActivity";
private static final long INITIAL_DELAY = 5000;
&#64;Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().endsWith(Intent.ACTION_BOOT_COMPLETED)) {
scheduleRecommendationUpdate(context);
}
}
private void scheduleRecommendationUpdate(Context context) {
AlarmManager alarmManager = (AlarmManager)context.getSystemService(
Context.ALARM_SERVICE);
Intent recommendationIntent = new Intent(context,
UpdateRecommendationsService.class);
PendingIntent alarmIntent = PendingIntent.getService(context, 0,
recommendationIntent, 0);
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
INITIAL_DELAY,
AlarmManager.INTERVAL_HALF_HOUR,
alarmIntent);
}
}
</pre>
<p>In order for the {@link android.content.BroadcastReceiver} class to execute after an TV
device starts up, you must register this class in your app manifest and attach an intent filter
for the completion of the device boot process. This sample code demonstrates how to add this
configuration to the manifest:</p>
<pre>
&lt;manifest ... &gt;
&lt;application ... &gt;
&lt;receiver android:name=&quot;.BootupActivity&quot; android:enabled=&quot;true&quot;
android:exported=&quot;false&quot;&gt;
&lt;intent-filter&gt;
&lt;action android:name=&quot;android.intent.action.BOOT_COMPLETED&quot;/&gt;
&lt;/intent-filter&gt;
&lt;/receiver&gt;
&lt;/application&gt;
&lt;/manifest&gt;
</pre>