简体   繁体   English

将媒体文件保存在 android

[英]Saving media files in android

I just started with android development and I am very confused about how to save media files to a custom folder in external storage.我刚开始使用 android 开发,我对如何将媒体文件保存到外部存储中的自定义文件夹感到非常困惑。 I have read about scoped storage, Mediastore and I still don't get it.我已经阅读了有关范围存储、Mediastore 的信息,但我仍然不明白。

I'm trying to save files to my own folder in the external storage (just like the Whatsapp folder in external storage).我正在尝试将文件保存到外部存储中我自己的文件夹中(就像外部存储中的 Whatsapp 文件夹一样)。 I want the structure to be as so:我希望结构是这样的:

(EXTERNAL STORAGE ROOT)
 |--- (RandomFolder)
 |--- (Whatsapp)
 |--- (MyFolder)
        |---(Images)
        |---(Videos)
 |--- ...

I do not want the media files to be stored in default media directories (such as Pictures/ or DCIM/).我不希望媒体文件存储在默认媒体目录(例如 Pictures/ 或 DCIM/)中。 I have some questions:我有一些问题:

  1. Which one to use?使用哪一个? Scoped storage or Mediastore API?范围存储或媒体存储 API?
  2. How to implement the above?如何实现上述内容?

Additional Information:附加信息:

  1. I want the files to remain even when the app is uninstalled即使卸载应用程序,我也希望文件保留
  2. My app targets Android 10 (API 29), but minSdkVersion is Android 8.0 (API 26)我的应用程序针对 Android 10 (API 29),但 minSdkVersion 是 Android 8.0 (API 26)
  3. I will be using OutputStream to save my files.我将使用 OutputStream 来保存我的文件。

So which method should I take?那么我应该采取哪种方法呢?

You can save an image and other media files to external storage, however, in order for those files to show up in the other apps, like the Gallery app, you need to register them in the MediaStore.您可以将图像和其他媒体文件保存到外部存储中,但是,为了让这些文件显示在其他应用程序中,例如图库应用程序,您需要在 MediaStore 中注册它们。 How are you saving the files?你是如何保存文件的? Are you creating the files from scratch or are you simply copying them from another directory?您是从头开始创建文件还是只是从另一个目录复制它们?

Here is an example of how to save a Bitmap object (jpg or png) to external storage and register it in the MediaStore.下面是如何将 Bitmap object(jpg 或 png)保存到外部存储并在 MediaStore 中注册的示例。 First any existing records of the file are deleted from the MediaStore and then the Bitmap is saved to external storage using the ContentResolver.insert() method.首先从 MediaStore 中删除文件的任何现有记录,然后使用 ContentResolver.insert() 方法将 Bitmap 保存到外部存储中。

Note that the DATA column in the MediaStore refers to the file's full path.请注意,MediaStore 中的 DATA 列是指文件的完整路径。

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.MediaStore;
import java.io.File;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Objects;

public class SaveImageToMediaStore
{
    public static boolean saveImage(
            Context context, Bitmap bitmap,
            int jpgQuality, int pngQuality, String fileFullPath)
    {
        try
        {
            deleteFileFromMediaStore(context, fileFullPath);

            saveImageAndInsertIntoMediaStore(context, fileFullPath, bitmap, jpgQuality, pngQuality);

            return true;
        }
        catch (Exception ex) { return false; }
    }

    public static boolean saveImageAndInsertIntoMediaStore(
            Context context, String fileFullPath,
            Bitmap bitmap, int jpgQuality, int pngQuality)
    {
        try
        {
            Bitmap.CompressFormat format;
            int quality;
            String mimeType;

            if (fileFullPath.toLowerCase().endsWith(".jpg") ||
                    fileFullPath.toLowerCase().endsWith(".jpeg"))
            {
                format = Bitmap.CompressFormat.JPEG;
                quality = jpgQuality;
                mimeType = "image/jpg";
            }
            else if (fileFullPath.toLowerCase().endsWith(".png"))
            {
                format = Bitmap.CompressFormat.PNG;
                quality = pngQuality;
                mimeType = "image/png";
            }
            else
            {
                return false;
            }

            ContentValues contentValues = new ContentValues();
            contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, getShortName(fileFullPath));
            contentValues.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);
            contentValues.put(MediaStore.MediaColumns.DATA, fileFullPath);

            ContentResolver resolver = context.getContentResolver();
            Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
            OutputStream out = resolver.openOutputStream(Objects.requireNonNull(uri));
            bitmap.compress(format, quality, out);
            Objects.requireNonNull(out).close();

            return true;
        }
        catch (Exception ex) { return false; }
    }

    public static boolean deleteFileFromMediaStore(
            Context context, String fileFullPath)
    {
        File file = new File(fileFullPath);

        String absolutePath, canonicalPath;
        try { absolutePath = file.getAbsolutePath(); }
        catch (Exception ex) { absolutePath = null; }
        try { canonicalPath = file.getCanonicalPath(); }
        catch (Exception ex) { canonicalPath = null; }

        ArrayList<String> paths = new ArrayList<>();

        if (absolutePath != null) paths.add(absolutePath);
        if (canonicalPath != null && !canonicalPath.equalsIgnoreCase(absolutePath))
            paths.add(canonicalPath);

        if (paths.size() == 0) return false;

        ContentResolver resolver = context.getContentResolver();
        Uri uri = MediaStore.Files.getContentUri("external");

        boolean deleted = false;

        for (String path : paths)
        {
            int result = resolver.delete(uri,
                    MediaStore.Files.FileColumns.DATA + "=?",
                    new String[] { path });

            if (result != 0) deleted = true;
        }

        return deleted;
    }

    public static String getShortName(String path)
    {
        if (path.endsWith("/")) path = path.substring(0, path.length() - 1);

        int pos = path.lastIndexOf('/');

        if (pos == -1) return path;

        return path.substring(pos + 1);
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM