Setting显示开发者选项的逻辑
默认User版本没有“开发者选项”,我们可以通过点击版本号7次来显示开发者模式,今天来看下代码中是如何处理的:
首先是packages/apps/Settings/src/com/android/settings/Settings.java的初始化处理:
布尔值showDev是否默认显示“开发者选项”:
final boolean showDev = mDevelopmentPreferences.getBoolean(
DevelopmentSettings.PREF_SHOW,
android.os.Build.TYPE.equals(“eng”));
如果想让开发者选项默认显示,不需要点击7次版本号,可直接将showDev置为true即可:
final boolean showDev = true;
如果showDev为false,则在如下代码中隐藏“开发者选项”:
if (id == R.id.development_settings) {
if (!showDev) {
target.remove(i);
}
}
下面看一下点击版本号显示开发者选项的部分:
代码路径:packages/apps/Settings/src/com/android/settings/DeviceInfoSettings.java
首先是定义点击次数:
static final int TAPS_TO_BE_A_DEVELOPER = 7;
点击版本号的处理逻辑,若mDevHitCountdown小于0,则表示”开发者选项“已经显示,参考Resume函数的处理:
if (preference.getKey().equals(KEY_BUILD_NUMBER)) {
// Don’t enable developer options for secondary users.
if (UserHandle.myUserId() != UserHandle.USER_OWNER) return true;
if (mDevHitCountdown > 0) {
if (mDevHitCountdown == 1) {
if (super.ensurePinRestrictedPreference(preference)) {
return true;
}
}
mDevHitCountdown–;
if (mDevHitCountdown == 0) {
getActivity().getSharedPreferences(DevelopmentSettings.PREF_FILE,
Context.MODE_PRIVATE).edit().putBoolean(
DevelopmentSettings.PREF_SHOW, true).apply();
if (mDevHitToast != null) {
mDevHitToast.cancel();
}
mDevHitToast = Toast.makeText(getActivity(), R.string.show_dev_on,
Toast.LENGTH_LONG);
mDevHitToast.show();
} else if (mDevHitCountdown > 0
&& mDevHitCountdown < (TAPS_TO_BE_A_DEVELOPER-2)) {
if (mDevHitToast != null) {
mDevHitToast.cancel();
}
mDevHitToast = Toast.makeText(getActivity(), getResources().getQuantityString(
R.plurals.show_dev_countdown, mDevHitCountdown, mDevHitCountdown),
Toast.LENGTH_SHORT);
mDevHitToast.show();
}
} else if (mDevHitCountdown < 0) {
if (mDevHitToast != null) {
mDevHitToast.cancel();
}
mDevHitToast = Toast.makeText(getActivity(), R.string.show_dev_already,
Toast.LENGTH_LONG);
mDevHitToast.show();
}
}
Resume函数:
@Override
public void onResume() {
super.onResume();
PreferenceGroup parentPreference = getPreferenceScreen();
mDevHitCountdown = getActivity().getSharedPreferences(DevelopmentSettings.PREF_FILE,
Context.MODE_PRIVATE).getBoolean(DevelopmentSettings.PREF_SHOW,
android.os.Build.TYPE.equals(“eng”)) ? -1 : TAPS_TO_BE_A_DEVELOPER;
mDevHitToast = null;
}
Setting的默认初始配置
frameworks/base/packages/SettingsProvider/res/values/default.xml
这里貌似可以修改很多东西,但要在
frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
中初始化才会生效:
true
/mnt/sdcard
true
60000
false
cell,bluetooth,wifi,nfc,wimax
bluetooth,wifi,nfc
true
true
true
102
false
100%
100%
true
false
false
false
true
true
true
true
false
0
true
false
com.google.android.backup/.BackupTransportService
true
true
false
true
true
1
/system/media/audio/ui/LowBattery.ogg
0
/system/media/audio/ui/Dock.ogg
/system/media/audio/ui/Undock.ogg
/system/media/audio/ui/Dock.ogg
/system/media/audio/ui/Undock.ogg
1
/system/media/audio/ui/Lock.ogg
/system/media/audio/ui/Unlock.ogg
/system/media/audio/ui/WirelessChargingStarted.ogg
false
false
1
true
true
false
false
0x13=0x01000100;
0x14=0x01010100;
0x15=0x02000001;
0x16=0x02010001;
0x200000013=0x02000601;
0x200000014=0x02010601;
0x200000015=0x03020101;
0x200000016=0x03010201;
0x200000023=0x02000301;
0x200000024=0x02010301;
0x200000037=0x03070201;
0x200000038=0x03000701:0x03010701:0x03020701;
https://ssl.gstatic.com/accessibility/javascript/android/AndroidVox_v1.js
false
200%
false
true
0
-1
-1
500
0
true
false
false
9
false
0
当然还有mtk_default.xml
修改完成后,在
frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
中的 private void loadGlobalSettings(SQLiteDatabase db) { … … }函数中增加初始化数据库的值:
然后执行:
./mk -t mm frameworks/base/packages/SettingsProvider/
生成目录:
out/target/product/esky82_tb_cn_kk/system/priv-app/SettingsProvider.apk
删除设置中情景模式的震动选项(会议模式和户外模式)
packages/apps/Settings/res/xml/audioprofile_settings.xml
注释掉会议模式和户外模式
packages/apps/Settings/res/xml/edit_profile_prefs.xml
注释掉:
<PreferenceCategory
android:key=“general”
android:title=“@string/sound_category_sound_title”/>
<com.mediatek.audioprofile.RingerVolumePreference
android:key=“ring_volume”
android:title=“@string/all_volume_title”
android:dialogTitle=“@string/all_volume_title”
android:persistent=“false”/>
packages/apps/Settings/src/com/medietek/audrioprofile/AduioProfileSettings.java
注释掉public void onCreate(Bundle icicle) {}中以下几行代码:
//pref = (AudioProfilePreference) findPreference(MEETING_PREF_KEY);
//pref.setOnSettingsClickListener(mProfileSettingListener);
//pref = (AudioProfilePreference) findPreference(OUTDOOR_PREF_KEY);
//pref.setOnSettingsClickListener(mProfileSettingListener);
或者改成以下:
这个方案得:import android.os.SystemProperties;
if (!SystemProperties.get(“ro.project.target”).equals(“es706”)) {
// Do nothing
} else {
pref = (AudioProfilePreference) findPreference(MEETING_PREF_KEY);
pref.setOnSettingsClickListener(mProfileSettingListener);
pref = (AudioProfilePreference) findPreference(OUTDOOR_PREF_KEY);
pref.setOnSettingsClickListener(mProfileSettingListener);
}
packages/apps/Settings/src/com/medietek/audrioprofile/Editprofile.java
private void initPreference() {}中注释以下:
// mVibrat = (CheckBoxPreference) findPreference(KEY_VIBRATE);
… …
// mVibrat.setEnabled(false);
还有这里,总之搜索mVibrat的结果都注释掉或者加个判断:
if (!isSmsCapable()) {
// parent.removePreference(mVibrat);
}
private void updatePreference() {
// mVibrat.setChecked(mProfileManager.getVibrationEnabled(mKey));
… …
还有这一大段:
// if (mVibrat != null) {
// final String name = AudioProfileManager.getVibrationKey(mKey);
// Xlog.d(TAG,"name " + name);
// String vibrateEnabled = Settings.System.getString(
// getContentResolver(), name);
// if (vibrateEnabled != null) {
// mVibrat.setChecked(“true”
// .equals(vibrateEnabled));
// Xlog.d(TAG,
// "vibrate setting is "
// + “true”.equals(vibrateEnabled));
// }
//
// }
还有:
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
Preference preference) {
Xlog.d(TAG, “Key :” + preference.getKey());
// if ((preference.getKey()).equals(KEY_VIBRATE)) {
// boolean isVibrate = mVibrat.isChecked();
// Xlog.d(TAG, “set vibrate” + isVibrate);
// mProfileManager.setVibrationEnabled(mKey, isVibrate);
// } else
显示设置中增加“永不休眠”功能
首先在frameworks\base\packages\SettingsProvider\res\values\defaults.xml中设置def_screen_off_timeout为-1,即
-1
然后修改alps\packages\apps\Settings\res\values\arrays.xml:
15 seconds
30 seconds
1 minute
2 minutes
10 minutes
30 minutes
never
15000
30000
60000
120000
600000
1800000
-1
接着修改对比语言value文件夹下的arrays.xml, 修改screen_timeout_entries对应的翻译。不用管那个msgid,只是google用来表示是他自己的资源而已,直接添加“永不休眠”即可。
然后是代码的改动:
frameworks/base/services/java/com/android/server/power/PowerManagerService.java
private void updateUserActivitySummaryLocked(long now, int dirty) {
…
//change code here ==============
Slog.d(TAG,“mScreenOffTimeoutSetting =”+mScreenOffTimeoutSetting);
//if (mUserActivitySummary != 0 ) {
if (mUserActivitySummary != 0 && mScreenOffTimeoutSetting > 0) {
//change code here end ==============
Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, nextTimeout);
}
Android修改应用的默认安装位置
Google默认的PackageManager,会读取应用AndroidManifest.xml的对应定义
installLocation规则如下:
1.如果没有定义安装位置,表示安装在手机内存上;
2.android:installLocation =“auto” :先查看手机内存是否足够,如果够就安装在手机内存上,不够就安装在T 卡上;
3.android:installLocation = “internalOnly”:表示安装在手机内存上;
4.android:installLocation = “preferExternal”:表示安装在 T 卡上;
如何在设置中增加“选取应用安装位置”的功能,让用户选择默认的安装位置?
修改如下文件:frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
将
loadSetting(stmt, Global.SET_INSTALL_LOCATION, 0);
改为:
loadSetting(stmt, Secure.SET_INSTALL_LOCATION, 1);
并将
loadSetting(stmt, Settings.Secure.SET_INSTALL_LOCATION, 0);
改为:
loadSetting(stmt, Settings.Secure.SET_INSTALL_LOCATION, 1);
这样修改之后,在设置>应用中会出现“选取应用安装位置”的功能,不过无论在这里选择什么,对于应用中AndroidManifest.xml文件中声明
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
ackages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
将
loadSetting(stmt, Global.SET_INSTALL_LOCATION, 0);
改为:
loadSetting(stmt, Secure.SET_INSTALL_LOCATION, 1);
并将
loadSetting(stmt, Settings.Secure.SET_INSTALL_LOCATION, 0);
改为:
loadSetting(stmt, Settings.Secure.SET_INSTALL_LOCATION, 1);
这样修改之后,在设置>应用中会出现“选取应用安装位置”的功能,不过无论在这里选择什么,对于应用中AndroidManifest.xml文件中声明
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-NdIgdplg-1714933054950)]
[外链图片转存中…(img-iGHdGi4g-1714933054950)]
[外链图片转存中…(img-YCf0yWmR-1714933054950)]
[外链图片转存中…(img-iPhoV22E-1714933054950)]
[外链图片转存中…(img-tGNXL6PL-1714933054951)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!