写这边文章主要是由于今天项目的需要!要求我在休眠中更改相关的时间以及添加一个“永不休眠”选项。
下面我们开始:
首先我们跟踪点击“设置”、“显示”、‘休眠“都调用了哪些相关类。将设备连上电脑,打开adb logcat ,点击“设置---显示”我们看到在控制台中显示如下:
见上图中红色部分,在点击”显示“的时候,在logcat中打印了上述内容。我们通过查找”DisplaySettings.java“从而定位相关的代码。查找如图:
其实根据经验我们也知道跟”设置“相关的东东都在android4.2/packages/apps/Settings中。既然知道了所处的位置,我们定位到android4.2/packages/apps/Settings/DisplaySettings.java中。
由于DisplaySettings extends SettingsPreferenceFragment 我们在onCreate()中可以找到相关配置:addPreferencesFromResource(R.xml.display_settings); 由此我们进入到display_settings.xml中进行查看。代码如下:
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 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/display_settings"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
<com.android.settings.BrightnessPreference
android:key="brightness"
android:title="@string/brightness"
android:dialogTitle="@string/brightness" />
<PreferenceScreen
android:key="wallpaper"
android:title="@string/wallpaper_settings_title"
android:fragment="com.android.settings.WallpaperTypeSettings" />
<CheckBoxPreference
android:key="accelerometer"
android:title="@string/accelerometer_title"/>
<ListPreference
android:key="screen_timeout"
android:title="@string/screen_timeout"
android:summary="@string/screen_timeout_summary"
android:persistent="false"
android:entries="@array/screen_timeout_entries"
android:entryValues="@array/screen_timeout_values" />
<PreferenceScreen
android:key="screensaver"
android:title="@string/screensaver_settings_title"
android:fragment="com.android.settings.DreamSettings" />
<com.android.settings.WarnedListPreference
android:key="font_size"
android:title="@string/title_font_size"
android:summary="@string/summary_font_size"
android:entries="@array/entries_font_size"
android:entryValues="@array/entryvalues_font_size"
android:dialogTitle="@string/dialog_title_font_size" />
<CheckBoxPreference
android:key="notification_pulse"
android:title="@string/notification_pulse_title"
android:persistent="false" />
<ListPreference
android:key="accelerometer_coornadite"
android:title="@string/accelerometer_coordinate_title"
android:persistent="false"
android:entries="@array/accelerometer_entries"
android:entryValues="@array/accelerometer_values" />
<PreferenceScreen
android:title="@string/screen_adaption_setting"
android:summary="@string/screen_adaption_summary">
<intent
android:action="android.intent.action.MAIN"
android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.ScreenAdaption" />
</PreferenceScreen>
<!-- mCube add start -->
<PreferenceScreen
android:key="gsensor_calibration"
android:title="@string/calibration_settings_title"
android:summary="@string/calibration_settings_summary">
<intent
android:action="android.intent.action.GSENSOR_CALIBRATE"
android:targetPackage="tw.com.domintech.gsensor"
android:targetClass="tw.com.domintech.gsensor.DMT_GSENSORActivity"/>
</PreferenceScreen>
<!-- mCube add end -->
<CheckBoxPreference android:title="@string/smart_brightness_title" android:key="smart_brightness" android:summary="@string/smart_brightness_summary" android:defaultValue="false"/>
<PreferenceScreen
android:key="wifi_display"
android:title="@string/wifi_display_settings_title"
android:fragment="com.android.settings.wfd.WifiDisplaySettings" />
</PreferenceScreen>
由此我们可以看出,此文件就是设置中左侧栏相关的东东。而跟我们话题相关的就是红色部分的内容了。
下面我们先简要介绍介绍android preference相关的东西:
首先,我们明确,preference是和数据存储相关的。
其次,它能帮助我们方便的进行数据存储!为什么这个地方一定要强调下方便的这个词呢?原因是,我们可以根本就不使用,我们有另外的N种办法可以实现同样的功能!它的出现,相当于为我们提供了一个方便的工具,当然了,这个工具并不是必须的。
preference都应用在什么场景呢?
这得从android对preference的实现说起,实际上,preference所存储的数据最后都会以xml文件格式的形式进行保存,而且其只能 保存一些基本格式的数据。例如string/boolean……。该xml文件存放的位置在data/data/你应用的包名/shared_prefs 文件夹下。
种种的限制与实现机制表明了,preference非常适合于参数设置功能。实际上,它也确实是干这个的,我们通过使用preference可以迅速的将某些值保存进xml文件中,然后我们可以读取这些设置信息进行相应的操作。
为 了简化与preference相关的应用开发,android为我们提供了一系列的api来帮助我们。主要有 PreferenceActivity,ListPreference,EditTextPreference,CheckBoxPreference,RingtonePreference
不多说,我们回到之前的配置文件,我们主要关注下面两个属性:
android:entries="@array/screen_timeout_entries"
android:entryValues="@array/screen_timeout_values"
通过查找 screen_timeout_entries 有如下相关文件中有:
而我烧写的固件在启动过程中的引导选择的简体中文,所以我们定位到/packages/apps/Settings/res/values-zh-rCN/arrays.xml:32: <string-array name="screen_timeout_entries"> :
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string-array name="timezone_filters">
<item msgid="5296756001147094692">"美洲"</item>
<item msgid="3005562397632768392">"欧洲"</item>
<item msgid="5696915123093701218">"非洲"</item>
<item msgid="4439789052790868249">"亚洲"</item>
<item msgid="956915953069815961">"澳大利亚"</item>
<item msgid="5345178126174698955">"太平洋"</item>
<item msgid="8392017019801393511">"全部"</item>
</string-array>
<string-array name="screen_timeout_entries">
<item msgid="3342301044271143016">"15 秒"</item>
<item msgid="8881760709354815449">"30 秒"</item>
<item msgid="7589406073232279088">"1 分钟"</item>
<item msgid="7001195990902244174">"2 分钟"</item>
<item msgid="7489864775127957179">"5 分钟"</item>
<item msgid="2314124409517439288">"10 分钟"</item>
<item msgid="6864027152847611413">"30 分钟"</item>
<!-- add by zfl -->
<item msgid="3149294732231243434">"永不"</item>
</string-array>
<string-array name="dream_timeout_entries">
<item msgid="3149294732238283185">"永不"</item>
<item msgid="2194151041885903260">"15 秒"</item>
<item msgid="5892295237131074341">"30 秒"</item>
<item msgid="3538441365970038213">"1 分钟"</item>
<item msgid="412343871668955639">"2 分钟"</item>
<item msgid="5076853889688991690">"5 分钟"</item>
<item msgid="1903860996174927898">"10 分钟"</item>
<item msgid="6415509612413178727">"30 分钟"</item>
</string-array>
通过查找 screen_timeout_values 有:
由此我们进入 ./packages/apps/Settings/res/xml/display_settings.xml:41: android:entryValues="@array/screen_timeout_values" /> 有:
...
<!-- Display settings. The delay in inactivity before the screen is turned off. These are shown in a list dialog. -->
<string-array name="screen_timeout_entries">
<item>15 seconds</item>
<item>30 seconds</item>
<item>1 minute</item>
<item>2 minutes</item>
<item>5 minutes</item>
<item>10 minutes</item>
<item>30 minutes</item>
</string-array>
<!-- Do not translate. -->
<string-array name="screen_timeout_values" translatable="false">
<!-- Do not translate. -->
<item>15000</item>
<!-- Do not translate. -->
<item>30000</item>
<!-- Do not translate. -->
<item>60000</item>
<!-- Do not translate. -->
<item>120000</item>
<!-- Do not translate. -->
<item>300000</item>
<!-- Do not translate. -->
<item>600000</item>
<!-- Do not translate. -->
<item>1800000</item>
<!-- forever -->
<item>864000000</item> <!-- 这里我只是设为10天-->
</string-array>
........
其实我们到这里已经能够达到所需要的了,只需要重新make ,pack一下就行。
但是既然是源码跟踪我们就看看相关的代码,他们是怎样进行调用的。让我们回到 DisplaySettings.java 的onCreat()中。
......
mScreenTimeoutPreference = (ListPreference) findPreference(KEY_SCREEN_TIMEOUT);
final long currentTimeout = Settings.System.getLong(resolver, SCREEN_OFF_TIMEOUT,
FALLBACK_SCREEN_TIMEOUT_VALUE);
mScreenTimeoutPreference.setValue(String.valueOf(currentTimeout));
mScreenTimeoutPreference.setOnPreferenceChangeListener(this);
disableUnusableTimeouts(mScreenTimeoutPreference);
updateTimeoutPreferenceDescription(currentTimeout);
......
主要是获取之前的休眠值并将其设为现在的默认值,注册相关的事件以及设置相关的键值。
我们主要跟中休眠值改变的时候相应的代码,也就是我们在界面上点击相关的选项时执行的。---onPreferenceChange :
public boolean onPreferenceChange(Preference preference, Object objValue) {
final String key = preference.getKey();
if (KEY_SCREEN_TIMEOUT.equals(key)) {
int value = Integer.parseInt((String) objValue);
try {
Settings.System.putInt(getContentResolver(), SCREEN_OFF_TIMEOUT, value);
updateTimeoutPreferenceDescription(value);
} catch (NumberFormatException e) {
Log.e(TAG, "could not persist screen timeout setting", e);
}
}
...............
return true;
}
private void updateTimeoutPreferenceDescription(long currentTimeout) {
ListPreference preference = mScreenTimeoutPreference;
String summary;
if (currentTimeout < 0) {
// Unsupported value
summary = "";
} else {
final CharSequence[] entries = preference.getEntries();
final CharSequence[] values = preference.getEntryValues();
if (entries == null || entries.length == 0) {
summary = "";
} else {
int best = 0;
for (int i = 0; i < values.length; i++) {
long timeout = Long.parseLong(values[i].toString());
if (currentTimeout >= timeout) {
best = i;
}
}
summary = preference.getContext().getString(R.string.screen_timeout_summary,
entries[best]);
}
}
preference.setSummary(summary);
}