以编程方式更改系统亮度

56

我想通过编程改变系统的亮度。出于这个目的,我正在使用以下代码:

WindowManager.LayoutParams lp = window.getAttributes();
lp.screenBrightness = (255);
window.setAttributes(lp);

因为我听说最大值是255。

但它没有任何效果。请建议任何可以改变亮度的东西。谢谢。


类似问题:https://dev59.com/_G865IYBdhLWcg3wl_o3 - Dhairya Vora
这是一个老问题。我已经在本页面底部提供了完整的答案。希望能节省大家的时间。 - Hitesh Sahu
请查看这篇博客。https://medium.com/p/18be3eecd6b7 - Pragnesh Ghoda シ
https://androidacademic.blogspot.com/2023/03/change-android-screen-brightness.html - Pragnesh Ghoda シ
16个回答

57
您可以使用以下内容:
// Variable to store brightness value
private int brightness;
// Content resolver used as a handle to the system's settings
private ContentResolver cResolver;
// Window object, that will store a reference to the current window
private Window window;

在你的onCreate方法中编写以下代码:
// Get the content resolver
cResolver = getContentResolver();
 
// Get the current window
window = getWindow();
    
try {
    // To handle the auto
    Settings.System.putInt(
        cResolver,
        Settings.System.SCREEN_BRIGHTNESS_MODE,
        Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL
    );
    // Get the current system brightness
    brightness = Settings.System.getInt(
        cResolver, Settings.System.SCREEN_BRIGHTNESS
    );
} catch (SettingNotFoundException e) {
    // Throw an error case it couldn't be retrieved
    Log.e("Error", "Cannot access system brightness");
    e.printStackTrace();
}

请编写代码以监测亮度变化。

然后您可以按以下方式设置更新后的亮度:

// Set the system brightness using the brightness variable value
Settings.System.putInt(
    cResolver, Settings.System.SCREEN_BRIGHTNESS, brightness
);
// Get the current window attributes
LayoutParams layoutpars = window.getAttributes();
// Set the brightness of this window
layoutpars.screenBrightness = brightness / 255f;
// Apply attribute changes to this window
window.setAttributes(layoutpars);

清单中的权限:

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

对于API >= 23,您需要通过设置活动来请求权限,详见此处:无法获取WRITE_SETTINGS权限


1
我需要用我的变量来改变亮度变量吗?比如在0-255之间??? - Usman Riaz
我收到了错误信息 - “SCREEN_BRIGHTNESS 无法解析或不是一个字段”,针对 System.SCREEN_BRIGHTNESS。 - Ganpat
1
有时亮度处于自动模式,在这种情况下,我们需要先禁用它,然后执行您分享的代码片段。但是,您分享的答案非常好。 - Terril Thomas
2
这个解决方案对我来说不起作用。我没有收到任何错误提示,但同时屏幕显示也没有任何变化。 - Charu
1
我可以使用System.putInt方法或窗口的布局参数方法,对吧?它们都可以在不同的方式下达到相同的结果,那我为什么需要两个呢?@RiteshGune - Itay Feldman
显示剩余4条评论

26
你可以设置窗口的 screenBrightness 属性,像这样:
WindowManager.LayoutParams layout = getWindow().getAttributes();
layout.screenBrightness = 1F;
getWindow().setAttributes(layout);     

这段代码/技术是从Almond Joseph Mendoza于2009年1月5日发表的一篇博客文章中获得改编的,题为“程序化更改屏幕亮度” (存档在Wayback Machine上)。

screenBrightness 属性 是一个浮点值,范围从 0 到 1,其中 0.0 表示 0% 的亮度,0.5 表示 50% 的亮度,1.0 表示 100% 的亮度。

请注意,这不会影响整个系统的亮度,而只会影响该特定窗口的亮度。但是,在大多数情况下,对于大多数应用程序来说,这可能是您所需要的全部内容。特别是它有一个优点,即不需要提升权限,而更改全局系统设置则需要提升权限。


18

我有同样的问题。

有两个解决方案:

这里,亮度 = (int)0到100范围,因为我使用了进度条。

第一个解决方案:

float brightness = brightness / (float)255;
WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.screenBrightness = brightness;
        getWindow().setAttributes(lp);

2个解决方法

