[英]Access permission denied to external file on Android 10
我的應用是 targetSdkVersion = 29
我拍了一張照片並保存在路徑中:
src = /storage/emulated/0/DCIM/Camera/IMG_20201120_091943.jpg
然后我想使用 FileInputStream/FileOutputStream 將此圖像復制到內部存儲。 雖然,我的應用程序具有 WRITE/READ 存儲權限,但是當我編碼時
InputStream inputStream = FileInputStream(src)
我收到一個 FileNotFoundException(打開失敗:EACCES 權限被拒絕)。
有人有同樣的問題嗎?
注意:我不想通過使用選項 AndroidManifest.xml 來解決這個問題,因為它是臨時的
android:requestLegacyExternalStorage="true"
當您的targetSdkVersion >= 29
您必須使用 ScopedStorage,請參閱文檔: https : //developer.android.com/training/data-storage/use-cases#opt-out-scoped-storage
所以簡短的回答是你不能真正做到這一點。 如果您的 targetSdkVersion 是 29,您應該使用 MediaStore API 來寫入共享存儲(“/storage/emulated/0/DCIM/Camera/IMG_20201120_091943.jpg”不是您的應用的私有,因此規則適用)
以下是如何使用 MediaStoreApi 將圖像插入到用戶的圖像中: https : //stackoverflow.com/a/56990305/5601663
此外,如果您真的只想保存文件,以便它僅在您的應用程序中可用,那么您不需要使用 MediaStoreApi,請參閱有關如何將文件保存在您的應用程序私有目錄中的文章: https://medium。 com/@maksymilian.wojcik/android-saving-files-in-internal-storage-image-from-byte-array-etc-dd7d1b86d309
編輯:您當然可以在清單上使用requestLegacyExternalStorage
標志,但您已經說過不想使用它
Edit2:我現在看到您想從共享存儲中讀取數據。 這也行不通,因為如果您的targetSdkVersion >= 29
,您需要使用存儲訪問框架或媒體存儲從那里讀取。 因此,對於這種情況,請按照此處描述的說明進行操作: https : //developer.android.com/training/data-storage/use-cases#import-image-media
我使用 FileInputStream/FileOutputStream 詳細顯示我的代碼
src = /storage/emulated/0/DCIM/Camera/IMG_20201120_091943.jpg
dst = /storage/emulated/0/Android/data/my_app/files/Pictures/IMG_20201118_113434.jpg
src 是保存照片的地方,dst 是我想將文件 src 復制到這里的地方
public void copy(String src, String dst) {
try {
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(src));
OutputStream outPutStream = new FileOutputStream(dst);
int len;
byte[] buf = new byte[1024];
while ((len = bufferedInputStream.read(buf)) > 0) {
outPutStream.write(buf, 0, len);
}
outPutStream.flush();
outPutStream.close();
bufferedInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
FileNotFoundException(打開失敗:EACCES 權限被拒絕)在行:
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(src));
在 Android 10 上,您無法使用 File API 訪問共享存儲中的文件,不幸的是,Android 文檔對此不一致,您可以在這里找到它想
要解決此問題,請在 Android 10 上使用 Uri API,盡管這在 Android 11 中不是問題
val uri = ContentUris.withAppendedId(MediaStore.Image.Media.EXTERNAL_CONTENT_URI, id)
applicationContext.contentResolver.openInputStream(uri).use { stream ->
// do your thing here
}
注意:您仍然可以對您的應用擁有的任何文件使用 File API
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.