如何在Android中保存文件(图像)并支持从21到29的API级别



所有上传到Google Play的新应用程序必须以Android 10(API 29级(或更高版本为目标。然而,当应用程序以API 29级为目标时,从Environment.getExternalStorageDirectory()返回的路径不再可直接访问应用程序。

文档建议使用Context.getExternalFilesDir()(不适合我的用例,因为放置在那里的文件是应用程序内部的,在卸载应用程序时会被删除(或MediaStore,此处有文档说明。

我被以下片段卡住了:

// Find all image files on the primary external storage device.
// On API <= 28, use VOLUME_EXTERNAL instead.
Uri collection = MediaStore.Images.Media.getContentUri(
MediaStore.VOLUME_EXTERNAL_PRIMARY);

由于我正在努力支持API<=28和API>=29我试过以下几种:

Uri collection;
if (VERSION.SDK_INT >= VERSION_CODES.Q) {
collection = MediaStore.Images.Media.getContentUri(
MediaStore.VOLUME_EXTERNAL_PRIMARY);
} else {
collection = MediaStore.Images.Media.getContentUri(
MediaStore.VOLUME_EXTERNAL);
}

然而,我仍然得到一个警告,MediaStore.VOLUME_EXTERNAL需要API级别29。此外,根据相同的文档,我正在尝试设置MediaColumns.RELATIVE_PATH,以便为系统提供存储新编写的文件的提示。代码片段如下:

ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, file.getFilename());
values.put(MediaStore.Images.Media.RELATIVE_PATH, "My_image_app_folder");
Uri uri = resolver.insert(collection, values);

这里也有同样的问题,该字段需要API 29级。

综上所述,如何存储一个文件(镜像(并支持从21到29的API级别?

也许这段代码可以帮助您:

我的照片存储在我的资产文件夹中,我不知道这对你来说是否有问题。最后,存储在文件夹";图片";安卓的,并被画廊认可。

AssetManager assetManager = Objects.requireNonNull(requireContext()).getAssets();
Context myContext = requireContext();
//Essential for creating the external storage directory for the first launch
myContext.getExternalFilesDir(null);
File photosFolder;
if (Build.VERSION_CODES.R > Build.VERSION.SDK_INT) {
photosFolder = new File(Environment.getExternalStorageDirectory(), "Pictures");
} else {
photosFolder = new File(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
}
if (!photosFolder.exists()) {
photosFolder.mkdir();
}
try {
pictures = assetManager.list("photos/dataset1");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
if (pictures != null) {
for (String filename : pictures) {
InputStream in;
OutputStream out;
try {
in = assetManager.open("photos/dataset1/" + filename);
File outFile = new File(photosFolder, filename);
out = new FileOutputStream(outFile);
copyFile(in, out);
in.close();
out.flush();
out.close();
MediaScannerConnection.scanFile(requireContext(), new String[]{outFile.toString()}, null, new MediaScannerConnection.OnScanCompletedListener() {
@Override
public void onScanCompleted(String path, Uri uri) {
Log.i("External Storage", "Scanned" + path + ":");
Log.i("External Storage", "uri " + uri);
}
});
} catch (IOException e) {
Log.e("tag", "Failed to copy asset file: " + filename, e);
}
}
} else {
Log.e("Error NPE", "la variable pictures est null");
}

最新更新