需求:实现屏保功能 实现原理: 1、自己写一个服务MyDreamService继承系统的屏保服务DreamService,在该服务中onAttachedToWindow()方法中初始化UI和一些资源,在onDetachedFromWindow()方法释放资源 2、在config.xml文件中替换掉自己原生的屏保服务,添加自己的屏保应用服务 3、在PowerManagerService.java文件中goToSleepNoUpdateLocked()方法中做如下处理:设置屏保时间到了就进入屏保界面、按Power键进入屏保界面 代码路径: frameworks/base/core/res/res/values/config.xml frameworks/base/services/core/java/com/android/server/power/Notifier.java frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java 一、如何编写一个屏保应用 1、编写一个服务MyDreamService继承系统的屏保服务DreamService在该服务中onAttachedToWindow()方法中初始化UI和一些资源,在onDetachedFromWindow()方法释放资源
public class MyDreamService extends DreamService {
private static final String TAG = "MyDreamService ";
private static final boolean DEBUG = true;
private ContentResolver resolver;
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
if(DEBUG) Log.i(TAG, "onAttachedToWindow()");
setInteractive(false);
setFullscreen(true);
View decorView = getWindow().getDecorView();
if(null != decorView){
int visibility = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
decorView.setSystemUiVisibility(visibility);
}
resolver = getContentResolver();
timeChange(true);
initView();
regisBroadCast();
}
private void initView() {
setContentView(R.layout.layout_screen);
}
private void timeChange(boolean isFirstInit) {
setWindowBrightness( 0.4f);
}
private void setWindowBrightness(float brightness) {
if(DEBUG) Log.i(TAG, "setWindowBrightness() brightness = "+brightness);
Window window = getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
lp.screenBrightness = brightness;
window.setAttributes(lp);
window.getWindowManager().updateViewLayout(window.getDecorView(), lp);
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
}
}
2、在AndroidManifest.xml文件中注册该服务
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.screensaver"
android:versionCode="1"
android:versionName="1.0"
coreApp="true"
android:sharedUserId="android.uid.system" >
<!-- <uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="27" />-->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:persistent="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:directBootAware="true"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MyDreamService"
android:exported="true"
android:label="ScreenSaver"
android:permission="android.permission.BIND_DREAM_SERVICE" >
<intent-filter>
<action android:name="android.service.dreams.DreamService" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
</application>
</manifest>
二、如何在系统中启动屏保应用 1、在config.xml文件中config_dreamsDefaultComponent字段配置为我们自己的包名加服务
<string name="config_dreamsDefaultComponent" translatable="false">com.zqc.screensaver/com.test.screensaver.MyDreamService</string>
2、在PowerManagerService.java文件中goToSleepNoUpdateLocked()方法中进行判断是设置时间进入屏保和按power键进入屏保
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -1583,6 +1583,7 @@ public final class PowerManagerService extends SystemService
* and only tucks itself in to SLEEP if requested with the flag
* {@link PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE}.
*/
+ private boolean showDream = false;
@SuppressWarnings("deprecation")
private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags, int uid) {
if (DEBUG_SPEW) {
@@ -1596,19 +1597,49 @@ public final class PowerManagerService extends SystemService
|| !mBootCompleted || !mSystemReady) {
return false;
}
-
+ showDream = false;
Trace.traceBegin(Trace.TRACE_TAG_POWER, "goToSleep");
try {
reason = Math.min(PowerManager.GO_TO_SLEEP_REASON_MAX,
Math.max(reason, PowerManager.GO_TO_SLEEP_REASON_MIN));
Slog.i(TAG, "Going to sleep due to " + PowerManager.sleepReasonToString(reason)
- + " (uid " + uid + ")...");
-
+ + " (uid " + uid + ")... reason "+reason);
+ switch (reason) {
+ case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
+ Slog.i(TAG, "Going to sleep due to device administration policy "
+ + "(uid " + uid +")...");
+ break;
+ case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
+ showDream = true;
+ Slog.i(TAG, "Going to sleep due to screen timeout (uid " + uid +")...");
+ break;
+ case PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH:
+ Slog.i(TAG, "Going to sleep due to lid switch (uid " + uid +")...");
+ break;
+ case PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON:
+ showDream = true;
+ Slog.i(TAG, "Going to sleep due to power button (uid " + uid +")...");
+ break;
+ case PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON:
+ Slog.i(TAG, "Going to sleep due to sleep button (uid " + uid +")...");
+ break;
+ case PowerManager.GO_TO_SLEEP_REASON_HDMI:
+ Slog.i(TAG, "Going to sleep due to HDMI standby (uid " + uid +")...");
+ break;
+ default:
+ Slog.i(TAG, "Going to sleep by application request (uid " + uid +")...");
+ reason = PowerManager.GO_TO_SLEEP_REASON_APPLICATION;
+ break;
+ }
mLastSleepTime = eventTime;
mLastSleepReason = reason;
mSandmanSummoned = true;
-
- setWakefulnessLocked(WAKEFULNESS_DOZING, reason, eventTime);
+ if(mDreamsEnabledSetting && !isDreaming() && showDream){
+ setWakefulnessLocked(WAKEFULNESS_DREAMING, reason, eventTime);
+ }else{
+ setWakefulnessLocked(WAKEFULNESS_DOZING, reason, eventTime);
+ }
+
int numWakeLocksCleared = 0;
@@ -1634,6 +1665,12 @@ public final class PowerManagerService extends SystemService
}
return true;
}
+ private boolean isDreaming(){
+ if (mDreamManager != null) {
+ return mDreamManager.isDreaming();
+ }
+ return false;
+ }
private void napInternal(long eventTime, int uid) {
synchronized (mLock) {
|