下面是我的代码
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);
}
}
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);
}
}