####一:通過DownloadManager下載檔案
在API 24以前我們通過
String filePath=cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));
這種方式來獲取下載完成後的檔案路徑,但是在Android N上面使用這種方法會丟擲SecurityException。
解決方法:
方法1:將targetSdkVersion指定到24以下,targetSdkVersion 23
;
方法2:修改DownloadManager.Request的下載路徑,例如:
request.setDestinationInExternalFilesDir(this, "apk", "test.apk");
先獲取下載的Uri,然後根據Uri獲取檔案的路徑
String uri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
if (uri != null) {
File file= new File(Uri.parse(uri).getPath());
String filePath = file.getAbsolutePath();
Log.d(TAG, "downloadFilePath->" + filePath);
}
複製程式碼
####二: 應用間共享檔案 看官方說明
對於面向 Android 7.0 的應用,Android 框架執行的StrictModeAPI 政策禁止在您的應用外部公開file://URI。如果一項包含檔案 URI 的 intent 離開您的應用,則應用出現故障,並出現FileUriExposedException異常。 要在應用間共享檔案,您應傳送一項content://URI,並授予 URI 臨時訪問許可權。進行此授權的最簡單方式是使用FileProvider類。如需瞭解有關許可權和共享檔案的詳細資訊,請參閱共享檔案
大概每個應用都有這種使用場景,在應用升級更新的時候,我們會將下載完成的Apk檔案以一個Intent傳送出去,讓系統安裝應用。 在Android N以前,我們的做法:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.parse("file://" + filename), "application/vnd.android.package-archive");
startActivity(intent);
複製程式碼
在Android N上面這種方式會丟擲FileUriExposedException異常。 適配Android N的方法:
- 在manifest中新增配置
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="@string/fileProvider_authorities"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
複製程式碼
- 在res目錄下建立xml/file_paths檔案,只有在file_paths中配置的目錄下的檔案才可以在應用間共享
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external-path"
path="." />
<cache-path
name="cache-path"
path="." />
<files-path
name="files-path"
path="." />
</paths>
複製程式碼
對應關係:
- external-path 對應
Environment.getExternalStorageDirectory()
- cache-path對應
getCacheDir()
- files-path對應
getFilesDir()
path指定對應目錄下的子目錄, path="." 表示該目錄下所有子目錄
- 共享檔案
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri contentUri = FileProvider.getUriForFile(context, getString(R.string.fileProvider_authorities), new File(filePath));
intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
startActivity(intent);
複製程式碼