Android 亮度調(diào)節(jié)

一、前言:

最近在做一個(gè)App的設(shè)置項(xiàng),亮度調(diào)節(jié)。真正做時(shí),發(fā)現(xiàn)Android亮度調(diào)節(jié)比預(yù)想要復(fù)雜一些。其實(shí)目前網(wǎng)上已有不少這方面的資料,但有些博文具有一定誤導(dǎo)性。在此將這塊內(nèi)容按照自己理解整理一下。

整體上看,Android亮度調(diào)節(jié)分為三個(gè)層次,分別是:Android系統(tǒng)亮度調(diào)節(jié)、Android App亮度調(diào)節(jié)和Android當(dāng)前屏幕(Window)亮度調(diào)節(jié)。

1.Android系統(tǒng)亮度調(diào)節(jié)

Android系統(tǒng)亮度調(diào)節(jié)全局性最高,常見(jiàn)于系統(tǒng)設(shè)置中的亮度設(shè)置項(xiàng)。Android中提供了獲取和設(shè)置系統(tǒng)亮度值(“手動(dòng)模式下的亮度值”)的接口,具體如下:

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

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

Android 2.1以后的系統(tǒng)中,系統(tǒng)亮度調(diào)節(jié)中新增了“自動(dòng)亮度”選項(xiàng)。“自動(dòng)亮度”是依據(jù)外界光源來(lái)自動(dòng)的改變系統(tǒng)亮度,目前大部分手機(jī)中對(duì)“自動(dòng)亮度”還可以進(jìn)行小幅度的調(diào)節(jié)其值。與自動(dòng)亮度相對(duì)應(yīng)的是“手動(dòng)亮度”,當(dāng)處于“手動(dòng)亮度”下,設(shè)置拖動(dòng)亮度進(jìn)度條會(huì)大幅度的改變Android系統(tǒng)亮度。“手動(dòng)亮度”和“自動(dòng)亮度”分別稱(chēng)之為Android系統(tǒng)的“亮度模式”。

與之相對(duì)應(yīng)的,Android系統(tǒng)中也提供了獲取和設(shè)置“亮度模式”的接口。

// 獲取系統(tǒng)亮度模式
Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE);</pre>

 // 設(shè)置系統(tǒng)亮度模式
 Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE, systemMode);</pre>

可是遺憾的是,Android中并未提供處于“自動(dòng)亮度”模式下的亮度值接口。上面所說(shuō)的獲取系統(tǒng)亮度值接口實(shí)際上都是指“手動(dòng)亮度”模式下的亮度值。

一般而言,通過(guò)手動(dòng)亮度值以及設(shè)置系統(tǒng)亮度模式接口,可以滿足常規(guī)的大部分針對(duì)Android系統(tǒng)亮度設(shè)置編碼需求,以完成系統(tǒng)亮度調(diào)節(jié)。

2.Android App亮度調(diào)節(jié)

與系統(tǒng)亮度不同的是,Android中并未直接提供針對(duì)于App層面的亮度調(diào)節(jié)方式。因此,對(duì)于需要進(jìn)行App的亮度調(diào)節(jié),可以通過(guò)系統(tǒng)亮度調(diào)節(jié)或當(dāng)前屏幕的亮度調(diào)節(jié)方式間接來(lái)實(shí)現(xiàn)。

3.Android當(dāng)前屏幕(Window)亮度調(diào)節(jié)

Android針對(duì)當(dāng)前屏幕(Window)提供了設(shè)置亮度的接口,常見(jiàn)寫(xiě)法如下:

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

其中,需要注意的是此處的brightness是一個(gè)0.0-1.0之間的一個(gè)float類(lèi)型數(shù)值。

默認(rèn)情況下,當(dāng)我們直接修改了系統(tǒng)亮度值后,當(dāng)前Window中是可以即時(shí)反應(yīng)出來(lái)亮度效果的,這是因?yàn)槟J(rèn)情況下,WindowManager.LayoutParams的screenBrightness的默認(rèn)值為WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE。

