android

Android自定义屏保

2018-03-14  本文已影响108人  OkCoco

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.
     * <p>
     * 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.
     * </p><p>
     * 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}.
     * </p><p>
     * See {@link android.os.PowerManager#isInteractive} for details.
     * </p>
     * You <em>cannot</em> receive this through components declared in
     * manifests, only by explicitly registering for it with
     * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
     * Context.registerReceiver()}.
     *
     * <p class="note">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
        /**
         *  获得唤醒锁时亮屏
         * <p>
         *     正常情况下,唤醒锁并不能真正唤醒设备,一旦屏幕已经打开,它们就只能继续工作。
         *     正如视频软件正常工作一样。
         * </p>
         */
        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();
        }
      mCpuWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getClass().getCanonicalName());

      synchronized (WakeUtil.class) {
            if (!mCpuWakeLock.isHeld()) {
                mCpuWakeLock.acquire();
            }
        }
上一篇下一篇

猜你喜欢

热点阅读