android开发详解

什么是OOBE 就是开机向导,在 Android 设备首次开机的时候,会先进行一系列的初始化,然后再进入主页。 初始化的操作一般有 登录或注册厂商账号、选择时区、选择语言等,TV的话还可能包括搜台等。 初始化的操作只在首次开机和安卓复位后才会出现,普通开关机不会出现。 源码的开机向导 8.0 源码

什么是OOBE

就是开机向导,在 Android 设备首次开机的时候,会先进行一系列的初始化,然后再进入主页。
初始化的操作一般有 登录或注册厂商账号、选择时区、选择语言等,TV的话还可能包括搜台等。
初始化的操作只在首次开机和安卓复位后才会出现,普通开关机不会出现。

源码的开机向导

8.0 源码 packages/apps/Provision
查看注册文件:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.provision">

    <original-package android:name="com.android.provision" />

    <!-- For miscellaneous settings -->
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />

    <application>
        <activity android:name="DefaultActivity"
                android:excludeFromRecents="true">
            <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.DEFAULT" />
                <category android:name="android.intent.category.SETUP_WIZARD" />
            </intent-filter>
        </activity>
    </application>
</manifest>

设置了 android:priority="1" ,值越大优先级越高,取值 -1000 ~~ 1000 。
这个应用也有 android.intent.category.HOME 属性,表明它也是主页应用,且优先级比主页高。为什么比主页高,因为主页没有设置 android:priority 属性,默认0 。

提一下, 6.0 的 Provision 源码并没有
<category android:name="android.intent.category.SETUP_WIZARD" />
在 8.0 上不加 <category android:name="android.intent.category.SETUP_WIZARD" /> 也没问题。
查看源码的 Launcher2 、Launcher3 ,确实没有配置 android:priority 属性。

<application
        android:name="com.android.launcher2.LauncherApplication"
        android:label="@string/application_name"
        android:icon="@mipmap/ic_launcher_home"
        android:hardwareAccelerated="true"
        android:largeHeap="@bool/config_largeHeap"
        android:supportsRtl="true">
        <activity
            android:name="com.android.launcher2.Launcher"
            android:launchMode="singleTask"
            android:clearTaskOnLaunch="true"
            android:stateNotNeeded="true"
            android:resumeWhilePausing="true"
            android:theme="@style/Theme"
            android:windowSoftInputMode="adjustPan"
            android:screenOrientation="nosensor">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.MONKEY"/>
            </intent-filter>
        </activity>
        //其他的省略

源码开机向导只有一个 DefaultActivity, 看看都干了啥。

public class DefaultActivity extends Activity {

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

        // Add a persistent setting to allow other apps to know the device has been provisioned.
        Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
        Settings.Secure.putInt(getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1);

        // remove this activity from the package manager.
        PackageManager pm = getPackageManager();
        ComponentName name = new ComponentName(this, DefaultActivity.class);
        pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);

        // terminate the activity.
        finish();
    }
}

首先, 把 DEVICE_PROVISIONEDUSER_SETUP_COMPLETE 置为 1 ,告诉其他应用初始化完毕。
然后用 PackageManager 把自己 disable 掉,这样此应用就不可用,不会再出现了。
如果要使 Provision 可用,pm.setComponentEnabledSetting 传入 COMPONENT_ENABLED_STATE_ENABLED 即可。
安卓复位后 Provision 会重新可用,为什么,后续分析。

然后,并没有用

按照如上操作开发了 OOBE 后,并没有达到理想效果,出现了选择主页的弹窗,why ?
参考这篇博客 https://juejin.im/post/5cc165946fb9a031ec6d2ab8 ,找到了思路。

我原先把 OOBE 放到 system/app/ 目录, 尝试把 OOBE 放到 system/priv-app/ 目录,两个目录的差别是 system/priv-app/ 目录权限更高,这样 android:priority=“1” 就有效了。

如何把 OOBE 放到 system/priv-app/ 目录

我用的是源码编译,修改 OOBE 的 Android.mk 文件,添加

LOCAL_PRIVILEGED_MODULE := true

这个表示把这个 app 放到 system/priv-app/ 目录;
如果不设置 或者 设为 false ,则是放到 system/app/ .
烧录测试,OK。

知秋君
上一篇 2024-07-15 09:02
下一篇 2024-07-15 08:36

相关推荐