做 Android 音视频播放器开发的时候,我们基本都会遇到一类需求:音量 & 亮度 调节。其中做亮度调节功能的时候,发现还是有一定复杂度的。

Android亮度调节分为两个类,分别是:

  • Android 系统亮度调节
  • Android 当前屏幕(Window)亮度调节(即App亮度调节)

一、Android系统亮度调节

Android系统亮度调节全局性最高,常见于系统设置中的亮度设置项。Android中提供了获取和设置系统亮度值的接口,具体如下:

// 获取系统亮度
Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS);
// 设置系统亮度
Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS,systemBrightness);

其中,需要注意的是,返回的亮度值是处于0-255之间的整型数值。

Android 2.1以后的系统中,系统亮度调节中新增了“自动亮度”选项。“自动亮度”是依据外界光源来自动的改变系统亮度,目前大部分手机中对“自动亮度”还可以进行小幅度的调节其值。与自动亮度相对应的是“手动亮度”,当处于“手动亮度”下,设置拖动亮度进度条会大幅度的改变Android系统亮度。“手动亮度”和“自动亮度”分别称之为Android系统的“亮度模式”。

与之相对应的,Android系统中也提供了获取和设置“亮度模式”的接口。

// 获取系统亮度模式
Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE);
// 设置系统亮度模式
Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE, systemMode);

可是遗憾的是,Android中并未提供处于“自动亮度”模式下的亮度值接口。上面所说的获取系统亮度值接口实际上都是指“手动亮度”模式下的亮度值。

一般而言,通过手动亮度值以及设置系统亮度模式接口,可以满足常规的大部分针对Android系统亮度设置编码需求,以完成系统亮度调节。

二、Android当前屏幕(Window)亮度调节(App亮度调节)

Android针对当前屏幕(Window)提供了设置亮度的接口,常见写法如下:

Window window = activity.getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
lp.screenBrightness = brightness;
window.setAttributes(lp);

其中,需要注意的是此处的brightness是一个0.0-1.0之间的一个float类型数值。

默认情况下,当我们直接修改了系统亮度值后,当前Window中是可以即时反应出来亮度效果的,这是因为默认情况下,WindowManager.LayoutParams的screenBrightness的默认值为WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE。

即表示Window没有自己的亮度参数,将依随系统亮度效果的变化而变化。这也就是我们最常见的:当调整系统亮度后,所有Window都即时反应出系统亮度设置效果。

当时,实际项目中我们还会遇到此类需求:系统设置亮度时只针对当前Window或App内生效,而不影响到系统本身的亮度设置。

假设当前Window内有一个SeekBar,UI与系统亮度调节UI基本类似,用户可以滑动此SeekBar,使得当前Window亮度即时发生变化,且不影响到系统亮度效果。如何实现呢?

此时我们需要启用WindowManager.LayoutParams的screenBrightness参数,使之具有自动的特定亮度值,设置此值后在当前Window范围内,其将覆盖掉系统亮度设置。

因此,有必要将用户选择的亮度值转换为相应的Window亮度值(为与系统亮度值相一致,假设SeekBar的最大值为255)。

// 根据亮度值修改当前window亮度
public void changeAppBrightness(Context context, int brightness) {
Window window = ((Activity) context).getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
if (brightness == -1) {
lp.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
} else {
lp.screenBrightness = (brightness <= 0 ? 1 : brightness) / 255f;
}
window.setAttributes(lp);
}

其中,brightness形参为用户选择的亮度值。

那么,上述代码中为什么有一个"brightness == -1"的判断呢?在此主要是考虑到App设置项中可能出现的“跟随系统亮度”或“恢复系统默认亮度”此类设置,当用户进行此类操作时,直接将screenBrightness参数还原成默认参数值即可。因为由前文描述“自动亮度”模式下系统亮度值是不能直接得到的,那么当系统处于“自动亮度”模式下,此时brightness参数值将无法准确确定,因此,将screenBrightness参数还原成默认参数值成为一个行之有效的方法。

三、Android App亮度调节可行方案分析

目前网上有不少博文中提到App亮度调节时,提出的方案是在App设置项中,首先记录下设置之前的系统亮度值和亮度模式,用户在App设置项进行亮度调节时,直接修改系统亮度值,当用户退出此App,或App至于后台(如按下Home按键等),再将系统亮度还原。初看起来貌似一个可行的方案。但是主要存在如下几个问题:

1.如何获取到设置之前的系统亮度值和亮度模式(因为之后在此App外部要恢复系统亮度值到此初始值)?当用户每次进入到设置页时获取?严格意义上来说,是没法准确记录的。因为Android的用户操作不可预知性,如进入到设置页,拖动SeekBar设置了一个亮度值,此时直接修改了系统的亮度值,如果此时用户在未将应用至于后台或未将应用退出的情况下直接在App外部修改了系统亮度设置,如小米中可以通过下拉标题栏,直接就可以设置系统亮度。因此,App亮度设置之前的系统亮度初始值获取存在困难。

2.如何判断用户来到了App外部?因为此时需要恢复系统亮度设置到初始系统亮度。如用户可以按下Home按键,长按Home按键直接切换App,直接Back按键等一步步退出此App,下拉标题栏直接点击其他App通知信息进入到其他App,手机自动锁屏后解锁时用户直接进入其他应用等等,此类操作场景也具有不可预知性,因此,判断用户来到了App外部以恢复系统亮度到初始值的时机上也存在一定困难。

