现在市面上的手机一般都带有护眼模式,因此这里自己在系统里面添加这样一个功能
系统的护眼模式,应该是默认关闭,用户可以在设置中操作,用户打开之后如果没有关闭会一直存在的,并且在所有视图之上,因此这里通过service来实现这个功能,并且我们需要将这个功能添加到设置中可以让用户自己选择打开还是关闭
这里主要通过WindowManager添加一个view ,然后通过控制view的背景颜色来实现护眼
mWindowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
view = new FrameLayout(this);
view.setBackgroundColor(Color.TRANSPARENT);
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR ;//显示在所有内容之上
params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL//即使在该window在可获得焦点情况下,仍然把该window之外的任何event发送到该window之后的其他window.
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE//让window不能获得焦点,这样用户快就不能向该window发送按键事件及按钮事件
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;//让该window不接受触摸屏事件
params.format = PixelFormat.TRANSLUCENT;//window透明
params.width = WindowManager.LayoutParams.MATCH_PARENT;//全屏
params.height = WindowManager.LayoutParams.MATCH_PARENT;
mWindowManager.addView(view,params);
护眼和不护眼
/**
* 开启护眼模式
*/
public void openEye() {
view.setBackgroundColor(getFilterColor(30));
}
/**
* 关闭护眼模式
*/
public void closeEye() {
view.setBackgroundColor(Color.TRANSPARENT);
mWindowManager.removeViewImmediate(view);
}
过滤蓝光的主要方法
/**
* 过滤蓝光
*
* @param blueFilterPercent 蓝光过滤比例[10-30-80]
*/
public int getFilterColor(int blueFilterPercent) {
int realFilter = blueFilterPercent;
if (realFilter < 10) {
realFilter = 10;
} else if (realFilter > 80) {
realFilter = 80;
}
int a = (int) (realFilter / 80f * 180);
int r = (int) (200 - (realFilter / 80f) * 190);
int g = (int) (180 - (realFilter / 80f) * 170);
int b = (int) (60 - realFilter / 80f * 60);
return Color.argb(a, r, g, b);
}
然后主要是service启动时开启护眼模式,service停止时关闭护眼模式
@Override
public void onDestroy() {
super.onDestroy();
closeEye();
}
然后我们可以在SettingsProvider添加护眼模式的默认属性值,这里默认关闭
false
然后要在frameworks\base\core\java\android\provider\Settings.java中定义这个全局变量EYESHIELD_MODE
public static final String EYESHIELD_MODE = "eyeshield_mode";//护眼模式
然后frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.java的loadGlobalSettings方法中load
loadBooleanSetting(stmt, Settings.Global.EYESHIELD_MODE,
R.bool.def_eyeshield_mode);
在设置中添加开关就是根据上面def_eyeshield_mode值来的 具体怎么添加可以参考我之前的文章一个基于Android 7.1 基于Android 7.1在Setting中增加开关 还有基于 4.4 基于Android 4.4 Settings增加开关
然后我们在\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\StatusBar.java的start方法中
注册观察者来监听
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.EYESHIELD_MODE), false,
mEyeshieldObserver);
private final ContentObserver mEyeshieldObserver = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
Intent intent =new Intent();
intent.setComponent(new ComponentName("com.android.systemui", "com.android.systemui.statusbar.service.EyeShieldService"));//这样不用导包
final Boolean mode = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.EYESHIELD_MODE, 0)!=0;
if(mode){
Log.e("Eyeshield"," [start-EyeShieldService] ");
mContext.startService(intent);
}else{
Log.e("Eyeshield"," [stop-EyeShieldService] ");
mContext.stopService(intent);
}
}
};
这里要调用一下观察者的onChange方法,否则开机时不会调用到
mEyeshieldObserver.onChange(false); // set up
这样的话 设置中只需要改变值即可 如下所示
Settings.Global.putInt(appActivity.getContentResolver(),
Settings.Global.EYESHIELD_MODE, 0);
Settings.Global.putInt(appActivity.getContentResolver(),
Settings.Global.EYESHIELD_MODE, 1);