Android 亮度調節功能開發思路整理


做 Android 音視頻播放器開發的時候,我們基本都會遇到一類需求:音量 & 亮度 調節。其中做亮度調節功能的時候,發現還是有一定復雜度的。

Android亮度調節分為兩個類,分別是:

  • Android 系統亮度調節
  • Android 當前屏幕(Window)亮度調節(即App亮度調節)

一、Android系統亮度調節

Android系統亮度調節全局性最高,常見於系統設置中的亮度設置項。Android中提供了獲取和設置系統亮度值的接口,具體如下:

// 獲取系統亮度
Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS);
// 設置系統亮度
Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS,systemBrightness);

其中,需要注意的是,返回的亮度值是處於0-255之間的整型數值。

Android 2.1以后的系統中,系統亮度調節中新增了“自動亮度”選項。“自動亮度”是依據外界光源來自動的改變系統亮度,目前大部分手機中對“自動亮度”還可以進行小幅度的調節其值。與自動亮度相對應的是“手動亮度”,當處於“手動亮度”下,設置拖動亮度進度條會大幅度的改變Android系統亮度。“手動亮度”和“自動亮度”分別稱之為Android系統的“亮度模式”。

與之相對應的,Android系統中也提供了獲取和設置“亮度模式”的接口。

// 獲取系統亮度模式
Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE);
// 設置系統亮度模式
Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE, systemMode);

可是遺憾的是,Android中並未提供處於“自動亮度”模式下的亮度值接口。上面所說的獲取系統亮度值接口實際上都是指“手動亮度”模式下的亮度值。

一般而言,通過手動亮度值以及設置系統亮度模式接口,可以滿足常規的大部分針對Android系統亮度設置編碼需求,以完成系統亮度調節。

二、Android當前屏幕(Window)亮度調節(App亮度調節)

Android針對當前屏幕(Window)提供了設置亮度的接口,常見寫法如下:

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

其中,需要注意的是此處的brightness是一個0.0-1.0之間的一個float類型數值。

默認情況下,當我們直接修改了系統亮度值后,當前Window中是可以即時反應出來亮度效果的,這是因為默認情況下,WindowManager.LayoutParams的screenBrightness的默認值為WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE。

即表示Window沒有自己的亮度參數,將依隨系統亮度效果的變化而變化。這也就是我們最常見的:當調整系統亮度后,所有Window都即時反應出系統亮度設置效果。

當時,實際項目中我們還會遇到此類需求:系統設置亮度時只針對當前Window或App內生效,而不影響到系統本身的亮度設置。

假設當前Window內有一個SeekBar,UI與系統亮度調節UI基本類似,用戶可以滑動此SeekBar,使得當前Window亮度即時發生變化,且不影響到系統亮度效果。如何實現呢?

此時我們需要啟用WindowManager.LayoutParams的screenBrightness參數,使之具有自動的特定亮度值,設置此值后在當前Window范圍內,其將覆蓋掉系統亮度設置。

因此,有必要將用戶選擇的亮度值轉換為相應的Window亮度值(為與系統亮度值相一致,假設SeekBar的最大值為255)。

// 根據亮度值修改當前window亮度
public void changeAppBrightness(Context context, int brightness) {
     Window window = ((Activity) context).getWindow();
     WindowManager.LayoutParams lp = window.getAttributes();
     if (brightness == -1) {
         lp.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
     } else {
         lp.screenBrightness = (brightness <= 0 ? 1 : brightness) / 255f;
     }
     window.setAttributes(lp);
}

其中,brightness形參為用戶選擇的亮度值。

那么,上述代碼中為什么有一個"brightness == -1"的判斷呢?在此主要是考慮到App設置項中可能出現的“跟隨系統亮度”或“恢復系統默認亮度”此類設置,當用戶進行此類操作時,直接將screenBrightness參數還原成默認參數值即可。因為由前文描述“自動亮度”模式下系統亮度值是不能直接得到的,那么當系統處於“自動亮度”模式下,此時brightness參數值將無法准確確定,因此,將screenBrightness參數還原成默認參數值成為一個行之有效的方法。 

三、Android App亮度調節可行方案分析

目前網上有不少博文中提到App亮度調節時,提出的方案是在App設置項中,首先記錄下設置之前的系統亮度值和亮度模式,用戶在App設置項進行亮度調節時,直接修改系統亮度值,當用戶退出此App,或App至於后台(如按下Home按鍵等),再將系統亮度還原。初看起來貌似一個可行的方案。但是主要存在如下幾個問題:

1.如何獲取到設置之前的系統亮度值和亮度模式(因為之后在此App外部要恢復系統亮度值到此初始值)?當用戶每次進入到設置頁時獲取?嚴格意義上來說,是沒法准確記錄的。因為Android的用戶操作不可預知性,如進入到設置頁,拖動SeekBar設置了一個亮度值,此時直接修改了系統的亮度值,如果此時用戶在未將應用至於后台或未將應用退出的情況下直接在App外部修改了系統亮度設置,如小米中可以通過下拉標題欄,直接就可以設置系統亮度。因此,App亮度設置之前的系統亮度初始值獲取存在困難。

2.如何判斷用戶來到了App外部?因為此時需要恢復系統亮度設置到初始系統亮度。如用戶可以按下Home按鍵,長按Home按鍵直接切換App,直接Back按鍵等一步步退出此App,下拉標題欄直接點擊其他App通知信息進入到其他App,手機自動鎖屏后解鎖時用戶直接進入其他應用等等,此類操作場景也具有不可預知性,因此,判斷用戶來到了App外部以恢復系統亮度到初始值的時機上也存在一定困難。

由此,App亮度調節方案推薦通過設置當前屏幕(Window)方式進行。

大致思路如下:

1. 用戶在設置項中進行亮度調節時,調用changeAppBrightness()方法,將改變當前屏幕(Window)的亮度,此時對系統亮度無任何影響,接下來存在的問題終於要就集中於當用戶來到本App其他Activity中,如果使得剛剛設置的亮度值得以即時反應出來。

2. 當用戶進行亮度調節后,將當前亮度設置值保存起來(如保存到SharedPreferences中),在基類Activity中的onResume方法中,可以取出SharedPreferences中的用戶所設置的App亮度值,然后changeAppBrightness()方法以實現每個當前屏幕的亮度調節。

 總體說來,通過設置當前屏幕(Window)的方式來設置App亮度更加簡單有效。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM