设备息屏?不存在的!保持 Android 常亮的几种方法!

一、前言

在实际开发过程中,会有一些需要保持屏幕常亮的需求。如果不特殊设置,通常我们的手机在静置一段时间之后,就会自动进入息屏状态,而我们要做的就是阻止它进入息屏状态。

这个功能,使用场景要从实际情况出发,例如:播放器,还有一些向智能电视投屏的手机 App ,都可能会有类似的需要。

本篇文章就对 Android 下,如何保持屏幕常亮,做一个简单的记录和总结。

二、几种常见的方法

2.1 被废弃的 WAKELOCK

如果你看过比较早的 Android 教程类的书籍的话,在说到保持屏幕常亮这个需求的时候,你应该会想到 WakeLock。可惜如果你现在还想只用 WakeLock 来限制屏幕常亮,你会发现已经做不到了,不过作为一个教科书式的方法,虽然已经被遗弃了,我们还是先来了解一下它。

WakeLock 使用起来也非常的简单。

@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.activity_main);  
  
    PowerManager powerManager = (PowerManager)getSystemService(POWER_SERVICE);  
    if (powerManager != null) {  
        mWakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "WakeLock");  
    }  
}  
  
@Override  
protected void onResume() {  
    super.onResume();  
    if (mWakeLock != null) {  
        mWakeLock.acquire();  
    }  
}  
  
@Override  
protected void onPause() {  
    super.onPause();  
    if (mWakeLock != null) {  
        mWakeLock.release();  
    }  
}

从上面的例子可以看到,WakeLock 主要是通过一个系统服务 PowerManager,然后通过调用它的 acquire() 方法获取一个 WakeLock 资源。

WakeLock 本身也是一种资源,在使用完成之后,别忘了调用 release() 方法进行释放。

而使用 WakeLock 还需要额外的声明 WAKE_LOCK 权限。

<uses-permission android:name="android.permission.WAKE_LOCK" />

前面使用 newWakeLock() 的时候,需要传递一个 Flag,而和屏幕相关的三个 Flag,在 Api Level 17+ 以上均已经被标识为 @Deprecated 了。

这三个 Flag 分别是:

  • SCREEN_DIM_WAKE_LOCK:只限制屏幕,保证亮起,但是允许它亮度变低。

  • SCREEN_BRIGHT_WAKE_LOCK:保证屏幕最高亮,但是键盘背光灯允许熄灭。

  • FULL_WAKE_LOCK:保证屏幕最高亮度,并且键盘背光灯不允许熄灭。

当然,有时候一些被标记为 @Deprecated 的 Api,虽然不再推荐使用,但是依然是可用的。可惜 WakeLock 不在此列,它在高版本上真的被废弃了,你再使用它去阻止息屏,你会发现真的没有效果。

其实这也很好理解,PowerManager 本身就是一个系统资源,如果任由开发者去使用它,可能导致屏幕永远没有机会息屏。可屏幕正是耗电大户,对于 Android 节能的思想,肯定是要被限制的。

既然 Google 已经对它标志位 @Deprecated ,并且实际上也不起作用了,我们就不要再使用它了。不过呢,Google 在废弃这些 Api 的同时,也提供了对应的解决方案,那就是使用 FLAG_KEEP_SCREEN_ON,接下去了解它。

2、FLAG_KEEP_SCREEN_ON

WakeLock 的 FULL_WAKE_LOCK 在被标记为废弃的同时,还提供了一个解决方案,那就是使用 FLAG_KEEP_SCREEN_ON 来控制屏幕常亮。

FLAG_KEEP_SCREEN_ON 使用起来也非常的简单,它是一个页面 Window 对象上的一个 Flag ,使用 addFlags() 方法就可以添加。

getWindow().
addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

当然,这里使用完成之后,也是需要取消掉的。取消这个 Flag 使用 clearFlags() 方法来取消。

getWindow().
clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

通常我们会在一个 Activity 的 onResume() 和 onPause() 方法中,分别调用这两个方法。

看看 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 上,并且保持设备屏幕高亮度的常亮。

其实这里也可以看出来,官方废弃 WakeLock 而推荐使用 FLAG_KEEP_SCREEN_ON ,一部分原因在于 WakeLock 是一个全局的资源,而 FLAG_KEEP_SCREEN_ON 只是一个和 window 相关的资源,作用范围更小了一些。并且它比 WakeLock 更好的一点在于,它不需要额外的申请权限,一般来说,我们还是推荐使用它的。

