做 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. System.InvalidOperationException: The binary operator NotEqual is not defined for the types 'Microsoft.EntityFrameworkCore.Storage.ValueBuffer' and 'Microsoft.EntityFrameworkCore.Storage.ValueBuffer'.

    .netcore 2.1使用左表连接时报错,原因是对数据库中实体 DateTimeOffset date做查询判断时,将数据库中date转为string进行了判断,这样判断是错误的,并且效率低,应该是 ...

  2. day01-day02 初识java、注释、变量、变量命名、基本数据类型

    1. 初识java 1) 什么是java java是一门高级的计算机编程语言 2) JDK的安装 2.1) 下载2.2) 安装2.3) 验证 3) 环境变量的配置 3.1) 打开环境变量3.2) 配置 ...

  3. [20191213]toad 12下BIND_AWARE提示无效.txt

    [20191213]toad 12下BIND_AWARE提示无效.txt --//链接http://blog.itpub.net/267265/viewspace-2130781/的测试,发现当时测试 ...

  4. Shell(七):文件包含

    和其他语言一样,Shell 也可以包含外部脚本(类似python中import的功能).这样可以很方便的封装一些公用的代码作为一个独立的文件. Shell 文件包含的语法格式如下: . filenam ...

  5. Linux Ipsec

    准备环境 1 主机ip:192.168.0.107 2 VPN服务器: ens32:192.168.0.102 ens33:127.16.1.10 环境测试 modprobe ppp-compress ...

  6. 【30天自制操作系统】day02:寄存器和Makefile

    基本寄存器 AX(accumulator):累加寄存器 CX(counter):计数寄存器 DX(data):数据寄存器 BX(base):基址寄存器 SP(stack pointer):栈指针寄存器 ...

  7. 针对windows系统如何解决openssl_pkey_export(): cannot get key from parameter 1这个问题

    为了解决这个问题我百度了很多方法,可是很多方法并没有效果. 方法一: 如果你安装的是phpstudy这个集成环境,那么 1.你就要去php拓展里面去打开php_opemssl中打开这个扩展. 2.去p ...

  8. MySQL实现统计数据并插入数据的存储过程

    统计存储过程,这里是将统计的结果插入一个表中,后台可以有定时任务来调此存储过程.以下业务是统计仓库中商品流转情况,包括:日期.商品总数.入库数量.出库数量. BEGIN DECLARE ES_COR_ ...

  9. JS基础语法---Array对象的方法

    Array对象的方法   Array.isArray(对象)---->判断这个对象是不是数组 instanceof关键字 判断对象是不是数组类型:两种方法: //1 instanceof var ...

  10. 入职小白随笔之Android四大组件——服务(Service)

    Service Android多线程编程 当我们在程序中执行一些耗时操作时,比如发起一条网络请求,考虑到网速等原因,服务器未必会立刻响应我们的请求,此时我们就需要将这些操作放在子线程中去运行,以防止主 ...