Android 在frameworks中修改Setting中的默认值 (二)
修改设置->关于手机->法律信息 下有一些Item,如开放源代码许可、Google法律信息等,这里分析的是Android 4.4的代码
如下图所示,想添加“Google法律信息”选项
查看Settings的源码在/Settings/src/com/android/settings/DeviceInfoSettings.java文件初始化时有这样一段代码
@Override public void onCreate(Bundle icicle) { super.onCreate(icicle); addPreferencesFromResource(R.xml.device_info_settings); //............................................省略 /* * Settings is a generic app and should not contain any device-specific * info. */ final Activity act = getActivity(); // These are contained in the "container" preference group PreferenceGroup parentPreference = (PreferenceGroup) findPreference(KEY_CONTAINER); Utils.updatePreferenceToSpecificActivityOrRemove(act, parentPreference, KEY_TERMS, Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY); Utils.updatePreferenceToSpecificActivityOrRemove(act, parentPreference, KEY_LICENSE, Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY); Utils.updatePreferenceToSpecificActivityOrRemove(act, parentPreference, KEY_COPYRIGHT, Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY); Utils.updatePreferenceToSpecificActivityOrRemove(act, parentPreference, KEY_TEAM, Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY); //..............................................省略 }看加载的资源文件device_info_settings.xml
<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2008 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:title="@string/about_settings"> <!-- System update settings - launches activity --> <PreferenceScreen android:key="system_update_settings" android:title="@string/system_update_settings_list_item_title" android:summary="@string/system_update_settings_list_item_summary"> <intent android:action="android.settings.SYSTEM_UPDATE_SETTINGS" /> </PreferenceScreen> <PreferenceScreen android:key="software_update" android:title="@string/software_update"> </PreferenceScreen> <PreferenceScreen android:key="mdm_fumo" android:title="@string/software_update"> </PreferenceScreen> <!-- MOTA --> <PreferenceScreen android:key="mtk_system_update"> <intent android:action="com.mediatek.intent.System_Update_Entry" /> </PreferenceScreen> <!-- software update service --> <PreferenceScreen android:key="scomo" android:title="@string/scomo_settings_title" android:summary="@string/software_updates_scomo_summary"> <intent android:action="android.intent.action.MAIN" android:targetPackage="com.mediatek.dm" android:targetClass="com.mediatek.dm.scomo.DmScomoActivity" /> </PreferenceScreen> <PreferenceScreen android:key="mdm_scomo" android:summary="@string/software_updates_scomo_summary" android:title="@string/scomo_settings_title"> <intent android:action="android.intent.action.MAIN" android:targetClass="com.mediatek.mediatekdm.scomo.DmScomoActivity" android:targetPackage="com.mediatek.mediatekdm" /> </PreferenceScreen> <PreferenceScreen android:key="additional_system_update_settings" android:title="@string/additional_system_update_settings_list_item_title"> <intent android:action="android.intent.action.MAIN" android:targetPackage="@string/additional_system_update" android:targetClass="@string/additional_system_update_menu" /> </PreferenceScreen> <!-- More Software updates - launches activity --> <PreferenceScreen android:key="more_software_updates" android:title="@string/software_updates_more_title" android:summary="@string/software_updates_more_summary"> <intent android:targetPackage="com.android.settings" android:targetClass="com.mediatek.settings.deviceinfo.SoftwareUpdates" /> </PreferenceScreen> <!-- Device status - launches activity --> <PreferenceScreen android:key="status_info" android:title="@string/device_status" android:summary="@string/device_status_summary"> <intent android:action="android.intent.action.MAIN" android:targetPackage="com.android.settings" android:targetClass="com.android.settings.deviceinfo.Status" /> </PreferenceScreen> <!-- Gemini Device status - launches Gemini activity --> <PreferenceScreen android:key="status_info_gemini" android:title="@string/device_status" android:summary="@string/device_status_summary"> <intent android:action="android.intent.action.MAIN" android:targetPackage="com.android.settings" android:targetClass="com.mediatek.settings.deviceinfo.StatusGemini" /> </PreferenceScreen> <!-- Legal Information --> <PreferenceScreen android:key="container" android:title="@string/legal_information"> <!-- Note: The titles given here probably won't be used. Instead, we programmatically fill the title with the label of the activity with the corresponding action. If there is not an activity for an action, the item will be removed from the list. --> <!-- Copyright information --> <PreferenceScreen android:key="copyright" android:title="@string/copyright_title"> <intent android:action="android.settings.COPYRIGHT" /> </PreferenceScreen> <!-- License information --> <PreferenceScreen android:key="license" android:title="@string/license_title"> <intent android:action="android.settings.LICENSE" /> </PreferenceScreen> <!-- Terms and conditions --> <PreferenceScreen android:key="terms" android:title="@string/terms_title"> <intent android:action="android.settings.TERMS" /> </PreferenceScreen> </PreferenceScreen> <PreferenceScreen android:key="safetylegal" android:title="@string/settings_safetylegal_title"> <intent android:action="android.settings.SAFETY" /> </PreferenceScreen> <!-- Contributors --> <!-- <PreferenceScreen android:key="contributors" android:title="@string/contributors_title"> <intent android:action="android.settings.TEAM" /> </PreferenceScreen> --> <PreferenceScreen android:key="regulatory_info" android:title="@string/regulatory_information"> <intent android:action="android.settings.SHOW_REGULATORY_INFO" /> </PreferenceScreen> <!-- Device hardware model --> <Preference android:key="device_model" style="?android:preferenceInformationStyle" android:title="@string/model_number" android:summary="@string/device_info_default" /> <!-- Device firmware version --> <Preference android:key="firmware_version" style="?android:preferenceInformationStyle" android:title="@string/firmware_version" android:summary="@string/device_info_default" /> <!-- Device FCC equipment id --> <Preference android:key="fcc_equipment_id" style="?android:preferenceInformationStyle" android:title="@string/fcc_equipment_id" android:summary="@string/device_info_default" /> <!-- Device Baseband version --> <Preference android:key="baseband_version" style="?android:preferenceInformationStyle" android:title="@string/baseband_version" android:summary="@string/device_info_default" /> <!-- Device 2nd Baseband version --> <Preference android:key="baseband_version_2" style="?android:preferenceInformationStyle" android:title="@string/baseband_version" android:summary="@string/device_info_default" /> <!-- Device Kernel version --> <Preference android:key="kernel_version" style="?android:preferenceInformationStyle" android:title="@string/kernel_version" android:summary="@string/device_info_default" /> <!-- Detailed build version --> <Preference android:key="build_number" style="?android:preferenceInformationStyle" android:title="@string/build_number" android:summary="@string/device_info_default" /> <!-- Detailed customer build version --> <Preference android:key="custom_build_version" style="?android:preferenceInformationStyle" android:title="@string/custom_build_version" android:summary="@string/device_info_default" /> <!-- SELinux status information --> <Preference android:key="selinux_status" style="?android:preferenceInformationStyle" android:title="@string/selinux_status" android:summary="@string/selinux_status_enforcing" /> </PreferenceScreen>在这个xml中配置的Action就是整个《关于手机》上的所有Item,从上面的信息中可以找到《法律信息》选项,有三个子项目
<!-- Legal Information --> <PreferenceScreen android:key="container" android:title="@string/legal_information"> <!-- Note: The titles given here probably won't be used. Instead, we programmatically fill the title with the label of the activity with the corresponding action. If there is not an activity for an action, the item will be removed from the list. --> <!-- Copyright information --> <PreferenceScreen android:key="copyright" android:title="@string/copyright_title"> <intent android:action="android.settings.COPYRIGHT" /> </PreferenceScreen> <!-- License information --> <PreferenceScreen android:key="license" android:title="@string/license_title"> <intent android:action="android.settings.LICENSE" /> </PreferenceScreen> <!-- Terms and conditions --> <PreferenceScreen android:key="terms" android:title="@string/terms_title"> <intent android:action="android.settings.TERMS" /> </PreferenceScreen> </PreferenceScreen>以上选项是否会显示出来是由updatePreferenceToSpecificActivityOrRemove函数处理,这个函数在/Settings/src/com/android/settings/Utils.java
public static boolean updatePreferenceToSpecificActivityOrRemove(Context context, PreferenceGroup parentPreferenceGroup, String preferenceKey, int flags) { Preference preference = parentPreferenceGroup.findPreference(preferenceKey); if (preference == null) { return false; } Intent intent = preference.getIntent(); if (intent != null) { // Find the activity that is in the system image PackageManager pm = context.getPackageManager(); List<ResolveInfo> list = pm.queryIntentActivities(intent, 0); int listSize = list.size(); for (int i = 0; i < listSize; i++) { ResolveInfo resolveInfo = list.get(i); if ((resolveInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { // Replace the intent with this specific activity preference.setIntent(new Intent().setClassName( resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name)); if ((flags & UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY) != 0) { // Set the preference title to the activity's label preference.setTitle(resolveInfo.loadLabel(pm)); } return true; } } } // Did not find a matching activity, so remove the preference parentPreferenceGroup.removePreference(preference); return false; }如在Settings中会调用
Utils.updatePreferenceToSpecificActivityOrRemove(act, parentPreference, KEY_TERMS, Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY);
去查找是否存在安装在/system/app/目录下对应的Action,如果存在就不处理,否则就不显示该Item。
目前我的手机上没有显示《Google法律信息》选项,说明没有找到注册“android.settings.TERMS”这个Action的Activity,就不显示该Item,我们可以写个测试程序,去注册“android.settings.TERMS”
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.cts_7301" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="19" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.cts_7301.activi" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.example.cts_7301.termsActivity" > <intent-filter> <action android:name="android.settings.TERMS" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> </application> </manifest>然后把这个Apk安装到/system/app/目录下
dzt@dzt-All-Series:~/workspace/cts_7301/bin$ ls AndroidManifest.xml classes classes.dex cts_7301.apk dexedLibs res resources.ap_ dzt@dzt-All-Series:~/workspace/cts_7301/bin$ adb push cts_7301.apk /system/app/ 3474 KB/s (549968 bytes in 0.154s) dzt@dzt-All-Series:~/workspace/cts_7301/bin$ adb push cts_7301.apk /system/app/ 3242 KB/s (549968 bytes in 0.165s) dzt@dzt-All-Series:~/workspace/cts_7301/bin$把Settings App完全关闭后再启动,此时就能看到刚刚注册的Action就能添加到Item
logcat
01-02 12:35:01.893 I/dzt (19718): ApplicationPackageManager---queryIntentActivitiesAsUser intent = Intent { act=android.settings.TERMS } flags = 0 userId = 0 01-02 12:35:01.895 I/dzt (19718): ApplicationPackageManager---queryIntentActivitiesAsUser list = [ResolveInfo{42a88520 com.example.cts_7301/.termsActivity m=0x108000}] 01-02 12:35:01.897 I/dzt (19718): ApplicationPackageManager---queryIntentActivitiesAsUser intent = Intent { act=android.settings.LICENSE } flags = 0 userId = 0 01-02 12:35:01.899 I/dzt (19718): ApplicationPackageManager---queryIntentActivitiesAsUser list = [ResolveInfo{42a91e68 com.android.settings/.SettingsLicenseActivity m=0x108000}] 01-02 12:35:01.901 I/dzt (19718): ApplicationPackageManager---queryIntentActivitiesAsUser intent = Intent { act=android.settings.COPYRIGHT } flags = 0 userId = 0 01-02 12:35:01.902 I/dzt (19718): ApplicationPackageManager---queryIntentActivitiesAsUser list = [] 01-02 12:35:01.902 I/dzt (19718): ApplicationPackageManager---queryIntentActivitiesAsUser intent = Intent { act=android.settings.SYSTEM_UPDATE_SETTINGS } flags = 0 userId = 0 01-02 12:35:01.904 I/dzt (19718): ApplicationPackageManager---queryIntentActivitiesAsUser list = [] 01-02 12:35:01.937 I/dzt (19718): ApplicationPackageManager---queryIntentActivitiesAsUser intent = Intent { act=com.android.settings.OPERATOR_APPLICATION_SETTING } flags = 128 userId = 0 01-02 12:35:01.938 I/dzt (19718): ApplicationPackageManager---queryIntentActivitiesAsUser list = [] 01-02 12:35:01.941 I/dzt (19718): ApplicationPackageManager---queryIntentActivitiesAsUser intent = Intent { act=com.android.settings.MANUFACTURER_APPLICATION_SETTING } flags = 128 userId = 0 01-02 12:35:01.943 I/dzt (19718): ApplicationPackageManager---queryIntentActivitiesAsUser list = [] 01-02 12:35:02.177 I/dzt (19718): ApplicationPackageManager---queryIntentActivitiesAsUser intent = Intent { act=com.android.settings.OPERATOR_APPLICATION_SETTING } flags = 128 userId = 0 01-02 12:35:02.179 I/dzt (19718): ApplicationPackageManager---queryIntentActivitiesAsUser list = [] 01-02 12:35:02.180 I/dzt (19718): ApplicationPackageManager---queryIntentActivitiesAsUser intent = Intent { act=com.android.settings.MANUFACTURER_APPLICATION_SETTING } flags = 128 userId = 0 01-02 12:35:02.181 I/dzt (19718): ApplicationPackageManager---queryIntentActivitiesAsUser list = []由于PackageManager是一个抽象类,调用queryIntentActivitiesAsUser最终会调用/frameworks/base/core/java/android/app/ApplicationPackageManager.java类的
@Override public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) { Log.i("dzt", "ApplicationPackageManager---queryIntentActivitiesAsUser intent = " + intent.toString() + " flags = "+flags + " userId = "+userId); try { List<ResolveInfo> list = mPM.queryIntentActivities( intent, intent.resolveTypeIfNeeded(mContext.getContentResolver()), flags, userId); Log.i("dzt", "ApplicationPackageManager---queryIntentActivitiesAsUser list = " + list.toString()); return list; } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } }这说明《法律信息》中的三个Item需要有Activity注册了对应的Action才会显示出来,不一定是Settings App也可以是其它的apk,但必需是安装在/system/app/目录下的才行。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。