11中将图像保存在外部SDCARD的DCIM文件夹中

11中将图像保存在外部SDCARD的DCIM文件夹中

本文介绍了如何在android 11中将图像保存在外部SDCARD的DCIM文件夹中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用以下代码将图像保存在内部存储的 DCIM 文件夹中:

i am saving image in DCIM folder of internal storage by using below code:

    public Uri saveBitmap(@NonNull final Context context, @NonNull final Bitmap bitmap,
                      @NonNull final Bitmap.CompressFormat format,
                      @NonNull final String mimeType,
                      @NonNull final String displayName) throws IOException {

    final ContentValues values = new ContentValues();
    values.put(MediaStore.MediaColumns.DISPLAY_NAME, displayName);
    values.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);
    values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM);

    final ContentResolver resolver = context.getContentResolver();
    Uri uri = null;

    try {
        final Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        uri = resolver.insert(contentUri, values);

        if (uri == null)
            throw new IOException("Failed to create new MediaStore record.");

        try (final OutputStream stream = resolver.openOutputStream(uri)) {
            if (stream == null)
                throw new IOException("Failed to open output stream.");

            if (!bitmap.compress(format, 95, stream))
                throw new IOException("Failed to save bitmap.");
        }

        return uri;
    }
    catch (IOException e) {

        if (uri != null) {
            // Don't leave an orphan entry in the MediaStore
            resolver.delete(uri, null, null);
        }

        throw e;
    }
}

现在我想将图片保存在外部 SDCARD 的 DCIM 文件夹中,但我不知道该怎么做.

now i want to save image in DCIM folder of external SDCARD but i don't know how to do it.

我知道我必须在这一行中进行更改:

i know that i have to made changes in this line :

values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM);

但是Environment.DIRECTORY_DCIM总是返回内部存储的DCIM文件夹.

but Environment.DIRECTORY_DCIM always return DCIM Folder of internal storage.

推荐答案

您需要使用新的 MediaStore.getExternalVolumeNames API 方法,在 API 29 中引入.

You need to obtain the existing Volumes using the new MediaStore.getExternalVolumeNames API method, introduced in API 29.

下一个示例获取卷列表,并尝试所有卷,首先优先考虑任何连接的 SD 卡,如果未找到 SD 卡或未能保存,则最后使用内部存储.

The next example obtains the list of volumes, and tries all of them, prioritizing first any attached SD-card and finally using internal storage if no SD-cards are found or fail to save.

您无需对 RELATIVE_PATH 内容值进行任何更改,因为这与所选卷相关.

You don't need to make any changes to the RELATIVE_PATH content value, as such is relative to the selected volume.

另请注意,我已使用 Nullable 返回值更改了 saveBitmap,而不是在失败时抛出异常.根据您的要求更改此设置.

Also note that I've changed saveBitmap with a Nullable return, instead of throwing an exception on failure. Change this according to your requirements.

@NonNull
private List<Uri> getContentUris(@NonNull final Context context) {

    final List<String> allVolumes = new ArrayList<>();

    // Add the internal storage volumes as last resort.
    // These will be kept at the bottom of the list if
    // any SD-card volumes are found
    allVolumes.add(MediaStore.VOLUME_EXTERNAL_PRIMARY);
    allVolumes.add(MediaStore.VOLUME_EXTERNAL);

    // Obtain the list of volume name candidates

    final Set<String> externalVolumeNames = MediaStore.getExternalVolumeNames(context);

    for (final String entry : externalVolumeNames) {
        // If the volume is "not" already cached in the list,
        // then is an SD-card, so prioritize it by adding it
        // at the top of the list
        if (!allVolumes.contains(entry))
            allVolumes.add(0, entry);
    }

    // Finally resolve the target Image content Uris

    final List<Uri> output = new ArrayList<>();

    for (final String entry : allVolumes) {
        output.add(MediaStore.Images.Media.getContentUri(entry));
    }

    return output;
}

@Nullable
public Uri saveBitmap(@NonNull final Context context, @NonNull final Bitmap bitmap,
                      @NonNull final Bitmap.CompressFormat format,
                      @NonNull final String mimeType,
                      @NonNull final String displayName) {

    final ContentValues values = new ContentValues();
    values.put(MediaStore.MediaColumns.DISPLAY_NAME, displayName);
    values.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);
    values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM);

    final ContentResolver resolver = context.getContentResolver();
    final List<Uri> contentUriList = getContentUris(context);

    for (final Uri contentUri : contentUriList) {

        Uri uri = null;

        try {
            uri = resolver.insert(contentUri, values);

            if (uri == null)
                throw new IOException("Failed to create new MediaStore record.");

            try (final OutputStream stream = resolver.openOutputStream(uri)) {
                if (stream == null)
                    throw new IOException("Failed to open output stream.");

                if (!bitmap.compress(format, 95, stream))
                    throw new IOException("Failed to save bitmap.");
            }

            return uri;
        }
        catch (IOException e) {
            Log.w(TAG, "Failed to save in volume: " + contentUri);

            if (uri != null) {
                // Don't leave an orphan entry in the MediaStore
                resolver.delete(uri, null, null);
            }

            // Do not throw, and try the next volume
        }
    }

    return null;
}

这篇关于如何在android 11中将图像保存在外部SDCARD的DCIM文件夹中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 05:04