Android 7.0 新特性詳解

Android 7.0 新特性(源自官方文檔)

Android 7.0(API 級(jí)別 24) 除了提供諸多新特性和功能外,還對(duì)系統(tǒng)和 API 行為做出了各種變更。本文重點(diǎn)介紹您應(yīng)該了解并在開(kāi)發(fā)應(yīng)用時(shí)加以考慮的一些主要變更。

如果您之前發(fā)布過(guò) Android 應(yīng)用,請(qǐng)注意您的應(yīng)用可能受到這些平臺(tái)變化的影響。

電池和內(nèi)存

Android 7.0 包括旨在延長(zhǎng)設(shè)備電池壽命和減少 RAM 使用的系統(tǒng)行為變更。這些變更可能會(huì)影響您的應(yīng)用訪問(wèn)系統(tǒng)資源,以及您的應(yīng)用通過(guò)特定隱式 intent 與其他應(yīng)用交互的方式。

低電耗模式

Android 6.0(API 級(jí)別 23)引入了低電耗模式,當(dāng)用戶設(shè)備未插接電源、處于靜止?fàn)顟B(tài)且屏幕關(guān)閉時(shí),該模式會(huì)推遲 CPU 和網(wǎng)絡(luò)活動(dòng),從而延長(zhǎng)電池壽命。而 Android 7.0 則通過(guò)在設(shè)備未插接電源且屏幕關(guān)閉狀態(tài)下、但不一定要處于靜止?fàn)顟B(tài)(例如用戶外出時(shí)把手持式設(shè)備裝在口袋里)時(shí)應(yīng)用部分 CPU 和網(wǎng)絡(luò)限制,進(jìn)一步增強(qiáng)了低電耗模式。

圖1_Image.png

圖 1. 低電耗模式如何應(yīng)用第一級(jí)系統(tǒng)活動(dòng)限制以延長(zhǎng)電池壽命的圖示。

當(dāng)設(shè)備處于充電狀態(tài)且屏幕已關(guān)閉一定時(shí)間后,設(shè)備會(huì)進(jìn)入低電耗模式并應(yīng)用第一部分限制:關(guān)閉應(yīng)用網(wǎng)絡(luò)訪問(wèn)、推遲作業(yè)和同步。如果進(jìn)入低電耗模式后設(shè)備處于靜止?fàn)顟B(tài)達(dá)到一定時(shí)間,系統(tǒng)則會(huì)對(duì) PowerManager.WakeLock、AlarmManager 鬧鈴、GPS 和 WLAN 掃描應(yīng)用余下的低電耗模式限制。無(wú)論是應(yīng)用部分還是全部低電耗模式限制,系統(tǒng)都會(huì)喚醒設(shè)備以提供簡(jiǎn)短的維護(hù)時(shí)間窗口,在此窗口期間,應(yīng)用程序可以訪問(wèn)網(wǎng)絡(luò)并執(zhí)行任何被推遲的作業(yè)/同步。

圖2_Image.png

圖 2. 低電耗模式如何在設(shè)備處于靜止?fàn)顟B(tài)達(dá)到一定時(shí)間后應(yīng)用第二級(jí)系統(tǒng)活動(dòng)限制的圖示。

請(qǐng)注意,激活屏幕或插接設(shè)備電源時(shí),系統(tǒng)將退出低電耗模式并移除這些處理限制。此項(xiàng)新增的行為不會(huì)影響有關(guān)使您的應(yīng)用適應(yīng) Android 6.0(API 級(jí)別 23)中所推出的舊版本低電耗模式的建議和最佳做法,如對(duì)低電耗模式和應(yīng)用待機(jī)模式進(jìn)行針對(duì)性優(yōu)化中所討論。您仍應(yīng)遵循這些建議(例如使用 Google 云消息傳遞 (GCM) 發(fā)送和接收消息)并開(kāi)始安排更新計(jì)劃以適應(yīng)新增的低電耗模式行為。

Project Svelte:后臺(tái)優(yōu)化

Android 7.0 移除了三項(xiàng)隱式廣播,以幫助優(yōu)化內(nèi)存使用和電量消耗。此項(xiàng)變更很有必要,因?yàn)殡[式廣播會(huì)在后臺(tái)頻繁啟動(dòng)已注冊(cè)偵聽(tīng)這些廣播的應(yīng)用。刪除這些廣播可以顯著提升設(shè)備性能和用戶體驗(yàn)。

移動(dòng)設(shè)備會(huì)經(jīng)歷頻繁的連接變更,例如在 WLAN 和移動(dòng)數(shù)據(jù)之間切換時(shí)。目前,可以通過(guò)在應(yīng)用清單中注冊(cè)一個(gè)接收器來(lái)偵聽(tīng)隱式 CONNECTIVITY_ACTION 廣播,讓?xiě)?yīng)用能夠監(jiān)控這些變更。由于很多應(yīng)用會(huì)注冊(cè)接收此廣播,因此單次網(wǎng)絡(luò)切換即會(huì)導(dǎo)致所有應(yīng)用被喚醒并同時(shí)處理此廣播。

