Android实现保持屏幕常亮功能
笔者所在公司做的app是股票类的,用户在查看股票报价页面的时候,往往需要开启盯盘模式,这个时候屏幕是不能黑屏的,黑屏会导致用户看不到一些关键报价涨跌,错过了买入卖出的最佳时机,就会给用户造成损失,这是股票类软件所不能容许的,所以一般的股票类app都会有屏幕常亮功能。
当初我们做这个功能的时候,在网上找了一些教程发现有些达不到效果,然后找到了一种比较完美的没有兼容性的实现方案,下面给大家分享一下。
网上有一种解决方案是使用powermanager来实现屏幕不锁屏:
/** * 打开休眠锁只能保持手机不休眠 * @param context */ @deprecated public static void openwakelock(context context) { powermanager powermanager = (powermanager) context.getsystemservice(service.power_service); powermanager.wakelock wakelock = powermanager.newwakelock(powermanager.screen_dim_wake_lock, "my lock"); //是否需计算锁的数量 wakelock.setreferencecounted(false); //请求常亮,onresume() wakelock.acquire(); }
但这种方式在实际的测试过程中并没有达到屏幕常亮的效果,而且还需要申明权限,不然会崩溃,所以这种方式被 pass 掉了:
<uses-permission android:name="android.permission.wake_lock" />
后来发现其实常亮功能很简单,只需要在在当前的activity中获取到window对象然后调用它的addflags方法加上一个windowmanager.layoutparams.flag_keep_screen_on 的标识。
window window = activity.getwindow(); window.addflags(windowmanager.layoutparams.flag_keep_screen_on);
然后关闭常亮功能的时候则只需要window清除这个windowmanager.layoutparams.flag_keep_screen_on标识即可
window.clearflags(windowmanager.layoutparams.flag_keep_screen_on);
所以我们简单的封装了一下,只要是哪个页面activity想要屏幕常亮则调用如下方法即可:
/** * 是否使屏幕常亮 * * @param activity */ public static void keepscreenlonglight(activity activity) { boolean isopenlight = commsharedutil.getinstance(activity).getboolean(commsharedutil.flag_is_open_long_light, true); window window = activity.getwindow(); if (isopenlight) { window.addflags(windowmanager.layoutparams.flag_keep_screen_on); } else { window.clearflags(windowmanager.layoutparams.flag_keep_screen_on); } }
在想要屏幕常亮的activity的oncreate()方法中调用如下方法即可:
@override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); longlightutils.keepscreenlonglight(this); }
因为屏幕常亮功能是可以在设置中设置开关的,而且下次用户进app需要保存上一次的设置,所以我们把是否打开常亮功能保存在了sharedpreferences中。
如果整个app的页面都要实现屏幕常亮该怎么做?难道在所有的activity中的oncreate()都写调用这个方法吗?
答案显然不是,这样太没有效率。
一般情况我们的项目里都会有baseactivity,basefragment之类的父类,来抽离出通用的方法和样式规范,所以我们可以在所有的activity都会继承的baseactivity中oncreate()判断是否需要屏幕常亮功能,这样它的子类就具有了这个功能,像这样:
public class baseactivity extends appcompatactivity { @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); longlightutils.keepscreenlonglight(this); } }
另外还有一种情况,我们的app中不是所有的activity都是会继承baseactivity,比如有些页面我们需要用h5和原生交互,为了交互更加方便安全一般会选用cordova,而负责交互打开h5页面的activity是需要继承cordovaactivity,这样才能实现交互。cordovaactivity是第三方的activity显然是和我们的baseactivity是没有关系的。
同时如果我们集成了一些第三方的sdk,打开他们的sdk里面的页面如果也需要屏幕常亮功能的话,该怎么办?因为我们也无法去修改他们的代码,不能在他们activity中加入屏幕常亮功能。
这个时候其实有个很黑科技的功能,可能你以前都没有见到过,那就是在application中有一个方法,
registeractivitylifecyclecallbacks,可以传入一个回调接口,里面有当前app中所有的activity的生命周期方法回调,可以获取到所有的activity实例,这样我们就能实现所有的app页面都能屏幕常亮了:
public class myapplication extends application{ @override public void oncreate() { super.oncreate(); registeractivitylifecyclecallbacks(new activitylifecyclecallbacks() { @override public void onactivitycreated(activity activity, bundle bundle) { } @override public void onactivitystarted(activity activity) { } @override public void onactivityresumed(activity activity) { longlightutils.keepscreenlonglight(activity); } @override public void onactivitypaused(activity activity) { } @override public void onactivitystopped(activity activity) { } @override public void onactivitysaveinstancestate(activity activity, bundle bundle) { } @override public void onactivitydestroyed(activity activity) { } }); } }
我们在activitylifecyclecallbacks的onactivityresumed方法中调用屏幕常亮的方法即可实现,application中registeractivitylifecyclecallbacks方法在热修复框架中应该是比较常用到的,非常的实用。
最后附上屏幕常亮的示例项目地址,有需要的朋友可以去看看。https://github.com/finddreams/screenlonglight
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。