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

前端 未结 4 1172
太阳男子
太阳男子 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
        }
    }
    

提交回复
热议问题