7

I'm having trouble trying to set screen brightness. To do so I use the following code:

Settings.System.putInt(cResolver, Settings.System.SCREEN_BRIGHTNESS, brightness); 

where brightness is a value between 0 and 255.

The problem is that in some device it works (Htc One, Nexus 5,...), in others dont! For example, if I use this function to set screen brightness in a Samsung device the screen doesnt get brighter or dimmer, altough if i go into "Notification Panel" (sliding down from the top of the screen) i can see the brightness level has changed.

Does anyone know a way to set brightness that works with all Android devices? And does anyone know why it works in some devices, but in other dont?

UPDATE 1:

This method is used in a BroadcastReceiver, so no Activities are there!

Stefano Munarini
  • 2,711
  • 2
  • 22
  • 26

2 Answers2

1

You can override the brightness for the current window, instead of changing the brightness settings.

    WindowManager.LayoutParams lp = getWindow().getAttributes();
    if (overrideBrightness)
        lp.screenBrightness =  BRIGHTNESS_OVERRIDE_FULL;
    else 
        lp.screenBrightness =  BRIGHTNESS_OVERRIDE_NONE;
    getWindow().setAttributes(lp);
dangVarmit
  • 5,641
  • 2
  • 22
  • 24
0

Changing the system setting for the brightness may work, but will not trigger the screen brightness to actually change. The WindowManager will need to receive an event to be refreshed, as pointed out in an answer to this related question. Furthermore, if the brightness switch is set to auto, your setting will be overridden as soon as the light sensor's value changes.

Unfortunately, in order to somehow cause the WindowManager to acknowledge the new brightness setting, you'll need an activity context. Instead of needlessly creating a new activity only to destroy it immediately, I would suggest creating a window, and applying the brightness value to the LayoutParams as suggested by others in this thread.

A common way of doing this is displaying a system modal window, and applying the LayoutParams to its attributes:

final View view = new View(this);
int dimension = 0;
int pixelFormat = PixelFormat.TRANSLUCENT;
if (DISPLAY) {
    view.setBackgroundColor(Color.argb(128, 255, 0, 0));
    dimension = LayoutParams.MATCH_PARENT;
    pixelFormat = PixelFormat.RGBA_8888;
}
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
        dimension, dimension,
        WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
        WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
        pixelFormat);
// 0f = minimum brightness; 1f = maximum brightness
float brightness = 1f;
params.screenBrightness = brightness;
Settings.System.putInt(cResolver,
        Settings.System.SCREEN_BRIGHTNESS, 255 * brightness);
final WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(view, params);

You'll need to add the following permission to your manifest:

<uses-permission android:name="android.permission.WRITE_SETTINGS" />

In the snippet, DISPLAY is a simple switch to enable display of the overlay window for testing purposes. (You should see a half-transparent red overlay.)

Community
  • 1
  • 1
Paul Lammertsma
  • 37,593
  • 16
  • 136
  • 187
  • What do you mean with "system modal window"? It's a kinda activity? – Stefano Munarini Dec 03 '13 at 11:18
  • In a sense, but it's somewhat of a grey area. Activities take care of communicating with the WindowManager to display views in a window decor. Instead of creating an activity, however, you can simply interact with it directly to add a view. The view is added with LayoutParams that specify that it's invisible, overlays all other applications, doesn't intercept touch or focus, and specifies a screen brightness. – Paul Lammertsma Dec 03 '13 at 11:56
  • This cause too much slow at the phone. It works fine, nothing to say, but can't develop something that makes a phone goes that slow! – Stefano Munarini Dec 03 '13 at 13:35
  • A single overlay should not have a significant performance impact as its dimensions are zero and PixelFormat is translucent. If you're executing this multiple times, you should of course reuse the view, otherwise you'll be creating several stacks of system modal windows. How often are you invoking this from your BroadcastReceiver? – Paul Lammertsma Dec 03 '13 at 14:20
  • Many times in a short time. So how to reuse views? – Stefano Munarini Dec 03 '13 at 14:21
  • In the snippet above, simply hold on to `view` and `params`, and update them using [`WindowManager.updateViewLayout(View, LayoutParams)`](http://developer.android.com/reference/android/view/ViewManager.html#updateViewLayout(android.view.View,%20android.view.ViewGroup.LayoutParams)). – Paul Lammertsma Dec 03 '13 at 14:36
  • @PaulLammertsma You don't require `SYSTEM_ALERT_WINDOW` permission for `TYPE_SYSTEM_OVERLAY`. Also, why not remove the view, right after adding it? – Vikram Dec 03 '13 at 18:24
  • @user2558882 You're absolutely right about the permission, it may be removed as I was confused with TYPE_SYSTEM_ALERT. Whether or not the view can be removed or updated is really dependent on how the implementation; updating it avoids unnecessary object allocation and enforces the screen brightness until the view is removed. – Paul Lammertsma Dec 03 '13 at 22:35