Android 开机向导定制
采用 rro_overlays 机制来定制开机向导,定制文件如下:
GmsSampleIntegrationOverlay$ tree
.
├── Android.bp
├── AndroidManifest.xml
└── res
└── raw
├── wizard_script_common_flow.xml
├── wizard_script_customize_flow.xml
└── wizard_script.xml
Android.bp
runtime_resource_overlay {
name: "GmsSampleIntegrationOverlay",
product_specific: true,
}
在项目对应的.mk 文件添加编译引用
makefile
PRODUCT_PACKAGES += \
GmsSampleIntegrationOverlay
AndroidManifest.xml
xml
<?xml version="1.0" encoding="utf-8"?>
<!--
#/*
# * Copyright (C) 2023 Lens Technology (Xiangtan) Co.,Ltd, All rights reserved.
# * Author: XT900109
# */
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xxxx.gmssampleintegrationsoverlay"
android:versionCode="1"
android:versionName="1.0">
<application android:hasCode="false" />
<overlay android:targetPackage="com.google.android.gmsintegration"
android:priority="0"
android:isStatic="true" />
</manifest>
rro_overlays/GmsSampleIntegrationOverlay/res/raw/wizard_script_lens_customize_flow.xml
自定义 wizard_script_customize_flow.xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
The wizard:uris recorded here have the inconvenience of being generated by hand, but they allow
for the full spread of launch flags (we need FLAG_ACTIVITY_NEW_TASK [0x10000000]), where the
<intent> tag processed by Intent.parseIntent() does not.
adb shell am to-intent-uri -a com.android.setupwizard.WELCOME -f 0x10000000 \-\-ez firstRun true
-->
<WizardScript xmlns:wizard="http://schemas.android.com/apk/res/com.google.android.setupwizard"
wizard:firstAction="user_terms_of_service1">
<WizardAction id="user_terms_of_service1"
wizard:uri="intent:#Intent;action=com.android.setupwizard.USER_TERMS_OF_SERVICE;end" >
<result wizard:action="user_service_notice" />
</WizardAction>
<WizardAction id="user_service_notice"
wizard:uri="intent:#Intent;action=com.android.setupwizard.USER_SETUP_FINISH;end" >
</WizardAction>
<!-- <WizardAction id="END_OF_SCRIPT"
wizard:uri="intent:#Intent;action=com.android.setupwizard.EXIT;end" />-->
</WizardScript>
在 wizard_script_common_flow.xml 文件里面添加引用
xml
<WizardAction id="user_terms_of_service"
wizard:script="android.resource://com.xxxx.gmssampleintegrationsoverlay/raw/wizard_script_customize_flow">
</WizardAction>
注意这里的 com.xxxx.gmssampleintegrationsoverlay 需要对应上面AndroidManifest.xml package
xml
<!-- Set screen lock options. The action must precede the payments action [RECOMMENDED, CUSTOMIZABLE] -->
<WizardAction id="lock_screen"
wizard:uri="intent:#Intent;action=com.google.android.setupwizard.LOCK_SCREEN;end" >
</WizardAction>
<!-- MY completion [CUSTOMIZABLE] -->
<WizardAction id="user_terms_of_service"
wizard:script="android.resource://com.xxxx.gmssampleintegrationsoverlay/raw/wizard_script_customize_flow">
</WizardAction>
<!-- Labeled end of script (for branching) [RECOMMENDED, CUSTOMIZABLE] -->
<WizardAction id="END_OF_SCRIPT" />
定义 com.android.setupwizard.USER_TERMS_OF_SERVICE
在项目的 AndroidManifest.xml
xml
<activity android:name=".setupwizard.SetupWFinishActivity"
android:exported="true" >
<intent-filter>
<action android:name="com.android.setupwizard.USER_SETUP_FINISH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
SetupWFinishActivity.java
java
package com.android.settings.setupwizard;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import com.android.settings.R;
public class SetupWFinishActivity extends Activity {
public static final String TAG = "SetupWFinishActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().setStatusBarColor(Color.WHITE);
getWindow().setNavigationBarColor(Color.WHITE);
getWindow().setNavigationBarDividerColor(Color.WHITE);
getActionBar().hide();
setContentView(R.layout.activity_setup_wfinish);
findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//: TODO
onNext();
}
});
}
public void onNext() {
int resultCode = Activity.RESULT_OK;
Intent intent = WizardManagerHelper.getNextIntent(getIntent(), resultCode);
Log.e(TAG, "onNext() intent:" + intent);
try {
startActivityForResult(intent, Activity.RESULT_OK);
} catch (ActivityNotFoundException e) {
Log.e(TAG, e.getMessage());
}
Intent returnIntent = new Intent();
setResult(Activity.RESULT_OK,returnIntent);
finish();
}
}
WizardManagerHelper的实现
java
static class WizardManagerHelper {
private static final String ACTION_NEXT = "com.android.wizard.NEXT";
static final String EXTRA_SCRIPT_URI = "scriptUri";
static final String EXTRA_ACTION_ID = "actionId";
private static final String EXTRA_RESULT_CODE = "com.android.setupwizard.ResultCode";
public static final String EXTRA_THEME = "theme";
static final String EXTRA_WIZARD_BUNDLE = "wizardBundle";
static final String EXTRA_IS_FIRST_RUN = "firstRun";
static final String EXTRA_IS_DEFERRED_SETUP = "deferredSetup";
static final String EXTRA_IS_PRE_DEFERRED_SETUP = "preDeferredSetup";
public static final String EXTRA_IS_SETUP_FLOW = "isSetupFlow";
public static Intent getNextIntent(Intent originalIntent, int resultCode) {
return getNextIntent(originalIntent, resultCode, null);
}
public static Intent getNextIntent(Intent originalIntent, int resultCode, Intent data) {
Intent intent = new Intent(ACTION_NEXT);
copyWizardManagerExtras(originalIntent, intent);
intent.putExtra(EXTRA_RESULT_CODE, resultCode);
if (data != null && data.getExtras() != null) {
intent.putExtras(data.getExtras());
}
intent.putExtra(EXTRA_THEME, originalIntent.getStringExtra(EXTRA_THEME));
return intent;
}
public static void copyWizardManagerExtras(Intent srcIntent, Intent dstIntent) {
dstIntent.putExtra(EXTRA_WIZARD_BUNDLE, srcIntent.getBundleExtra(EXTRA_WIZARD_BUNDLE));
for (String key :
Arrays.asList(
EXTRA_IS_FIRST_RUN,
EXTRA_IS_DEFERRED_SETUP,
EXTRA_IS_PRE_DEFERRED_SETUP,
EXTRA_IS_SETUP_FLOW)) {
dstIntent.putExtra(key, srcIntent.getBooleanExtra(key, false));
}
for (String key : Arrays.asList(EXTRA_THEME, EXTRA_SCRIPT_URI, EXTRA_ACTION_ID)) {
dstIntent.putExtra(key, srcIntent.getStringExtra(key));
}
}
}