Home | History | Annotate | Download | only in start
      1 page.title=Handling TV Hardware
      2 page.tags="unsupported"
      3 trainingnavtop=true
      4 
      5 @jd:body
      6 
      7 <div id="tb-wrapper">
      8 <div id="tb">
      9   <h2>This lesson teaches you how to</h2>
     10   <ol>
     11     <li><a href="#runtime-check">Check for a TV Device</a>
     12     <li><a href="#handle-features">Handle Unsupported Hardware Features</a></li>
     13     <li><a href="#controllers">Manage Hardware Controllers</a>
     14     </li>
     15   </ol>
     16 </div>
     17 </div>
     18 
     19 <p>
     20   TV hardware is substantially different from other Android devices. TVs do not
     21   include some of the hardware features found on other Android devices, such as touch screens,
     22   cameras, and GPS receivers. TVs are also completely dependent on secondary hardware devices.
     23   In order for users to interact with TV apps, they must use a remote control or game pad. When
     24   you build an app for TV, you must carefully consider the hardware limitations and requirements of
     25   operating on TV hardware.
     26 </p>
     27 
     28 <p>
     29   This lesson discusses how to check if your app is running on a TV, how to handle unsupported
     30   hardware features, and discusses the requirements for handling controllers for TV devices.
     31 </p>
     32 
     33 
     34 <h2 id="runtime-check">Check for a TV Device</h2>
     35 
     36 <p>
     37   If you are building an app that operates both on TV devices and other devices, you may need to
     38   check what kind of device your app is running on and adjust the operation of your app. For
     39   instance, if you have an app that can be started through an {@link android.content.Intent}, your
     40   application should check the device properties to determine if it should start a TV-oriented
     41   activity or a phone activity.
     42 </p>
     43 
     44 <p>
     45   The recommended way to determine if your app is running on a TV device is to use the {@link
     46   android.app.UiModeManager#getCurrentModeType UiModeManager.getCurrentModeType()} method to check
     47   if the device is running in television mode. The following example code shows you how to check if
     48   your app is running on a TV device:
     49 </p>
     50 
     51 <pre>
     52 public static final String TAG = "DeviceTypeRuntimeCheck";
     53 
     54 UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE);
     55 if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) {
     56     Log.d(TAG, "Running on a TV Device")
     57 } else {
     58     Log.d(TAG, "Running on a non-TV Device")
     59 }
     60 </pre>
     61 
     62 
     63 <h2 id="handle-features">Handle Unsupported Hardware Features</h2>
     64 
     65 <p>
     66   Depending on the design and functionality of your app, you may be able to work around certain
     67   hardware features being unavailable. This section discusses what hardware features are typically
     68   not available for TV, how to detect missing hardware features, and suggests alternatives to
     69   using these features.
     70 </p>
     71 
     72 
     73 <h3 id="unsupported-features">Unsupported TV hardware features</h3>
     74 
     75 <p>
     76   TVs have a different purpose from other devices, and so they do not have hardware features that
     77   other Android-powered devices often have. For this reason, the Android system does not support
     78   the following features for a TV device:
     79 </p>
     80 
     81 <table>
     82   <tr>
     83     <th>Hardware</th>
     84     <th>Android feature descriptor</th>
     85   </tr>
     86   <tr>
     87     <td>Touchscreen</td>
     88     <td>{@code android.hardware.touchscreen}</td>
     89   </tr>
     90   <tr>
     91     <td>Touchscreen emulator</td>
     92     <td>{@code android.hardware.faketouch}</td>
     93   </tr>
     94   <tr>
     95     <td>Telephony</td>
     96     <td>{@code android.hardware.telephony}</td>
     97   </tr>
     98   <tr>
     99     <td>Camera</td>
    100     <td>{@code android.hardware.camera}</td>
    101   </tr>
    102   <tr>
    103     <td>Bluetooth</td>
    104     <td>{@code android.hardware.bluetooth}</td>
    105   </tr>
    106   <tr>
    107     <td>Near Field Communications (NFC)</td>
    108     <td>{@code android.hardware.nfc}</td>
    109   </tr>
    110   <tr>
    111     <td>GPS</td>
    112     <td>{@code android.hardware.location.gps}</td>
    113   </tr>
    114   <tr>
    115     <td>Microphone <sup><a href="#cont-mic">[1]</a></sup></td>
    116     <td>{@code android.hardware.microphone}</td>
    117   </tr>
    118   <tr>
    119     <td>Sensors</td>
    120     <td>{@code android.hardware.sensor}</td>
    121   </tr>
    122 </table>
    123 
    124 <p id="cont-mic" class="note">
    125   <strong>[1]</strong> Some TV controllers have a microphone, which is
    126   not the same as the microphone hardware feature described here. The controller microphone is fully
    127   supported.
    128 </p>
    129 
    130 <p>
    131   See the <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html#features-reference">
    132   Features Reference</a> for a complete list of features, subfeatures, and their descriptors.
    133 </p>
    134 
    135 
    136 <h3 id="declare-hardware-requirements">Declaring hardware requirements for TV</h3>
    137 
    138 <p>
    139   Android apps can declare hardware feature requirements in the app manifest to ensure that they do
    140   not get installed on devices that do not provide those features. If you are extending an existing
    141   app for use on TV, closely review your app's manifest for any hardware requirement
    142   declarations that might prevent it from being installed on a TV device.
    143 </p>
    144 
    145 <p>
    146   If your app uses hardware features (such as a touchscreen or camera) that are not available on
    147   TV, but can operate without the use of those features, modify your app's manifest to
    148   indicate that these features are not required by your app. The following manifest code snippet
    149   demonstrates how to declare that your app does not require hardware features which are unavailable
    150   on TV devices, even though your app may use these features on non-TV devices:
    151 </p>
    152 
    153 <pre>
    154 &lt;uses-feature android:name="android.hardware.touchscreen"
    155         android:required="false"/&gt;
    156 &lt;uses-feature android:name="android.hardware.faketouch"
    157         android:required="false"/&gt;
    158 &lt;uses-feature android:name="android.hardware.telephony"
    159         android:required="false"/&gt;
    160 &lt;uses-feature android:name="android.hardware.camera"
    161         android:required="false"/&gt;
    162 &lt;uses-feature android:name="android.hardware.bluetooth"
    163         android:required="false"/&gt;
    164 &lt;uses-feature android:name="android.hardware.nfc"
    165         android:required="false"/&gt;
    166 &lt;uses-feature android:name="android.hardware.gps"
    167         android:required="false"/&gt;
    168 &lt;uses-feature android:name="android.hardware.microphone"
    169         android:required="false"/&gt;
    170 &lt;uses-feature android:name="android.hardware.sensor"
    171         android:required="false"/&gt;
    172 </pre>
    173 
    174 <p class="note"><strong>Note:</strong> Some features have subfeatures like {@code android.hardware.camera.front},
    175   as described in the <a href="guide/topics/manifest/uses-feature-element.html#features-reference">
    176   Feature Reference</a>. Be sure to mark as {@code required="false"} any subfeatures also used in
    177   your app.</p>
    178 
    179 <p>
    180   All apps intended for use on TV devices must declare that the touch screen feature is not required
    181   as described in <a href="{@docRoot}training/tv/start/start.html#no-touchscreen">Get Started with
    182   TV Apps</a>. If your app normally uses one or more of the features listed above, change the
    183   {@code android:required} attribute setting to {@code false} for those features in your manifest.
    184 </p>
    185 
    186 <p class="caution">
    187   <strong>Caution:</strong> Declaring a hardware feature as required by setting its
    188   value to {@code true}  prevents your app from being installed on TV
    189   devices or appearing in the Android TV home screen launcher.
    190 </p>
    191 
    192 <p>
    193   Once you decide to make hardware features optional for your app, you must check for the
    194   availability of those features at runtime and then adjust your app's behavior. The next section
    195   discusses how to check for hardware features and suggests some approaches for changing the
    196   behavior of your app.
    197 </p>
    198 
    199 <p>
    200   For more information on filtering and declaring features in the manifest, see the
    201   <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code uses-feature}</a>
    202   guide.
    203 </p>
    204 
    205 
    206 <h3 id="hardware-permissions">Declaring permissions that imply hardware features</h3>
    207 
    208 <p>
    209   Some <a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">{@code uses-permission}</a>
    210   manifest declarations <em>imply hardware features</em>. This behavior means that requesting some
    211   permissions in your app manifest can exclude your app from from being installed and used on TV
    212   devices. The following commonly requested permissions create an implicit hardware feature
    213   requirement:
    214 </p>
    215 
    216 <table>
    217   <tr>
    218     <th>Permission</th>
    219     <th>Implied hardware feature</th>
    220   </tr>
    221   <tr>
    222     <td>{@link android.Manifest.permission#RECORD_AUDIO}</td>
    223     <td>{@code android.hardware.microphone}</td>
    224   </tr>
    225   <tr>
    226     <td>{@link android.Manifest.permission#CAMERA}</td>
    227     <td>{@code android.hardware.camera} <em>and</em> <br>
    228       {@code android.hardware.camera.autofocus}</td>
    229   </tr>
    230   <tr>
    231     <td>{@link android.Manifest.permission#ACCESS_COARSE_LOCATION}</td>
    232     <td>{@code android.hardware.location} <em>and</em> <br>
    233       {@code android.hardware.location.network}</td>
    234   </tr>
    235   <tr>
    236     <td>{@link android.Manifest.permission#ACCESS_FINE_LOCATION}</td>
    237     <td>{@code android.hardware.location} <em>and</em> <br>
    238       {@code android.hardware.location.gps}</td>
    239   </tr>
    240 </table>
    241 
    242 <p>
    243   For a complete list of permission requests that imply a hardware feature requirement, see the
    244   <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html#permissions-features">{@code
    245   uses-feature}</a> guide. If your app requests one of the features listed above, include a
    246   <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code uses-feature}</a>
    247   declaration in your manifest for the implied hardware feature that indicates it is not
    248   required ({@code android:required="false"}).
    249 </p>
    250 
    251 
    252 <h3 id="check-features">Checking for hardware features</h2>
    253 
    254 <p>
    255   The Android framework can tell you if hardware features are not available on the device where
    256   your app is running. Use the {@link android.content.pm.PackageManager#hasSystemFeature(String)}
    257   method to check for specific features at runtime. This method takes a single string argument that
    258   specifies the feature you want to check.
    259 </p>
    260 
    261 <p>The following code example demonstrates how to detect the availability of hardware features
    262   at runtime:</p>
    263 
    264 <pre>
    265 // Check if the telephony hardware feature is available.
    266 if (getPackageManager().hasSystemFeature("android.hardware.telephony")) {
    267     Log.d("HardwareFeatureTest", "Device can make phone calls");
    268 }
    269 
    270 // Check if android.hardware.touchscreen feature is available.
    271 if (getPackageManager().hasSystemFeature("android.hardware.touchscreen")) {
    272     Log.d("HardwareFeatureTest", "Device has a touch screen.");
    273 }
    274 </pre>
    275 
    276 
    277 <h4 id="no-touchscreen">Touch screen</h4>
    278 
    279 <p>
    280   Since most TVs do not have touch screens, Android does not support touch screen interaction for
    281   TV devices. Furthermore, using a touch screen is not consistent with a viewing environment where
    282   the user is seated 10 feet away from the display. Make sure that your UI elements and text do not
    283   require or imply the use of a touchscreen.
    284 </p>
    285 
    286 <p>
    287   On TV devices, you should design your app to work with this interaction model by supporting
    288   navigation using a directional pad (D-pad) on a TV remote control. For more information on
    289   properly supporting navigation using TV-friendly controls, see
    290   <a href="{@docRoot}training/tv/start/navigation.html">Creating TV Navigation</a>.
    291 </p>
    292 
    293 
    294 <h4 id="no-camera">Camera</h4>
    295 
    296 <p>
    297   Although a TV typically does not have a camera, you can still provide a photography-related
    298   app on a TV. For example, if you have an app that takes, views, and edits photos, you can
    299   disable its picture-taking functionality for TVs and still allow users to view and even edit
    300   photos. If you decide to enable your camera-related app to work on a TV, add the
    301   following feature declaration your app manifest:
    302 </p>
    303 
    304 <pre>
    305 &lt;uses-feature android:name="android.hardware.camera" android:required="false" /&gt;
    306 </pre>
    307 
    308 <p>
    309   If you enable your app to run without a camera, add code to your app
    310   that detects if the camera feature is available and makes adjustments to the operation of your
    311   app. The following code example demonstrates how to detect the presence of a camera:
    312 </p>
    313 
    314 <pre>
    315 // Check if the camera hardware feature is available.
    316 if (getPackageManager().hasSystemFeature("android.hardware.camera")) {
    317     Log.d("Camera test", "Camera available!");
    318 } else {
    319     Log.d("Camera test", "No camera available. View and edit features only.");
    320 }
    321 </pre>
    322 
    323 
    324 <h4 id="no-gps">GPS</h4>
    325 
    326 <p>
    327   TVs are stationary, indoor devices, and do not have built-in global positioning system (GPS)
    328   receivers. If your app uses location information, you can still allow users to search for
    329   a location, or use a static location provider such as a zip code configured during the TV device
    330   setup.
    331 </p>
    332 
    333 <pre>
    334 // Request a static location from the location manager
    335 LocationManager locationManager = (LocationManager) this.getSystemService(
    336         Context.LOCATION_SERVICE);
    337 Location location = locationManager.getLastKnownLocation("static");
    338 
    339 // Attempt to get postal or zip code from the static location object
    340 Geocoder geocoder = new Geocoder(this);
    341 Address address = null;
    342 try {
    343   address = geocoder.getFromLocation(location.getLatitude(),
    344           location.getLongitude(), 1).get(0);
    345   Log.d("Zip code", address.getPostalCode());
    346 
    347 } catch (IOException e) {
    348   Log.e(TAG, "Geocoder error", e);
    349 }
    350 </pre>
    351 
    352 
    353 <h2 id="controllers">Handling Controllers</h2>
    354 
    355 <p>
    356   TV devices require a secondary hardware device for interacting with apps, in the form of a basic
    357   remote controller or game controller. This means that your app must support D-pad input. It also
    358   means that your app may need to handle controllers going offline and input from more than one
    359   type of controller.
    360 </p>
    361 
    362 
    363 <h3 id="d-pad-minimum">D-pad minimum controls</h3>
    364 
    365 <p>
    366   The default controller for a TV device is a D-pad. In general, your app should be operable from a
    367   remote controller that only has up, down, left, right, select, Back, and Home buttons. If your app
    368   is a game that typically requires a game controller with additional controls, your app should
    369   attempt to allow gameplay with these D-pad controls. In this case, your app should also warn the
    370   user that
    371   a controller is required and allow them to exit your game gracefully using the D-pad controller.
    372   For more information about handling navigation with D-pad controller for TV devices, see
    373   <a href="{@docRoot}training/tv/start/navigation.html">Creating TV Navigation</a>.
    374 </p>
    375 
    376 
    377 <h3 id="controller-disconnects">Handle controller disconnects</h3>
    378 
    379 <p>
    380   Controllers for TV are frequently Bluetooth devices which may attempt to save power by periodically
    381   going into sleep mode and disconnecting from the TV device. This means that an app might be
    382   interrupted or restarted if it is not configured to handle these reconnect events. These events
    383   can happen in any of the following circumstances:
    384 </p>
    385 
    386 <ul>
    387   <li>While watching a video which is several minutes long, a D-Pad or game controller goes into
    388   sleep mode, disconnects from the TV device and then reconnects later on.
    389   </li>
    390   <li>During gameplay, a new player joins the game using a game controller that is not currently
    391   connected.
    392   </li>
    393   <li>During gameplay, a player leaves the game and disconnects a game controller.
    394   </li>
    395 </ul>
    396 
    397 <p>
    398   Any TV app activity that is subject to disconnect and reconnect events must be configured to
    399   handle reconnection events in the app manifest. The following code sample demonstrates how to
    400   enable an activity to handle configuration changes, including a keyboard or navigation device
    401   connecting, disconnecting, or reconnecting:
    402 </p>
    403 
    404 <pre>
    405 &lt;activity
    406   android:name=&quot;com.example.android.TvActivity&quot;
    407   android:label=&quot;&#64;string/app_name&quot;
    408   <strong>android:configChanges="keyboard|keyboardHidden|navigation"</strong>
    409   android:theme=&quot;&#64;style/Theme.Leanback&quot;&gt;
    410 
    411   &lt;intent-filter&gt;
    412     &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
    413     &lt;category android:name="android.intent.category.LEANBACK_LAUNCHER" /&gt;
    414   &lt;/intent-filter&gt;
    415   ...
    416 &lt;/activity&gt;
    417 </pre>
    418 
    419 <p>
    420   This configuration change allows the app to continue running through a reconnection event, rather
    421   than being restarted by the Android framework, which is not a good user experience.
    422 </p>
    423 
    424 
    425 <h3 id="d-pad-variants">Handle D-pad input variations</h3>
    426 
    427 <p>
    428   TV device users may have more than one type of controller that they use with their TV. For
    429   example, a user might have both a basic D-pad controller and a game controller. The key codes
    430   provided by a game controller when it is being used for D-pad functions may vary from the key
    431   codes sent by a physical D-pad.
    432 </p>
    433 
    434 <p>
    435   Your app should handle the variations of D-pad input from a game controller, so the user does not
    436   have to physically switch controllers to operate your app. For more information on handling these
    437   input variations, see <a href="{@docRoot}training/game-controllers/controller-input.html#dpad">
    438   Handling Controller Actions</a>.
    439 </p>
    440