26

有没有办法检查应用程序是否在 Android TV 或 Android Mobile 上运行?

我知道如何检查正在运行的构建。如果应用程序在 Android TV vs Mobile 上运行,我想启动特定服务。希望将两人安置在同一个图书馆下。

4

4 回答 4

41

来自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");
}
于 2015-05-05T17:27:51.363 回答
22
private boolean isDirectToTV() {
  return(getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEVISION)
      || getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK));
}

true如果设备将自己宣传为具有android.hardware.type.televisionandroid.software.leanback系统功能,这将返回。Android TV 和 Fire TV 可以正确处理这个问题;我还没有在其他环境中尝试过。

于 2014-11-25T23:52:45.337 回答
6

一些选项是:

1)查询系统大屏

2)使用反射检测电视特定类

3)使用hasSystemFeature检测触摸屏的缺失

更多信息

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

谷歌电视的类似答案

从 Android 应用识别 GoogleTv

于 2014-11-25T23:52:04.330 回答
3

总结以前的答案:

  • 如果uiModeManager.currentModeType == UI_MODE_TYPE_TELEVISION那绝对是电视
  • 我们不能靠currentModeType说它是电视,因为有些电视设备实际上是退货的UI_MODE_TYPE_NORMAL
  • 所以我们应该检查FEATURE_TELEVISION棒棒糖前和FEATURE_LEANBACK棒棒糖设备。
  • 如果您不仅想支持电视,还想支持带屏幕的固定设备,您可以添加额外的检查来预测它
  • 你应该小心不要在电话上显示电视用户界面

这是我们实际使用的 kotlin 代码:

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
    }
}
于 2019-11-19T10:52:48.897 回答