3、KEEPSCREENON

除了给 Window 添加一个 FLAG_KEEP_SCREEN_ON 的 Flag 之外,还可以对当前页面中,可见的 View 调用 setKeepScreenOn() 方法来设置屏幕常亮。

setKeepScreenOn() 是 View 对象上的方法,同时也提供了布局中的属性 android:keepScreenOn="true" 来方便我们在布局中对其进行设置。

需要注意的一点,使用 setKeepScreenOn() 设置的常亮标识,需要当前 View 保持屏幕可见才行。所以一般而言,我们会在页面的根布局中,添加此属性。

/**
* View flag indicating that the screen should remain on while the
* window containing this view is visible to the user.  This effectively
* takes care of automatically setting the WindowManager's
* {@link WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON}.
*/
public static final int KEEP_SCREEN_ON = 0x04000000;

从这里可以看出来,它只作用在一个被显示的 Window 上,并且保持设备屏幕高亮度的常亮。

其实这里也可以看出来,官方废弃 WakeLock 而推荐使用 FLAG_KEEP_SCREEN_ON ,一部分原因在于 WakeLock 是一个全局的资源,而 FLAG_KEEP_SCREEN_ON 只是一个和 window 相关的资源,作用范围更小了一些。并且它比 WakeLock 更好的一点在于,它不需要额外的申请权限,一般来说,我们还是推荐使用它的。

3、KEEPSCREENON

除了给 Window 添加一个 FLAG_KEEP_SCREEN_ON 的 Flag 之外,还可以对当前页面中,可见的 View 调用 setKeepScreenOn() 方法来设置屏幕常亮。

setKeepScreenOn() 是 View 对象上的方法,同时也提供了布局中的属性 android:keepScreenOn="true" 来方便我们在布局中对其进行设置。

需要注意的一点,使用 setKeepScreenOn() 设置的常亮标识,需要当前 View 保持屏幕可见才行。所以一般而言,我们会在页面的根布局中,添加此属性。

/**
* View flag indicating that the screen should remain on while the
* window containing this view is visible to the user.  This effectively
* takes care of automatically setting the WindowManager's
* {@link WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON}.
*/
public static final int KEEP_SCREEN_ON = 0x04000000;

通过注释文档可以看到,实际上它的原理和 FLAG_KEEP_SCREEN_ON 一样的,只是它更简单,只需要对某个 View 设置,如果该 View 可见即生效,否者就不生效。

4、MEDIAPLAYER的 SETSCREENONWHILEPLAYING()

如果我们是使用一个 MediaPlayer 来进行视频播放的话,MediaPlayer 还提供了 setScreenOnWhilePlaying() 方法,来设置屏幕常量。

它的方法实现如下:

/**
 * Control whether we should use the attached SurfaceHolder to keep the
 * screen on while video playback is occurring.  This is the preferred
 * method over {@link #setWakeMode} where possible, since it doesn't
 * require that the application have permission for low-level wake lock
 * access.
 *
 * @param screenOn Supply true to keep the screen on, false to allow it
 * to turn off.
 */
public void setScreenOnWhilePlaying(boolean screenOn) {
    if (mScreenOnWhilePlaying != screenOn) {
        if (screenOn && mSurfaceHolder == null) {
            Log.w(TAG, "setScreenOnWhilePlaying(true) is ineffective without a SurfaceHolder");
        }
        mScreenOnWhilePlaying = screenOn;
        updateSurfaceScreenOn();
    }
}

之后通过 updateSurfaceScreenOn() 方法来限制屏幕是否常亮。

private void updateSurfaceScreenOn() {
    if (mSurfaceHolder != null) {
        mSurfaceHolder.setKeepScreenOn(mScreenOnWhilePlaying && mStayAwake);
    }
}

它操作的是 SurfaceHolder 的 setKeepScreenOn() 方法,而另外一个条件 mStayAwake ,实际上就是当前的播放状态,当正在播放的时候,它就为 true,所以使用这种方式,只会在视频播放的时候,保持屏幕常亮,正常来说这也是我们对一般播放器的要求。

三、小结

看完本篇文章,你应该知道当你需要保持屏幕常亮的时候,你需要如何做了吧!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值