Android初探开机引导

因为需求有做开机引导,所以简单的学习下这块功能的流程,并简单的做个总结

主要参考文章:
https://www.jianshu.com/p/d2951f6fb2a8
https://blog.csdn.net/ansondroider/article/details/103297638

做开机引导,主要要做到的效果就是只有第一次使用的时候会打开,只打开一次,当执行完开机引导的流程之后,之后开机都不会再展示

要实现开机引导,那么就一定是系统应用,按照原理来说,需要两个步骤,第一,需要引导页的优先级比LAUNCHER高。第二,需要流程完毕之后执行某些操作让应用下次不会启动。

1. 设置应用的优先级

可以设置android:priority属性,系统会判断启动priority优先级高的。

        <activity android:name=".ProvisionedActivity">
            <intent-filter android:priority="1">
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.COMMON_HOME" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

这样配置之后,其它应用的优先级如果没有设置的话默认就是0,这样就会优先打开引导页。

2. 引导页只开启一次

自己可以在引导页中写自己想要做的逻辑。当执行完所有逻辑之后,需要配置

        // Add a persistent setting to allow other apps to know the device has been provisioned.
        Settings.Global.putInt(contentResolver, Settings.Global.DEVICE_PROVISIONED, 1)
        Settings.Secure.putInt(contentResolver, Settings.Secure.USER_SETUP_COMPLETE, 1)
        // remove this activity from the package manager.
        PackageManager pm = context.getPackageManager();
        ComponentName componentName = new ComponentName(packageName, activityName);
        pm.setComponentEnabledSetting(componentName,PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP);

这里主要做了设置Settings.Global.DEVICE_PROVISIONED和Settings.Secure.USER_SETUP_COMPLETE两个参数,还有PackageManager.setComponentEnabledSetting方法禁用组件

第一个参数是组件名
第二个参数是状态
不可用状态:COMPONENT_ENABLED_STATE_DISABLED
可用状态:COMPONENT_ENABLED_STATE_ENABLED
默认状态:COMPONENT_ENABLED_STATE_DEFAULT
第三个参数flags
DONT_KILL_APP或者0,0表示杀死包含该组件的app

3. 使用过程中出现的问题

(1)priority设置无效

运行时会发现设置priority优先级比LAUNCHER高,在开机之后也会提示让你选择打开应用,而不是默认打开优先级高的,关于这个问题,可以参考这篇文章
https://blog.csdn.net/ansondroider/article/details/103297638
只需要把应用安装到system/priv-app中,就能解决这个问题。正常来说一般系统应用也是安装在这么文件夹中,只是平时调试的时候会为了方便直接run,所以可能出现这个问题。
将应用安装到该文件夹中可以使用这个命令,然后重启

adb push xxx.apk /system/priv-app
(2)不设置Settings.Global.DEVICE_PROVISIONED和Settings.Secure.USER_SETUP_COMPLETE

看了很多文章,都没有讲到为什么要设置这两属性,因为要达成目的,我们只需要设置priority和调用setComponentEnabledSetting方法就行,为什么要设置这两个参数?不设置会有什么影响。
其实简单来说,系统在其他地方有用到这两个参数,举个简单的例子,我直接

        Settings.Global.putInt(contentResolver, Settings.Global.DEVICE_PROVISIONED, 0)
        Settings.Secure.putInt(contentResolver, Settings.Secure.USER_SETUP_COMPLETE, 0)

去运行程序,能够很明显的测出这种情况下按Home键没反应,除此之外屏保也会不显示。
所以这两个参数还是需要在这个地方设为1的。

推荐阅读更多精彩内容