20

How do you get the preferred 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?

hpique
  • 112,774
  • 126
  • 328
  • 461
  • I guess the focus of the question for me is this (thanks David): Can I get the current actual screen brightness as set by the system when in automatic mode? – Yossi Nov 14 '11 at 00:39
  • @hpique could you find a solution for this question/problem? – safari Dec 12 '13 at 15:02

2 Answers2

45

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.

davidcesarino
  • 15,491
  • 15
  • 66
  • 108
  • Thanks, great answer, but as you state at the beginning, you don't have the answer to the specific question. I'll give you the bounty if no answer turns up. – Yossi Nov 14 '11 at 00:41
  • Thanks, but don't worry about that. My main intention was adding something to the topic because I've already researched this (as you can see). I'll actually be glad if someone pops here with a positive answer on this issue. :-) – davidcesarino Nov 14 '11 at 01:44
  • 4
    David, about item 2 above (Listen to screen brightness changes): Google's Power Control appwidget registers a ContentObserver in order to listens to changes to the brightness settings. Not quite the same as listening for actual screen brightness changes, but better than nothing: resolver.registerContentObserver(Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS), false, this); resolver.registerContentObserver(Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE), false, this); – Nicolai Buch-Andersen Jan 17 '12 at 22:30
  • Thanks, I didn't notice that. That's some valuable information. However, our problem here still remains (the bounty question... the main was already answered even though he didn't accept it yet)... – davidcesarino Jan 18 '12 at 00:06
  • 1
    This is one of the most exhaustive answers I've ever seen. Thank you! Although there is a way to listen to screen brightness changes: ContentObserver settingsContentObserver = new ContentObserver(new Handler()) { @Override public void onChange(boolean selfChange) { } }}; getApplicationContext().getContentResolver() .registerContentObserver(Settings.System.CONTENT_URI, true, settingsContentObserver); – Makks129 Nov 26 '14 at 20:49
  • @Makks129 You're welcome. I don't think the above snippet listens for screen brightness changes. :) – davidcesarino Nov 29 '14 at 03:39
  • @DavidCesarino It doesn't trigger when brightness automatically changes when on auto, but it does trigger when user changes it manually. – Makks129 Nov 29 '14 at 11:40
-1

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.

Ifor
  • 2,757
  • 1
  • 17
  • 23