开发者

Get preferred screen brightness in Android

How do you get the preferr开发者_开发百科ed screen brightness in Android?

To change the screen brightness I use WindowManager.LayoutParams.screenBrightness. According to the documentation:

This can be used to override the user's preferred brightness of the screen. A value of less than 0, the default, means to use the preferred screen brightness. 0 to 1 adjusts the brightness from dark to full bright.

When screenBrightness is less than 0 I would like to start with the preferred screen brightness. How can I get this value?


I'll try to answer because I already searched for this some time ago. My short answer is: I've never found a way to get current brightness level when on auto mode, after extensive research.

I will break this into multiple answers. I won't skip premises, so as to googlers can find this helpful. Skip what you don't need.

1- Get brightness setting value

When screenBrightness is less than 0 I would like to start with the preferred screen brightness. How can I get this value?

For a person who has that amount of reputation, I'm sure you already know the drill about searching. There are tons of answers about this here on SO. Just check the right panel with similar questions... that said, I won't detail much.

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

This is how Android's BrightnessPreference.java do it in 2.3.5 (see line 68). It's also the same (for practical reasons) of what lfor posted.

It's not named old Brightness for nothing. This is a setting stored somewhere, not the current value. You can only be sure that it's the same of what the user is experiencing if you're into manual brightness mode. Otherwise, you just don't know. You should check:

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

2- Listen to screen brightness changes

As we know, generally, when we want to listen to changes in Android, we can try listening to Intent actions, registering BroadcastReceivers and all that. However, AFAIK, there is no ACTION_ for brightness changes, like SCREEN_[ON|OFF], for example. Maybe there is one hidden in the system, but I've never seen it, and if it's not publicly available, you have all the possible pitfalls of dealing with that.

There is a message, dated Dec 2010, from Dianne Hackborn, where she says that "there is no broadcast for screen brightness changes".

So, I don't believe there is a way to hook up into something like that. Of course, you can change the setting itself:

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

3- Listen to ambient light changes

You can, however, aprox. detect the amount of light. You need to implements SensorEventListener and:

// 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- Guess the brightness change

After all that said, I must also repeat Hackborn's question: "what are you trying to accomplish?" (this is for the bounty owner). I'd be happy to see how Android maps ambient lux to screen brightness. I'm quite sure it's not a linear thing (map Sensor.getMaximumRange() linearly to the 0..1 float interval). I've seen that generally this is mapped logarithmic (provide finer adjustments into the lower brightness range), but I have no idea about the parameters. Perhaps there is a suggested default way that everyone uses, but I'm no expert.

If you could find how Android does it by looking into the place in the sources where it does that, that would be great. But anyway, I didn't come all this long to leave you with the same question. What I've found is that Sensor.getMaximumRange() is not consistent with what you get from the SensorEvent values[0]. Here, I have a Sharp sensor (Nexus S), and although the report max is 3,000, I've seen values of up to 10,240.

So, getting the sensor is not reliable (?). I'm guessing, by the behavior I've seen using Android, that somehow it maps getMaximumValue() to the max brightness, and any value above it just doesn't make a difference.

5- Where to go from here

I'd look more into Android sources. Somewhere, probably in a lower level, hardware managing stuff, you could see how they map. Still, I wonder if that's reliable, considering what Dianne Hackborn said (they seem to not want you to do that). I'd guess they had a reason to not expose that. Perhaps need: why does the app must know the system setting? It either needs to provide his own, app-wide level, or, in extreme cases, provide its own "autobrightness change method" (as in point 4 above) for a system-wide replacement or the manager. Perhaps that's what the original developers thought.

Anyway, if anyone find other details, I'd be extremely happy to know.


As of now (android 12) the situation is more complicated than described by @davidcesarino in his comprehensive answer. I did look at the source code as suggested, and it is pretty complicated. Among other things, auto brightness mode has both a fast and a slow brightness change in response to changes in ambient light level.

However the whole thing depends on a bunch of system resources which are presumably specified by the device manufacturer, and they are all hidden in com.android.internal.R.styleable, which isn't accessible from a user-built app.

You may be able to get at them by using context.getResources().getIdentifier(...) if you can find the name of the resource by looking at the Android source code. However getIdentifier() is currently deprecated and may disappear at some time in the future.

More problematically, Settings.System.SCREEN_BRIGHTNESS is no longer necessarily the brightness set by the user in the Settings page: this depends on how the device manufacturer configured it. On my new Samsung Galaxy S21, it's the adjusted brightness in auto mode. Even stranger, in auto mode the Settings page brightness slider shows the adjusted value, and will move as you move the phone between a brightly it and a dimly lit area.

There are two ways to set the screen brightness programmatically. You can set Settings.System.SCREEN_BRIGHTNESS (range is 0 .. 255), but on versions of Android later than API level 23 this requires a runtime permission which can only be requested dynamically.

You can also set the brightness for your app's current top-level window only using getWindow().getAttributes().screenBrightness(range is 0.0F .. 1.0F, or -1.0F not to override the system setting).

If you just want to set the screen brightness within your app, that is the easiest solution since it requires no permissions.

Another way of achieving a similar effect, at least if your screen uses a dark background, is to reduce the opacity of all the widgets. This works nicely on an OLED screen, where only lit pixels consume power, but not so well on a backlit screen.

However it doesn't seem to be possible on Android to determine programmatically whether the display is backlit or an OLED, see this stackoverflow question

I have posted a little app on github which you can play with to see how your device does brightness control in the various ways mentioned. It also contains code to do all of the things that I describe above, which you can copy if you need to.


Well to answer the question as asked you can get the prefered brightness from Settings.system.SCREEN_BRIGHTNESS The range looks to be 0-255.

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

What the curent brightness actualy is at the moment, as set by Automatic mode or an app setting it's own brightness is a different question realy and I would also be interested in the answer.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