当前位置: 首页 > 知识库问答 >
问题:

在android中保存媒体文件

万知
2023-03-14

我刚刚开始android开发,对于如何将媒体文件保存到外部存储的自定义文件夹非常困惑。我读过关于内窥镜存储,纵隔,但我还是不明白。

我正在尝试将文件保存到外部存储中自己的文件夹中(就像外部存储中的Whatsapp文件夹一样)。我希望结构是这样的:

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

我不希望媒体文件存储在默认媒体目录(如Pictures/或DCIM/)中。我有些问题:

  1. 要用哪一个?作用域存储或纵隔API?
  2. 如何实现上述操作?

其他信息:

  1. 即使卸载了应用程序,我也希望文件保持不变
  2. 我的应用程序以Android 10(API 29)为目标,但minSdkVersion是Android 8.0(API 26)
  3. 我将使用OutputStream保存文件。

那么应该采取哪种方法呢?

共有1个答案

甄永年
2023-03-14

您可以将图像和其他媒体文件保存到外部存储中,但是,为了让这些文件显示在其他应用程序中,比如Gallery应用程序中,您需要将它们注册到纵隔存储中。你是怎么保存文件的?您是从头开始创建文件,还是简单地从另一个目录复制文件?

下面是一个如何将位图对象(jpg或png)保存到外部存储器并将其注册到纵隔器中的示例。首先,从纵隔存储中删除文件的任何现有记录,然后使用ContentResolver.Insert()方法将位图保存到外部存储。

请注意,纵隔中的数据列指的是文件的完整路径。

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

}
 类似资料:
  • 问题内容: 我想爱Django,但是开发环境中的静态文件和媒体文件业务让我发疯。请把我从愚蠢中解救出来。 我在开发机器上。我的项目目录的根目录中有文件夹。 在settings.py我有:和。 在我有: 但是我获取媒体文件的唯一方法是通过引用/media/media/例如 。 我期望(并且想要) 谁能告诉我这里发生了什么,并给我一个设置媒体文件处理的简单方法吗? 非常感谢你。 但这留下了两个问题:

  • 在我的应用程序中,我让用户注册/登录他们的社交媒体帐户,即。领英、谷歌和脸书。 我的问题是,一旦我获得了用户的个人资料图片网址,我应该在我的系统中保存图像,还是允许我简单地保存网址,让图像从用户的社交媒体帐户中提供?我甚至不确定我是否被允许保存这张照片,因为从技术上来说,它可能是领英、谷歌或脸书的财产。

  • 我试图让媒体播放器播放存储在本地/外部存储器中的媒体文件。 媒体文件使用单独的活动下载并存储在本地/外部存储中。有关存储的示例代码,请参阅下面。 对于播放同一文件,我使用。 但是,媒体播放器拒绝播放文件,并且总是以错误(1,)失败。我真的是无能为力,使这个媒体播放器运行,因为我似乎已经做了一切与代码示例内联,使它从本地/外部存储读取文件。 注意:当我替换一个本地文件与一个文件从res/生文件夹,这

  • 本文向大家介绍Android中扫描多媒体文件操作详解,包括了Android中扫描多媒体文件操作详解的使用技巧和注意事项,需要的朋友参考一下 这篇文章从系统源代码分析,讲述如何将程序创建的多媒体文件加入系统的媒体库,如何从媒体库删除,以及大多数程序开发者经常遇到的无法添加到媒体库的问题等。本人将通过对源代码的分析,一一解释这些问题。 Android中的多媒体文件扫描机制 Android提供了一个很棒

  • 如何将文件保存在/storage/emulated/0/中? 我的代码只在android 9或更低版本上运行(如果我在manifest中使用preserveLegacyExternalStorage属性,则在android 10上运行,但在android 11上不运行)

  • 我想保存Whatsapp的状态。通过使用此代码,我可以保存图像 但现在我想保存视频文件太,为此我使用这个代码,但它不为我工作的文件,我得到后,这个代码被破坏 我的目标是Android11