同理,在之前版本的 Android 中,應(yīng)用可以注冊(cè)接收來(lái)自其他應(yīng)用(例如相機(jī))的隱式 ACTION_NEW_PICTURE 和 ACTION_NEW_VIDEO 廣播。當(dāng)用戶使用相機(jī)應(yīng)用拍攝照片時(shí),這些應(yīng)用即會(huì)被喚醒以處理廣播。

為緩解這些問(wèn)題,Android 7.0 應(yīng)用了以下優(yōu)化措施:

  • 面向 Android 7.0 開(kāi)發(fā)的應(yīng)用不會(huì)收到 CONNECTIVITY_ACTION 廣播,即使它們已有清單條目來(lái)請(qǐng)求接受這些事件的通知。在前臺(tái)運(yùn)行的應(yīng)用如果使用 BroadcastReceiver 請(qǐng)求接收通知,則仍可以在主線程中偵聽(tīng) CONNECTIVITY_CHANGE。
  • 應(yīng)用無(wú)法發(fā)送或接收 ACTION_NEW_PICTURE 或 ACTION_NEW_VIDEO 廣播。此項(xiàng)優(yōu)化會(huì)影響所有應(yīng)用,而不僅僅是面向 Android 7.0 的應(yīng)用。
    如果您的應(yīng)用使用任何 intent,您仍需要盡快移除它們的依賴(lài)關(guān)系,以正確適配 Android 7.0 設(shè)備。Android 框架提供多個(gè)解決方案來(lái)緩解對(duì)這些隱式廣播的需求。例如,JobScheduler API 提供了一個(gè)穩(wěn)健可靠的機(jī)制來(lái)安排滿足指定條件(例如連入無(wú)限流量網(wǎng)絡(luò))時(shí)所執(zhí)行的網(wǎng)絡(luò)操作。您甚至可以使用 JobScheduler 來(lái)適應(yīng)內(nèi)容提供程序變化。

如需了解有關(guān) Android N 中后臺(tái)優(yōu)化以及如何改寫(xiě)應(yīng)用的詳細(xì)信息,請(qǐng)參閱后臺(tái)優(yōu)化

權(quán)限更改

Android 7.0 做了一些權(quán)限更改,這些更改可能會(huì)影響您的應(yīng)用。

系統(tǒng)權(quán)限更改

為了提高私有文件的安全性,面向 Android 7.0 或更高版本的應(yīng)用私有目錄被限制訪問(wèn) (0700)。此設(shè)置可防止私有文件的元數(shù)據(jù)泄漏,如它們的大小或存在性。此權(quán)限更改有多重副作用:

  • 私有文件的文件權(quán)限不應(yīng)再由所有者放寬,為使用 MODE_WORLD_READABLE 和/或 MODE_WORLD_WRITEABLE 而進(jìn)行的此類(lèi)嘗試將觸發(fā) SecurityException。
    注:迄今為止,這種限制尚不能完全執(zhí)行。應(yīng)用仍可能使用原生 API 或 File API 來(lái)修改它們的私有目錄權(quán)限。但是,我們強(qiáng)烈反對(duì)放寬私有目錄的權(quán)限。

  • 傳遞軟件包網(wǎng)域外的 file:// URI 可能給接收器留下無(wú)法訪問(wèn)的路徑。因此,嘗試傳遞 file:// URI 會(huì)觸發(fā) FileUriExposedException。分享私有文件內(nèi)容的推薦方法是使用 FileProvider。

  • DownloadManager 不再按文件名分享私人存儲(chǔ)的文件。舊版應(yīng)用在訪問(wèn) COLUMN_LOCAL_FILENAME 時(shí)可能出現(xiàn)無(wú)法訪問(wèn)的路徑。面向 Android 7.0 或更高版本的應(yīng)用在嘗試訪問(wèn) COLUMN_LOCAL_FILENAME 時(shí)會(huì)觸發(fā) SecurityException。通過(guò)使用 DownloadManager.Request.setDestinationInExternalFilesDir() 或 DownloadManager.Request.setDestinationInExternalPublicDir() 將下載位置設(shè)置為公共位置的舊版應(yīng)用仍可以訪問(wèn) COLUMN_LOCAL_FILENAME 中的路徑,但是我們強(qiáng)烈反對(duì)使用這種方法。對(duì)于由 DownloadManager 公開(kāi)的文件,首選的訪問(wèn)方式是使用ContentResolver.openFileDescriptor()。

