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/目录下

[email protected]:~/workspace/cts_7301/bin$ ls
AndroidManifest.xml  classes  classes.dex  cts_7301.apk  dexedLibs  res  resources.ap_
[email protected]:~/workspace/cts_7301/bin$ adb push cts_7301.apk /system/app/
3474 KB/s (549968 bytes in 0.154s)
[email protected]:~/workspace/cts_7301/bin$ adb push cts_7301.apk /system/app/
3242 KB/s (549968 bytes in 0.165s)
[email protected]:~/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/目录下的才行。

时间: 2024-08-23 23:50:21

Android 在frameworks中修改Setting中的默认值 (二)的相关文章

Android 在frameworks中修改Setting中的默认值

在frameworks中跟Setting默认值相关的几个文件 /frameworks/base/packages/SettingsProvider/res/values/defaults.xml /frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java 在defaults.xml文件中定义了相关的值,DatabaseHelper.java会把相应的值读取出来保

在MyEclipse中修改jsp页面的默认打开方式

在JavaWeb项目中,当然有很多jsp页面,但是我发现,双击打开jsp页面总是卡机,相对于打开其他java文件而言非常慢,感觉很不舒服,MyEclipse中默认打开jsp页面是以可视化的形式展现的,但是大多数情况我们都喜欢以代码方式打开jsp页面. 有两种方式来解决打开jsp页面较慢的问题. 单击选中jsp页面,点击右键---open with  --- MyEclipse JSP Editor  以这种方式打开就非常快不会出现卡机的情况. 但是这种方式每次打开jsp页面时都很繁琐,有没有更好

?Swift语言中为外部参数设置默认值,可变参数,常量参数,变量参数,输入输出参数

引用自这里:Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数 目录[-] 7.4.4  为外部参数设置默认值 7.4.5  可变参数 7.4.6  常量参数和变量参数 7.4.7  输入-输出参数 7.4.4  为外部参数设置默认值 开发者也可以对外部参数设置默认值.这时,调用的时候,也可以省略参数传递本文选自Swift1.2语言快速入门v2.0. [示例7-11]以下的代码就为外部参数toString.withJoiner设置了默认的参数"Swift"和&qu

?Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数

Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数 7.4.4  为外部参数设置默认值 开发者也可以对外部参数设置默认值.这时,调用的时候,也可以省略参数传递本文选自Swift1.2语言快速入门v2.0. [示例7-11]以下的代码就为外部参数toString.withJoiner设置了默认的参数"Swift"和"---".代码如下: import Foundation func join(string s1: String, toString

【翻译自mos文章】11.2.0.4及更高版本号的asm实例中MEMORY_TARGET 和 MEMORY_MAX_TARGET的默认值和最小值

[翻译自mos文章]11.2.0.4及更高版本号的asm实例中MEMORY_TARGET 和 MEMORY_MAX_TARGET的默认值和最小值 来源于: Default and Minimum MEMORY_TARGET & MEMORY_MAX_TARGET Value for ASM 11.2.0.4 and Onwards (文档 ID 1982132.1) APPLIES TO: Oracle Database - Enterprise Edition - Version 11.2.0

使用Kotlin开发Android应用(III):扩展函数和默认值

使用Kotlin开发Android应用(III):扩展函数和默认值 @author ASCE1885的 Github 简书 微博 CSDN 原文链接 通过前面两篇文章,我们学习了Kotlin的基本知识,并知道如何配置工程,本文将接着介绍Java没有的而Kotlin实现了的有趣的特性.记住当你对Kotlin语言有任何疑问时,请参考官方指南.该指南组织的很好,而且容易理解,本文将不会介绍语言的基本知识. 扩展函数 Kotlin的扩展函数功能使得我们可以为现有的类添加新的函数,而不用修改原来的类.例如

如何修改情景模式的默认值

一,针对每个情景模式的默认值修改: 1,默认铃声是统一在alps/build/target/product/core.mk文件中设置,其中ro.config.notification_sound表示通知的默认铃声,ro.config.ringtone表示语音来电和视频来电的铃声,若希望语音来电和视频来电分开设置,请参考FAQ08273 [Audio Profile]如何设置视频来电铃的默认铃声: PRODUCT_PROPERTY_OVERRIDES:=\ ro.config.notificati

JIRA中设置[描述]字段的默认值

公司使用JIRA已经一段时间了,期间也是各种需求,免不了很多自定义的功能或需求,在没有购买技术支持的情况下,有的或许可以自行尝试实现,有的也只能是无能为力.当然,这篇文章别的不说,单说设置描述description字段的默认值的实现方式. 所需要设置默认值的字段就是上图中红框的描述字段,这里是汉化后的界面,如果是未汉化此处应为description,我要实现的就是右侧方框中自动出现我设置的格式,也即只要用户创建一个问题,在弹出的窗口中就会自动出现我定义的描述默认值. 1.备份源文件 要修改的文件

【CSS中width、height的默认值】

对于初学者来说,CSS中的width.height的默认值是很神奇的,因为经常看到如下这样的代码:明明只给一个#father标签(红色的div)设置了一个width,为啥它在浏览器中显示出来是有一个固定的height的呢. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>测试宽度</title> <style type="tex