Android TV and Micro-Consoles


Some of the following will discuss Android TV (“ATV”) specific needs; most of the rest will discuss your application being connected to a TV, such as a set-top box or micro-console (we’ll use “STB” for both). Both topics should complement each other.

UI Size

A user is likely to be sitting several feet away from the TV. Fonts, buttons, and other UI elements need to take this into account. Most UI elements in your application should be sized larger, especially fonts. Consider this when designing your application’s UI for different resolutions.

TV Safe Area

There is a technical aspect of TV transmission that can reduce a TV’s usable screen area along the edges; this is called “overscan.” Mobile devices do not have this issue and generally, TVs with a “Game Mode” do not either. However, overscan should be taken into account. A good rule-of-thumb is to make sure you leave a 5% margin around the screen for overscan. Meaning, ensure important application elements are placed inside this margin – health, score, etc.

The slickest way of handling overscan, which is seen in many consoles (and will hopefully be added to Android), is to draw a box around the edge of the “display.” In some cases, because of overscan, some of the entire box will not be visible to the user. The user then is asked, using the controller, to shrink the box’s edges until they see each edge. This box can then be used for placement of UI elements and can allow precise corner placements.

Critical Note on Unity:

In the discussions below, a new keycode is mentioned — KEYCODE_DPAD_CENTER. This keycode is not currently handled in Unity. There is no current work around. Thankfully, many remotes and most “Mini-Controllers” use KEYCODE_BUTTON_A which translated to Button0 in Unity. All charts reflect this.

In Unity API Specifics, section DPAD and System Buttons, it shows how a KEYCODE_DPAD_xxx translation in Unity is not controller specific. Of course, in multi-controller games this is critical; therefore, some Remotes and Mini-Controllers will not be capable of multi-controller gaming. Thankfully, many of these types of controllers use AXIS_HAT_X/Y instead, which translates to Axis5/6 in Unity. All charts reflect this.

The Remote

Consider that many STBs come with just a remote. In the above pages, we discuss a fully featured console-like controller. When considering what controls your application might need, a remote is mostly a subset of the console-like controller discussed. The only addition is KEYCODE_DPAD_CENTER which should just mimic “A button” functionality. The below chart describes the minimum input you should consider from a remote.

The Remote Control
ActionKeycodeUses and Notes
Push UpKEYCODE_DPAD_UP
AXIS_HAT_Y @ -1.0
Use for "Up." 
Use both keycode values for the same action.
Push DownKEYCODE_DPAD_DOWN
AXIS_HAT_Y @ 1.0
Use for "Down." 
Use both keycode values for the same action.
Push LeftKEYCODE_DPAD_LEFT
AXIS_HAT_X @ -1.0
Use for "Left." 
Use both keycode values for the same action.
Push RightKEYCODE_DPAD_RIGHT
AXIS_HAT_X @ 1.0
Use for "Right." 
Use both keycode values for the same action.
Push Center/OKKEYCODE_DPAD_CENTER
KEYCODE_BUTTON_A
Use for "Affirm, OK, Primary Action." 
Use both keycode values for the same action.
BackKEYCODE_BACKUse for "Back, Negative, Pause." 
HomeKEYCODE_HOMEUsed in OS only.

The Mini-Controller

This controller is very much like a remote (see The Remote above) with an extra button. Sometimes the “OK” button remains in the center of the DPAD. Sometimes the “OK” button is placed with the extra button, thus looking very much like a gamepad from the 1980s. In either case, handling the new button is the same. See the chart below which describes the minimum input you should consider from a mini-controller.

The Mini-Controller
ActionKeycodeUses and Notes
Push UpKEYCODE_DPAD_UP
AXIS_HAT_Y @ -1.0
Use for "Up." 
Use both keycode values for the same action.
Push DownKEYCODE_DPAD_DOWN
AXIS_HAT_Y @ 1.0
Use for "Down." 
Use both keycode values for the same action.
Push LeftKEYCODE_DPAD_LEFT
AXIS_HAT_X @ -1.0
Use for "Left." 
Use both keycode values for the same action.
Push RightKEYCODE_DPAD_RIGHT
AXIS_HAT_X @ 1.0
Use for "Right." 
Use both keycode values for the same action.
Push Center/OK
or A button
KEYCODE_DPAD_CENTER
KEYCODE_BUTTON_A
Use for "Affirm, OK, Primary Action." 
Use both keycode values for the same action.
Other Button
or B button
KEYCODE_BUTTON_BUse for "Back, Negative" in menus.
Use for other game actions (optional).
BackKEYCODE_BACKUse for "Back, Negative, Pause." 
HomeKEYCODE_HOMEUsed in OS only.

Remote and Mini-Controller Sources

When discussing the console-like controller and filtering events, SOURCE_GAMEPAD and SOURCE_JOYSTICK are the sources used to filter. However, with the simplicity of the remote, a new, additional source should be used for filtering — SOURCE_DPAD.

Remote and Mini-Controller Keycode Overlap

