Android TV因未完成开机向导导致HOME按键失效的解决方案

Android TV因未完成开机向导导致HOME按键失效的解决方案

在调试 Android TV 设备时,可能会遇到遥控器 HOME 键失效 的问题。这种现象并非由按键映射错误引起,而是与设备的开机向导(Provision)状态有关。本文将逐步分析问题原因并提供解决方法。

一、查看logcat 日志

按下 HOME 键 后,通过 logcat 捕获的日志可能显示如下信息:

HdmiControlService: Local playback device not available
WindowManager: One touch play failed: 2
WindowManager: Not starting activity because user setup is in progress: Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 (has extras) }
  • 从日志可以看出,系统未启动意图为 android.intent.action.MAIN 的 Activity,具体原因是 用户设置未完成。

  • 这受以下 Settings.Secure 属性 控制:

    • USER_SETUP_COMPLETE
    • TV_USER_SETUP_COMPLETE
  • 如果上述属性未设置为 1,系统会限制某些关键功能的使用,例如无法启动 Launcher。

二、检查Settings属性

使用控制台命令

settings get global device_provisioned 
settings get secure user_setup_complete 
settings get secure tv_user_setup_complete 

确保以上三个属性值均为 1。若结果为 0 或其他值,则表明开机向导未正确完成。

补充说明

  1. 查看系统中所有 Settings 属性:

    settings list secure
    settings list global

  2. 修改或新增 Settings 值:

    settings put secure <key> <value>
    settings put global <key> <value>

  3. Settings 值存储路径:
    /data/system/users/0/settings_secure.xml
    /data/system/users/0/settings_global.xml

三、检查Provison 开机向导是否存在

执行以下命令,检查开机向导应用是否已编译进系统:

pm list packges | grep provision

如果未找到 Provision 应用,可能是系统构建时遗漏了此模块。

其代码路径通常为:
packages/apps/Provision/src/com/android/provision/DefaultActivity.java

关键代码如下:

public class DefaultActivity extends Activity {

    @Override
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        // 设置相关属性
        Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
        Settings.Secure.putInt(getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1);
        Settings.Secure.putInt(getContentResolver(), Settings.Secure.TV_USER_SETUP_COMPLETE, 1);

        // 禁用自身,使其只执行一次
        PackageManager pm = getPackageManager();
        ComponentName name = new ComponentName(this, DefaultActivity.class);
        pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);

        // 结束 Activity
        finish();
    }
}

功能说明:

  1. 设置 DEVICE_PROVISIONED、USER_SETUP_COMPLETE 和 TV_USER_SETUP_COMPLETE 属性。
  2. 启动后禁用自身,仅执行一次。

四、定制化系统的特殊情况

在定制化系统中,开机引导可能并非由 Provision 应用完成,而是由其他应用(如 Settings 或 Launcher)接管。可使用以下命令查找相关代码位置:

grep -rnw USER_SETUP_COMPLETE frameworks/

示例问题排查

  1. Override 情况
    某些系统可能会通过 override 替换 Provision 应用,例如:

     overrides: [
         "Home",
         "Launcher3QuickStep",
         "Provision",
     ],
    

在这种情况下,需要检查替代应用是否正确设置了相关属性。

  1. 未执行代码

    若 Provision 应用已编译进系统但未运行。provision成功编译进去了,但是就是没有执行里面的代码,我遇到这个情况的时候尚未查到背后的原因,解决方法是将Provision里面的内容加到我自己的某个APK里面去,来代替Provision的功能。

    如果想要在自己的APP中进行Settings设置可以参考如下代码:

    private void initializeDeviceSettings() {
    try {
    Settings.Global.putInt( getContentResolver(), Settings.Global.DEVICE_PROVISIONED , 1);
    Settings.Secure.putInt( getContentResolver(), "user_setup_complete", 1);
    Settings.Secure.putInt( getContentResolver(), "tv_user_setup_complete", 1);
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

这里之所以

使用user_setup_complete而不是Settings.Secure.USER_SETUP_COMPLETE

使用tv_user_setup_complete 而不是Settings.Secure.TV_USER_SETUP_COMPLETE

是因为这两个属性是隐藏的。

五、取消对开机引导的判断

如果不希望依赖 Provision 或类似逻辑,可修改框架源码,直接跳过相关属性的检查。代码位置如下:

frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

    public boolean isUserSetupComplete() {
        boolean isSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(),
                Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
        if (mHasFeatureLeanback) {
            isSetupComplete &= isTvUserSetupComplete();
        } else if (mHasFeatureAuto) {
            isSetupComplete &= isAutoUserSetupComplete();
        }
        return isSetupComplete;
    }

    private boolean isAutoUserSetupComplete() {
        return Settings.Secure.getIntForUser(mContext.getContentResolver(),
                "android.car.SETUP_WIZARD_IN_PROGRESS", 0, UserHandle.USER_CURRENT) == 0;
    }

    private boolean isTvUserSetupComplete() {
        return Settings.Secure.getIntForUser(mContext.getContentResolver(),

frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java

    private boolean isTvUserSetupComplete() {
        boolean isTvSetupComplete = Settings.Secure.getInt(getContext().getContentResolver(),
                Settings.Secure.USER_SETUP_COMPLETE, 0) != 0;
        isTvSetupComplete &= Settings.Secure.getInt(getContext().getContentResolver(),
                Settings.Secure.TV_USER_SETUP_COMPLETE, 0) != 0;
        return isTvSetupComplete;
    }

可通过修改或注释以上代码逻辑,直接取消对 Settings 属性的依赖。

相关推荐
恋猫de小郭3 小时前
Android Studio 正式版 10 周年回顾,承载 Androider 的峥嵘十年
android·ide·android studio
aaaweiaaaaaa6 小时前
php的使用及 phpstorm环境部署
android·web安全·网络安全·php·storm
工程师老罗8 小时前
Android记事本App设计开发项目实战教程2025最新版Android Studio
android
pengyu12 小时前
系统化掌握 Dart 编程之异常处理(二):从防御到艺术的进阶之路
android·flutter·dart
消失的旧时光-194312 小时前
android Camera 的进化
android
基哥的奋斗历程13 小时前
Openfga 授权模型搭建
android·adb
Pakho love1 天前
Linux:文件与fd(被打开的文件)
android·linux·c语言·c++
勿忘初心911 天前
Android车机DIY开发之软件篇(九) NXP AutomotiveOS编译
android·arm开发·经验分享·嵌入式硬件·mcu
lingllllove1 天前
PHP中配置 variables_order详解
android·开发语言·php
消失的旧时光-19431 天前
Android-音频采集
android·音视频