權(quán)限更改
自從Android 6.0加了動態(tài)獲取一些權(quán)限以后Android N 做了一些權(quán)限更改,這些更改可能會影響您的應(yīng)用铃诬。
系統(tǒng)權(quán)限更改
為了提高私有文件的安全性,面向 Android N 或更高版本的應(yīng)用私有目錄被限制訪問 (0700)。 此設(shè)置可防止私有文件的元數(shù)據(jù)泄漏,如它們的大小或存在待侵。 此權(quán)限更改有多重副作用:
私有文件的文件權(quán)限不應(yīng)再由所有者放寬,為使用MODE_WORLD_READABLE和/或MODE_WORLD_WRITEABLE而進(jìn)行的此類嘗試將觸發(fā)SecurityException姨裸。
注:迄今為止秧倾,這種限制尚不能完全執(zhí)行。 應(yīng)用仍可能使用原生 API 或FileAPI 來修改它們的私有目錄權(quán)限傀缩。 但是那先,我們強(qiáng)烈反對放寬私有目錄的權(quán)限。
傳遞軟件包網(wǎng)域外的file://URI 可能給接收器留下無法訪問的路徑赡艰。 因此售淡,嘗試傳遞file://URI 會觸發(fā)FileUriExposedException。 分享私有文件內(nèi)容的推薦方法是使用FileProvider慷垮。
DownloadManager不再按文件名分享私人存儲的文件揖闸。 舊版應(yīng)用在訪問COLUMN_LOCAL_FILENAME時可能出現(xiàn)無法訪問的路徑。 面向 Android N 或更高版本的應(yīng)用在嘗試訪問COLUMN_LOCAL_FILENAME時會觸發(fā)SecurityException料身。 通過使用DownloadManager.Request.setDestinationInExternalFilesDir()或DownloadManager.Request.setDestinationInExternalPublicDir()將下載位置設(shè)置為公共位置的舊版應(yīng)用仍可以訪問COLUMN_LOCAL_FILENAME中的路徑汤纸,但是我們強(qiáng)烈反對使用這種方法。 訪問由DownloadManager公開的文件的首選方式是使用ContentResolver.openFileDescriptor()芹血。
應(yīng)用間共享文件
對于面向 Android N 的應(yīng)用贮泞,Android 框架執(zhí)行的StrictModeAPI 政策禁止向您的應(yīng)用外公開file://URI。 如果一項(xiàng)包含文件 URI 的 Intent 離開您的應(yīng)用幔烛,應(yīng)用失敗啃擦,并出現(xiàn)FileUriExposedException異常。
若要在應(yīng)用間共享文件饿悬,您應(yīng)發(fā)送一項(xiàng)content://URI令蛉,并授予 URI 臨時訪問權(quán)限。 進(jìn)行此授權(quán)的最簡單方式是使用FileProvider類狡恬。 如需有關(guān)權(quán)限和共享文件的更多信息珠叔,請參閱共享文件。
無障礙改進(jìn)
為提高平臺對于視力不佳或視力受損用戶的可用性傲宜,Android N 做出了一些更改运杭。這些更改一般并不要求更改您的應(yīng)用代碼,不過您應(yīng)仔細(xì)檢查并使用您的應(yīng)用測試這些功能函卒,以評估它們對用戶體驗(yàn)的潛在影響辆憔。
屏幕縮放
Android N 支持用戶設(shè)置顯示尺寸,以放大或縮小屏幕上的所有元素报嵌,從而提升設(shè)備對視力不佳用戶的可訪問性虱咧。用戶無法將屏幕縮放至低于最小屏幕寬度sw320dp,該寬度是 Nexus 4 的寬度锚国,也是常規(guī)中等大小手機(jī)的寬度腕巡。
當(dāng)設(shè)備密度發(fā)生更改時,系統(tǒng)會以如下方式通知正在運(yùn)行的應(yīng)用:
如果是面向 API 級別 23 或更低版本系統(tǒng)的應(yīng)用血筑,系統(tǒng)會自動終止其所有后臺進(jìn)程绘沉。 這意味著如果用戶切換離開此類應(yīng)用煎楣,轉(zhuǎn)而打開“Settings”屏幕并更改Display size設(shè)置,則系統(tǒng)會像處理內(nèi)存不足的情況一樣終止該應(yīng)用车伞。如果應(yīng)用具有任何前臺進(jìn)程择懂,則系統(tǒng)會如處理運(yùn)行時變更中所述將配置變更通知給這些進(jìn)程,就像對待設(shè)備屏幕方向變更一樣另玖。
如果是面向 Android N 的應(yīng)用困曙,則其所有進(jìn)程(前臺和后臺)都會收到有關(guān)配置變更的通知,如處理運(yùn)行時變更中所述谦去。
大多數(shù)應(yīng)用并不需要進(jìn)行任何更改即可支持此功能慷丽,不過前提是這些應(yīng)用遵循 Android 最佳實(shí)踐。具體要檢查的事項(xiàng):
在屏幕寬度為sw320dp的設(shè)備上測試您的應(yīng)用鳄哭,并確保其充分運(yùn)行要糊。
當(dāng)設(shè)備配置發(fā)生變更時,更新任何與密度相關(guān)的緩存信息窃诉,例如緩存位圖或從網(wǎng)絡(luò)加載的資源杨耙。當(dāng)應(yīng)用從暫停狀態(tài)恢復(fù)運(yùn)行時,檢查配置變更飘痛。
注:如果您要緩存與配置相關(guān)的數(shù)據(jù)珊膜,則最好也包括相關(guān)元數(shù)據(jù),例如該數(shù)據(jù)對應(yīng)的屏幕尺寸或像素密度宣脉。 保存這些元數(shù)據(jù)便于您在配置變更后決定是否需要刷新緩存數(shù)據(jù)车柠。
避免用像素單位指定尺寸,因?yàn)橄袼夭粫S屏幕密度縮放塑猖。應(yīng)改為使用與密度無關(guān)像素(dp) 單位指定尺寸竹祷。
設(shè)置向?qū)е械囊曈X設(shè)置
Android N 在“Welcome”屏幕中加入了“Vision Settings”,用戶可以在新設(shè)備上設(shè)置以下無障礙功能設(shè)置:Magnification gesture羊苟、Font size塑陵、Display size和TalkBack。 此項(xiàng)變更增強(qiáng)了與不同屏幕設(shè)置相關(guān)的錯誤的可見性蜡励。 要評估此功能的影響令花,您應(yīng)在啟用這些設(shè)置的狀態(tài)下測試應(yīng)用。 您可以在Settings > Accessibility中找到這些設(shè)置凉倚。
NDK 應(yīng)用鏈接至平臺庫
Android N 做了一些命名空間更改兼都,以阻止加載非公開 API。 如果您使用 NDK稽寒,則只能使用 Android 平臺提供的公開 API扮碧。 在下一個官方發(fā)布的 Android 版本上使用非公開 API 會導(dǎo)致應(yīng)用崩潰。
為提醒您使用了非公開 API,在 Android N 設(shè)備上運(yùn)行的應(yīng)用會在有應(yīng)用調(diào)用非公開 API 時在日志消息輸出中生成一個錯誤慎王。 此錯誤還會作為消息顯示在設(shè)備屏幕上蚓土,以幫助增強(qiáng)您對此情況的認(rèn)識。 您應(yīng)檢查應(yīng)用代碼以刪除使用非公開平臺 API柬祠,并使用預(yù)覽版設(shè)備或模擬器全面測試應(yīng)用北戏。
如果您的應(yīng)用依賴平臺庫,則請參見 NDK 文檔漫蛔,了解使用公開 API 等效項(xiàng)替換普通私有 API 的典型修復(fù)。 您還可以鏈接至平臺庫旧蛾,而無需實(shí)現(xiàn)此應(yīng)用莽龟,如果應(yīng)用使用的庫是平臺的一部分(例如libpng),但不屬于 NDK锨天,則更可如此毯盈。 此情況下,請確保您的 APK 包含您打算鏈接到的所有 .so 文件病袄。
注意:有些第三方庫可能會鏈接至非公開 API搂赋。 如果您的應(yīng)用使用這些庫,那么當(dāng)您的應(yīng)用在下一個官方發(fā)布的 Android 版本上運(yùn)行時可能會出現(xiàn)崩潰現(xiàn)象益缠。
應(yīng)用不應(yīng)依賴或使用不屬于 NDK 的原生庫脑奠,因?yàn)檫@些庫可能會發(fā)生更改或從一個 Android 版本遷移至另一版本。 例如幅慌,從 OpenSSL 切換至 BoringSSL 即屬于此類更改宋欺。 此外,不同的設(shè)備可能提供不同級別的兼容性胰伍,因?yàn)椴粚儆?NDK 中的平臺庫沒有兼容性要求齿诞。 如果您必須在較舊設(shè)備上訪問非 NDK 庫,則請依據(jù) Android API 級別進(jìn)行加載骂租。
為幫助您診斷此類問題祷杈,下面列舉了一些在您試圖使用 Android N 開發(fā)應(yīng)用時可能遇到的Java和 NDK 錯誤:
Java 錯誤示例:
java.lang.UnsatisfiedLinkError: dlopen failed: library "/system/lib/libcutils.so"
is not accessible for the namespace "classloader-namespace"
NDK 錯誤示例:
dlopen failed: cannot locate symbol "__system_property_get" referenced by ...
以下是遇到這類錯誤的應(yīng)用的一些典型修復(fù):
可以使用標(biāo)準(zhǔn) JNI 函數(shù)來替代使用 libandroid_runtime.so 中的 getJavaVM 和 getJNIEnv:
AndroidRuntime::getJavaVM -> GetJavaVM from
AndroidRuntime::getJNIEnv -> JavaVM::GetEnv or
JavaVM::AttachCurrentThread from .
可以使用公開alternative __system_property_get來替代使用libcutils.so中的property_get符號。如需這樣做渗饮,請使用__system_property_get及以下 include 函數(shù):
#include <sys/system_properties.h>
應(yīng)使用應(yīng)用本地版本來替代使用libcrypto.so中的SSL_ctrl符號但汞。例如,您應(yīng)在.so文件中靜態(tài)鏈接libcyrpto.a抽米,或者在應(yīng)用中包含您自己的來自 BoringSSL 或 OpenSSL 的動態(tài)libcrypto.so特占。
待續(xù)。云茸。是目。