Notice that the KEYCODES of the Remote, Mini-Controller, and Console-like controller overlap, so that the user’s expectations are met when moving from one controller to the other. The Console-like controller is the super-set of the controllers with one exception: KEYCODE_DPAD_CENTER, which should act like KEYCODE_BUTTON_A in your application, needs to be added. Keep in mind, if your application needs inputs beyond what the Remote offers, the user should be alerted that they need a certain type of controller, and the application should allow a graceful exit using inputs only offered by the minimum input device, the Remote.

Android TV Needs

As of this writing, Android TV is still in “Developer Preview” mode, so some information may change. Please check the Android TV documentation for additional or changed requirements.

ATV will support a new Leanback UI which is meant for TV scenarios. Only the applications that are designed to work in Leanback mode will be visible; this includes Google Play. To indicate that an application is designed for Leanback mode, developers are required to add some new items to their manifest.

A new intent category has been added so that an application can indicate that a certain activity should be added to the Leanback launcher. An application must declare at least one activity in its manifest that handles a launch intent of type ACTION_MAIN combined with the new Leanback category. Most applications will support the “normal” launcher along with the Leanback launcher. An example of this:

<activity . . . >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>

The Leanback launcher allows Leanback-specific banners. A developer indicates this banner in a similar way to indicating their application’s icon, android:icon. The syntax for the banner is android:logo, and can be either in the application or activity tag like an icon. No extra text is added on top of or below the banner. Applications should put the banner in the drawable-xhdpi folder with a size of 320x180. In Unity, this folder is in the Assets\Plugins\Android\res\drawable-xhdpi folder. Text should be included in the banner image if needed to disambiguate the application in the launcher.

The launcher uses a flag to differentiate games from all other Leanback applications. Games are displayed in a separate row from regular applications. To indicate whether your application is a game or not, you must use a new metadata declaration in the manifest at the application level.

<application . . .>
<meta-data android:name="isGame" android:value=[ "true" | "false" ]/>
</application>

Above we described only the needs for the new Launcher. Below, we’ll discuss items that currently may be in your application, which may need some thought or change.

The current “Developer Preview” of ATV does not include a browser. This means that certain types of in-game advertising will not work. Ads that ask a user to follow a link or install an application from Google Play will not work. Interstitial and video ads that require no user interaction should be fine.

Making sure your application’s manifest precisely reflects hardware features and permissions needed is critical, or else the application may not be listed in the launcher or Play Store. We’ll go over some common mistakes below.

By default, Google Play assumes that an application requires touchscreen support. ATV, of course, has no touchscreen. To be listed properly, your application needs to declare in its manifest the following element:

<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>

Further, your application must not define any touch requirements without indicating that it is not required, android:required="false". If ATV doesn’t have the particular piece of hardware listed in the manifest, and your application doesn’t indicate that it is not required, the application will not be listed. Be sure to check all features listed in the application’s manifest.

Some features you should not rely on:

Features Not Typical on ATV
android.hardware.bluetoothandroid.hardware.sensor.gyroscope
android.hardware.cameraandroid.hardware.sensor.light
android.hardware.camera.autofocusandroid.hardware.sensor.proximity
android.hardware.camera.flashandroid.hardware.telephony
android.hardware.camera.frontandroid.hardware.telephony.cdma
android.hardware.location.gpsandroid.hardware.telephony.gsm
android.hardware.microphoneandroid.hardware.faketouch
android.hardware.nfcandroid.hardware.touchscreen
android.hardware.sensor.accelerometerandroid.hardware.touchscreen.multitouch
android.hardware.sensor.barometer android.hardware.touchscreen.multitouch.distinct
android.hardware.sensor.compass android.hardware.touchscreen.multitouch.jazzhand

Some permissions in an application’s manifest can imply certain hardware features are required, even if they are not directly declared. Google Play assumes these implied features are required, unless you specify otherwise in the manifest, by declaring that the feature is explicitly not required, like the touchscreen example above.

PermissionImplied Feature
BLUETOOTH
BLUETOOTH_ADMIN
android.hardware.bluetooth
CAMERAandroid.hardware.camera
android.hardware.camera.autofocus
ACCESS_MOCK_LOCATION
ACCESS_LOCATION_EXTRA_COMMANDS
INSTALL_LOCATION_PROVIDER
android.hardware.location
ACCESS_COARSE_LOCATIONandroid.hardware.location.network
android.hardware.location
ACCESS_FINE_LOCATIONandroid.hardware.location.gps
android.hardware.location
RECORD_AUDIO android.hardware.microphone
CALL_PHONE
CALL_PRIVILEGED
MODIFY_PHONE_STATE
PROCESS_OUTGOING_CALLS
READ_SMS
RECEIVE_SMS
RECEIVE_MMS
RECEIVE_WAP_PUSH
SEND_SMS
WRITE_APN_SETTINGS
WRITE_SMS
android.hardware.telephony
ACCESS_WIFI_STATE
CHANGE_WIFI_STATE
CHANGE_WIFI_MULTICAST_STATE
android.hardware.wifi

Instead, check for features at runtime by calling PackageManager.hasSystemFeature(), which can allow your application to dynamically use hardware and/or and remove features as needed.

 


NVIDIA® GameWorks™ Documentation Rev. 1.0.220830 ©2014-2022. NVIDIA Corporation and affiliates. All Rights Reserved.