ATO版本上存在该问题,非ATO版本正常。
在Settings/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java下打印log,发现:
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!TextUtils.equals(preference.getKey(), KEY_BUILD_NUMBER)) {
return false;
}
if (Utils.isMonkeyRunning()) {
return false;
}
// Don't enable developer options for secondary non-demo users.
if (!(mUm.isAdminUser() || mUm.isDemoUser())) {
mMetricsFeatureProvider.action(
mContext, MetricsEvent.ACTION_SETTINGS_BUILD_NUMBER_PREF);
return false;
}
// Don't enable developer options until device has been provisioned
if (!Utils.isDeviceProvisioned(mContext)) {
mMetricsFeatureProvider.action(
mContext, MetricsEvent.ACTION_SETTINGS_BUILD_NUMBER_PREF);
return false;
}
......
如注释:Don't enable developer options until device has been provisioned,是Utils.isDeviceProvisioned()的值为false, 才return,导致无法开启开发者选项。
/frameworks/base/core/java/android/provider/Settings.java
public static boolean isDeviceProvisioned(Context context) {
return Settings.Global.getInt(context.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 0) != 0;
}
即是Settings.Global.DEVICE_PROVISIONED的值存在问题。
ATO版本 get device_provisioned 为 0,
非ATO版本 get device_provisioned 为 1.
查看device_provisioned 默认值,
/frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
loadBooleanSetting(stmt, Settings.Global.DEVICE_PROVISIONED,
R.bool.def_device_provisioned);
frameworks/base/packages/SettingsProvider/res/values/defaults.xml
<bool name="def_device_provisioned">false</bool>
可知该值默认为false,即0
搜全局看是哪个地方进行的修改.
/packages/apps/Provision/src/com/android/provision/DefaultActivity.java
/**
* Application that sets the provisioned bit, like SetupWizard does.
*/
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();
}
}
Provision这个APK,可能很多人都不知道有这个APK存在。Provision的作用很简单,就是一个系统初始化引导程序,原生的Android里面Provision只做了一件事,就是写入一个DEVICE_PROVISIONED标记。不过这个标记作用很大,这个标记只会在系统全新升级(双清)的时候写入一次,代表了Android系统升级准备完成,可以正常工作。
从这可以看出,是因为ATO版本没有系统初始化引导程序导致的,我们知道,无论是客制化的SetupWizard还是Google的SetupWizard, 都会在Android.mk文件中声明去覆盖此apk。在自己的apk中也会进行写入一个DEVICE_PROVISIONED标记的动作。
查看客制化的SetupWizard Android.mk文件可发现,存在:
LOCAL_OVERRIDES_PACKAGES := Provision
因为在ATO版本时不编译SetupWizard,而LOCAL_OVERRIDES_PACKAGES后,Provision也不会生效,才导致此值未被写入,故注释掉这条即可。