Support fake Android TV devices

Android TV is included in some modern Smart TVs, and there are also external set-top-boxes to get Android TV for any TV with HDMI input.

However, there are also some set-top-boxes which almost, but not quite, support Android TV.

With not so much extra effort, it is possible to make an Android app supporting those fake Android TV devices as well as the real ones.

In addition to the guidelines from Google for building Android TV apps, do this to support the fake TV Android TV devices as well:

  1. If you build an app for both Android TV and mobile (smartphone/tablet), make sure to build a separate .apk for Android TV, using Gradle flavors. (This is a good idea anyway since it will keep down the .apk size.)
  2. Do not use the television resource qualifier, put TV resources in unqualified resource directories instead. (When building a separate .apk for TV only, this resource qualifier is not necessary.)
  3. Specify both android.intent.category.LAUNCHER and android.intent.category.LEANBACK_LAUNCHER in the intent-filter for the launcher activity in the app manifest.:
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    
  4. Specify Leanback support with required=false in the app manifest:
    <uses-feature
        android:name="android.software.leanback"
        android:required="false" />
    
  5. Specify both android:icon and android:banner in the app manifest:
    <application
        android:banner="@drawable/my_banner"
        android:icon="@drawable/my_icon">
    
  6. If you use the Leanback SearchFragment, you need to disable voice search on the fake devices, since they usually does not support speech recognition:
        static boolean isRealAndroidTvDevice(Context context) {
            UiModeManager uiModeManager = (UiModeManager) context.getSystemService(UI_MODE_SERVICE);
            return (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION);
        }        
    
        if (!isRealAndroidTvDevice(context)) {
            setSpeechRecognitionCallback(new SpeechRecognitionCallback() {
                @Override
                public void recognizeSpeech() {
                    // do nothing
                }
            });
        }
    
  7. The fake Android TV devices usually get the display pixel density wrong. You can programatically fix this in onCreate on the launcher activity:
        if (!isRealAndroidTvDevice(context)) {
            DisplayMetrics metrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(metrics);
            metrics.density = 2.0f;
            metrics.densityDpi = 320;
            metrics.scaledDensity = 2.0f;
            getResources().getDisplayMetrics().setTo(metrics);
        }
    
This entry was posted in Android. Bookmark the permalink.

3 Responses to Support fake Android TV devices

  1. Jeff Huff says:

    Mikael,

    Have you tried to hide the speech orb inside the SearchBar so that it just shows the search text view? I have tried changing the focus (requestFocus), visibility and such in my SearchSupportFragment subclass onCreateView, onViewCreated, onStart etc and making any change to the speech orb causes the SearchBox not to call back to the search provider.

  2. Rad says:

    Nice article, but how is this function declared:

    isRealAndroidTvDevice(context)

    How do you differentiate real from the fake devices and do you think it would hurt in any way if no check is made and all devices are forced with the “corrected” metrics?

  3. See point 6 for isRealAndroidTvDevice.

    I don’t think you should attempt to change the metrics on a real Android TV device, since they likely have it correct and you may mess it up.

Comments are closed.