我只是使用了一个虚拟活动来调用,当我的进度条停止寻找时。

 Intent intent = new Intent(getBaseContext(), DummyBrightnessActivity.class);
                    Log.d("brightend", String.valueOf(brightness / (float)255));
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //this is important
                    //in the next line 'brightness' should be a float number between 0.0 and 1.0
                    intent.putExtra("brightness value", brightness / (float)255); 
                    getApplication().startActivity(intent);

现在来到 DummyBrightnessActivity.class

 public class DummyBrightnessActivity extends Activity{

private static final int DELAYED_MESSAGE = 1;

private Handler handler;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);            
    handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if(msg.what == DELAYED_MESSAGE) {
                DummyBrightnessActivity.this.finish();
            }
            super.handleMessage(msg);
        }
    };
    Intent brightnessIntent = this.getIntent();
    float brightness = brightnessIntent.getFloatExtra("brightness value", 0);
    WindowManager.LayoutParams lp = getWindow().getAttributes();
    lp.screenBrightness = brightness;
    getWindow().setAttributes(lp);

    Message message = handler.obtainMessage(DELAYED_MESSAGE);
    //this next line is very important, you need to finish your activity with slight delay
    handler.sendMessageDelayed(message,200); 
}

}

别忘了在清单文件中注册DummyBrightnessActivity。

希望这可以帮到你!


我正在使用自定义对话框进行操作,但是它没有起作用。我想要改变整个系统的亮度。我运行了代码并检查了系统设置的亮度,但它没有受到影响。 - Usman Riaz
首先,在亮度值为0到100之间使用静态值进行检查,然后再使用动态值。请添加<uses-permission android:name="android.permission.WRITE_SETTINGS"/>。 - Bhoomika Brahmbhatt
解决方案二:你为什么需要虚拟活动?看起来非常低效。 - Sevastyan Savanyuk
这是完美的解决方案,应该被接受!因为在清单中没有需要"android.permission.WRITE_SETTINGS",但这确实完成了工作。 - Arun K Babu

14
在我的情况下,我只想在显示一个Fragment时点亮屏幕,而不是更改整个系统的设置。 有一种方法可以仅更改应用程序/活动/片段的亮度。 我使用LifecycleObserver来调整一个Fragment的屏幕亮度:
class ScreenBrightnessLifecycleObserver(private val activity: WeakReference<Activity?>) :
    LifecycleObserver {

    private var defaultScreenBrightness = 0.5f

    init {
        activity.get()?.let {
            defaultScreenBrightness = it.window.attributes.screenBrightness
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun lightUp() {
        adjustScreenBrightness(1f)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun lightDown() {
        adjustScreenBrightness(defaultScreenBrightness)
    }

    private fun adjustScreenBrightness(brightness: Float) {
        activity.get()?.let {
            val attr = it.window.attributes
            attr.screenBrightness = brightness
            it.window.attributes = attr
        }
    }
}

在您的Fragment中添加LifecycleObserver,例如:

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

        // ...

        lifecycle.addObserver(ScreenBrightnessLifecycleObserver(WeakReference(activity)))

        // ...

        return binding.root
}

1
很棒的解决方案。一个建议:由于您的类是LifecycleObserver,因此可以使Activity引用可为空,并在Lifecycle.Event.ON_DESTROY中将其设置为null。 您可以使Activity成员可为空,但构造函数参数不可为空-然后可以基于非空构造函数参数计算defaultScreenBrightness-无需“null case”,然后您就不需要默认值0.5。 - Singed
请勿直接使用此接口。相反,实现DefaultLifecycleObserverLifecycleEventObserver中的任一接口以接收有关生命周期事件的通知。有关详细信息,请参阅LifecycleObserver文档。 - alizeyn

10

我尝试了其他人发表的几种解决方案,但它们都没有完全正确地工作。geet的答案基本上是正确的,但有一些语法错误。我在我的应用程序中创建并使用了以下功能,它非常有效。请注意,这将按照原始问题中要求更改系统亮度。

public void setBrightness(int brightness){

    //constrain the value of brightness
    if(brightness < 0)
        brightness = 0;
    else if(brightness > 255)
        brightness = 255;


    ContentResolver cResolver = this.getApplicationContext().getContentResolver();
    Settings.System.putInt(cResolver, Settings.System.SCREEN_BRIGHTNESS, brightness);

}

8

完整答案

我不想使用窗口管理器来设置亮度。我希望亮度能够反映在系统级别和用户界面上。以上的任何答案都没有对我起作用。最终,这个方法对我有用。

在 Android Manifest 中添加写入设置权限

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

写入设置是受保护的设置,因此需要请求用户允许编写系统设置:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (Settings.System.canWrite(this)) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
                intent.setData(Uri.parse("package:" + getPackageName()));
                startActivity(intent);
            }
        }

