Android初探开机引导

483 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情

前言

这篇文章也是我前不久写过的一篇文章,www.jianshu.com/p/6f8e62911… 个人感觉还是一个挺不错的内容,所以想做个分享,当然一般开发系统软件的才会接触到,开发应用APP的话基本不会怎么涉及,但是怎么说呢,扩展一下也不错。

主要参考文章:
www.jianshu.com/p/d2951f6fb…
blog.csdn.net/ansondroide…

简介

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

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

设置应用的优先级

可以设置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,这样就会优先打开引导页。

引导页只开启一次

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

        // 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

使用过程中出现的问题

(1)priority设置无效

运行时会发现设置priority优先级比LAUNCHER高,在开机之后也会提示让你选择打开应用,而不是默认打开优先级高的,关于这个问题,可以参考这篇文章
blog.csdn.net/ansondroide…
只需要把应用安装到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的