在應(yīng)用間共享文件

對(duì)于面向 Android 7.0 的應(yīng)用,Android 框架執(zhí)行的 StrictMode API 政策禁止在您的應(yīng)用外部公開(kāi) file:// URI。如果一項(xiàng)包含文件 URI 的 intent 離開(kāi)您的應(yīng)用,則應(yīng)用出現(xiàn)故障,并出現(xiàn) FileUriExposedException 異常。

要在應(yīng)用間共享文件,您應(yīng)發(fā)送一項(xiàng) content:// URI,并授予 URI 臨時(shí)訪問(wèn)權(quán)限。進(jìn)行此授權(quán)的最簡(jiǎn)單方式是使用 FileProvider 類(lèi)。如需了解有關(guān)權(quán)限和共享文件的詳細(xì)信息,請(qǐng)參閱共享文件

無(wú)障礙改進(jìn)

為提高平臺(tái)對(duì)于視力不佳或視力受損用戶的易用性,Android 7.0 做出了一些更改。這些更改一般并不要求更改您的應(yīng)用代碼,不過(guò)您應(yīng)仔細(xì)檢查并使用您的應(yīng)用測(cè)試這些功能,以評(píng)估它們對(duì)用戶體驗(yàn)的潛在影響。

屏幕縮放

Android 7.0 支持用戶設(shè)置顯示尺寸,以放大或縮小屏幕上的所有元素,從而提升設(shè)備對(duì)視力不佳用戶的可訪問(wèn)性。用戶無(wú)法將屏幕縮放至低于最小屏幕寬度 sw320dp,該寬度是 Nexus 4 的寬度,也是常規(guī)中等大小手機(jī)的寬度。

圖3_1_Image.png
圖3_2_Image.png

圖 3. 右側(cè)屏幕顯示的是一臺(tái)運(yùn)行

Android 7.0 系統(tǒng)映像的設(shè)備增大顯示尺寸后的效果。

當(dāng)設(shè)備密度發(fā)生更改時(shí),系統(tǒng)會(huì)以如下方式通知正在運(yùn)行的應(yīng)用:

  • 如果是面向 API 級(jí)別 23 或更低版本系統(tǒng)的應(yīng)用,系統(tǒng)會(huì)自動(dòng)終止其所有后臺(tái)進(jìn)程。這意味著如果用戶切換離開(kāi)此類(lèi)應(yīng)用,轉(zhuǎn)而打開(kāi) Settings 屏幕并更改 Display size 設(shè)置,則系統(tǒng)會(huì)像處理內(nèi)存不足的情況一樣終止該應(yīng)用。如果應(yīng)用具有任何前臺(tái)進(jìn)程,則系統(tǒng)會(huì)如處理運(yùn)行時(shí)更改中所述將配置變更通知給這些進(jìn)程,就像對(duì)待設(shè)備屏幕方向變更一樣。

  • 如果是面向 Android 7.0 的應(yīng)用,則其所有進(jìn)程(前臺(tái)和后臺(tái))都會(huì)收到有關(guān)配置變更的通知,如處理運(yùn)行時(shí)更改中所述。
    大多數(shù)應(yīng)用并不需要進(jìn)行任何更改即可支持此功能,不過(guò)前提是這些應(yīng)用遵循 Android 最佳做法。具體要檢查的事項(xiàng):

  • 在屏幕寬度為 sw320dp 的設(shè)備上測(cè)試您的應(yīng)用,并確保其充分運(yùn)行。

  • 當(dāng)設(shè)備配置發(fā)生變更時(shí),更新任何與密度相關(guān)的緩存信息,例如緩存位圖或從網(wǎng)絡(luò)加載的資源。當(dāng)應(yīng)用從暫停狀態(tài)恢復(fù)運(yùn)行時(shí),檢查配置變更。
    注:如果您要緩存與配置相關(guān)的數(shù)據(jù),則最好也包括相關(guān)元數(shù)據(jù),例如該數(shù)據(jù)對(duì)應(yīng)的屏幕尺寸或像素密度。保存這些元數(shù)據(jù)便于您在配置變更后決定是否需要刷新緩存數(shù)據(jù)。

  • 避免用像素單位指定尺寸,因?yàn)橄袼夭粫?huì)隨屏幕密度縮放。應(yīng)改為使用與密度無(wú)關(guān)像素 (dp) 單位指定尺寸。

