Android各版本重要變更記錄

本文來自同步博客html

Android M:運行時權限

運行時權限屬於比較熟悉的話題不深刻展開。除了support包可讓應用完成運行時權限,github上也有好多擴展。用得比較多的是Google官方的EasyPermissionsjava

Android N:提升私有文件的安全性

私有文件安全性的變更官方文檔提到了三點反作用,詳見文檔。下面記錄開發中碰見的兩點。android

應用間共享文件

在調用照片拍照、調用包管理器安裝apk等場景下都須要跨應用共享文件。在版本N以前,直接使用「file://+文件路徑」的方式就能夠共享。git

可是在N以後,這樣操做會拋出異常FileUriExposedExceptiongithub

實際上在共享文件時,接受共享的應用可能並無向系統申請讀取文件的權限,也可能沒有訪問該文件的權限。若是擁有者應用經過修改文件的權限,讓其餘任何應用均可以訪問它,這顯然是不安全的。安全

N要求使用「content://+文件路徑」的方式共享文件,並在共享的那一刻生成針對指定應用的臨時權限。這種分享私有文件方法,Google推薦使用FileProvider完成。ide

參考其餘博客,這裏記錄兩個注意點:工具

  1. FileProvidersupport包提供的功能,並不須要檢查Android的版本進行區分處理。統一使用FileProvider向外共享文件便可。
  2. FileProviderAvailable Files的配置須要注意pathname、以及paths裏面的不一樣標籤的意義。不少使用者混淆了,詳細請參考官方文檔。下圖是某網友的總結。
 
file://與content://關係
DownloadManagerCOLUMN_LOCAL_FILENAME字段限制

N之前的應用能夠訪問COLUMN_LOCAL_FILENAME字段,可是以後的版本若訪問該字段,將報SecurityExceptionui

有一種不推薦的方式可讓應用繼續訪問這個字段:在下載文件時,經過DownloadManager.Request.setDestinationInExternalFilesDir()DownloadManager.Request.setDestinationInExternalPublicDir()把文件存儲在公共目錄。google

Google推薦使用ContentResolver.openFileDescriptor()

而我在開發中碰到須要獲取下載文件最終存儲的完整路徑的場景,下面記錄個人處理方式:

String path = "";
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
    String fileUri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
    if (fileUri != null) {
        path = Uri.parse(fileUri).getPath();
    }
} else {
    //Android 7.0以上的方式:請求獲取寫入權限,這一步報錯過期的方式:DownloadManager.COLUMN_LOCAL_FILENAME
    int fileNameIdx = c.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME);
    path = c.getString(fileNameIdx);
}

 

Android O:安裝非認證渠道APK

O開始屏蔽了全局的「安裝未知應用」設置開關,而是將之做爲權限與每一個應用綁定。任何須要安裝APK的應用須要在AndroidManifest中註冊android.permission.REQUEST_INSTALL_PACKAGES權限,不然將沒法安裝應用。

能夠選擇使用ACTION_MANAGE_UNKNOWN_APP_SOURCES發起 Intent操做,預先將用戶引導至安裝未知應用權限界面。也可使用PackageManager.canRequestPackageInstalls(),查詢此權限的狀態。

Android P:限制非SDK接口的使用

很慶幸也很不幸,我負責的項目沒有檢測到使用了非SDK接口。

有關非SDK接口相關介紹參考這篇文章
文中提到的veridex工具須要本身下載Android的源代碼,具體操做參考官方文檔

相關文章
相關標籤/搜索