Android自定义屏保

Android亮屏、熄屏的时候会发出广播,通常在熄屏广播中启动屏保

  • 注册屏幕广播
 /**
     * 注册广播
     *
     * @param mContext 上下文环境
     * @param receiver 将要注册的广播
     */
    public void registerScreenSaverReceiver(Context mContext, ScreenReceiver receiver) {
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        filter.addAction(Intent.ACTION_SCREEN_ON);
        mContext.registerReceiver(receiver, filter);
    }

在该广播的Action中有着这样的注释:

/**
     * Broadcast Action: Sent when the device wakes up and becomes interactive.
     * 

* For historical reasons, the name of this broadcast action refers to the power * state of the screen but it is actually sent in response to changes in the * overall interactive state of the device. *

* This broadcast is sent when the device becomes interactive which may have * nothing to do with the screen turning on. To determine the * actual state of the screen, use {@link android.view.Display#getState}. *

* See {@link android.os.PowerManager#isInteractive} for details. *

* You cannot receive this through components declared in * manifests, only by explicitly registering for it with * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter) * Context.registerReceiver()}. * *

This is a protected intent that can only be sent * by the system. */

这就是说,由于历史原因,该广播Action表示屏幕的电信号状态,但是实际上该广播是在屏幕不可进行交互时发出
注:不能通过在Manifest.xml文件注册的方式接收该广播,仅仅支持通过代码registerReceiver(Broadcast ,IntentFilter)的方式进行注册

在 onReceive(Context context, Intent intent) 方法中进行开启自定义屏保:

public class ScreenReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //拿到屏幕锁,亮屏,随即释放,否则屏幕就会保持常量
        WakeUtil.getInstance().wakeScreenLock();
        WakeUtil.getInstance().releaseScreenLock();
        //屏蔽系统的屏保
        mKeyguardManager = (KeyguardManager) MyApplication.getInstance().getSystemService(Context.KEYGUARD_SERVICE);
        mKeyguardLock = mKeyguardManager.newKeyguardLock("ScreenLockService");
        mKeyguardLock.disableKeyguard();
        //TODO 开启自定义的屏保;例如:跳转一个Activity,显示屏保图片

    }
}
  • 保持屏幕常量

通常,保持屏幕常量有如下方法:

  1. getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    官方注释:
/** Window flag: as long as this window is visible to the user, keep the device's screen turned on and bright. */
        public static final int FLAG_KEEP_SCREEN_ON     = 0x00000080;

即当window对用户可见时,保持屏幕常量。

  1. 通过PowerManager.WakeLock
mScreenWakeLock = powerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK,
                this.getClass().getCanonicalName());
if (!mScreenWakeLock.isHeld()) {
     mScreenWakeLock.acquire();
}

对于方法newWakeLock(int levelAndFlags, String tag),下面看看该flag和level分别代表什么意义。

PowerManager.ACQUIRE_CAUSES_WAKEUP|PowerManager.SCREEN_DIM_WAKE_LOCK
        /**
         *  获得唤醒锁时亮屏
         * 

* 正常情况下,唤醒锁并不能真正唤醒设备,一旦屏幕已经打开,它们就只能继续工作。 * 正如视频软件正常工作一样。 *

*/ public static final int ACQUIRE_CAUSES_WAKEUP = 0x10000000; /** * 保证亮屏状态 (可能会变暗); * 允许关闭背光 * @deprecated Most applications should use * {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON} instead * of this type of wake lock, as it will be correctly managed by the platform * as the user moves between applications and doesn't require a special permission. */ @Deprecated public static final int SCREEN_DIM_WAKE_LOCK = 0x00000006;

可以看出该方法已经过时,系统更推荐使用方法1.

3.通过设置系统进入屏保的时间

    try {
            Settings.System.putInt(mContext.getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, paramInt);
        } catch (Exception localException) {
            localException.printStackTrace();
        }

paramInt代表进入屏保或锁屏的时间,单位毫秒ms。这里可设置为Integer.MAX_VALUE。

同样可以通过这种方式进行屏幕亮度(0-255)等的设置:

        try {
            Settings.System.putInt(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, paramInt);
        } catch (Exception localException) {
            localException.printStackTrace();
        }
  • 进入浅休眠(熄屏状态下CPU仍在运行)
      mCpuWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getClass().getCanonicalName());

      synchronized (WakeUtil.class) {
            if (!mCpuWakeLock.isHeld()) {
                mCpuWakeLock.acquire();
            }
        }

你可能感兴趣的:(Android自定义屏保)