需求確立
描述
一般, Kiosk 模式下不管處於什麼界面,都要求屏幕保持常亮的。雖然在 App 內可以通過代碼實現屏幕常亮,但是現在的需求是在系統設置裏增加永不休眠的功能,可勾選的實現動態修改。涉及到系統 Apk 的修改,沒辦法只能去修改源碼了。
確認
簡單整理下需求:
- 針對 Settings.apk 設置 -> 顯示 -> 睡眠功能,添加永不休眠選項,支持切換休眠爲永不休眠
- 實現開機默認選中永不休眠,並且開啓永不休眠功能
功能實現
源碼過於龐大,不可能去分析每行代碼。通過 Google 查閱資料,基本定位實現該功能所需要修改的文件,主要是PowerManagerService.java
和DisplaySettings.java
兩個文件,現在就具體講講實現永不休眠功能的步驟。
添加永不休眠選項
Settings.apk 已經實現休眠功能,首先需要在選項裏添加永不休眠選項,僅支持英文和中文
找到packages/apps/Settings/res/values-zh-rCN/arrays.xml
文件,搜索 screen_timeout_entries
,插入<item>"永不休眠"</item>
代碼。示例如下:
<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>
<item>"永不休眠"</item>
</string-array>
找到packages/apps/Settings/res/values/arrays.xml
文件,搜索 screen_timeout_entries
,插入<item>Never</item>
代碼,搜索screen_timeout_values
,插入<item>0</item>
代碼。示例如下:
<!-- 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>
<item>Never</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>
<!-- Do not translate. -->
<item>0</item>
</string-array>
默認選中永不休眠選項
默認休眠時間是 1 分鐘,現在修改爲永不休眠
找到frameworks/base/packages/SettingsProvider/res/values/defaults.xml
文件,
將<integer name="def_screen_off_timeout">60000</integer>
替換爲<integer name="def_screen_off_timeout">0</integer>
即可。示例如下:
<resources>
<bool name="def_dim_screen">true</bool>
- <integer name="def_screen_off_timeout">60000</integer>
+ <integer name="def_screen_off_timeout">0</integer>
<integer name="def_sleep_timeout">-1</integer>
<bool name="def_airplane_mode_on">false</bool>
<bool name="def_theater_mode_on">false</bool>
實現永不休眠功能
1.找到packages/apps/Settings/src/com/android/settings/DisplaySettings.java
中的updateTimeoutPreferenceDescription
,修改如下:
private void updateTimeoutPreferenceDescription(long currentTimeout) {
ListPreference preference = mScreenTimeoutPreference;
String summary;
/* never screen off begin */
final CharSequence[] entries = preference.getEntries();
final CharSequence[] values = preference.getEntryValues();
/* never screen off end */
if (currentTimeout < 0) {
// Unsupported value
/* never screen off begin */
if (entries != null || entries.length != 0){
summary = (entries[entries.length-1]).toString();
}else{
summary = "";
}
/* never screen off end */
} else {
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;
}
}
if (entries.length != 0) {
summary = preference.getContext().getString(R.string.screen_timeout_summary,
entries[best]);
} else {
summary = "";
}
}
}
preference.setSummary(summary);
}
2.找到frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
中的getScreenOffTimeoutLocked
方法,修改如下:
private int getScreenOffTimeoutLocked(int sleepTimeout) {
int noSleepTimeout = 0;
int timeout = mScreenOffTimeoutSetting;
if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
}
if (mUserActivityTimeoutOverrideFromWindowManager >= 0) {
timeout = (int)Math.min(timeout, mUserActivityTimeoutOverrideFromWindowManager);
}
if (sleepTimeout >= 0) {
timeout = Math.min(timeout, sleepTimeout);
}
/* never screen off begin */
noSleepTimeout = mScreenOffTimeoutSetting;
if (noSleepTimeout == 0) {
noSleepTimeout = mMaximumScreenOffTimeoutFromDeviceAdmin;
return Math.max(noSleepTimeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
}
/* never screen off end */
return Math.max(timeout, mMinimumScreenOffTimeoutConfig);
}
小結
如何從源碼上實現永不休眠功能,具體實現也就這樣了,這裏僅是簡單記錄下。
Android-6.0 永不休眠補丁,提供下載