Android 10 如何自定义屏保功能

需求:实现屏保功能
实现原理:
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);
+                       }
+           
 
             // Report the number of wake locks that will be cleared by going to sleep.
             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) {
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值