即表示W(wǎng)indow沒(méi)有自己的亮度參數(shù),將依隨系統(tǒng)亮度效果的變化而變化。這也就是我們最常見(jiàn)的:當(dāng)調(diào)整系統(tǒng)亮度后,所有Window都即時(shí)反應(yīng)出系統(tǒng)亮度設(shè)置效果。

當(dāng)時(shí),實(shí)際項(xiàng)目中我們還會(huì)遇到此類(lèi)需求:系統(tǒng)設(shè)置亮度時(shí)只針對(duì)當(dāng)前Window或App內(nèi)生效,而不影響到系統(tǒng)本身的亮度設(shè)置。

假設(shè)當(dāng)前Window內(nèi)有一個(gè)SeekBar,UI與系統(tǒng)亮度調(diào)節(jié)UI基本類(lèi)似,用戶可以滑動(dòng)此SeekBar,使得當(dāng)前Window亮度即時(shí)發(fā)生變化,且不影響到系統(tǒng)亮度效果。如何實(shí)現(xiàn)呢?

此時(shí)我們需要啟用WindowManager.LayoutParams的screenBrightness參數(shù),使之具有自動(dòng)的特定亮度值,設(shè)置此值后在當(dāng)前Window范圍內(nèi),其將覆蓋掉系統(tǒng)亮度設(shè)置。

因此,有必要將用戶選擇的亮度值轉(zhuǎn)換為相應(yīng)的Window亮度值(為與系統(tǒng)亮度值相一致,假設(shè)SeekBar的最大值為255)。

// 根據(jù)亮度值修改當(dāng)前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形參為用戶選擇的亮度值。

那么,上述代碼中為什么有一個(gè)"brightness == -1"的判斷呢?在此主要是考慮到App設(shè)置項(xiàng)中可能出現(xiàn)的“跟隨系統(tǒng)亮度”或“恢復(fù)系統(tǒng)默認(rèn)亮度”此類(lèi)設(shè)置,當(dāng)用戶進(jìn)行此類(lèi)操作時(shí),直接將screenBrightness參數(shù)還原成默認(rèn)參數(shù)值即可。因?yàn)橛汕拔拿枋觥白詣?dòng)亮度”模式下系統(tǒng)亮度值是不能直接得到的,那么當(dāng)系統(tǒng)處于“自動(dòng)亮度”模式下,此時(shí)brightness參數(shù)值將無(wú)法準(zhǔn)確確定,因此,將screenBrightness參數(shù)還原成默認(rèn)參數(shù)值成為一個(gè)行之有效的方法。

4.Android App亮度調(diào)節(jié)可行方案分析

目前網(wǎng)上有不少博文中提到App亮度調(diào)節(jié)時(shí),提出的方案是在App設(shè)置項(xiàng)中,首先記錄下設(shè)置之前的系統(tǒng)亮度值和亮度模式,用戶在App設(shè)置項(xiàng)進(jìn)行亮度調(diào)節(jié)時(shí),直接修改系統(tǒng)亮度值,當(dāng)用戶退出此App,或App至于后臺(tái)(如按下Home按鍵等),再將系統(tǒng)亮度還原。初看起來(lái)貌似一個(gè)可行的方案。但是主要存在如下幾個(gè)問(wèn)題:

  1. 如何獲取到設(shè)置之前的系統(tǒng)亮度值和亮度模式(因?yàn)橹笤诖薃pp外部要恢復(fù)系統(tǒng)亮度值到此初始值)?當(dāng)用戶每次進(jìn)入到設(shè)置頁(yè)時(shí)獲取?嚴(yán)格意義上來(lái)說(shuō),是沒(méi)法準(zhǔn)確記錄的。因?yàn)锳ndroid的用戶操作不可預(yù)知性,如進(jìn)入到設(shè)置頁(yè),拖動(dòng)SeekBar設(shè)置了一個(gè)亮度值,此時(shí)直接修改了系統(tǒng)的亮度值,如果此時(shí)用戶在未將應(yīng)用至于后臺(tái)或未將應(yīng)用退出的情況下直接在App外部修改了系統(tǒng)亮度設(shè)置,如小米中可以通過(guò)下拉標(biāo)題欄,直接就可以設(shè)置系統(tǒng)亮度。因此,App亮度設(shè)置之前的系統(tǒng)亮度初始值獲取存在困難。

  2. 如何判斷用戶來(lái)到了App外部?因?yàn)榇藭r(shí)需要恢復(fù)系統(tǒng)亮度設(shè)置到初始系統(tǒng)亮度。如用戶可以按下Home按鍵,長(zhǎng)按Home按鍵直接切換App,直接Back按鍵等一步步退出此App,下拉標(biāo)題欄直接點(diǎn)擊其他App通知信息進(jìn)入到其他App,手機(jī)自動(dòng)鎖屏后解鎖時(shí)用戶直接進(jìn)入其他應(yīng)用等等,此類(lèi)操作場(chǎng)景也具有不可預(yù)知性,因此,判斷用戶來(lái)到了App外部以恢復(fù)系統(tǒng)亮度到初始值的時(shí)機(jī)上也存在一定困難。

