How to configure Cordova app to filter TV devices by default

In this article, we'll be covering how to do configure Cordova to automatically filter supported devices. Thus saving you or someone else ticking and unticking hundreds if not thousands of boxes on Android app stores.

If you never used Cordova before, here's an official explanation.

Cordova wraps your HTML/JavaScript app into a native container which can access the device functions of several platforms. These functions are exposed via a unified JavaScript API, allowing you to easily write one set of code to target nearly every phone or tablet on the market today and publish to their app stores.

Basically, it creates a native application wrapper/shell for your web application. This is super neat and has many advantages, of course, here are just some of them on top of my head:

  • Faster updates - deploy changes without user installing another APK

  • Use same tech stack as web - instead of dedicated platform teams, you could just have one team that works on all platforms since they all use the same technology

  • Avoid weird proprietary technology - imagine trying to hire Play Station developers to create an app V.S. web developers.

No doubt this approach also comes with disadvantages too. We'll need to find ways to configure things which is very easy to do on these platforms. The issue we are taking a look today is trying to get our Android package (APK) to automatically filter the supported devices when we upload it to an app store. So far I've only tested this on Amazon's Appstore, so I'm not sure if it works 100% on Google's play store. But I'm quite confident it should work fine.

Instructions

Here's the snippet that we need to insert into config.xml file, in the root level of our Cordova app.

<config-file parent="/manifest" target="AndroidManifest.xml">
    <uses-feature android:name="android.software.leanback" android:required="true" />
    <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
</config-file>

What does is it doing and why do we need it?

config-file tag

<config-file> tag Cordova official documentation states that it allows you to append new children to an XML document tree. The children are XML literals to be inserted in the target document, which in our case is the AndroidManifest.xml. The parent attribute means where about it inserts into the file, thus they will all be inserted inside the <manifest> tag.

<?xml version='1.0' encoding='utf-8'?>
<manifest ... xmlns:android="http://schemas.android.com/apk/res/android">
    ...
    <uses-feature android:name="android.software.leanback" android:required="true" />
    <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
    ...
</manifest>

Notice how the <config-file> tag is gone in the AndroidManifest.xml file after the insertion.

android.software.leanback

This basically tells the app store that our app is designed for TV devices or the "lean back experience".

<uses-feature android:name="android.software.leanback" android:required="true" />

Declare that your app uses the Leanback user interface required by Android TV. If you are developing an app that runs on mobile (phones, wearables, tablets, etc.) as well as Android TV, set the required attribute value to false. If you set the required attribute value to true, your app will run only on devices that use the Leanback UI. - Android official documentation

android.hardware.touchscreen

This should be quite easy to guess, basically says our app is not designed for touch input devices. Which disables those devices by default when we upload our APK.

The app uses the device's touchscreen capabilities for gestures that are more interactive than basic touch events, such as a fling. This is a superset of the android.hardware.faketouch feature. - Android official documentaion

Final Product

Here is what we get at the end, of course, there are probably plenty other XML tags within <widget> I've left them out here just to make sure everything is easy to read.

`<?xml version='1.0' encoding='utf-8'?>
<widget ... xmlns:android="http://schemas.android.com/apk/res/android">
    ...
    <platform name="android">
        <config-file parent="/manifest" target="AndroidManifest.xml">
            <uses-feature android:name="android.software.leanback" android:required="true" />
            <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
        </config-file>
    </platform>
    ...
</widget>