Android ROM开发之定制Google SetupWizard

之前的博客Android ROM开发之预制GMS 给自己挖了一个坑——针对定制GMS会另写一篇,本篇补坑。定制GMS本身是一个很广泛的问题,简单的如根据需求取舍GMS包中的某些应用,复杂点的如定制Chrome的书签,主页,设置项等。本篇拿如何定制Google SetupWizard(SUW)开刀,通过本篇也可看出Google是如何在不公开GMS代码的前提下给众多合作伙伴预留下可定制的方法的。

定制 SUW 需要了解下面的知识点

SUW 部分页面是可以在源码中实现的

SUW只在第一次开机才运行,通过它可以设置系统语言、时区、Wifi 开关、Google 帐号等,它是一个隶属与GMS包里的独立应用,但这个应用的某些页面是可以在源码中实现的。
Android ROM开发之定制Google SetupWizard_第1张图片
比如上面这个界面黑色框起来的部分就是在Settings下面实现的,这点是我在做Settins下的锁屏功能时发现的,Settings的锁屏一改动,上图的界面也跟着改变了,然后停在该界面用命令
adb shell dumpsys activity activities|grep mFocusedActivity
查看当前页面在哪个包中,输出信息如下:
mFocusedActivity: ActivityRecord{2a1f2a3b u0 com.android.settings/.SetupChooseLockGeneric t2}
原来发现它的实现类在Settings模块下的SetupChooseLockGeneric类中。

wizard_script配置文件

wizard_script 文件定义了 SUW 的页面跳转行为,要追加页面就需要更改 wizard_script 文件内容。这个信息Google在发布GMS包时会有专门文档做说明,由于牵涉保密性,这里无法共享出来了。wizard_script文件的内容形式如下:

<WizardAction wizard:uri="intent:#Intent;action=com.google.android.setupwizard.START_VPA;end" id="start_vpa">
    <result wizard:action="date_time" />
</WizardAction>
<WizardAction wizard:uri="intent:#Intent;action=com.android.setupwizard.DATE_TIME;end" id="date_time">
    <result wizard:action="user_name" />
</WizardAction>

WizardAction节点对应的就是SUW里面的一个页面,其中uri代表当前action可以处理的intent, id表示当前action,result代表点当前action跳转的目的action。

Runntime Resource Overlay(RRO)机制

这个知识点在Android 运行时资源替换—-Runtime Resource Overlay 这篇博文里介绍过,在此不重复介绍。

了解了上面的三个知识点,就可以通过RRO机制,替换掉原始SUW里面的wizard_script,从而使wizard_script能调用到我们在源码里添加的的intent。从而实现SUW的定制需求。下面开始上干货。

现在需求是在SUW WiFi 连接界面之后追加一个 SIM 卡数据设置界面。根据之前的三点知识。首先在Settings目录下编写新增的页面,java代码部分不是本篇重点,不贴出具体代码了,贴下在AndroidManifest.xml文件中注册intent的代码片段:

<activity  android:name="com.android.settings.SetupSetMobileData" android:taskAffinity="com.android.wizard" android:theme="@android:style/Theme.Material.Light.NoActionBar" android:configChanges="orientation|keyboardHidden|keyboard|screenSize" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.settings.SET_MOBILEDATA" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
</activity>

记住这里的android:name="android.settings.SET_MOBILEDATA"

然后准备修改wizard_script,按理说该文件Google会release给合作伙伴,但我在实际开发过程中邮件沟通了半天,也没有拿到,因此直接采取破解SUW获取wizard_script的暴力手段。破解SUW后直接grep关键字wizard_script,获取到如下信息:
<string name="wizard_script_uri">android.resource://com.google.android.setupwizard/xml/wizard_script</string>
打开xml/wizard_script文件进行修改,需求是在wifi页面后追加新页面,因此搜索关键字wifi,直觉定位到这个WizardAction

<WizardAction wizard:uri="intent:#Intent;action=com.android.setupwizard.WIFI_SETTINGS;end" id="wifi_settings"> 
    <result wizard:action="connection_check" /> 
</WizardAction>
<WizardAction wizard:uri="intent:#Intent;action=com.android.setupwizard.CONNECTION_CHECK;end" id="connection_check">
    <result wizard:resultCode="1" wizard:action="no_account_date_time" wizard:name="skip" />
    <result wizard:action="walled_garden" />
</WizardAction>

它原来的逻辑是wifi_settings界面之后,会跳转到connection_check。现在准备让wifi_settings这个action跳转到新增的SIM卡设置界面,SIM卡设置界面之后在跳转至connection_check,也就是在原来的页面里嵌入一个新增页面。根据wizard_script的规则,修改wizard_script文件。上面让记住的android:name="android.settings.SET_MOBILEDATA"这个新加的intent该用上了,修后的片段如下:

<WizardAction wizard:uri="intent:#Intent;action=com.android.setupwizard.WIFI_SETTINGS;end" id="wifi_settings"> 
        <result wizard:action="mobile_data_set" /> 
</WizardAction> 
<WizardAction wizard:uri="intent:#Intent;action=android.settings.SET_MOBILEDATA;end" id="mobile_data_set"> 
        <result wizard:action="connection_check" /> 
</WizardAction> 
<WizardAction wizard:uri="intent:#Intent;action=com.android.setupwizard.CONNECTION_CHECK;end" id="connection_check"> 
 <result wizard:resultCode="1" wizard:action="no_account_date_time" wizard:name="skip" /> 
        <result wizard:action="walled_garden" />
</WizardAction>

只修改需要的地方,其他内容原样保留。将这份修改后的wizard_script文件保存为wizard_script_user.xml。

最后该制作SetupWizardOverlay.apk了。overlay目录结构
Android ROM开发之定制Google SetupWizard_第2张图片
其中的AndroidManifest.xml文件内容

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.android.setupwizard.overlay"> 
    <overlay android:targetPackage="com.google.android.setupwizard" android:priority="1"/> 
</manifest> 

config.xml文件内容

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
<string name="wizard_script_uri" translatable="false">
"android.resource://com.google.android.setupwizard.overlay/raw/wizard_script_user.xml"
</string> 
</resources> 

这里用overlay apk下的raw/wizard_script_user.xml替换掉了原生的wizard_script文件。

最终的效果图如下:Android ROM开发之定制Google SetupWizard_第3张图片

你可能感兴趣的:(android,ROM)