Android 屏幕亮度限制,最大亮度设为目前亮度多少、最小亮度设为以前亮度多少

Android 屏幕 亮度太亮、亮度太暗,最大亮度设为目前亮度多少、最小亮度设为以前亮度多少


一、需求-场景-注意事项

需求: Android 屏幕适配,最大亮度设为目前亮度多少、最小亮度设为以前亮度多少。

场景: 首先要搞清楚,为什么会有这样的场景,对于搞应用开发的很难理解。

  • Android系统一样的,但是定制需求里面 不同的客户有自己的屏幕,屏幕规格、显示效果完全不一样,实际情况下会有少许异常。
  • 异常情况一:亮度在0%-30% 屏幕亮度调节不变化;亮度在80%-100% 屏幕亮度不变化。
  • 异常情况而:亮度在0%-30% 屏幕太暗了;屏幕在80% 开始,亮度太亮了。
  • 屏幕原因:功耗要求,要求功耗低一些,尽量低功耗。

注意事项:
如上,场景和需求,那么实际情况需要达到什么效果和闭坑:

  • 效果要求:实际的亮度要达到要求,按照需求来。裁剪、截取亮度范围值。
  • UI要求:对于SystemUI/系统设置里面 亮度条调节需要有作用。
  • 兼顾实际需求和效果,综合处理。

真实需求: 要求 屏幕亮度为原最大亮点85%

二、参考资料

Android 亮度范围定制

这是之前产品需求的解决方案,这里有解决方案,极具参考意义: 主要修改两个点:


修改点一:
修改位置:\frameworks\base\core\java\com\android\internal\display\BrightnessSynchronizer.java
设置最低亮度为最大亮度的65%,即:255*0.65=166

修改点二:
 /frameworks/base/core/java/android/os/PowerManager.java
BRIGHTNESS_MIN 最小亮度调节范围改为0.65f

注意事项:
实际效果有待各自实际验证:这里有两个特别注意点

LightsService分析 — 概述
LightsService分析 — 流程分析
LightsService

三、修改的文件

frameworks/base/services/core/java/com/android/server/lights/LightsService.java

四、解决方案

LightsService.java 中的 setBrightness(float brightness, int brightnessMode) 方法中进行修改

在这里插入图片描述

获取到:brightnessInt 后如果如下需求

  • 最大亮度值限制为85% 217,如:brightnessInt>=217 brightnessInt=217
  • 最小亮度值限制为30% 76,如:brightnessInt <=76 brightnessInt=76

五、源码相关介绍

这里分析一下关联的类,从整体来感知、认识相关关联知识点,让知识点穿了起来:

  • brightness : 亮度范围值:0-255
  • LightsService: 可以理解为系统亮度服务,最终调用native 方法,
  • BrightnessSynchronizer: 可以理解为一个协调器
    同样,还有PowerManager 相关知识点的

核心摘要 brightness - LightsService - BrightnessSynchronizer

  • 亮度范围 0-255: 这是数据模型和通信协议。它定义了亮度值的表示方法,是三者交互的“通用语言”。

  • LightsService.java: 这是底层硬件抽象服务。它接收 0-255 的亮度值,并通过 HAL 层将其转换为驱动能识别的具体信号,最终控制 LED 灯(如通知灯、背光)。

  • BrightnessSynchronizer: 这是高层业务逻辑与显示管理的协调器。它在不同的亮度系统(如显示背光和 LED 灯)之间进行转换和同步,确保它们使用共同的 0-255 语言进行通信。

工作流程举例(设置屏幕亮度)

假设用户拖动亮度滑块到中间位置:

  • 1、UI 层: 滑块控件产生一个值,比如 128 (在 0-255 范围内)。

  • 2、SystemUI / Settings: 通过 IPowerManager 接口调用 PowerManagerService 的 setTemporaryBrightness 方法,并传入 128。

  • 3、PowerManagerService: 接收到 128 这个值。它可能会利用 BrightnessSynchronizer 的一些方法来进行内部计算或持久化(比如转换为浮点数用于计算)。

  • 4、BrightnessSynchronizer: (在此例中主要起辅助作用,确保 PMS 内部逻辑一致)。

  • 5、PowerManagerService: 最终决定要将屏幕亮度设置为 128。它调用 LightsService 的 setLight 方法,指定 LIGHT_ID_BACKLIGHT 和亮度值。

  • 6、LightsService.java: 收到指令,lightId 是背光,亮度是 128。它通过 Lights HAL 调用到 Vendor 实现的 HAL 代码。

  • 7、HAL & Driver: HAL 实现可能将 128/255 ≈ 50% 的亮度转换为硬件特定的 PWM 值或寄存器值,并写入屏幕背光驱动。

  • 8、硬件: 屏幕亮度发生变化。

核心知识点-对比表

特性BrightnessSynchronizerLightsService.javaSCREEN_BRIGHTNESS (0-255)
核心角色协调器、转换器执行者、硬件抽象数据契约、通用语言
功能层级框架层,业务逻辑系统服务层,接近HAL贯穿所有层
主要职责在不同亮度系统间同步和转换数据控制物理LED/灯光硬件定义亮度值的表示法
工作内容被其他组件调用的工具 floatToInt, intToFloat, 同步逻辑接收指令,调用HAL接口无,它是一个数值范围
关联关系为下游(如PMS/LightsService)准备数据是BrightnessSynchronizer下游的消费者是两者之间通信的桥梁和基础

