Android的框架设计有考虑到开机向导这一场景,因此我们实现开机向导参考Android的Provision.apk
Provision: MSM8976/repo/packages/apps/Provision
它的主要作用是作为开机引导用户进行一些基本设置.在原生的 android 系统中,provision非常的简单,只有一个空白的 activity,这个主要就是留给 厂商自己定制开机向导(像 OPPO,VIVO,小米等厂商会让你登陆和注册其账号帐号,连接WiFi等),因此我们得理解Android的设计意图而进行定制.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tomorrow_p.setupwizard">
<!--android:sharedUserId="android.uid.system"-->
<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
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/setupwizard_AppTheme">
<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.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.tomorrow_p.setupwizard.SimActivity">
<intent-filter>
<action android:name="com.android.provision.SimActivity"></action>
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</activity>
<activity android:name="com.tomorrow_p.setupwizard.OpenActivity">
<intent-filter>
<action android:name="com.android.provision.OpenActivity"></action>
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</activity>
</application>
</manifest>
1. DefaultActivity是原生系统Provision中唯一的activity;配置了category.HOME属性,category.HOME是桌面程序的标记(Launcher程序都会配置);priority=1,配置优先级,这样就会在系统的Launcher之前启动.
2. Provision中的关键代码:
// 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, WelcomeActivity.class);
pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
这里代码主要设置DEVICE_PROVISIONED标记同时禁止本身Activity组件的功能
API:
void setComponentEnabledSetting (ComponentName componentName, int newState, int flags)
componentName:组件名称
newState:组件新的状态,可以设置三个值,分别是如下:
不可用状态:COMPONENT_ENABLED_STATE_DISABLED
可用状态:COMPONENT_ENABLED_STATE_ENABLED
默认状态:COMPONENT_ENABLED_STATE_DEFAULT
flags:行为标签,值可以是DONT_KILL_APP或者0. 0说明杀死包含该组件的app
主要代码:
以下代码有注释掉跳转到注册和登录账户模块以及调用系统的WiFi设置向导模块
同时需要配置系统签名以及系统应用标识
package com.tomorrow_p.setupwizard;
import android.content.ComponentName;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Locale;
public class DefaultActivity extends BaseActivity implements View.OnClickListener {
private static final String[] PLANETS = new String[]{"English", "简体中文", "繁体中文"};
private String mCurrentStatus = PLANETS[1];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().hide();
setContentView(R.layout.setupwizard_activity_default);
WheelView mWheelView = (WheelView) findViewById(R.id.wheelview);
mWheelView.setOffset(1