如何检测Android上的屏幕亮度范围?

问题描述 投票:0回答:4

我使用以下代码来设置屏幕亮度,这在大多数手机上都可以正常工作:

    protected fun setBrightness(value: Float) {
        //Set the system brightness using the brightness variable value
        Settings.System.putInt(contentResolver, Settings.System
            .SCREEN_BRIGHTNESS, (value * 255).toInt())
        //Get the current window attributes
        val layoutpars = window.getAttributes()
        //Set the brightness of this window
        layoutpars.screenBrightness = value
        //Apply attribute changes to this window
        window.setAttributes(layoutpars)
    }

当我传递值 1(表示最大值)时,它会转换为 255,据说这是设置屏幕亮度的最大值。然而,在小米8上,将值设置为255不会将亮度设置为全范围,如以下屏幕截图所示:

在打印一些调试值并进行实验后,看起来小米8上的最大亮度值实际上是1024(或者至少,将该值乘以1设置完整的亮度条)。

似乎不同的 Android 设备可能有不同的亮度等级。是否有一些 API 可以获取亮度最大值,这样我就不需要硬编码不同的常量?

android brightness screen-brightness
4个回答
7
投票

使用此方法获得亮度最大值

public int getMaxBrightness(Context context, int defaultValue){

    PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    if(powerManager != null) {
        Field[] fields = powerManager.getClass().getDeclaredFields();
        for (Field field: fields) {

            //https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/os/PowerManager.java

            if(field.getName().equals("BRIGHTNESS_ON")) {
                field.setAccessible(true);
                try {
                    return (int) field.get(powerManager);
                } catch (IllegalAccessException e) {
                    return defaultValue;
                }
            }
        }
    }
    return defaultValue;
}

我已经在几台设备上对此进行了测试(主要是 android 9、10 设备,包括一些小米设备,通常将亮度设置为高于通常的 255),看起来效果很好。

Google 不提倡使用反射访问隐藏字段/方法。任何 Android 更新都可能会破坏此解决方案。

另一种可能的解决方案是使用反射访问PowerManager类中的

getMaximumScreenBrightnessSetting()
方法。但我没有测试过,因此无法确认结果。

NB:如果您使用此值来设置亮度百分比,请记住这一点:从 android 9 开始,亮度设置为对数。因此,设置亮度百分比可能看起来不像亮度滑块中显示的百分比(较低的百分比可能看起来高于亮度滑块上的设置值),但物理亮度将设置正确。


5
投票

特定于某些小米设备。例如小米红米Note 7有0-4000范围。

官方文档定义 SCREEN_BRIGHTNESS 范围为 0-255。所以,我认为没有API可以获取亮度的最大值。

在某些(不是全部)设备上,有一个文件“/sys/class/leds/lcd-backlight/max_brightness”可以包含最大值。


1
投票

而不是设置 255 作为最大值。我更喜欢用这种方式将亮度设置为最大。只是将 1F 传递给屏幕亮度。

WindowManager.LayoutParams layout = getWindow().getAttributes();
layout.screenBrightness = 1F;
getWindow().setAttributes(layout);

它在不同的 Android 设备上运行良好。


0
投票

我还尝试获取亮度(Android P、API 28 的对数变体)。这就是我所做的(见下面的代码):

  • 对 Google 公开可用的 API (https://cs.android.com/) 进行逆向工程,
  • 使用反射来获取最小和最大亮度值,
  • 从 MathUtils 中获取所需的数学方法并

只需调用 getCurrentBrightness 即可检索百分比标签亮度值。不幸的是,即使使用该设置,我也无法准确确定 Android 显示设置中所示的相同亮度值...

你知道还有什么问题吗?

public class BrightnessUtils {
    public static double getCurrentBrightness(Context mContext) {
        float screenBrightness = 0;
        try {
            screenBrightness = Settings.System.getFloat(mContext.getContentResolver(), "screen_brightness");
        } catch (Exception e){
            Log.d("Exception", e.toString());
        }

        return getPercentage((double) (screenBrightness != 0 ? convertLinearToGammaFloat(screenBrightness, getMinimumScreenBrightnessSetting(mContext), getMaximumScreenBrightnessSetting(mContext)) : 0), 0, 65535);
    }

    public static float norm(float start, float stop, float value) {
        return (value - start) / (stop - start);
    }

    public static float sqrt(float a) {
        return (float) Math.sqrt(a);
    }

    public static float log(float a) {
        return (float) Math.log(a);
    }

    public static float lerp(int start, int stop, float amount) {
        return lerp((float) start, (float) stop, amount);
    }

    public static float lerp(float start, float stop, float amount) {
        return start + (stop - start) * amount;
    }

    public static float constrainedMap(
            float rangeMin, float rangeMax, float valueMin, float valueMax, float value) {
        return lerp(rangeMin, rangeMax, lerpInvSat(valueMin, valueMax, value));
    }

    public static float lerpInvSat(float a, float b, float value) {
        return saturate(lerpInv(a, b, value));
    }

    public static float lerpInv(float a, float b, float value) {
        return a != b ? ((value - a) / (b - a)) : 0.0f;
    }

    public static float saturate(float value) {
        return constrain(value, 0.0f, 1.0f);
    }

    public static float constrain(float amount, float low, float high) {
        return amount < low ? low : (amount > high ? high : amount);
    }

    public static float brightnessIntToFloat(int brightnessInt) {
        final float minFloat = 0.0f;
        final float maxFloat = 1.0f;
        final float minInt = 1;
        final float maxInt = 255;
        return constrainedMap(minFloat, maxFloat, minInt, maxInt, brightnessInt);
    }

    public static int convertLinearToGammaFloat(float val, float min, float max) {
        final int GAMMA_SPACE_MIN = 0;
        final int GAMMA_SPACE_MAX = 65535;

        // Hybrid Log Gamma constant values
        final float R = 0.5f;
        final float A = 0.17883277f;
        final float B = 0.28466892f;
        final float C = 0.55991073f;
        // For some reason, HLG normalizes to the range [0, 12] rather than [0, 1]
        final float normalizedVal = norm(min, max, val) * 12.0f;
        final float ret;
        if (normalizedVal <= 1f) {
            ret = sqrt(normalizedVal) * R;
        } else {
            ret = A * log(normalizedVal - B) + C;
        }

        return Math.round(lerp(GAMMA_SPACE_MIN, GAMMA_SPACE_MAX, ret));
    }

    private static double getPercentage(double d, int i, int i2) {
        if (d > ((double) i2)) {
            return 1.0d;
        }
        double d2 = (double) i;
        if (d < d2) {
            return 0.0d;
        }
        return (d - d2) / ((double) (i2 - i));
    }

    public static float getMinimumScreenBrightnessSetting (Context context) {
        final android.content.res.Resources res = android.content.res.Resources.getSystem();
        int id = res.getIdentifier("config_screenBrightnessSettingMinimum", "integer", "android");
        if (id != 0) {
            try {
                return res.getInteger(id);
            }
            catch (android.content.res.Resources.NotFoundException e) {
                // ignore
            }
        }
        return 0;
    }

    public static float getMaximumScreenBrightnessSetting (Context context) {
        final android.content.res.Resources res = android.content.res.Resources.getSystem();
        final int id = res.getIdentifier("config_screenBrightnessSettingMaximum", "integer", "android");
        if (id != 0) {
            try {
                return res.getInteger(id);
            }
            catch (android.content.res.Resources.NotFoundException e) {
                // ignore
            }
        }
        return 255;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.