现在你可以轻松设置亮度

            ContentResolver cResolver = getContentResolver();
            Settings.System.putInt(cResolver, Settings.System.SCREEN_BRIGHTNESS, brightness);

亮度值应该在0-255的范围内,因此如果您有一个范围为(0-max)的滑块,那么您可以将值归一化在(0-255)的范围内。

private float normalize(float x, float inMin, float inMax, float outMin, float outMax) {
    float outRange = outMax - outMin;
    float inRange  = inMax - inMin;
  return (x - inMin) *outRange / inRange + outMin;
}

现在您可以像这样将亮度从0-255的范围内更改为0-100%:

 float brightness = normalize(progress, 0, 100, 0.0f, 255.0f);

希望这能节省您的时间。


4

这个在Kitkat 4.4下对我起作用,但在Android L中就不行了。

private void stopBrightness() {
    Settings.System.putInt(this.getContentResolver(),
            Settings.System.SCREEN_BRIGHTNESS, 0);
}

3
WindowManager.LayoutParams params = getWindow().getAttributes();
    params.screenBrightness = 10; // range from 0 - 255 as per docs
    getWindow().setAttributes(params);
    getWindow().addFlags(WindowManager.LayoutParams.FLAGS_CHANGED);

这对我很有用。不需要虚拟活动。这仅适用于您当前的活动。


3

以下是如何更改系统亮度的完整代码

    private SeekBar brightbar;

    //Variable to store brightness value
    private int brightness;
    //Content resolver used as a handle to the system's settings
    private ContentResolver Conresolver;
    //Window object, that will store a reference to the current window
    private Window window;

    /** Called when the activity is first created. */
    @Override
    public void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        //Instantiate seekbar object
        brightbar = (SeekBar) findViewById(R.id.ChangeBright);

        //Get the content resolver
        Conresolver = getContentResolver();

        //Get the current window
        window = getWindow();

        brightbar.setMax(255);

        brightbar.setKeyProgressIncrement(1);

        try {
            brightness = System.getInt(Conresolver, System.SCREEN_BRIGHTNESS);
        } catch (SettingNotFoundException e) {
            Log.e("Error", "Cannot access system brightness");
            e.printStackTrace();
        }

        brightbar.setProgress(brightness);

        brightbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
            public void onStopTrackingTouch(SeekBar seekBar) {
                System.putInt(Conresolver, System.SCREEN_BRIGHTNESS, brightness);

                LayoutParams layoutpars = window.getAttributes();

                layoutpars.screenBrightness = brightness / (float) 255;

                window.setAttributes(layoutpars);
            }

            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

                if (progress <= 20) {

                    brightness = 20;
                } else {

                    brightness = progress;
                }
            }
        });
    }

或者你可以查看这个教程来获取完整的代码
祝编码愉快:)


2
private SeekBar Brighness = null;

@Override
protected void onCreate(Bundle savedInstanceState) {

     super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_lcd_screen_setting);
     initUI();
     setBrightness();
}

private void setBrightness() {

    Brighness.setMax(255);
    float curBrightnessValue = 0;

    try {
        curBrightnessValue = android.provider.Settings.System.getInt(
                getContentResolver(),
                android.provider.Settings.System.SCREEN_BRIGHTNESS);
    } catch (Settings.SettingNotFoundException e) {
        e.printStackTrace();
    }
    int screen_brightness = (int) curBrightnessValue;
    Brighness.setProgress(screen_brightness);

    Brighness.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        int progress = 0;


        @Override
        public void onProgressChanged(SeekBar seekBar, int progresValue,
                                      boolean fromUser) {
            progress = progresValue;
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            // Do something here,
            // if you want to do anything at the start of
            // touching the seekbar
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            android.provider.Settings.System.putInt(getContentResolver(),
                    android.provider.Settings.System.SCREEN_BRIGHTNESS,
                    progress);
        }
    });
}

initUI(){
   Brighness = (SeekBar) findViewById(R.id.brightnessbar);
}

在清单文件中添加以下内容:
<uses-permission android:name="android.permission.WRITE_SETTINGS"
 tools:ignore="ProtectedPermissions"/>

在清单文件中添加一个权限。 - arshad shaikh
1
<uses-permission android:name="android.permission.WRITE_SETTINGS"/> - arshad shaikh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接