六、源码知识点

日常调用设置亮度Brightness

通过 Settings.System 直接取值和设置值实现

public final class BrightnessUtils {

    private BrightnessUtils() {
        throw new UnsupportedOperationException("u can't instantiate me...");
    }

    /**
     * Return whether automatic brightness mode is enabled.
     *
     * @return {@code true}: yes<br>{@code false}: no
     */
    public static boolean isAutoBrightnessEnabled() {
        try {
            int mode = Settings.System.getInt(
                    Utils.getApp().getContentResolver(),
                    Settings.System.SCREEN_BRIGHTNESS_MODE
            );
            return mode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Enable or disable automatic brightness mode.
     * <p>Must hold {@code <uses-permission android:name="android.permission.WRITE_SETTINGS" />}</p>
     *
     * @param enabled True to enabled, false otherwise.
     * @return {@code true}: success<br>{@code false}: fail
     */
    public static boolean setAutoBrightnessEnabled(final boolean enabled) {
        return Settings.System.putInt(
                Utils.getApp().getContentResolver(),
                Settings.System.SCREEN_BRIGHTNESS_MODE,
                enabled ? Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
                        : Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL
        );
    }

    /**
     * 获取屏幕亮度
     *
     * @return 屏幕亮度 0-255
     */
    public static int getBrightness() {
        try {
            return Settings.System.getInt(
                    Utils.getApp().getContentResolver(),
                    Settings.System.SCREEN_BRIGHTNESS
            );
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 设置屏幕亮度
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.WRITE_SETTINGS" />}</p>
     * 并得到授权
     *
     * @param brightness 亮度值
     */
    public static boolean setBrightness(@IntRange(from = 0, to = 255) final int brightness) {
        ContentResolver resolver = Utils.getApp().getContentResolver();
        boolean b = Settings.System.putInt(resolver, Settings.System.SCREEN_BRIGHTNESS, brightness);
        resolver.notifyChange(Settings.System.getUriFor("screen_brightness"), null);
        return b;
    }

    /**
     * 设置窗口亮度
     *
     * @param window     窗口
     * @param brightness 亮度值
     */
    public static void setWindowBrightness(@NonNull final Window window,
                                           @IntRange(from = 0, to = 255) final int brightness) {
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.screenBrightness = brightness / 255f;
        window.setAttributes(lp);
    }

    /**
     * 获取窗口亮度
     *
     * @param window 窗口
     * @return 屏幕亮度 0-255
     */
    public static int getWindowBrightness(@NonNull final Window window) {
        WindowManager.LayoutParams lp = window.getAttributes();
        float brightness = lp.screenBrightness;
        if (brightness < 0) return getBrightness();
        return (int) (brightness * 255);
    }
}

LightsService.java 源码了解

直接看类构成,类构成、核心方法、内部类等:

在这里插入图片描述

在这里插入图片描述

setBrightness(float brightness, int brightnessMode) 到底是被谁调用的

这里只是提出一个简单流程图,如果需要了解流程,暂自己去分析下:

DisplayPowerController.updatePowerState()
-> DisplayPowerController.sendUpdatePowerState()
   -> ... (经过一些内部计算和路由)
   -> LightsSession.setBrightness()
      -> LightsManager.setBrightness() // 接口调用
         -> LightsService.setBrightness() // 具体实现

PowerManagerService PMS 关联的LishtService 知识点

关联Lights 相关内容如下:
在这里插入图片描述

DisplayPowerController

这里我们不详细分析,只看类定义如下:
在这里插入图片描述

控制显示屏的电源状态。

  • 处理接近传感器、光线传感器以及状态间的动画效果包括屏幕关闭动画。
  • 该组件独立于电源管理服务的其他部分运行
  • 特别说明:它不共享任何状态,仅通过异步回调进行通信以通知电源管理器某些状态已发生变化。
  • 该类内部的所有操作都在其处理器上序列化执行但外部可能被其他线程访问。
  • 请注意,只要显示屏未就绪,电源管理服务就会保证持有暂停锁因此此处完成的大部分工作无需担心持有暂停锁的问题
    ,除非某些操作独立于显示屏就绪信号而发生。
  • 为便于调试,您可通过修改开发者选项中的“动画程序时长缩放”选项
  • 调慢色彩淡入淡出和亮度动画的播放速度。

总结

  • 这里给出了限制最大亮度和最小亮度限制的解决方案,在实际开发中解决屏幕太亮或者太暗的常见解决方案
  • 通过需求,这里了解Android 体系里面的一个服务 LightsService 服务和关联的部分知识点。

这里综合 对比下 Android 亮度范围定制,都是屏幕量暗的解决方案,搞清楚适合的场景:

  • Android 亮度范围定制 解决了0%-30% 或者 80%-100% 亮度无变化的解决方案,但是实际第三方 通过ContentProvider 或者 Settings 得到的值就不全了,比如说:60-225 范围了。 但是系统SystemUI 能够通过进度条控制亮度,调节有用。 主要解决高亮度和低亮度下系统亮度条无变化的 问题。
  • 这里设置最大亮度值大和最低量亮度值,取终。 目的解决了亮度太亮和亮度太暗的问题,亮度范围也可以是0-255区间范围。 但是会造成 比如 30% 和 80% 以上,亮度条调节无用了。

每种解决方案有自己的诉求,根据实际客需 解决实际问题即可。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

野火少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值