由此,App亮度调节方案推荐通过设置当前屏幕(Window)方式进行。

大致思路如下:

1. 用户在设置项中进行亮度调节时,调用changeAppBrightness()方法,将改变当前屏幕(Window)的亮度,此时对系统亮度无任何影响,接下来存在的问题终于要就集中于当用户来到本App其他Activity中,如果使得刚刚设置的亮度值得以即时反应出来。

2. 当用户进行亮度调节后,将当前亮度设置值保存起来(如保存到SharedPreferences中),在基类Activity中的onResume方法中,可以取出SharedPreferences中的用户所设置的App亮度值,然后changeAppBrightness()方法以实现每个当前屏幕的亮度调节。

总体说来,通过设置当前屏幕(Window)的方式来设置App亮度更加简单有效。

Android 亮度调节功能开发思路整理的更多相关文章

  1. [转]Android应用程序框架思路整理

    一.一般Android应用程序架构(Book,购彩,Market). 普通的应用程序由于只需要用到Android的联网与显示的功能,所以应用程序大体上是呈现为UI(Activities)与网络(Net ...

  2. android插件式开发资料整理

    1.DL : Apk动态载入框架 2.android中的动态载入机制

  3. Android 音视频开发学习思路

    Android 音视频开发这块目前的确没有比较系统的教程或者书籍,网上的博客文章也都是比较零散的.只能通过一点点的学习和积累把这块的知识串联积累起来. 初级入门篇: Android 音视频开发(一) ...

  4. [Android实例] 最全的Android开发资源整理--进阶必备

    本帖最后由 一切随枫 于 2014-6-9 12:08 编辑 原文链接: http://stormzhang.github.io/android/2014/06/05/android-awesome- ...

  5. 收集整理Android开发所需的Android SDK、开发中用到的工具、Android开发教程、Android设计规范,免费的设计素材等。

    AndroidDevTools Android Dev Tools官网地址:www.androiddevtools.cn 收集整理Android开发所需的Android SDK.开发中用到的工具.An ...

  6. Android 项目优化(七):阿里巴巴Android开发手册整理总结

    本来之前觉得Android项目优化系列的文章基本整理完毕了,但是近期看了一下<阿里Android开发手册>有了很多收获,想再整理一篇,下面就开始吧. 先在这里列一下之前整理的文章及链接: ...

  7. 最全的Android开发资源整理--进阶必备

    原文链接: http://stormzhang.github.io/android/2014/06/05/android-awesome-resources/ (友情提醒:最近google的很多服务被 ...

  8. 2020年Android开发最新整理阿里巴巴、字节跳动、小米面经,你不看看吗?

    前言 2020年是转折的一年,上半年疫情原因,很多学android开发的小伙伴失业了,虽找到了一份工作,但高不成低不就,下半年金九银十有想法更换一份工作,很多需要大厂面试经验和大厂面试真题的小伙伴,想 ...

  9. Android常见开发思路

    开发思路 刷新: 重新获取数据 清空list 更新适配器 关闭进度条. 加载更多 1. 重新获取数据 添加list 更新适配器 添加轮播条. 自己设计轮播条View 引入lib库文件 设置轮播条数据. ...

随机推荐

  1. iOS Privacy Policy

    This application respects and protects the privacy of all users who use the service. In order to pro ...

  2. birt fatal error致命异常错误

  3. springcloud配置中心

    SpringCloud Config简介 Spring Cloud Config 是 Spring Cloud 团队创建的一个全新项目,用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持 ...

  4. 在kubernetes 集群内访问k8s API服务

    所有的 kubernetes 集群中账户分为两类,Kubernetes 管理的 serviceaccount(服务账户) 和 useraccount(用户账户).基于角色的访问控制(“RBAC”)使用 ...

  5. java基础|自定义java线程池

    线程池创建的参数 在创建线程的各种方式中我们有讲到过通过创建线程池来完成异步操作,但实际上jdk提供的Executors来创建线程池都还有些缺陷,线程池有以下几个参数: 代码节选自源码ThreadPo ...

  6. 高级Java开发人员最常访问的几个网站

    这是高级Java开发人员最常访问的几个网站. 这些网站提供新闻,一般问题或面试问题的答案,精彩的讲座等.质量是优秀网站的关键因素,这此网站都有较高的质量内容.下面逐一介绍: 1. Stackoverf ...

  7. pillow模块Image.crop()函数切割图片方法,参数说明

    使用Image.crop()方法对图片进行切割. 参数: Image.crop(left, up, right, below) left:与左边界的距离 up:与上边界的距离 right:还是与左边界 ...

  8. JS---DOM---元素创建的不同方式---三种方式,5个案例

    元素创建-----为了提高用户的体验   元素创建的三种方式: 1. document.write("标签的代码及内容"); 2. 对象.innerHTML="标签及代码 ...

  9. 搭建mount+nfs远程挂载

    需求背景: 192.168.10.100 源服务器 目录:/root/test 目录属主属组普通用户,权限777 192.168.10.111 目标服务器 目录:/root/test111 目录属主属 ...

  10. Android Fragment 多层叠加时点击穿透解决方案

    一.问题现象 多层fragment叠加时,点击上层fragment会使下层fragment的控件对应点击事件响应,这种现象就是点击穿透. 对于这种情况,我们一般都是对baseFragment进行vie ...