由此,App亮度調(diào)節(jié)方案推薦通過(guò)設(shè)置當(dāng)前屏幕(Window)方式進(jìn)行。

大致思路如下:用戶在設(shè)置項(xiàng)中進(jìn)行亮度調(diào)節(jié)時(shí),調(diào)用changeAppBrightness()方法,將改變當(dāng)前屏幕(Window)的亮度,此時(shí)對(duì)系統(tǒng)亮度無(wú)任何影響,接下來(lái)存在的問(wèn)題終于要就集中于當(dāng)用戶來(lái)到本App其他Activity中,如果使得剛剛設(shè)置的亮度值得以即時(shí)反應(yīng)出來(lái)。

當(dāng)用戶進(jìn)行亮度調(diào)節(jié)后,將當(dāng)前亮度設(shè)置值保存起來(lái)(如保存到SharedPreferences中),在基類(lèi)Activity中的onResume方法中,可以取出SharedPreferences中的用戶所設(shè)置的App亮度值,然后changeAppBrightness()方法以實(shí)現(xiàn)每個(gè)當(dāng)前屏幕的亮度調(diào)節(jié)。

總體說(shuō)來(lái),通過(guò)設(shè)置當(dāng)前屏幕(Window)的方式來(lái)設(shè)置App亮度更加簡(jiǎn)單有效。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1 調(diào)節(jié)Activity亮度 先看調(diào)節(jié)方式: 從上述代碼可以看出,調(diào)節(jié)Activity亮度,是通過(guò)設(shè)置窗口屬性來(lái)調(diào)...
    marine8888閱讀 1,475評(píng)論 0 0
  • 在Android源碼中,提供的快捷開(kāi)關(guān)相對(duì)是比較少的,Android4.0系統(tǒng)默認(rèn)提供的桌面快捷開(kāi)關(guān)AppWidg...
    Sunny君907閱讀 1,125評(píng)論 0 0
  • 引言 注意標(biāo)題,是“App內(nèi)部亮度調(diào)節(jié)”而非“系統(tǒng)亮度”或是“當(dāng)前window亮度” Android官方僅提供了“...
    OldJii閱讀 1,190評(píng)論 0 0
  • 亮度設(shè)置應(yīng)用設(shè)計(jì)1.1 設(shè)置進(jìn)度條范圍背光設(shè)置是在:設(shè)置->聲音和顯示->亮度,通過(guò)進(jìn)度條來(lái)設(shè)置的。 文件:pac...
    ccsosnfs閱讀 585評(píng)論 0 0
  • 還有1501天,我30歲了。 今天沒(méi)有什么特別的,還是很普通的一天。嘗試了新的工作,發(fā)現(xiàn),很多事情覺(jué)得很難,可能是...
    追風(fēng)箏遇上了荷西閱讀 301評(píng)論 0 0

友情鏈接更多精彩內(nèi)容