設(shè)置向?qū)е械囊曈X(jué)設(shè)置

Android 7.0 在“Welcome”屏幕中加入了“Vision Settings”,用戶可以在新設(shè)備上設(shè)置以下無(wú)障礙功能設(shè)置:Magnification gesture、Font size、Display size 和話語(yǔ)提示。此項(xiàng)變更讓您可以更容易發(fā)現(xiàn)與不同屏幕設(shè)置有關(guān)的錯(cuò)誤。要評(píng)估此功能的影響,您應(yīng)在啟用這些設(shè)置的狀態(tài)下測(cè)試應(yīng)用。您可以在 Settings > Accessibility 中找到這些設(shè)置。

NDK 應(yīng)用鏈接至平臺(tái)庫(kù)

從 Android 7.0 開(kāi)始,系統(tǒng)將阻止應(yīng)用動(dòng)態(tài)鏈接非公開(kāi) NDK 庫(kù),這種庫(kù)可能會(huì)導(dǎo)致您的應(yīng)用崩潰。此行為變更旨在為跨平臺(tái)更新和不同設(shè)備提供統(tǒng)一的應(yīng)用體驗(yàn)。即使您的代碼可能不會(huì)鏈接私有庫(kù),但您的應(yīng)用中的第三方靜態(tài)庫(kù)可能會(huì)這么做。因此,所有開(kāi)發(fā)者都應(yīng)進(jìn)行相應(yīng)檢查,確保他們的應(yīng)用不會(huì)在運(yùn)行 Android 7.0 的設(shè)備上崩潰。如果您的應(yīng)用使用原生代碼,則只能使用公開(kāi) NDK API。

您的應(yīng)用可通過(guò)以下三種方式嘗試訪問(wèn)私有平臺(tái) API:

  • 您的應(yīng)用直接訪問(wèn)私有平臺(tái)庫(kù)。您應(yīng)更新您的應(yīng)用以添加該應(yīng)用的庫(kù)副本,或使用公開(kāi) NDK API
  • 您的應(yīng)用使用一個(gè)可訪問(wèn)私有平臺(tái)庫(kù)的第三方庫(kù)。即使您確定您的應(yīng)用不會(huì)直接訪問(wèn)私有庫(kù),您仍應(yīng)針對(duì)此情景測(cè)試您的應(yīng)用。
  • 您的應(yīng)用引用一個(gè)其 APK 中未包含的庫(kù)。例如,如果您嘗試使用您自己的 OpenSSL 副本,但忘記將它與應(yīng)用的 APK 進(jìn)行捆綁,則可能會(huì)出現(xiàn)此情況。正常情況下,此應(yīng)用可在包含 libcrypto.so 的 Android 平臺(tái)版本上運(yùn)行。不過(guò),此應(yīng)用在不包含此庫(kù)的新版 Android(例如,Android 6.0 和更高的版本)上會(huì)崩潰。為修復(fù)此問(wèn)題,請(qǐng)確保您的 APK 捆綁您的所有非 NDK 庫(kù)。
    應(yīng)用不應(yīng)使用 NDK 中未包含的原生庫(kù),因?yàn)檫@些庫(kù)可能會(huì)發(fā)生更改或在不同 Android 版本之間的可用性不同。例如,從 OpenSSL 切換至 BoringSSL 即屬于此類(lèi)更改。此外,由于不屬于 NDK 中的平臺(tái)庫(kù)沒(méi)有兼容性要求,因此不同的設(shè)備可能提供不同級(jí)別的兼容性。

為降低此限制可能對(duì)當(dāng)前發(fā)布的應(yīng)用的影響,面向 API 級(jí)別 23 或更低級(jí)別的應(yīng)用在 Android N 上可暫時(shí)訪問(wèn)頗為常用的一組庫(kù),例如 libandroid_runtime.so、libcutils.so、libcrypto.so 和 libssl.so。如果您的應(yīng)用加載其中某個(gè)庫(kù),logcat 會(huì)生成一個(gè)警告,并在目標(biāo)設(shè)備上顯示一個(gè) Toast 來(lái)通知您。如果您看到這些警告,您應(yīng)更新您的應(yīng)用以添加該應(yīng)用自己的庫(kù)副本,或僅使用公開(kāi) NDK API。將來(lái)發(fā)布的 Android 平臺(tái)可能會(huì)完全限制對(duì)私有庫(kù)的使用,并導(dǎo)致您的應(yīng)用崩潰。

