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

标签 android media android-external-storage android-storage

上传到 Google Play 的所有新应用都必须面向 Android 10(API 级别 29)或更高版本。但是,当应用程序以 API 级别 29 为目标时,从 Environment.getExternalStorageDirectory() 返回的路径应用程序不再可以直接访问。
文档建议使用 Context.getExternalFilesDir() (不适合我的用例,因为放置在那里的文件是应用程序内部的,并且在卸载应用程序时会被删除)或 MediaStore ,记录在 here .
我陷入了以下 fragment :

// 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为系统提供存储新写入文件的位置的提示。代码 fragment 如下:
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 级别?

最佳答案

也许这段代码可以帮助你:
我的图片存储在我的 Assets 文件夹中,我不知道这对您来说是否有问题。
最后,图片 a 存储在 android 的“图片”文件夹中,并被图库识别。

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");
    }

关于android - 如何在 Android 中保存文件(图像)并支持从 21 到 29 的 API 级别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64407601/

相关文章:

android - Android 版本 < 23 中的状态栏图标和文本色调

Java 应用程序在 Debian 上打开和播放媒体错误

html - 媒体查询似乎不起作用

android - 测试应用中的存储访问框架

java - 编辑外部存储中的文件

android - android 多久检查一次外部存储可用性

android - Android 如何跟踪每个应用程序的数据使用情况?

android - 如何在android中使用Jsoup解析HTML标签

android - 如何设置 flutter 位置的间隔以接收数据

ios - Cordova 媒体插件破坏 iOS 上的 HTML5 音频标签