Android10定制Google开机向导 您所在的位置:网站首页 关闭android设置向导通知 Android10定制Google开机向导

Android10定制Google开机向导

2024-02-15 09:19| 来源: 网络整理| 查看: 265

文章目录 1.简介2.修改wizard_script.xml3.编写自己的Activity3.1 AndroidManifest.xml声明action3.2 如何退出Activity 4 开机向导调试方法

1.简介

Google开机向导com.google.android.setupwizard是没有源码的,但Google提供了客制化接口,可以做OEM定制。开机向导应用以APK的形式存放在vendor/partner_gms/apps/SetupWizard

下面以Android10为例,讲述开机向导客制化的方法。

2.修改wizard_script.xml

vendor/partner_gms/apps/GmsSampleIntegration/res/raw/wizard_script.xml

--- a/idh.code/vendor/partner_gms/apps/GmsSampleIntegration/res/raw/wizard_script.xml +++ b/idh.code/vendor/partner_gms/apps/GmsSampleIntegration/res/raw/wizard_script.xml @@ -190,11 +190,13 @@ + +

参考oem_post_setup,在后面添加自定义的action。注意,如果客制化应用有多个Activity,就要在这里定义多个action,不能在自己的应用内跳转!

3.编写自己的Activity

怎样编写Activity属于应用开发,不是本篇讨论的范畴。我们主要看下如何才能将自己的Activity添加到开机向导。

3.1 AndroidManifest.xml声明action

测试一下,看看能否通过命令调起这个Activity:

am start -a com.android.setupwizard.MY_POST_SETUP

到这一步,客制化Activity已经成功地添加到开机向导了,它将在Google开机向导的最后一步被调起。但还有一个问题,此时无法退出开机向导。

3.2 如何退出Activity

(1) 首先想到的是finish()。然而事与愿违,finish()是不行的。测试结果:finish()结束了当前Activity之后,会跳回上一个页面,而不是结束开机向导;此时点击下一步,又进入了客制化Activity;这样就进入了死循环,开机向导永远无法结束。

(2) 参考博客 https://blog.csdn.net/u012824529/article/details/90109914 添加下面这段跳转代码,实测点击跳转,开机向导会crash。看来Android10已经不能这么干了(其他Android版本没有验证)。

// Google Wizard Manager Constants private static final String ACTION_NEXT = "com.android.wizard.NEXT"; private static final String EXTRA_ACTION_ID = "actionId"; private static final String EXTRA_SCRIPT_URI = "scriptUri"; private static final String EXTRA_RESULT_CODE = "com.android.setupwizard.ResultCode"; public static void onNext(Intent intent, Activity activity, int resultCode) { Intent nextIntent = new Intent(ACTION_NEXT); nextIntent.putExtra(EXTRA_SCRIPT_URI, intent.getStringExtra(EXTRA_SCRIPT_URI)); nextIntent.putExtra(EXTRA_ACTION_ID, intent.getStringExtra(EXTRA_ACTION_ID)); nextIntent.putExtra(EXTRA_THEME, intent.getStringExtra(EXTRA_THEME)); nextIntent.putExtra(EXTRA_RESULT_CODE, resultCode); activity.startActivityForResult(nextIntent, 10000); }

(3) 正确的跳转办法,使用Android原生方法WizardManagerHelper.getNextIntent

class MyClickListner implements OnClickListener { @Override public void onClick(View v) { switch (v.getId()) { case R.id.button: try { onNext(Activity.RESULT_OK); } catch (Exception e) { e.printStackTrace(); } break; default: break; } } } public void onNext(int requestCode) { int resultCode = Activity.RESULT_OK; Intent intent = WizardManagerHelper.getNextIntent(getIntent(), resultCode); try { startActivityForResult(intent, requestCode); } catch (ActivityNotFoundException e) { Log.e(TAG, e.getMessage()); } }

关键代码是这句:

Intent intent = WizardManagerHelper.getNextIntent(getIntent(), resultCode);

代码位于frameworks/opt/setupwizard/library/main/src/com/android/setupwizardlib/util/WizardManagerHelper.java

遗憾的是,这个方法没有开放到sdk里面供普通应用使用。既然没法直接调用,我们就把它抽出来,做成一个工具类吧。

自定义WizardManagerHelper.java

package com.my.mysetupwizard; import java.util.Arrays; import android.content.Intent; public 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)); } } } 4 开机向导调试方法

开机向导只在首次开机时启动,想要再次启动开机向导,只能重刷固件或者恢复出厂设置,这个太麻烦了,不适合调试。

Google开机向导SetupWizard没有源码,不好分析。我们从Android原生开机向导Provision的代码里面得到了一些信息。

packages/apps/Provision/src/com/android/provision/DefaultActivity.java

private void setProvision() { // 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(); }

可见,完成开机向导的时候,做了3件事,

(1) Settings.Global.DEVICE_PROVISIONED 设置为1;

(2) Settings.Secure.USER_SETUP_COMPLETE 设置为1;

(3) DISABLE自己。

根据以上分析,想要使能开机向导,我们做一下这3件事的反向操作,就可以了。

1.通过命令使能开机向导 adb shell settings put global device_provisioned 0 settings put secure user_setup_complete 0 pm enable com.google.android.setupwizard/com.google.android.setupwizard.SetupWizardActivity sync reboot 2.查询settings的值 settings get global device_provisioned settings get secure user_setup_complete 3.通过代码实现 +Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0); +Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 0); +ComponentName name = new ComponentName("com.google.android.setupwizard", "com.google.android.setupwizard.SetupWizardActivity"); +mContext.getPackageManager().setComponentEnabledSetting(name,PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有