所有應(yīng)用在調(diào)用既非公開(kāi)又不可暫時(shí)訪問(wèn)的 API 時(shí)都會(huì)生成一個(gè)運(yùn)行時(shí)錯(cuò)誤。結(jié)果就是 System.loadLibrary 和 dlopen(3) 同時(shí)返回 NULL,并可能導(dǎo)致您的應(yīng)用崩潰。您應(yīng)檢查應(yīng)用代碼以移除對(duì)私有平臺(tái) API 的使用,并使用預(yù)覽版設(shè)備或模擬器全面測(cè)試應(yīng)用。如果您不確定您的應(yīng)用是否使用私有庫(kù),您可以檢查 logcat 以識(shí)別運(yùn)行時(shí)錯(cuò)誤。

下表描述的是根據(jù)應(yīng)用使用的私有原生庫(kù)及其目標(biāo) API 級(jí)別 (android:targetSdkVersion),應(yīng)用預(yù)期顯示的行為。

Paste_Image.png

檢查您的應(yīng)用是否使用私有庫(kù)

為幫助您識(shí)別加載私有庫(kù)的問(wèn)題,logcat 可能會(huì)生成一個(gè)警告或運(yùn)行時(shí)錯(cuò)誤。例如,如果您的應(yīng)用面向 API 級(jí)別 23 或更低級(jí)別,并在運(yùn)行 Android 7.0 的設(shè)備上嘗試訪問(wèn)私有庫(kù),您可能會(huì)看到一個(gè)類(lèi)似于下面所示的警告:

03-21 17:07:51.502 31234 31234 W linker  : library "libandroid_runtime.so"
("/system/lib/libandroid_runtime.so") needed or dlopened by
"/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible
for the namespace "classloader-namespace" - the access is temporarily granted
as a workaround for http://b/26394120

這些 logcat 警告通知您哪個(gè)庫(kù)正在嘗試訪問(wèn)私有平臺(tái) API,但不會(huì)導(dǎo)致您的應(yīng)用崩潰。但是,如果應(yīng)用面向 API 級(jí)別 24 或更高級(jí)別,logcat 會(huì)生成以下運(yùn)行時(shí)錯(cuò)誤,您的應(yīng)用可能會(huì)崩潰:

java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so"
("/system/lib/libcutils.so") needed or dlopened by
"/system/lib/libnativeloader.so" is not accessible for the namespace
"classloader-namespace"
  at java.lang.Runtime.loadLibrary0(Runtime.java:977)
  at java.lang.System.loadLibrary(System.java:1602)
  

如果您的應(yīng)用使用動(dòng)態(tài)鏈接到私有平臺(tái) API 的第三方庫(kù),您可能也會(huì)看到上述 logcat 輸出。利用 Android 7.0DK 中的 readelf 工具,您可以通過(guò)運(yùn)行以下命令生成給定 .so 文件的所有動(dòng)態(tài)鏈接的共享庫(kù)列表:

aarch64-linux-android-readelf -dW libMyLibrary.so

更新您的應(yīng)用

通過(guò)下面的一些步驟,您可以修復(fù)上述類(lèi)型的錯(cuò)誤并確保您的應(yīng)用不會(huì)在將來(lái)的更新版平臺(tái)上崩潰:

  • 如果您的應(yīng)用使用私有平臺(tái)庫(kù),您應(yīng)更新它,以添加該應(yīng)用自己的庫(kù)副本或使用公開(kāi) NDK API。
  • 如果您的應(yīng)用使用訪問(wèn)私有符號(hào)的第三方庫(kù),則聯(lián)系庫(kù)作者以更新庫(kù)。
  • 請(qǐng)確保將您的所有非 NDK 庫(kù)與您的 APK 打包在一起。
  • 使用標(biāo)準(zhǔn) JNI 函數(shù)而非來(lái)自 libandroid_runtime.so 的 getJavaVM 和 getJNIEnv:
AndroidRuntime::getJavaVM -> GetJavaVM from <jni.h>
AndroidRuntime::getJNIEnv -> JavaVM::GetEnv or
JavaVM::AttachCurrentThread from <jni.h>.

  • 使用 __system_property_get 而非來(lái)自 libcutils.so 的私有 property_get 符號(hào)。為此,請(qǐng)使用 __system_property_get 及以下 include 函數(shù):
#include <sys/system_properties.h>

