Android系统屏保功能开发(Android10)

Android系统屏保功能开发

1 AndroidManifest.xml 文件配置

需要先配置为系统应用

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.xxx.xxx"
    android:sharedUserId="android.uid.system">
    <uses-permission android:name="android.permission.BIND_DREAM_SERVICE" />
    ...
    <!--屏保服务类-->
    <service
            android:name=".display.xxx.MyDream"
            android:enabled="true"
            android:exported="true"
            android:icon="@drawable/bg_screensaver_clock"
            android:label="@string/display_dream_clock"
            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>
</manifest>

实现 DreamService

在这里,我实现了一个基类,方便扩展多种屏保。

public abstract class BaseDream extends DreamService {
   

    public static final String TAG = BaseDream.class.getName();
    public boolean mLowProfile;

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
   
        wakeUp();
        return true;
    }

    @Override
    public void onWakeUp() {
   
        super.onWakeUp();
        wakeupDream();
    }

    protected void wakeupDream() {
   
        PowerManager pm = getSystemService(PowerManager.class);
        pm.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
                "com.android.systemui:NODOZE");
    }

    @Override
    public void onCreate() {
   
        super.onCreate();
    }

    @Override
    public void onAttachedToWindow() {
   
        super.onAttachedToWindow();
        init();
        hideBar();
    }

    @Override
    public void onDreamingStarted() {
   
        super.onDreamingStarted();
    }

    @Override
    public void onDreamingStopped() {
   
        super.onDreamingStopped();
    }

    @Override
    public void onDetachedFromWindow() {
   
        super.onDetachedFromWindow();
        release();
    }

    @Override
    public void onDestroy() {
   
        super.onDestroy();
    }

    protected abstract void init();

    protected abstract void release();

    private void hideBar() {
   
        getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LOW_PROFILE
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
    }

    public void setLowProfile(boolean lowProfile) {
   
        if (mLowProfile != lowProfile) {
   
            mLowProfile = lowProfile;
            int flag = View.SYSTEM_UI_FLAG_LOW_PROFILE;
            applySystemUiVisibilityFlags(mLowProfile ? flag : 0, flag);
        }
    }

    private void applySystemUiVisibilityFlags(int flags, int mask) {
   
        View v = getWindow() == null ? null : getWindow().getDecorView();
        if (v != null) {
   
            v.setSystemUiVisibility(applyFlags(v.getSystemUiVisibility(), flags, mask));
        }
    }

    private int applyFlags(int oldFlags, int flags, int mask) {
   
        return (oldFlags&~mask) | (flags&mask);
    }
}

实现时钟屏保类,不外乎就是在这个服务里自定义自己的UI。

/**
 * 系统默认屏保:时钟屏保
 * 详情见 device\rockchip\rk3399\PRODUCT\overlay\frameworks\base\core\res\res\values\config.xml
 * <string name="config_dreamsDefaultComponent"
 * translatable="false">com.XXX.XXX/com.XXX.XXX.display.screensaver.dream.MyDream</string>
 */
public class ClockDream extends BaseDream {
   
    public static final String TAG = ClockDream.class.getSimpleName();

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
   
        super.onConfigurationChanged(newConfig);
        refreshLayoutParams();
    }

    private void refreshLayoutParams() {
   
    }

    @Override
    protected void init() {
   
        setInteractive(false);
        setFullscreen(true);
        setLowProfile(true);
		// 设置布局文件
        setContentView(R.layout.view_dream_screensaver);
        ...
    }

    @Override
    protected void release() {
   
        ...
    }
    ...
}

到这里开发基本完成,那怎么才能把我们定义好的屏保设置为当前屏保呢,其实在系统启动的时候,会加载 AndroidManifest.xml 清单文件,解析并将配置为屏保的服务存储起来,通过系统服务来向应用层提供屏保列表的遍历、设置接口。

2 PowerManagerService 分析

屏保从何时启动,在系统SystemServer startOtherServices 服务启动阶段, PowerManagerService 系统服务准备就绪时,调用 systemReady() 方法,注册了更新屏保的系统广播,通过接收 Intent.ACTION_DREAMING_STARTED、Intent.ACTION_DREAMING_STOPPED 广播来对外提供控制屏保的启动与停止, 另一种方式就是通过接口来控制,上述两种方式最后调用的接口最后都会调用到 DeamManagerService 服务的接口。

//frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
public final class PowerManagerService extends SystemService
    implements Watchdog.Monitor {
    

    // Message: 当发生用户活动超时(界面无操作)以更新电源状态时发送.
    private static final int MSG_USER_ACTIVITY_TIMEOUT = 1;
    // Message: 当设备进入或退出dreaming或dozing状态时发送
    private static final int MSG_SANDMAN = 2;
    // Message: 当屏幕亮度提升到期时发送
    private static final int MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT = 3;
    // Message: 轮询以查找长期持有的唤醒锁.
    private static final int MSG_CHECK_FOR_LONG_WAKELOCKS = 4;

    public void systemReady(IAppOpsService appOps) {
   
        mSystemReady = true;
        mAppOps = appOps;
        mDreamManager = getLocalService(DreamManagerInternal.class);
        mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);
        mPolicy = getLocalService(WindowManagerPolicy.class);

        //省略代码...
        ilter = new IntentFilter();
        filter.addAction(Intent.ACTION_DREAMING_STARTED);
        filter.addAction(Intent.ACTION_DREAMING_STOPPED);
        mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);
    }

    private final class DreamReceiver extends 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值