[03] Android系统亮度调节

链接:http://developer.android.com/reference/android/provider/Settings.System.html

 

  最近在做的项目,需要使用亮度调节实现夜间模式,需求是进入 App之后,保持屏幕亮度不变,如果点下亮度切换按钮,就能在两种亮度值之间切换。此外,如果 App被切换到后台,或者锁屏,都需要还原回原始系统亮度。

  一开始想的比较简单,以为用 Settings.System的设置就可以实现,动手写代码之后,才发现有以下几个问题需要处理:

    1. 在 App入口不唯一的情况下(通过Widget、Notification,第一次进入的不是同一个界面),如何取到系统亮度的初始值,用于还原操作;

    2. 怎么判断 App被切换到了后台;

    3. 监听锁屏事件;

    4. 光改变系统亮度值,不改变 Activity所占有的 Window亮度,是不会有作用的。

 

  解决方法:

    1. 使用单例模式,保证使用亮度调节之前,都对原始系统亮度值进行过保存,以下是获取系统亮度值的代码

    private static void initBrightnessSetting() {
        int brightness = 200;
        int mode = 0;
        try {
            brightness = Settings.System.getInt(sContext.getContentResolver(),
                    Settings.System.SCREEN_BRIGHTNESS);
        } catch (SettingNotFoundException e) {
            e.printStackTrace();
        }
        try {
            mode = Settings.System.getInt(sContext.getContentResolver(),
                    Settings.System.SCREEN_BRIGHTNESS_MODE);
        } catch (SettingNotFoundException e) {
            e.printStackTrace();
        }
        sOriginalBrightness = brightness;
        sOriginalMode = mode;
    }

 

    2. 有两种方法,第一种是在每个 Activity执行 onPause回调的时候获取当前的 Android任务列表,第二种是在 App中建立一个 Stack/List存储每个 Activity的状态(代码略,只需要在最后一个执行 onPause的 Activity中对标志位进行重置即可)。推荐后者。

    public static boolean isBackground() {
        boolean isBackground = true;
        List<RunningTaskInfo> taskInfo = getRunningTaskInfos(1);
        if (taskInfo.size() > 0) {
            if (taskInfo.get(0).baseActivity.getPackageName().equals(
                    SinaNewsApplication.getAppPackageName())) {
                isBackground = false;
                Logger.TEST.info(taskInfo.get(0).baseActivity.getClassName());
            }
        }

        return isBackground;
    }

 

    3. 原先我一直认为 Android没有一个好的监听锁屏方法,只能使用监听 Intent.ACTION_SCREEN_OFF的方法,这次做亮度调节的时候,才发现一个事实..锁屏 == 亮度为零。不知道为什么,采用静态注册的方法不能监听到 ACTION_SCREEN_OFF的广播,必须要在某个组件里动态注册监听器。怎么判断是哪个 Activity的 Window对象来改变亮度呢?就需要用到第二个问题中的 Activity Stack,把栈顶的 Activity拿出来就可以了。

 

    4. 很多博客写到系统亮度调节,都会说这么做就可以了:

        Settings.System.putInt(sContext.getContentResolver(),
                Settings.System.SCREEN_BRIGHTNESS_MODE, systemMode);
        Settings.System.putInt(sContext.getContentResolver(),
                Settings.System.SCREEN_BRIGHTNESS, systemBrightness);

    这么做确实能改变系统的亮度值,但是你会发现亮度值变了,屏幕还是原来的亮度,这是因为系统的亮度值并没有应用到当前 Activity的 Window对象,所以还需要:

        Window window = activity.getWindow();
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.screenBrightness = brightness;
        window.setAttributes(lp);

    如果先启动了 Activity A设置了一次亮度200,然后跳转到 Activity B又做了一次同样的操作设置亮度50,退出 B之后,发现 A的亮度还是200。出现这种现象的原因就是,处于后台的 Activity的 Window的亮度值在设置后,并不会随着它之上的 Activity的 Window亮度所更改。所以还需要在每个 Activity的 onResume方法中进行判断。

 

 

 

 

  

 

posted @ 2013-12-19 17:57  海通  阅读(827)  评论(0编辑  收藏  举报