注:系統(tǒng)屬性的可用性和內(nèi)容未通過(guò) CTS 進(jìn)行測(cè)試。應(yīng)執(zhí)行進(jìn)一步修復(fù)以避免同時(shí)使用這些屬性。

  • 使用來(lái)自 libcrypto.so 的 SSL_ctrl 符號(hào)的本地版本。例如,您應(yīng)在您的 .so 文件中靜態(tài)鏈接 libcyrpto.a,或從 BoringSSL/OpenSSL 添加一個(gè)動(dòng)態(tài)鏈接的 libcrypto.so 版本,并將其打包到您的 APK 中。

Android for Work

Android 7.0 包含一些針對(duì)面向 Android for Work 的應(yīng)用的變更,包括對(duì)證書(shū)安裝、密碼重置、二級(jí)用戶管理、設(shè)備標(biāo)識(shí)符訪問(wèn)權(quán)限的變更。如果您是要針對(duì) Android for Work 環(huán)境開(kāi)發(fā)應(yīng)用,則應(yīng)仔細(xì)檢查這些變更并相應(yīng)地修改您的應(yīng)用。

  • 您必須先安裝授權(quán)證書(shū)安裝程序,然后 DPC 才能對(duì)其進(jìn)行設(shè)置。對(duì)于面向 N SDK 的配置文件和設(shè)備所有者應(yīng)用,您應(yīng)在設(shè)備規(guī)范控制器 (DPC) 調(diào)用 DevicePolicyManager.setCertInstallerPackage() 之前安裝授權(quán)證書(shū)安裝程序。如果尚未安裝此安裝程序,則系統(tǒng)會(huì)引發(fā) IllegalArgumentException。
  • 針對(duì)設(shè)備管理員的重置密碼限制現(xiàn)在也適用于配置文件所有者。設(shè)備管理員無(wú)法再使用 DevicePolicyManager.resetPassword() 來(lái)清除或更改已經(jīng)設(shè)置的密碼。設(shè)備管理員仍可以設(shè)置密碼,但只能在設(shè)備沒(méi)有密碼、PIN 碼或圖案時(shí)這樣做。
  • 即使設(shè)置了限制,設(shè)備所有者和配置文件所有者仍可以管理帳戶。而且,即使具有 DISALLOW_MODIFY_ACCOUNTS 用戶限制,設(shè)備所有者和配置文件所有者仍可調(diào)用 Account Management API。
  • 設(shè)備所有者可以更輕松地管理二級(jí)用戶。當(dāng)設(shè)備在設(shè)備所有者模式下運(yùn)行時(shí),系統(tǒng)將自動(dòng)設(shè)置 DISALLOW_ADD_USER 限制。這樣可以防止用戶創(chuàng)建非托管二級(jí)用戶。此外,CreateUser() 和 createAndInitializeUser() 方法已棄用,取而代之的是 DevicePolicyManager.createAndManageUser() 方法。
  • 設(shè)備所有者可以訪問(wèn)設(shè)備標(biāo)識(shí)符。設(shè)備所有者可以使用 DevicePolicyManagewr.getWifiMacAddress() 訪問(wèn)設(shè)備的 WLAN MAC 地址。如果設(shè)備上從未啟用 WLAN,則此方法將返回一個(gè) null 值。
  • 工作模式設(shè)置控制工作應(yīng)用訪問(wèn)。當(dāng)工作模式關(guān)閉時(shí),系統(tǒng)啟動(dòng)器通過(guò)使工作應(yīng)用顯示為灰色來(lái)指示它們不可用。啟用工作模式會(huì)再次恢復(fù)正常行為。
  • 從 Settings UI 安裝包含客戶端證書(shū)鏈和對(duì)應(yīng)的私鑰的 PKCS #12 文件時(shí),系統(tǒng)不再將該證書(shū)鏈中的 CA 證書(shū)安裝到受信任的憑據(jù)存儲(chǔ)空間。當(dāng)應(yīng)用稍后嘗試檢索客戶端證書(shū)鏈時(shí),這不會(huì)影響 KeyChain.getCertificateChain() 的結(jié)果。如果需要,使用 .crt 或 .cer 文件擴(kuò)展名的 DER 編碼格式通過(guò) Settings UI 單獨(dú)將 CA 證書(shū)安裝到受信任的憑據(jù)存儲(chǔ)空間。
  • 從 Android 7.0 開(kāi)始,可針對(duì)每個(gè)用戶管理指紋登記和存儲(chǔ)空間。如果配置文件所有者的設(shè)備規(guī)范客戶端 (DPC) 面向 Android N 設(shè)備上的 Android N 之前的版本,則用戶仍可以在該設(shè)備上設(shè)置指紋,但工作應(yīng)用不能訪問(wèn)設(shè)備指紋。當(dāng) DPC 面向 Android N 和更高版本時(shí),用戶可以通過(guò)轉(zhuǎn)到 Settings > Security > Work profile security 專(zhuān)門(mén)為托管配置文件設(shè)置指紋。
  • DevicePolicyManager.getStorageEncryptionStatus() 返回新的加密狀態(tài) ENCRYPTION_STATUS_ACTIVE_PER_USER,以表明加密處于活動(dòng)狀態(tài),且加密密鑰與用戶關(guān)聯(lián)。僅當(dāng) DPC 面向 API 級(jí)別 24 和更高級(jí)別時(shí)才會(huì)返回新的狀態(tài)。對(duì)于面向更早的 API 級(jí)別的應(yīng)用,即使加密密鑰是用戶或配置文件特有的,系統(tǒng)也會(huì)返回 ENCRYPTION_STATUS_ACTIVE。
  • 在 Android 7.0 中,如果設(shè)備通過(guò)單獨(dú)的工作挑戰(zhàn)安裝了托管配置文件,則原本通常會(huì)影響整個(gè)設(shè)備的多個(gè)方法將會(huì)改變其行為方式。這些方法將僅應(yīng)用于托管配置文件,而不是影響整個(gè)設(shè)備。(此類(lèi)方法的完整列表位于 DevicePolicyManager.getParentProfileInstance() 文檔中。)例如,DevicePolicyManager.lockNow() 只鎖定托管配置文件,而不是鎖定整個(gè)設(shè)備。對(duì)于上述每個(gè)方法,您可以通過(guò)對(duì) DevicePolicyManager 的父實(shí)例調(diào)用該方法來(lái)獲取以前的行為;您可以通過(guò)調(diào)用 DevicePolicyManager.getParentProfileInstance() 獲取此父項(xiàng)。例如,如果您調(diào)用父實(shí)例的 lockNow() 方法,則整個(gè)設(shè)備將被鎖定。
    如需了解有關(guān) Android 7.0 中針對(duì) Android for Work 所做變更的詳細(xì)信息,請(qǐng)參閱 Android for Work 更新

