How can I check if an app is running on an Android TV

前端 未结 4 1121
太阳男子
太阳男子 2021-02-07 06:29

Is there a way to check if an app is running on an Android TV or Android Mobile?

I know how to check the running build. I want to start a specific service if the app is

相关标签:
4条回答
  • 2021-02-07 06:56

    Assuming previos answers:

    • If uiModeManager.currentModeType == UI_MODE_TYPE_TELEVISION that's definitely a TV
    • We can't rely on currentModeType to say that it is TV, because some TV devices are actually return UI_MODE_TYPE_NORMAL
    • So we should check FEATURE_TELEVISION for pre-lollipop and FEATURE_LEANBACK for lollipop devices.
    • if you want to support not only tv's, but stationary devices with screen, you may add additional checks to predict it
    • you should be careful with that to not show tv ui on the phone

    This is a kotlin code we actually use:

    enum class UiModeType {
        NORMAL,
        DESK,
        CAR,
        TV,
        APPLIANCE,
        WATCH,
        VR
    }
    
    private val modeType: Int
        get() = uiModeManager.currentModeType
    
    fun getUiModeType(): UiModeType = when {
        modeType == UI_MODE_TYPE_APPLIANCE -> UiModeType.APPLIANCE
        modeType == UI_MODE_TYPE_CAR -> UiModeType.CAR
        modeType == UI_MODE_TYPE_DESK -> UiModeType.DESK
        modeType == UI_MODE_TYPE_TELEVISION -> UiModeType.TV
    
        sdkInt >= Build.VERSION_CODES.KITKAT_WATCH &&
            modeType == UI_MODE_TYPE_WATCH -> UiModeType.WATCH
    
        sdkInt >= Build.VERSION_CODES.O &&
            modeType == UI_MODE_TYPE_VR_HEADSET -> UiModeType.VR
    
        isLikelyTelevision() -> UiModeType.TV
    
        modeType == UI_MODE_TYPE_NORMAL -> UiModeType.NORMAL
        else -> UiModeType.NORMAL
    }
    
    private fun isLikelyTelevision(): Boolean = with(packageManager) {
        return@with when {
            sdkInt >= Build.VERSION_CODES.LOLLIPOP &&
                hasSystemFeature(PackageManager.FEATURE_LEANBACK) -> true
            sdkInt < Build.VERSION_CODES.LOLLIPOP &&
                @Suppress("DEPRECATION")
                hasSystemFeature(PackageManager.FEATURE_TELEVISION) -> true
            isBatteryAbsent() &&
                hasSystemFeature(PackageManager.FEATURE_USB_HOST) &&
                hasSystemFeature(PackageManager.FEATURE_ETHERNET) &&
                !hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)
    }
    
    @SuppressLint("NewApi")
    private fun isBatteryAbsent(): Boolean {
        return if (sdkInt >= Build.VERSION_CODES.LOLLIPOP) {
            batteryManager?.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) == 0
        } else {
            false
        }
    }
    
    0 讨论(0)
  • 2021-02-07 06:59

    From Handling TV Hardware in Android Docs:

    public static final String TAG = "DeviceTypeRuntimeCheck";
    
        UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE);
        if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) {
            Log.d(TAG, "Running on a TV Device");
        } else {
            Log.d(TAG, "Running on a non-TV Device");
    }
    
    0 讨论(0)
  • 2021-02-07 07:03

    Some options are:

    1) Query the system for a large screen

    2) Use reflection to detect TV specific classes

    3) Use hasSystemFeature to detect the lack of touchscreen

    More info

    https://developer.android.com/training/tv/start/hardware.html

    And a similar answer for Google TV

    Identify GoogleTv from Android app

    0 讨论(0)
  • 2021-02-07 07:03
    private boolean isDirectToTV() {
      return(getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEVISION)
          || getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK));
    }
    

    This will return true if the device is advertising itself as having either the android.hardware.type.television or android.software.leanback system features. Android TV and Fire TV handle this correctly; I have not tried it on other environment as yet.

    0 讨论(0)
提交回复
热议问题