做項目在主頁檢查更新的時候,檢查到apk需要更新,於是我美滋滋的得到了下載的apk,然後調用一下去安裝apk方法,以爲理所當然的沒啥問題,可是當我下載完了的時候,在調用安裝的代碼時,拋出了一個異常FileUriExposedException,MMP 這是個什麼鬼,欺負我英語不好嗎,於是日常百度,搜嘎,原來由於
在android7.0,修改了對私有存儲的限制,而我的編譯版本爲25,導致在獲取資源的時候,不能通過Uri.fromFile(..)來獲取uri了,但是在寫入數據的時候是可以通過Uri.fromFile(..)來獲取uri的,android 官網給出的解決辦法是通過FileProvider來解決這一問題,我們需要在AndroidManifest.xml 配製provider節點
<provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:grantUriPermissions="true" android:exported="false"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_path" /> </provider>注意了,這個applacationId 必須要在grade文件裏面配置哦 如果你不配置的話你可以直接寫上你的包名
<?xml version="1.0" encoding="utf-8"?> <paths> <external-path path="Android/data/你的包名/" name="files_root" /> <external-path path="." name="external_storage_root" /> </paths>
/** 安裝一個apk文件 */ public static void install(Context context, File uriFile) { Intent intent = new Intent(Intent.ACTION_VIEW); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); Uri contentUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID+".fileprovider", uriFile); intent.setDataAndType(contentUri, "application/vnd.android.package-archive"); } else { intent.setDataAndType(Uri.fromFile(uriFile), "application/vnd.android.package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } if (App.getIntence().getPackageManager().queryIntentActivities(intent, 0).size() > 0) { App.getIntence().startActivity(intent); } }這裏要注意的是這句代碼,這裏BuildConfig 是導入的我當前項目的包名,如果你不想這麼做的話,你可以直接寫你自己的包名列如: 包名com.test 來替換
我們項目中可能會用到其他一些第三方sdk有用到拍照功能或者關於某些獲取資源操作的話,他爲了適配android7.0也添加了這個節點,此時有些人可能就不知道如何下手了,其實很簡單我們只要重寫一個類 繼承自FileProvider,然後就按上述方法在添加一個節點就可以了;例如:
public class MyFileProvider extends FileProvider { }
然後
<provider android:name=".util.MyFileProvider" android:authorities="${applicationId}.provider" android:grantUriPermissions="true" android:exported="false"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
這個file_paths文件 是第三方sdk的 而不是我新建的那個
大功告成~~~