详解Android屏幕亮度和息屏的实现

1.前言

在实际应用的设备中,特别是对于基于安卓平控制的终端设备,需要投放至外面使用, 例如自动售货机、安卓采集器、广告牌等,但外面环境由于光照环境的影响,屏幕显示的效果有所差异,因此需要基于关照强度的变化修改屏幕显示的亮度。
同时由于特殊的应用场景,例如检测到有人员流动等屏幕亮起,否则处于息屏状态。本项目的整体运行效果如下所示。
在这里插入图片描述

2.屏幕亮度的修改

对于屏幕的亮度修改有两种方式,一种是修改基于当前Activity的修改,该修改的效果仅仅针对于当前界面有效果,切换至其他界面时,便恢复至系统的亮度值。还有一种是基于对于系统的屏幕亮度的修改,该修改的效果如同我们在安卓的“设置–显示–亮度”中修改的效果一样,是对于安卓系统的整体修改。

2.1 获取当前亮度值

在设置当前亮度前,可先获取当前系统设置的亮度数据,系统的亮度值默认区间是0-255,可通过系统提供的ContentResolver接口的访问系统的ContentProver的数据,在Activity中可通过getContentResolver()方法得到当前的ContentResolver实例,从而实现对系统的ContentProver数据的访问,而Settings.System.SCREEN_BRIGHTNESS只在系统Settings中定义好的访问的key(“screen_brightness”),通过以上方式获取当前系统的亮度值。

	 int screenBrightness = 255;
        try {
            screenBrightness = Settings.System.getInt(MyApplication.mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS);
        } catch (Exception localException) {

        }

2.2 设置当前屏幕界面亮度

获取到当前亮度值后,可参照该值,根据业务需设置对应的亮度值,如果仅仅是对于当前屏幕的亮度的设置,可直接通过修改当前Window的LayoutParams属性,来实现,如下所示。

 		Window localWindow = activity.getWindow();
        WindowManager.LayoutParams localLayoutParams = localWindow.getAttributes();
        float f = paramInt / 255.0F;
        localLayoutParams.screenBrightness = f;
        localWindow.setAttributes(localLayoutParams);

系统的源码解释如下:

/**
* 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.
*/
public float screenBrightness = BRIGHTNESS_OVERRIDE_NONE;
大意为:在调节屏幕亮度时,用户应首选该方法。该值区间为0-1,对应于从黑到全亮的调节。

2.3 设置系统屏幕亮度

对于获取屏幕亮度和设置当前屏幕界面的亮度值,不需要申请权限,但是设置系统亮度值时,需要申请WRITE_SETTINGS权限,特别是当安卓版本6.0之后,还需要动态申请该权限。
在6.0后除了常见的9大类危险权限外,对于设置悬浮窗(SYSTEM_ALERT_WINDOW)和修改系统设置(WRITE_SETTINGS)这两个权限还需要特殊设置,修改系统设置权限的授权 WRITE_SETTINGS,与其他权限不同是使用startActivityForResult来启动系统设置的授权界面,让用户动态授权实现的,同时还需要在AndroidManifest.xml中添加如下

<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
/**
     * 申请权限
     */
    private void requestWriteSettings() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //大于等于23 请求权限
            if (!Settings.System.canWrite(getApplicationContext())) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
                intent.setData(Uri.parse("package:" + getPackageName()));
                startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS);
            }
        } else {
            //小于23直接设置
        }
    }
 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_WRITE_SETTINGS) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                //Settings.System.canWrite方法检测授权结果
                if (Settings.System.canWrite(getApplicationContext())) {
                    Toast.makeText(MainActivity.this, "获取了权限", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(MainActivity.this, "您拒绝了权限", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

如下图所示,需用户手动授权该权限。
在这里插入图片描述权限申请成功后,就可以对 系统的亮度进行调节设置了,在2.1中我们提到通过getContentResolver()方法对系统应用的Settings.System.SCREEN_BRIGHTNESS对应的值进行获取,同样我们也可以通过该方式对该值进行赋值操作。
在设置亮度值之前,我们需要先设置亮度模式,该模式包括以下两种

  • SCREEN_BRIGHTNESS_MODE_AUTOMATIC=1 为自动调节屏幕亮度

  • SCREEN_BRIGHTNESS_MODE_MANUAL=0 为手动调节屏幕亮度
    只有设置为手动调节模式时,才可以动态设置系统的亮度值,因此系统屏幕亮度的设置分为两步:

  • 判断是否为手动模式,如不是设置为手动模式;

  • 设置系统屏幕亮度

	 ContentResolver resolver = MyApplication.mContext.getContentResolver();
        try {
            if (Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL != (Settings.System.getInt(MyApplication.mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE))) {
                //设置为手动调节模式
                Settings.System.putInt(resolver, Settings.System.SCREEN_BRIGHTNESS_MODE,
                        Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
            }
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
        }
        //保存到系统中
        Uri uri = android.provider.Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
        android.provider.Settings.System.putInt(resolver, Settings.System.SCREEN_BRIGHTNESS, brightness);
        resolver.notifyChange(uri, null);

3 亮屏与息屏

对于安卓屏幕亮屏与息屏的操作,有两种方式,一种是通过WakeLock方法,通过锁定和解锁的方式控制屏幕的亮和灭;还有一种是通过设置FLAG_KEEP_SCREEN_ON方式实现。
对于屏幕亮度的熄灭都是针对于当前界面而言的,如切换界面后,屏幕的亮熄就受系统的设置的亮屏时间限制。

3.1 WakeLock方式

该方式需要申请WAKE_LOCK权限,且在使用时acquire()和release()需要成对出现,避免出现死锁的情况。

 <uses-permission android:name="android.permission.WAKE_LOCK"/>
	    PowerManager pm = (PowerManager) MyApplication.mContext.getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "TAG");
        wakeLock.acquire();//保持屏幕常亮
         // wakeLock.acquire(30*1000);//保持屏幕常亮30s

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                wakeLock.release();//10s后息屏
            }
        },10000);
		

