当夜间使用手机等终端, 直接降低屏幕亮度, 能减少光线强度对眼镜的刺激, 这也是最简单, 也相对有效的方式. 同时记得先添加相应权限
通过设置屏幕亮度来实现的方法, 有两种:
一般, Android里每个Activity对应一个可视的界面, 针对每个Activity去设置亮度, 方法如下:
public static void setBrightness(Activity activity , float brightnessValue)
{
WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
if(brightnessValue > 1.0f)
{
lp.screenBrightness = 1.0f;
}
else if(brightnessValue <= 0.0f)
{
lp.screenBrightness = 0.0f;
}
else
{
lp.screenBrightness = brightnessValue;
}
activity.getWindow().setAttributes(lp);
}
这里, 我们直接在程序的某个Activity, 比如入口Activity去设置整个手机的亮度. 由于已经设置手机全局的亮度, 那么后面无论跳转到哪个界面, 甚至退出程序, 手机的亮度依然是所设置的亮度. 这种方法相对第一种而言算是一劳永逸. 但这里我们先要理清思路, 考虑好几个点:
打开应用后, 获取手机原来的亮度值并保存它(可用于退出应用后恢复正常亮度) ---> 如果手机打开自动亮度调节则关闭自动调节, 然后设置合适的较低亮度 ---> 将设置的亮度值应用到手机中 ---> 最后,退出应用时利用保存的原亮度值恢复原来亮度, 并重新打开手机的自动亮度调节.
接下来, 贴上关键代码:
首先是获取手机屏幕亮度值:
/**
* 获取当前系统亮度
*
获取失败返回-1,获取成功返回正常非负数
* @param context
* @return
*/
public static int getSystemBrightness(Context context)
{
int brightnessValue = -1;
try
{
brightnessValue = Settings.System.
getInt(context.getContentResolver(),Settings.System.SCREEN_BRIGHTNESS);
}
catch (Exception e)
{
e.printStackTrace();
}
return brightnessValue;
}
保存, 直接放在SharePreference里面就好了, 相关代码就不写了.
然后检测手机是否打开亮度自动调节的开关:
/**
* 是否打开自动调节亮度
* @param contentResolver
* @return
*/
public static boolean isAutoBrightness(ContentResolver contentResolver)
{
boolean autoBrightness = false;
try
{
autoBrightness
= Settings.System.getInt(contentResolver ,
Settings.System.SCREEN_BRIGHTNESS_MODE)
== Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
}
catch (Exception e)
{
e.printStackTrace();
}
return autoBrightness;
}
如果打开, 就关闭:
/**
* 停止自动调节亮度
* @param activity
*/
public static void closeAutoBrightness(Activity activity)
{
Settings.System.putInt(activity.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
}
最后还会用到打开亮度调节:
public static void openAutoBrightness(Activity activity)
{
Settings.System.putInt(activity.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
}
关闭亮度调节后, 就设置亮度, 直接使用第一种方法中的相关代码即可. 但因为要将该亮度的设置应用到全局, 所以需要将该亮度值保存到手机中:
/**
* 保存全局的亮度值设置
* @param contentResolver
* @param brightnessValue 亮度值
*/
public static void saveBrightness
(ContentResolver contentResolver , int brightnessValue)
{
Uri uri = android.provider.
Settings.System.getUriFor(screen_brightness);
android.provider.Settings.System.putInt(contentResolver,
screen_brightness , brightnessValue);
contentResolver.notifyChange(uri, null);
}
自定义View, 相信很多人都很熟悉. 而自定义Theme跟这个类似, 也是实现夜间模式最常用的方法, 因为它不止可以实现夜间模式, 还能实现常见的主题更换功能. 这里就不细说, 只讲思路. 假设我们的应用界面是白色背景, 黑色文字, 夜间模式就是黑色背景, 灰白色的文字. 这种夜间模式有别于第一种的调节亮度, 由于背景和内容文字可以随意的设置颜色和透明度, 这种夜间模式看起来更直观,也可以更舒服.
自定义Theme利用的是, 在XML中定义要用到的背景和文字颜色属性, 比如:
这里, 我们应当明白一个概念, 当不必深究, window(窗口). Android的设计理念中, 给几乎每个显示的组件都设置包含在一个window中. Activity也有它自己的window. 通过在window添加一层灰黑色有一定透明度的view, 使它看起来是屏幕变暗了, 当然实际上手机的亮度是没有变化的, 这种实现, 可以叫遮罩, 类似相机拍照时在镜头套一层膜或者镜片上去, 使呈现的效果有所不同. 但是这种方法, 也有不好的地方, 就是类似上面说的单独在每个Activity去设置它的亮度. 这里每进入一个界面就需要重新套一层view上去, 相对一劳永逸的方法而言, 显得没优势. 那么直接上代码:
WindowManager manager = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_APPLICATION,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP;
params.y = 10;// 距离底部的距离是10像素 如果是 top 就是距离top是10像素
TextView tv = new TextView(this);
tv.setBackgroundColor(0x55000000);
manager.addView(tv,params);
代码中, 通过WindowManager.LayoutParams的参数设置, 禁止所添加遮罩层的触摸和聚焦. 这样使得即使添上一层View, 也不会影响Activity视图中的组件正常使用.
其实上面三种方法, 放在现在来看, 都不是新的技术, 而网上我也看过很多相关的代码, 这里这只是放在一起做个对比和总结. 上面根据三种实现方法说了各自的特点, 综合而言, 第一, 二种方法比较可取, 而究竟选择第一还是第二种方法, 应该看具体需求, 如果你的应用只是简单的要求降低亮度, 不想修改太多的代码, 那么第一种会比较适合; 如果希望有良好的体验, 希望看起来更酷, 甚至还想添加其他的主题, 比如蓝色, 绿色的主题等等, 那么无疑第二种是最好的选择. 自定义属性的广泛应用, 给我们实现更个性化的视觉效果(比如自定义组件, 自定义主题等)提供了便利.