Android 6.0 API
運(yùn)行時(shí)權(quán)限
運(yùn)行時(shí)申請(qǐng)權(quán)限,需要targetSDK>=23,并且手機(jī)的系統(tǒng)大于6.0,
不滿足以上條件時(shí),應(yīng)用只需要在androidManifest.xml文件下填寫好需要的權(quán)限,即可在應(yīng)用安裝的時(shí),
用戶無感知的情況下獲取私密權(quán)限,比如訪問手機(jī)相冊(cè),聯(lián)系人之類的。
低電耗模式和應(yīng)用待機(jī)模式
低電耗模式
如果用戶拔下設(shè)備的電源插頭,并在屏幕關(guān)閉后的一段時(shí)間內(nèi)使其保持不活動(dòng)狀態(tài),設(shè)備會(huì)進(jìn)入低電耗模式,在該模式下設(shè)備會(huì)嘗試讓系統(tǒng)保持休眠狀態(tài)。在該模式下,設(shè)備會(huì)定期短時(shí)間恢復(fù)正常工作,以便進(jìn)行應(yīng)用同步,還可讓系統(tǒng)執(zhí)行任何掛起的操作。如下圖,其中Doze表示喚醒狀態(tài),用來進(jìn)行應(yīng)用同步。
[圖片上傳失敗...(image-ab1cae-1535274187117)]
低電耗模式限制
暫停訪問網(wǎng)絡(luò)。
系統(tǒng)將忽略 wake locks。
標(biāo)準(zhǔn)
AlarmManager鬧鈴(包括setExact()和setWindow())推遲到下一維護(hù)時(shí)段。如果您需要設(shè)置在低電耗模式下觸發(fā)的鬧鈴,請(qǐng)使用
setAndAllowWhileIdle()或setExactAndAllowWhileIdle()。一般情況下,使用
setAlarmClock()設(shè)置的鬧鈴將繼續(xù)觸發(fā) — 但系統(tǒng)會(huì)在這些鬧鈴觸發(fā)之前不久退出低電耗模式。
系統(tǒng)不執(zhí)行 Wi-Fi 掃描。
系統(tǒng)不允許運(yùn)行同步適配器。
系統(tǒng)不允許運(yùn)行
JobScheduler
對(duì)應(yīng)用可能造成的影響
最大的影響時(shí)鬧鐘和定時(shí)器,因?yàn)楫?dāng)系統(tǒng)處于低電耗模式時(shí),不會(huì)觸發(fā) Android 5.1(API 級(jí)別 22)或更低版本中的鬧鈴。這時(shí)可引入了兩種新的
AlarmManager方法:setAndAllowWhileIdle()和setExactAndAllowWhileIdle()。通過這些方法,您可以設(shè)置即使設(shè)備處于低電耗模式也會(huì)觸發(fā)的鬧鈴。在低電耗模式下,消息推送不一定能及時(shí)到達(dá),只有在低電耗模式期間的Doze階段才能正常接受消息推送。
應(yīng)用待機(jī)模式
應(yīng)用待機(jī)模式允許系統(tǒng)判定應(yīng)用在用戶未主動(dòng)使用它時(shí)處于空閑狀態(tài)。當(dāng)用戶有一段時(shí)間未觸摸應(yīng)用時(shí),系統(tǒng)便會(huì)作出此判定。如果拔下了設(shè)備電源插頭,系統(tǒng)會(huì)為其視為空閑的應(yīng)用停用網(wǎng)絡(luò)訪問以及暫停同步和作業(yè)。
取消支持Apache HTTP客戶端
Android 6.0 版移除了對(duì) Apache HTTP 客戶端的支持。如果您的應(yīng)用使用該客戶端,并以 Android 2.3(API 級(jí)別 9)或更高版本為目標(biāo)平臺(tái),請(qǐng)改用 HttpURLConnection 類。此 API 效率更高,因?yàn)樗梢酝ㄟ^透明壓縮和響應(yīng)緩存減少網(wǎng)絡(luò)使用,并可最大限度降低耗電量。要繼續(xù)使用 Apache HTTP API,您必須先在 build.gradle 文件中聲明以下編譯時(shí)依賴項(xiàng)
<pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang="java" contenteditable="false" cid="n299" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Consolas, "Liberation Mono", Courier, monospace; font-size: 0.9em; white-space: normal; display: block; break-inside: avoid; text-align: left; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(223, 226, 229); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;">android {
useLibrary 'org.apache.http.legacy'
}</pre>
BoringSSL
Android 正在從使用 OpenSSL 庫轉(zhuǎn)向使用 BoringSSL 庫。如果您要在應(yīng)用中使用 Android NDK,請(qǐng)勿鏈接到并非 NDK API 組成部分的加密庫,如 libcrypto.so 和 libssl.so。這些庫并非公共 API,可能會(huì)在不同版本和設(shè)備上毫無征兆地發(fā)生變化或出現(xiàn)故障。此外,您還可能讓自己暴露在安全漏洞的風(fēng)險(xiǎn)之下。請(qǐng)改為修改原生代碼,以通過 JNI 調(diào)用 Java 加密 API,或靜態(tài)鏈接到您選擇的加密庫。
Android 6.0 變更
目錄運(yùn)行時(shí)權(quán)限低電耗模式和應(yīng)用待機(jī)模式取消支持 Apache HTTP 客戶端BoringSSL硬件標(biāo)識(shí)符訪問權(quán)通知音頻管理器變更文本選擇瀏覽器書簽變更Android 密鑰庫變更WLAN 和網(wǎng)絡(luò)連接變更相機(jī)服務(wù)變更運(yùn)行時(shí)APK 驗(yàn)證USB 連接Android for Work 變更
Android 6.0(API 級(jí)別 23)除了提供諸多新特性和功能外,還對(duì)系統(tǒng)和 API 行為做出了各種變更。本文重點(diǎn)介紹您應(yīng)該了解并在開發(fā)應(yīng)用時(shí)加以考慮的一些主要變更。
如果您之前發(fā)布過 Android 應(yīng)用,請(qǐng)注意您的應(yīng)用可能受到這些平臺(tái)變更的影響。
運(yùn)行時(shí)權(quán)限
此版本引入了一種新的權(quán)限模式,如今,用戶可直接在運(yùn)行時(shí)管理應(yīng)用權(quán)限。這種模式讓用戶能夠更好地了解和控制權(quán)限,同時(shí)為應(yīng)用開發(fā)者精簡了安裝和自動(dòng)更新過程。用戶可為所安裝的各個(gè)應(yīng)用分別授予或撤銷權(quán)限。
對(duì)于以 Android 6.0(API 級(jí)別 23)或更高版本為目標(biāo)平臺(tái)的應(yīng)用,請(qǐng)務(wù)必在運(yùn)行時(shí)檢查和請(qǐng)求權(quán)限。要確定您的應(yīng)用是否已被授予權(quán)限,請(qǐng)調(diào)用新增的 checkSelfPermission() 方法。要請(qǐng)求權(quán)限,請(qǐng)調(diào)用新增的 requestPermissions()方法。即使您的應(yīng)用并不以 Android 6.0(API 級(jí)別 23)為目標(biāo)平臺(tái),您也應(yīng)該在新權(quán)限模式下測試您的應(yīng)用。
如需了解有關(guān)在您的應(yīng)用中支持新權(quán)限模式的詳情,請(qǐng)參閱使用系統(tǒng)權(quán)限。如需了解有關(guān)如何評(píng)估新模式對(duì)應(yīng)用的影響的提示,請(qǐng)參閱權(quán)限最佳做法。
低電耗模式和應(yīng)用待機(jī)模式
此版本引入了針對(duì)空閑設(shè)備和應(yīng)用的最新節(jié)能優(yōu)化技術(shù)。這些功能會(huì)影響所有應(yīng)用,因此請(qǐng)務(wù)必在這些新模式下測試您的應(yīng)用。
低電耗模式:如果用戶拔下設(shè)備的電源插頭,并在屏幕關(guān)閉后的一段時(shí)間內(nèi)使其保持不活動(dòng)狀態(tài),設(shè)備會(huì)進(jìn)入低電耗模式,在該模式下設(shè)備會(huì)嘗試讓系統(tǒng)保持休眠狀態(tài)。在該模式下,設(shè)備會(huì)定期短時(shí)間恢復(fù)正常工作,以便進(jìn)行應(yīng)用同步,還可讓系統(tǒng)執(zhí)行任何掛起的操作。
應(yīng)用待機(jī)模式:應(yīng)用待機(jī)模式允許系統(tǒng)判定應(yīng)用在用戶未主動(dòng)使用它時(shí)處于空閑狀態(tài)。當(dāng)用戶有一段時(shí)間未觸摸應(yīng)用時(shí),系統(tǒng)便會(huì)作出此判定。如果拔下了設(shè)備電源插頭,系統(tǒng)會(huì)為其視為空閑的應(yīng)用停用網(wǎng)絡(luò)訪問以及暫停同步和作業(yè)。
要詳細(xì)了解這些節(jié)能變更,請(qǐng)參閱對(duì)低電耗模式和應(yīng)用待機(jī)模式進(jìn)行針對(duì)性優(yōu)化。
取消支持 Apache HTTP 客戶端
Android 6.0 版移除了對(duì) Apache HTTP 客戶端的支持。如果您的應(yīng)用使用該客戶端,并以 Android 2.3(API 級(jí)別 9)或更高版本為目標(biāo)平臺(tái),請(qǐng)改用 HttpURLConnection 類。此 API 效率更高,因?yàn)樗梢酝ㄟ^透明壓縮和響應(yīng)緩存減少網(wǎng)絡(luò)使用,并可最大限度降低耗電量。要繼續(xù)使用 Apache HTTP API,您必須先在 build.gradle 文件中聲明以下編譯時(shí)依賴項(xiàng):
<pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang="" contenteditable="false" cid="n396" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Consolas, "Liberation Mono", Courier, monospace; font-size: 0.9em; white-space: normal; display: block; break-inside: avoid; text-align: left; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(223, 226, 229); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;">android {
useLibrary 'org.apache.http.legacy'
}</pre>
BoringSSL
Android 正在從使用 OpenSSL 庫轉(zhuǎn)向使用 BoringSSL 庫。如果您要在應(yīng)用中使用 Android NDK,請(qǐng)勿鏈接到并非 NDK API 組成部分的加密庫,如 libcrypto.so 和 libssl.so。這些庫并非公共 API,可能會(huì)在不同版本和設(shè)備上毫無征兆地發(fā)生變化或出現(xiàn)故障。此外,您還可能讓自己暴露在安全漏洞的風(fēng)險(xiǎn)之下。請(qǐng)改為修改原生代碼,以通過 JNI 調(diào)用 Java 加密 API,或靜態(tài)鏈接到您選擇的加密庫。
硬件標(biāo)識(shí)符訪問權(quán) (WLAN掃描和藍(lán)牙功能)
為給用戶提供更嚴(yán)格的數(shù)據(jù)保護(hù),從此版本開始,對(duì)于使用 WLAN API 和 Bluetooth API 的應(yīng)用,Android 移除了對(duì)設(shè)備本地硬件標(biāo)識(shí)符的編程訪問權(quán)。WifiInfo.getMacAddress() 方法和 BluetoothAdapter.getAddress() 方法現(xiàn)在會(huì)返回常量值 02:00:00:00:00:00。
現(xiàn)在,要通過藍(lán)牙和 WLAN 掃描訪問附近外部設(shè)備的硬件標(biāo)識(shí)符,您的應(yīng)用必須擁有 ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION 權(quán)限。即使用以下api時(shí)
WifiManager.getScanResults()BluetoothDevice.ACTION_FOUNDBluetoothLeScanner.startScan()
注:當(dāng)運(yùn)行 Android 6.0(API 級(jí)別 23)的設(shè)備發(fā)起后臺(tái) WLAN 或藍(lán)牙掃描時(shí),在外部設(shè)備看來,該操作的發(fā)起來源是一個(gè)隨機(jī)化 MAC 地址。
通知
此版本移除了 Notification.setLatestEventInfo() 方法。請(qǐng)改用 Notification.Builder 類來構(gòu)建通知。要重復(fù)更新通知,請(qǐng)重復(fù)使用 Notification.Builder 實(shí)例。調(diào)用 build() 方法可獲取更新后的 Notification 實(shí)例。
adb shell dumpsys notification 命令不再打印輸出您的通知文本。請(qǐng)改用 adb shell dumpsys notification --noredact 命令打印輸出 notification 對(duì)象中的文本。
音頻管理器變更
不再支持通過 AudioManager 類直接設(shè)置音量或?qū)⑻囟ㄒ纛l流靜音。setStreamSolo() 方法已棄用,您應(yīng)該改為調(diào)用 requestAudioFocus() 方法。類似地,setStreamMute() 方法也已棄用,請(qǐng)改為調(diào)用 adjustStreamVolume() 方法并傳入方向值 ADJUST_MUTE 或 ADJUST_UNMUTE。
Android 密鑰庫變更
從此版本(23)開始,Android 密鑰庫提供程序不再支持 DSA。但仍支持 ECDSA。
WLAN 和網(wǎng)絡(luò)連接變更
現(xiàn)在,您的應(yīng)用只能更改由您創(chuàng)建的
WifiConfiguration對(duì)象的狀態(tài)。系統(tǒng)不允許您修改或刪除由用戶或其他應(yīng)用創(chuàng)建的WifiConfiguration對(duì)象。在之前的版本中,如果應(yīng)用利用帶有
disableAllOthers=true設(shè)置的enableNetwork()強(qiáng)制設(shè)備連接特定 WLAN 網(wǎng)絡(luò),設(shè)備將會(huì)斷開與移動(dòng)數(shù)據(jù)網(wǎng)絡(luò)等其他網(wǎng)絡(luò)的連接。在此版本中,設(shè)備不再斷開與上述其他網(wǎng)絡(luò)的連接。如果您的應(yīng)用的targetSdkVersion為“20”或更低,則會(huì)固定連接所選 WLAN 網(wǎng)絡(luò)。如果您的應(yīng)用的targetSdkVersion為“21”或更高,請(qǐng)使用多網(wǎng)絡(luò) API(如openConnection()、bindSocket()和新增的bindProcessToNetwork()方法)來確保通過所選網(wǎng)絡(luò)傳送網(wǎng)絡(luò)流量。
相機(jī)服務(wù)變更(該用Camera2代替Camera)
在此版本中,相機(jī)服務(wù)中共享資源的訪問模式已從之前的“先到先得”訪問模式更改為高優(yōu)先級(jí)進(jìn)程優(yōu)先的訪問模式。對(duì)服務(wù)行為的變更包括:
根據(jù)客戶端應(yīng)用進(jìn)程的“優(yōu)先級(jí)”授予對(duì)相機(jī)子系統(tǒng)資源的訪問權(quán),包括打開和配置相機(jī)設(shè)備。帶有對(duì)用戶可見 Activity 或前臺(tái) Activity 的應(yīng)用進(jìn)程一般會(huì)被授予較高的優(yōu)先級(jí),從而使相機(jī)資源的獲取和使用更加可靠;
當(dāng)高優(yōu)先級(jí)的應(yīng)用嘗試使用相機(jī)時(shí),系統(tǒng)可能會(huì)“驅(qū)逐”正在使用相機(jī)客戶端的低優(yōu)先級(jí)應(yīng)用。在已棄用的
CameraAPI 中,這會(huì)導(dǎo)致系統(tǒng)為被驅(qū)逐的客戶端調(diào)用onError()。在Camera2API 中,這會(huì)導(dǎo)致系統(tǒng)為被驅(qū)逐的客戶端調(diào)用onDisconnected();在配備相應(yīng)相機(jī)硬件的設(shè)備上,不同的應(yīng)用進(jìn)程可同時(shí)獨(dú)立打開和使用不同的相機(jī)設(shè)備。但現(xiàn)在,如果在多進(jìn)程用例中同時(shí)訪問相機(jī)會(huì)造成任何打開的相機(jī)設(shè)備的性能或能力嚴(yán)重下降,相機(jī)服務(wù)會(huì)檢測到這種情況并禁止同時(shí)訪問。即使并沒有其他應(yīng)用直接嘗試訪問同一相機(jī)設(shè)備,此變更也可能導(dǎo)致低優(yōu)先級(jí)客戶端被“驅(qū)逐”。
更改當(dāng)前用戶會(huì)導(dǎo)致之前用戶帳戶擁有的應(yīng)用內(nèi)活動(dòng)相機(jī)客戶端被驅(qū)逐。對(duì)相機(jī)的訪問僅限于訪問當(dāng)前設(shè)備用戶擁有的用戶個(gè)人資料。舉例來說,這意味著,當(dāng)用戶切換到其他帳戶后,“來賓”帳戶實(shí)際上無法讓使用相機(jī)子系統(tǒng)的進(jìn)程保持運(yùn)行狀態(tài)。
APK 驗(yàn)證
該平臺(tái)現(xiàn)在執(zhí)行的 APK 驗(yàn)證更為嚴(yán)格。如果在清單中聲明的文件在 APK 中并不存在,該 APK 將被視為已損壞。移除任何內(nèi)容后必須重新簽署 APK。
ps:如果應(yīng)用安裝時(shí)提示apk損壞,很有可能是打包時(shí)有些文件沒能正確導(dǎo)入,這個(gè)問題多半是因?yàn)?strong>混淆導(dǎo)致的。