该方式的原理是,wakelock是一种锁的机制,只要有应用获取到该锁,CPU就无法进入休眠状态,一直处于工作状态。在通过newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, “TAG”)方式,第一个参数设置锁的级别及标志位,可通过查看PowerManager获取需要参数值,第二个是设置应用的标志位,通过为类名。
设置成功后,通过 wakeLock.acquire()使其保持常亮状态,或通过设置拥有时间(wakeLock.acquire(30*1000)),在时间结束后便自动释放该锁,即屏幕熄灭。也可通过 wakeLock.release()方式主动释放。

3.2 设置FLAG方式

设置FLAG的方式的实现由两种方式,一种是直接在该Activity的xml中设置,还有一种是在代码中动态设置。

3.2.1 xml配置

该方式比较简单,直接在使用的Activty的xml根目录中添加keepScreenOn即可。

<android.support.constraint.ConstraintLayout
    .....
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:keepScreenOn="true"
    tools:context=".MainActivity">
   
3.2.2动态设置FLAG

该方式可以根据业务需要动态设置是否常亮或息屏,通过以下方式实现。

//保持常亮
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

//息屏
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

通过给当期的Window添加FLAG和清除FLAG的方式,实现屏幕熄灭。

3.3 设置系统息屏时间

除了以上简单粗暴的方式外,我们还同样可以参考2.1和2.3中亮度调节方案,通过getContentResolver()方法获取系统屏幕息屏时间和设置该时间。实现原理基本类似,只需替换key即可。如下所示。

//获取息屏时间
 int result = 0;
        try {
            result = Settings.System.getInt(MyApplication.mContext.getContentResolver(),
                    Settings.System.SCREEN_OFF_TIMEOUT);
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
        }
      //设置息屏时间
      Settings.System.putInt(MyApplication.mContext.getContentResolver(),
                Settings.System.SCREEN_OFF_TIMEOUT, time);
        Uri uri = Settings.System
                .getUriFor(Settings.System.SCREEN_OFF_TIMEOUT);
        MyApplication.mContext.getContentResolver().notifyChange(uri, null);

需要注意的是该方式设置的 不是对于当前界面的息屏时间,而是设置系统的息屏时间,因此如独立使用时仍然需要添加和申请系统权限(WRITE_SETTINGS)。

4 小结

本文主要讲述了在安卓终端使用时对屏幕的常有两种操作,即亮度和息屏操作。概括如下:

  1. 屏幕亮度或息屏时间的获取可通过getContentResolver()获取系统数据库的值,且不需要申请权限,可参考2.1和3.3
  2. 如果是对于当期界面亮度或屏幕熄灭的操作,可直接通过修改WindowManager的LayoutParams方法实现对亮度或息屏操作,参考2.2、3.1和 3.2;
  3. 但对于系统的设置需要申请WRITE_SETTINGS权限,具体可参考2.3中权限申请的实现细节,对于系统属性的修改是通过getContentResolver()方式实现,可参考2.3和3.3。

备注:本文的参考Demo的github下载地址,欢迎star和fork。

猜你喜欢

转载自blog.csdn.net/xk7298/article/details/93300488
今日推荐