21

如何在 Android 中获得首选的屏幕亮度?

要更改屏幕亮度,我使用WindowManager.LayoutParams.screenBrightness。根据文档:

这可用于覆盖用户首选的屏幕亮度。默认值小于 0 表示使用首选屏幕亮度。0 到 1 将亮度从暗调整为全亮。

screenBrightness小于 0 我想从首选的屏幕亮度开始。我怎样才能得到这个值?

4

3 回答 3

47

我会尝试回答,因为我前段时间已经搜索过了。我的简短回答是:经过广泛研究,我从未找到在自动模式下获得当前亮度级别的方法。

我将把它分解成多个答案。我不会跳过前提,以便 googlers 可以发现这很有帮助。跳过你不需要的东西。

1-获取亮度设置值

screenBrightness小于 0 我想从首选的屏幕亮度开始。我怎样才能得到这个值?

对于一个有这么多声誉的人,我相信你已经知道搜索的技巧。SO上有很多关于这个的答案。只需检查具有类似问题的右侧面板......也就是说,我不会详细说明。

int oldBrightness = Settings.System.getInt(getContext().getContentResolver(), 
             Settings.System.SCREEN_BRIGHTNESS);

这就是 AndroidBrightnessPreference.java在 2.3.5 中的做法(参见第 68 行)。它也与 lfor 发布的内容相同(出于实际原因)。

它不是无缘无故地命名为的亮度。这是存储在某处的设置,而不是当前值。如果您进入手动亮度模式,您只能确定它与用户的体验相同。否则,你只是不知道。你应该检查:

int mode = Settings.System.getInt(getContext().getContentResolver(),
                     Settings.System.SCREEN_BRIGHTNESS_MODE);

2-听屏幕亮度变化

我们知道,一般来说,当我们想监听Android中的变化时,我们可以尝试监听Intentactions,注册BroadcastReceivers等等。但是,AFAIK没有ACTION_亮度变化,SCREEN_[ON|OFF]例如 。也许系统中隐藏了一个,但我从未见过它,如果它不是公开可用的,那么您处理它时可能会遇到所有可能的陷阱。

2010 年 12 月,黛安·哈克伯恩 (Dianne Hackborn) 发来一条消息,她说“没有关于屏幕亮度变化的广播”

所以,我不相信有办法连接到这样的东西。当然,您可以更改设置本身:

Settings.System.putInt(getContext().getContentResolver(),
    SCREEN_BRIGHTNESS_MODE, SCREEN_BRIGHTNESS_MODE_AUTOMATIC);

3-聆听环境光的变化

但是,您可以。检测光量。您需要implements SensorEventListener并且:

// class definition:
private SensorManager sensorManager;

@Override
public void onSensorChanged(SensorEvent event) {
    float values = event.values[0]; // Ambient LUX
}
// onCreate:
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);   
sensorManager.registerListener(this,
    sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT),
    SensorManager.SENSOR_DELAY_UI);

4-猜亮度变化

说了这么多,我还必须重复哈克伯恩的问题:“你想要完成什么?” (这是给赏金所有者的)。我很高兴看到 Android 如何将环境照度映射到屏幕亮度。我很确定这不是线性的(Sensor.getMaximumRange()线性映射到 0..1 浮点间隔)。我已经看到这通常是映射的对数(对较低的亮度范围提供更精细的调整),但我不知道这些参数。也许每个人都使用建议的默认方式,但我不是专家。

如果您可以通过查看它执行此操作的源中的位置来找到Android 是如何执行此操作的,那就太好了。但不管怎样,我来这么久也没有给你留下同样的问题。我发现这Sensor.getMaximumRange()与您从SensorEvent values[0]. 在这里,我有一个 Sharp 传感器 (Nexus S),虽然报告最大值为 3,000,但我看到的值高达 10,240。

因此,获取传感器并不可靠(?)。我猜测,根据我在使用 Android 时看到的行为,它以某种方式将 getMaximumValue() 映射到最大亮度,而高于它的任何值都没有任何区别。

5- 从这里去哪里

我会更多地研究Android资源。在某个地方,可能在较低级别的硬件管理中,您可以看到它们是如何映射的。不过,我想知道这是否可靠,考虑到 Dianne Hackborn 所说的话(他们似乎不希望你这样做)。我猜他们有理由不暴露这一点。或许需要:为什么app一定要知道系统设置?它要么需要提供自己的应用范围级别,要么在极端情况下,为系统范围的替换或管理器提供自己的“自动亮度更改方法”(如上文第 4 点)。也许这就是原始开发人员的想法。

无论如何,如果有人找到其他细节,我会非常高兴知道。

于 2011-11-13T20:02:23.133 回答
0

截至目前(android 12),情况比@davidcesarino 在他的综合回答中描述的要复杂。我确实按照建议查看了源代码,它非常复杂。除其他外,自动亮度模式具有快速和缓慢的亮度变化,以响应环境光水平的变化。

然而,整个事情取决于一堆可能由设备制造商指定的系统资源,它们都隐藏在 中com.android.internal.R.styleable,无法从用户构建的应用程序中访问。

context.getResources().getIdentifier(...)如果您可以通过查看 Android 源代码找到资源的名称,则可以使用它们来获取它们 。但是 getIdentifier(),目前已弃用,并且可能会在将来的某个时间消失。

更有问题的 Settings.System.SCREEN_BRIGHTNESS是,用户在“设置”页面中设置的亮度不再一定是:这取决于设备制造商如何配置它。在我的新三星 Galaxy S21 上,这是在自动模式下调整的亮度。更奇怪的是,在自动模式下,设置页面亮度滑块会显示调整后的值,并且会随着您在明亮区域和昏暗区域之间移动手机而移动。

有两种以编程方式设置屏幕亮度的方法。您可以设置Settings.System.SCREEN_BRIGHTNESS(范围为 0 .. 255),但在 API 级别 23 之后的 Android 版本上,这需要只能动态请求的运行时权限。

getWindow().getAttributes().screenBrightness您还可以仅使用(范围为 0.0F .. 1.0F 或 -1.0F 以不覆盖系统设置)设置应用程序当前顶级窗口的亮度 。

如果您只想在应用程序中设置屏幕亮度,这是最简单的解决方案,因为它不需要权限。

至少如果您的屏幕使用深色背景,实现类似效果的另一种方法是降低所有小部件的不透明度。这在 OLED 屏幕上效果很好,只有点亮的像素会消耗电力,但在背光屏幕上效果不佳。

但是,在 Android 上似乎无法以编程方式确定显示器是背光还是 OLED,请参阅此 stackoverflow 问题

在 github 上发布了一个小应用程序,您可以使用它来查看您的设备如何以上述各种方式进行亮度控制。它还包含完成我上面描述的所有事情的代码,如果需要,您可以复制这些代码。

于 2022-02-07T20:35:35.573 回答
-1

很好地回答所问的问题,您可以从Settings.system.SCREEN_BRIGHTNESS获得首选亮度范围看起来是 0-255。

int UserBrightness = Settings.System.getInt(getContentResolver(), 
            Settings.System.SCREEN_BRIGHTNESS,-1); 

目前的实际亮度是多少,由自动模式或应用程序设置它自己的亮度是一个不同的问题,我也会对答案感兴趣。

于 2011-11-13T16:05:37.110 回答