注解保留

Android 7.0 修復(fù)了一個(gè)注解可見(jiàn)性被忽略的錯(cuò)誤。這種問(wèn)題會(huì)導(dǎo)致應(yīng)用可在運(yùn)行時(shí)訪問(wèn)原本不允許訪問(wèn)的注解。這些注解包括:

  • VISIBILITY_BUILD:僅應(yīng)編譯時(shí)可見(jiàn)。
  • VISIBILITY_SYSTEM:運(yùn)行時(shí)應(yīng)可見(jiàn),但僅限底層系統(tǒng)。
    如果您的應(yīng)用依賴(lài)這種行為,請(qǐng)為運(yùn)行時(shí)必須可用的注解添加保留政策。您可通過(guò)使用 @Retention(RetentionPolicy.RUNTIME) 來(lái)執(zhí)行此操作。

其他重要說(shuō)明

  • 如果一個(gè)應(yīng)用在 Android 7.0 上運(yùn)行,但卻是針對(duì)更低 API 級(jí)別開(kāi)發(fā)的,那么在用戶更改顯示尺寸時(shí),系統(tǒng)將終止此應(yīng)用進(jìn)程。應(yīng)用必須能夠妥善處理此情景。否則,當(dāng)用戶從最近使用記錄中恢復(fù)運(yùn)行應(yīng)用時(shí),應(yīng)用將會(huì)出現(xiàn)崩潰現(xiàn)象。
    您應(yīng)測(cè)試應(yīng)用以確保不會(huì)發(fā)生此行為。要進(jìn)行此測(cè)試,您可以通過(guò) DDMS 手動(dòng)終止應(yīng)用,以造成相同的崩潰現(xiàn)象。
    在密度發(fā)生更改時(shí),系統(tǒng)不會(huì)自動(dòng)終止面向 N 及更高版本的應(yīng)用;不過(guò),這些應(yīng)用仍可能對(duì)配置變更做出不良響應(yīng)。

  • Android 7.0 上的應(yīng)用應(yīng)能夠妥善處理配置變更,并且在后續(xù)啟動(dòng)時(shí)不會(huì)出現(xiàn)崩潰現(xiàn)象。您可以通過(guò)更改字體大小 (Setting >Display > Font size) 并隨后從最近使用記錄中恢復(fù)運(yùn)行應(yīng)用,來(lái)驗(yàn)證應(yīng)用行為。

  • 由于之前的 Android 版本中的一項(xiàng)錯(cuò)誤,系統(tǒng)未能將對(duì)主線程上的一個(gè) TCP 套接字的寫(xiě)入操作舉報(bào)為違反嚴(yán)格模式。Android 7.0 修復(fù)了此錯(cuò)誤。呈現(xiàn)出這種行為的應(yīng)用現(xiàn)在會(huì)引發(fā) android.os.NetworkOnMainThreadException。一般情況下,我們不建議在主線程上執(zhí)行網(wǎng)絡(luò)操作,因?yàn)檫@些操作通常會(huì)出現(xiàn)可能導(dǎo)致 ANR 和卡頓的高尾延遲。

  • Debug.startMethodTracing() 方法系列現(xiàn)在默認(rèn)在您的共享存儲(chǔ)空間上的軟件包特定目錄中存儲(chǔ)輸出,而非 SD 卡根目錄。這意味著應(yīng)用不再需要請(qǐng)求 WRITE_EXTERNAL_STORAGE 權(quán)限來(lái)使用這些 API 。

  • 許多平臺(tái) API 現(xiàn)在開(kāi)始檢查在 Binder 事務(wù)間發(fā)送的大負(fù)載,系統(tǒng)現(xiàn)在會(huì)將 TransactionTooLargeExceptions 作為 RuntimeExceptions 再次引發(fā),而不再只是默默記錄或抑制它們。一個(gè)常見(jiàn)例子是在 Activity.onSaveInstanceState() 上存儲(chǔ)過(guò)多數(shù)據(jù),導(dǎo)致 ActivityThread.StopInfo 在您的應(yīng)用面向 Android 7.0 時(shí)引發(fā) RuntimeException。

  • 如果應(yīng)用向 View 發(fā)布 Runnable 任務(wù),并且 View 未附加到窗口,系統(tǒng)會(huì)用 View 為 Runnable 任務(wù)排隊(duì);在 View 附加到窗口之前,不會(huì)執(zhí)行 Runnable 任務(wù)。此行為會(huì)修復(fù)以下錯(cuò)誤:

    • 如果一項(xiàng)應(yīng)用是從并非預(yù)期窗口 UI 線程的其他線程發(fā)布到 View,則 Runnable 可能會(huì)因此運(yùn)行錯(cuò)誤的線程。
      如果 Runnable 任務(wù)是從并非環(huán)路線程的其他線程發(fā)布,則應(yīng)用可能會(huì)曝光 Runnable 任務(wù)。
    • 如果 Android 7.0 上一項(xiàng)有 DELETE_PACKAGES 權(quán)限的應(yīng)用嘗試刪除一個(gè)軟件包,但另一項(xiàng)應(yīng)用已經(jīng)安裝了這個(gè)軟件包,則系統(tǒng)需要用戶進(jìn)行確認(rèn)。在這種情況下,應(yīng)用在調(diào)用 PackageInstaller.uninstall() 時(shí)預(yù)計(jì)的返回狀態(tài)應(yīng)為 STATUS_PENDING_USER_ACTION。
  • 名為 Crypto 的 JCA 提供程序已棄用,因?yàn)樗鼉H有的 SHA1PRNG 算法為弱加密。應(yīng)用無(wú)法再使用 SHA1PRNG(不安全地)派生密鑰,因?yàn)椴辉偬峁┐颂峁┏绦颉H缧枇私庠敿?xì)信息,請(qǐng)參閱博文 Android N 中已棄用“Crypto”安全提供程序

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,466評(píng)論 25 708
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,981評(píng)論 19 139
  • 午后,我在擦拭著杯子,待整理完畢,坐下來(lái)打開(kāi)電腦,寫(xiě)寫(xiě)文章。 或者,捧著一本書(shū),癱在沙發(fā)上啃著紙上的文字,品著其中...
    老顯閱讀 445評(píng)論 0 2
  • 一個(gè)月前看可愛(ài)的詛咒的時(shí)候,第一次看到救贖性轉(zhuǎn)折點(diǎn)的時(shí)候,就有點(diǎn)震驚,這不是是我大部分的日常嗎,一直想寫(xiě)可愛(ài)的...
    寶谷米的紅閱讀 776評(píng)論 0 0
  • 張雨綺《美人魚(yú)》后似乎大蛻變 動(dòng)不動(dòng)就在微博興風(fēng)作浪 不時(shí)曬個(gè)大白腿與鎖骨 風(fēng)情堪稱(chēng)俏嬌娘 娛樂(lè)圈,沒(méi)有作品沒(méi)有關(guān)...
    辣八閱讀 640評(píng)論 0 0