【Android】屏幕超时休眠
前语
屏幕超时休眠指的是在设备一段时刻没有操作后,主动封闭屏幕显现以节约电量并避免误触。当屏幕进入休眠状况时,通常会封闭屏幕背光,但设备或许仍在运转后台进程。
正文
Settings使用相关
Settings使用的屏幕超时休眠界面相关代码定位到:
packages/apps/Settings/res/xml/display_settings.xml
屏幕超时休眠的控件的key值为screen_timeout。屏幕超时休眠列表选项信息,依据key值找到控件,随后依据android:entries和android:entryValues相关代码定位到:
packages/apps/Settings/res/values/arrays.xml
相关Controller代码定位到:
packages/apps/Settings/src/com/android/settings/display/TimeoutPreferenceController.java
@Override
public void updateState(Preference preference) {
final TimeoutListPreference timeoutListPreference = (TimeoutListPreference) preference;
final long currentTimeout = Settings.System.getLong(mContext.getContentResolver(),
SCREEN_OFF_TIMEOUT, FALLBACK_SCREEN_TIMEOUT_VALUE);//获取到设置的屏幕超时休眠时刻
timeoutListPreference.setValue(String.valueOf(currentTimeout));
final DevicePolicyManager dpm =
(DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
if (dpm != null) {
final RestrictedLockUtils.EnforcedAdmin admin =
RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(mContext);
final long maxTimeout =
dpm.getMaximumTimeToLock(null /* admin */, UserHandle.myUserId());
timeoutListPreference.removeUnusableTimeouts(maxTimeout, admin);
}
updateTimeoutPreferenceDescription(timeoutListPreference, currentTimeout);//更新屏幕超时休眠时刻描绘
EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(
mContext, UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT,
UserHandle.myUserId());
if(admin != null) {
timeoutListPreference.removeUnusableTimeouts(0/* disable all*/, admin);
}
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
try {
int value = Integer.parseInt((String) newValue);//获取到设置的新的屏幕超时休眠时刻
Settings.System.putInt(mContext.getContentResolver(), SCREEN_OFF_TIMEOUT, value);//设置新的屏幕超时休眠时刻
updateTimeoutPreferenceDescription((TimeoutListPreference) preference, value);//更新屏幕超时休眠时刻描绘
} catch (NumberFormatException e) {
Log.e(TAG, "could not persist screen timeout setting", e);
}
return true;
}
//更新屏幕超时休眠时刻描绘
private void updateTimeoutPreferenceDescription(TimeoutListPreference preference,
long currentTimeout) {
final String summary;
// 省掉部分源代码
preference.setSummary(summary);//设置描绘信息
}
特点值相关
屏幕超时休眠默许时刻,定位到:
frameworks/base/packages/SettingsProvider/res/values/defaults.xml
<integer name="def_screen_off_timeout">15000</integer>
默许时刻特点值是写在SQLite中,详细概况见:
packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
屏幕超时休眠默许最低时刻,定位到:
frameworks/base/core/res/res/values/config.xml
<!-- User activity timeout: Minimum screen off timeout in milliseconds.
Sets a lower bound for the {@link Settings.System#SCREEN_OFF_TIMEOUT} setting
which determines how soon the device will go to sleep when there is no
user activity.
This value must be greater than zero, otherwise the device will immediately
fall asleep again as soon as it is awoken.
-->
<integer name="config_minimumScreenOffTimeout">10000</integer>
由上述注释信息,可知屏幕超时休眠默许最低时刻需求设置在 \(0\) 以上。既然如此,咱们假如设置的值是一个小于最低默许值的数值,乃至是一个小于等于 \(0\) 的数值又会产生什么事情呢?
在framework/base目录下搜 \(screen\_off\_timeout\) 能够定位到:
core/java/android/provider/Settings.java
public static final String SCREEN_OFF_TIMEOUT = "screen_off_timeout";
private static final Validator SCREEN_OFF_TIMEOUT_VALIDATOR = NON_NEGATIVE_INTEGER_VALIDATOR;//屏幕超时休眠时刻校验器
//省掉部分源代码
static {
//省掉部分源代码
VALIDATORS.put(SCREEN_OFF_TIMEOUT, SCREEN_OFF_TIMEOUT_VALIDATOR);//增加校验器
//省掉部分源代码
}
所以检查校验器NON_NEGATIVE_INTEGER_VALIDATOR相关代码,定位到:
framework/base/core/java/android/provider/SettingsValidators.java
public static final Validator NON_NEGATIVE_INTEGER_VALIDATOR = new Validator() {
@Override
public boolean validate(@Nullable String value) {
try {
return Integer.parseInt(value) >= 0;
} catch (NumberFormatException e) {
return false;
}
}
};
由上述校验器代码可知,若传入的值是个负数,校验器会对传入的值进行反常抛出,确保代码不溃散。
项目实战
修正休眠时刻列表
依据Settings使用的xml界面的android:entries和android:entryValues相关代码定位到:
packages/apps/Settings/res/values/arrays.xml
直接增加item即可。
若新增的item的value低于屏幕超时休眠默许最低时刻,需求修正体系默许最低值
frameworks/base/core/res/res/values/config.xml
<integer name="config_minimumScreenOffTimeout">10000</integer>
修正体系默许屏幕超时休眠时刻
修正defaults.xml下的def_screen_off_timeout特点值即可。
frameworks/base/packages/SettingsProvider/res/values/defaults.xml
<integer name="def_screen_off_timeout">15000</integer>
三方app自界说屏幕超时休眠时刻
首要,在Settings使用中增加一个播送,在源代码中增加一个action来接纳即可,定位到途径:
packages/apps/Settings/AndroidManifest.xml
<!-- 找到一个已有的receiver,或许新增一个receiver都是可行的,随后声明一个自界说ACTION -->
<receiver android:name=".SettingsInitialize">
<intent-filter>
<action android:name="自界说ACTION"/>
<action android:name="android.intent.action.USER_INITIALIZE"/>
<action android:name="android.intent.action.PRE_BOOT_COMPLETED"/>
</intent-filter>
</receiver>
在播送接纳器的类中完成接纳的逻辑
packages/apps/Settings/src/com/android/settings/SettingsInitialize.java
@Override
public void onReceive(Context context, Intent broadcast) {
//begin:新增的代码
String action = broadcast.getAction();
if (context.getString(自界说ACTION的字符串资源途径).equals(action)) {
final long currentTimeout = Settings.System.getLong(context.getContentResolver(),
SCREEN_OFF_TIMEOUT, TimeoutPreferenceController.FALLBACK_SCREEN_TIMEOUT_VALUE);
int value = broadcast.getIntExtra("screen_off_timeout", (int)currentTimeout);
Settings.System.putInt(context.getContentResolver(), SCREEN_OFF_TIMEOUT, value);
return ;
}
//end:新增的代码
final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
UserInfo userInfo = um.getUserInfo(UserHandle.myUserId());
final PackageManager pm = context.getPackageManager();
managedProfileSetup(context, pm, broadcast, userInfo);
webviewSettingSetup(context, pm, userInfo);
refreshExistingShortcuts(context);
}
在自己的三方使用中增加如下中心代码
Intent screenTimeoutIntent = new Intent("自界说ACTION");
int value = 20000;//新界说的屏幕超时休眠时刻
screenTimeoutIntent.putExtra("screen_off_timeout", value);
//若Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND找不到,就用0x01000000硬编码替换
screenTimeoutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
sendBroadcast(screenTimeoutIntent);//宣布播送,告诉更新屏幕超时休眠时刻
若是期望能够自界说的屏幕超时休眠时刻能够低于体系默许最低超时休眠时刻,则需求连同体系默许休眠时刻一同修正。