提问人:Kraken 提问时间:10/21/2023 更新时间:10/22/2023 访问量:48
将文件写入Android中的下载目录
Write file to Download directory in Android
问:
下面是我的代码
File downloadsDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
long currentTimestamp = System.currentTimeMillis();
String filename = "downloaded_image_" + currentTimestamp + ".png";
File imageFile = new File(downloadsDirectory, filename);
try {
FileOutputStream outputStream = new FileOutputStream(imageFile);
outputStream.write(imageBytes);
outputStream.close();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
我已添加权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
现在我上面的代码在 Android 12 上运行良好。
但它在 Android 8 和 Android 10 上失败,并出现错误
java.lang.RuntimeException:java.io.FileNotFoundException:/storage/emulated/0/Download/downloaded_image_1697897803982.png:打开失败:EACCES(权限被拒绝)
在互联网上,我被告知以下代码应该适用于所有 API(大于 24),但下面的代码是否意味着我的代码不应该在 Android 12 上运行,而可以在 Android 8/9 上运行?我不明白,我的代码(上面的代码)在 Android 12 上工作,但在 8/9 上不工作,但下面应该工作。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
StorageManager storageManager = getSystemService(StorageManager.class);
StorageVolume storageVolume = storageManager.getStorageVolumes().get(0);
File downloadsDirectory = storageVolume.getDirectory(Environment.DIRECTORY_DOWNLOADS);
long currentTimestamp = System.currentTimeMillis();
String filename = "downloaded_image_" + currentTimestamp + ".png";
File imageFile = new File(downloadsDirectory, filename);
try {
FileOutputStream outputStream = new FileOutputStream(imageFile);
outputStream.write(imageBytes);
outputStream.close();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
File downloadsDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
long currentTimestamp = System.currentTimeMillis();
String filename = "downloaded_image_" + currentTimestamp + ".png";
File imageFile = new File(downloadsDirectory, filename);
try {
FileOutputStream outputStream = new FileOutputStream(imageFile);
outputStream.write(imageBytes);
outputStream.close();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
答:
0赞
Abdul Muteen
10/22/2023
#1
Android 10 引入了分区存储,这限制了应用访问外部存储空间的方式。要使您的代码在不同的 Android 版本上运行,您应该考虑检查运行时权限,尤其是对于 Android 10 及更高版本。
以下是适用于 Android 8、9、10 及更高版本的代码的更新版本。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// Android 10 and above
Context context = getApplicationContext();
ContentResolver contentResolver = context.getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Downloads.DISPLAY_NAME, filename);
contentValues.put(MediaStore.Downloads.MIME_TYPE, "image/png");
contentValues.put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS);
Uri contentUri = MediaStore.Downloads.EXTERNAL_CONTENT_URI;
Uri itemUri = contentResolver.insert(contentUri, contentValues);
if (itemUri != null) {
try {
OutputStream outputStream = contentResolver.openOutputStream(itemUri);
if (outputStream != null) {
outputStream.write(imageBytes);
outputStream.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
throw new RuntimeException("Failed to create a file in the Downloads directory.");
}
} else {
// Android 8 and 9
File downloadsDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
if (!downloadsDirectory.exists()) {
downloadsDirectory.mkdirs();
}
long currentTimestamp = System.currentTimeMillis();
String filename = "downloaded_image_" + currentTimestamp + ".png";
File imageFile = new File(downloadsDirectory, filename);
try {
FileOutputStream outputStream = new FileOutputStream(imageFile);
outputStream.write(imageBytes);
outputStream.close();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw a RuntimeException(e);
}
}
评论