1.前言
在實際應用的裝置中,特别是對于基于安卓平控制的終端裝置,需要投放至外面使用, 例如自動售貨機、安卓采集器、廣告牌等,但外面環境由于光照環境的影響,螢幕顯示的效果有所差異,是以需要基于關照強度的變化修改螢幕顯示的亮度。
同時由于特殊的應用場景,例如檢測到有人員流動等螢幕亮起,否則處于息屏狀态。本項目的整體運作效果如下所示。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TPB9UNJpnTyh2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL4gzNzAjM0QTMyIjNwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
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);
系統的源碼解釋如下:
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 小結
本文主要講述了在安卓終端使用時對螢幕的常有兩種操作,即亮度和息屏操作。概括如下:
- 螢幕亮度或息屏時間的擷取可通過getContentResolver()擷取系統資料庫的值,且不需要申請權限,可參考2.1和3.3
- 如果是對于當期界面亮度或螢幕熄滅的操作,可直接通過修改WindowManager的LayoutParams方法實作對亮度或息屏操作,參考2.2、3.1和 3.2;
- 但對于系統的設定需要申請WRITE_SETTINGS權限,具體可參考2.3中權限申請的實作細節,對于系統屬性的修改是通過getContentResolver()方式實作,可參考2.3和3.3。
備注:本文的參考Demo的github下載下傳位址,歡迎star和fork。