1page.title=Handling TV Hardware 2page.tags="unsupported" 3trainingnavtop=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> 52public static final String TAG = "DeviceTypeRuntimeCheck"; 53 54UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE); 55if (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>Near Field Communications (NFC)</td> 104 <td>{@code android.hardware.nfc}</td> 105 </tr> 106 <tr> 107 <td>GPS</td> 108 <td>{@code android.hardware.location.gps}</td> 109 </tr> 110 <tr> 111 <td>Microphone <sup><a href="#cont-mic">[1]</a></sup></td> 112 <td>{@code android.hardware.microphone}</td> 113 </tr> 114 <tr> 115 <td>Sensors</td> 116 <td>{@code android.hardware.sensor}</td> 117 </tr> 118 <tr> 119 <td>Screen in portrait orientation</td> 120 <td>{@code android.hardware.screen.portrait}</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<uses-feature android:name="android.hardware.touchscreen" 155 android:required="false"/> 156<uses-feature android:name="android.hardware.faketouch" 157 android:required="false"/> 158<uses-feature android:name="android.hardware.telephony" 159 android:required="false"/> 160<uses-feature android:name="android.hardware.camera" 161 android:required="false"/> 162<uses-feature android:name="android.hardware.nfc" 163 android:required="false"/> 164<uses-feature android:name="android.hardware.location.gps" 165 android:required="false"/> 166<uses-feature android:name="android.hardware.microphone" 167 android:required="false"/> 168<uses-feature android:name="android.hardware.sensor" 169 android:required="false"/> 170</pre> 171 172<p class="note"><strong>Note:</strong> Some features have subfeatures like {@code android.hardware.camera.front}, 173 as described in the <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html#features-reference"> 174 Feature Reference</a>. Be sure to mark as {@code required="false"} any subfeatures also used in 175 your app.</p> 176 177<p> 178 All apps intended for use on TV devices must declare that the touch screen feature is not required 179 as described in <a href="{@docRoot}training/tv/start/start.html#no-touchscreen">Get Started with 180 TV Apps</a>. If your app normally uses one or more of the features listed above, change the 181 {@code android:required} attribute setting to {@code false} for those features in your manifest. 182</p> 183 184<p class="caution"> 185 <strong>Caution:</strong> Declaring a hardware feature as required by setting its 186 value to {@code true} prevents your app from being installed on TV 187 devices or appearing in the Android TV home screen launcher. 188</p> 189 190<p> 191 Once you decide to make hardware features optional for your app, you must check for the 192 availability of those features at runtime and then adjust your app's behavior. The next section 193 discusses how to check for hardware features and suggests some approaches for changing the 194 behavior of your app. 195</p> 196 197<p> 198 For more information on filtering and declaring features in the manifest, see the 199 <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code uses-feature}</a> 200 guide. 201</p> 202 203 204<h3 id="hardware-permissions">Declaring permissions that imply hardware features</h3> 205 206<p> 207 Some <a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">{@code uses-permission}</a> 208 manifest declarations <em>imply hardware features</em>. This behavior means that requesting some 209 permissions in your app manifest can exclude your app from from being installed and used on TV 210 devices. The following commonly requested permissions create an implicit hardware feature 211 requirement: 212</p> 213 214<table> 215 <tr> 216 <th>Permission</th> 217 <th>Implied hardware feature</th> 218 </tr> 219 <tr> 220 <td>{@link android.Manifest.permission#RECORD_AUDIO}</td> 221 <td>{@code android.hardware.microphone}</td> 222 </tr> 223 <tr> 224 <td>{@link android.Manifest.permission#CAMERA}</td> 225 <td>{@code android.hardware.camera} <em>and</em> <br> 226 {@code android.hardware.camera.autofocus}</td> 227 </tr> 228 <tr> 229 <td>{@link android.Manifest.permission#ACCESS_COARSE_LOCATION}</td> 230 <td>{@code android.hardware.location} <em>and</em> <br> 231 {@code android.hardware.location.network}</td> 232 </tr> 233 <tr> 234 <td>{@link android.Manifest.permission#ACCESS_FINE_LOCATION}</td> 235 <td>{@code android.hardware.location} <em>and</em> <br> 236 {@code android.hardware.location.gps}</td> 237 </tr> 238</table> 239 240<p> 241 For a complete list of permission requests that imply a hardware feature requirement, see the 242 <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html#permissions-features">{@code 243 uses-feature}</a> guide. If your app requests one of the features listed above, include a 244 <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code uses-feature}</a> 245 declaration in your manifest for the implied hardware feature that indicates it is not 246 required ({@code android:required="false"}). 247</p> 248 249 250<h3 id="check-features">Checking for hardware features</h2> 251 252<p> 253 The Android framework can tell you if hardware features are not available on the device where 254 your app is running. Use the {@link android.content.pm.PackageManager#hasSystemFeature(String)} 255 method to check for specific features at runtime. This method takes a single string argument that 256 specifies the feature you want to check. 257</p> 258 259<p>The following code example demonstrates how to detect the availability of hardware features 260 at runtime:</p> 261 262<pre> 263// Check if the telephony hardware feature is available. 264if (getPackageManager().hasSystemFeature("android.hardware.telephony")) { 265 Log.d("HardwareFeatureTest", "Device can make phone calls"); 266} 267 268// Check if android.hardware.touchscreen feature is available. 269if (getPackageManager().hasSystemFeature("android.hardware.touchscreen")) { 270 Log.d("HardwareFeatureTest", "Device has a touch screen."); 271} 272</pre> 273 274 275<h4 id="no-touchscreen">Touch screen</h4> 276 277<p> 278 Since most TVs do not have touch screens, Android does not support touch screen interaction for 279 TV devices. Furthermore, using a touch screen is not consistent with a viewing environment where 280 the user is seated 10 feet away from the display. Make sure that your UI elements and text do not 281 require or imply the use of a touchscreen. 282</p> 283 284<p> 285 On TV devices, you should design your app to work with this interaction model by supporting 286 navigation using a directional pad (D-pad) on a TV remote control. For more information on 287 properly supporting navigation using TV-friendly controls, see 288 <a href="{@docRoot}training/tv/start/navigation.html">Creating TV Navigation</a>. 289</p> 290 291 292<h4 id="no-camera">Camera</h4> 293 294<p> 295 Although a TV typically does not have a camera, you can still provide a photography-related 296 app on a TV. For example, if you have an app that takes, views, and edits photos, you can 297 disable its picture-taking functionality for TVs and still allow users to view and even edit 298 photos. If you decide to enable your camera-related app to work on a TV, add the 299 following feature declaration your app manifest: 300</p> 301 302<pre> 303<uses-feature android:name="android.hardware.camera" android:required="false" /> 304</pre> 305 306<p> 307 If you enable your app to run without a camera, add code to your app 308 that detects if the camera feature is available and makes adjustments to the operation of your 309 app. The following code example demonstrates how to detect the presence of a camera: 310</p> 311 312<pre> 313// Check if the camera hardware feature is available. 314if (getPackageManager().hasSystemFeature("android.hardware.camera")) { 315 Log.d("Camera test", "Camera available!"); 316} else { 317 Log.d("Camera test", "No camera available. View and edit features only."); 318} 319</pre> 320 321 322<h4 id="no-gps">GPS</h4> 323 324<p> 325 TVs are stationary, indoor devices, and do not have built-in global positioning system (GPS) 326 receivers. If your app uses location information, you can still allow users to search for 327 a location, or use a static location provider such as a zip code configured during the TV device 328 setup. 329</p> 330 331<pre> 332// Request a static location from the location manager 333LocationManager locationManager = (LocationManager) this.getSystemService( 334 Context.LOCATION_SERVICE); 335Location location = locationManager.getLastKnownLocation("static"); 336 337// Attempt to get postal or zip code from the static location object 338Geocoder geocoder = new Geocoder(this); 339Address address = null; 340try { 341 address = geocoder.getFromLocation(location.getLatitude(), 342 location.getLongitude(), 1).get(0); 343 Log.d("Zip code", address.getPostalCode()); 344 345} catch (IOException e) { 346 Log.e(TAG, "Geocoder error", e); 347} 348</pre> 349 350 351<h2 id="controllers">Handling Controllers</h2> 352 353<p> 354 TV devices require a secondary hardware device for interacting with apps, in the form of a basic 355 remote controller or game controller. This means that your app must support D-pad input. It also 356 means that your app may need to handle controllers going offline and input from more than one 357 type of controller. 358</p> 359 360 361<h3 id="d-pad-minimum">D-pad minimum controls</h3> 362 363<p> 364 The default controller for a TV device is a D-pad. In general, your app should be operable from a 365 remote controller that only has up, down, left, right, select, Back, and Home buttons. If your app 366 is a game that typically requires a game controller with additional controls, your app should 367 attempt to allow gameplay with these D-pad controls. In this case, your app should also warn the 368 user that 369 a controller is required and allow them to exit your game gracefully using the D-pad controller. 370 For more information about handling navigation with D-pad controller for TV devices, see 371 <a href="{@docRoot}training/tv/start/navigation.html">Creating TV Navigation</a>. 372</p> 373 374 375<h3 id="controller-disconnects">Handle controller disconnects</h3> 376 377<p> 378 Controllers for TV are frequently Bluetooth devices which may attempt to save power by periodically 379 going into sleep mode and disconnecting from the TV device. This means that an app might be 380 interrupted or restarted if it is not configured to handle these reconnect events. These events 381 can happen in any of the following circumstances: 382</p> 383 384<ul> 385 <li>While watching a video which is several minutes long, a D-Pad or game controller goes into 386 sleep mode, disconnects from the TV device and then reconnects later on. 387 </li> 388 <li>During gameplay, a new player joins the game using a game controller that is not currently 389 connected. 390 </li> 391 <li>During gameplay, a player leaves the game and disconnects a game controller. 392 </li> 393</ul> 394 395<p> 396 Any TV app activity that is subject to disconnect and reconnect events must be configured to 397 handle reconnection events in the app manifest. The following code sample demonstrates how to 398 enable an activity to handle configuration changes, including a keyboard or navigation device 399 connecting, disconnecting, or reconnecting: 400</p> 401 402<pre> 403<activity 404 android:name="com.example.android.TvActivity" 405 android:label="@string/app_name" 406 <strong>android:configChanges="keyboard|keyboardHidden|navigation"</strong> 407 android:theme="@style/Theme.Leanback"> 408 409 <intent-filter> 410 <action android:name="android.intent.action.MAIN" /> 411 <category android:name="android.intent.category.LEANBACK_LAUNCHER" /> 412 </intent-filter> 413 ... 414</activity> 415</pre> 416 417<p> 418 This configuration change allows the app to continue running through a reconnection event, rather 419 than being restarted by the Android framework, which is not a good user experience. 420</p> 421 422 423<h3 id="d-pad-variants">Handle D-pad input variations</h3> 424 425<p> 426 TV device users may have more than one type of controller that they use with their TV. For 427 example, a user might have both a basic D-pad controller and a game controller. The key codes 428 provided by a game controller when it is being used for D-pad functions may vary from the key 429 codes sent by a physical D-pad. 430</p> 431 432<p> 433 Your app should handle the variations of D-pad input from a game controller, so the user does not 434 have to physically switch controllers to operate your app. For more information on handling these 435 input variations, see <a href="{@docRoot}training/game-controllers/controller-input.html#dpad"> 436 Handling Controller Actions</a>. 437</p> 438