如何正确保存到图片文件夹

Bry*_*yan 5 android image bitmap save mediastore

我正在尝试将用户创建的位图保存到设备上的默认“图片”文件夹中。我将从似乎是更常见方法的选项开始:

public void saveImageToExternalStorage(String filename, Bitmap image) {
    String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator;
    try {
        File directory = new File(path);
        if (!directory.exists()) {
            directory.mkdirs();
        }

        File file = new File(directory, filename + ".jpeg");
        file.createNewFile();

        OutputStream outputStream = new FileOutputStream(file);
        image.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);

        outputStream.flush();
        outputStream.close();
    } catch (IOException exception) {
        exception.printStackTrace();
    }
}
Run Code Online (Sandbox Code Playgroud)

这应该保存到“图片”文件夹中,但Environment.getExternalStorageDirectory().getAbsolutePath()似乎创建了一个这样的新文件结构file://storage/emulated/11/Pictures/并将图片保存到那个文件夹中。我也试过Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)同样的结果。但这不是我的任何测试设备或模拟器上的默认“图片”文件夹。这让我寻找其他方法,我发现了这个:

public void saveImageToExternalStorage(String filename, Bitmap image) {
    try {
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.TITLE, filename);
        values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");

        Uri filepath = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        OutputStream outputStream = getContentResolver().openOutputStream(filepath);

        image.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
        outputStream.close();
    } catch (IOException exception) {
        exception.printStackTrace();
    }
}
Run Code Online (Sandbox Code Playgroud)

这实际上保存到默认文件结构,它显然是这样的:content://media/external/images/media/4282. 但是似乎没有办法指定图像的文件名(Media.TITLE只是设置标题属性,而不是实际的文件名),它保存为(看似)随机的数字字符串。我查看了API 指南MediaStore.Images.Media似乎没有任何其他变量可以设置文件名。根据Android Developer Guides,这似乎也不是正确的保存方式。我想知道是否有任何方法可以保存到此文件夹,同时还可以设置我自己的文件名。如果这种方法会在其他设备上产生不可预见的问题。

编辑: 对于任何感兴趣的人,这是我当前的代码,基于@CommonsWare 的回答:

public void saveImageToExternalStorage(Context context, String filename, Bitmap image) throws IOException {
    File directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    File file = new File(directory, filename + ".jpeg");

    FileOutputStream outputStream = new FileOutputStream(file);
    mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);

    outputStream.flush();
    outputStream.getFD().sync();
    outputStream.close();

    MediaScannerConnection.scanFile(context, new String[] {file.getAbsolutePath()}, null, null);
}
Run Code Online (Sandbox Code Playgroud)

Com*_*are 5

这应该保存到“图片”文件夹中

getExternalStorageDirectory()返回外部存储的根,而不是其中的某个位置(例如,Pictures/, DCIM/, Movies/)。

我也尝试过Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),结果相同

这将为您提供正确的目录,或者设备认为正确的目录(通常Pictures/在外部存储中为当前用户命名)。

但 Environment.getExternalStorageDirectory().getAbsolutePath() 似乎创建了一个新的文件结构,如下所示 file://storage/emulated/11/Pictures/

11有点不寻常,并且getAbsolutePath()不会返回带有file://方案的内容,但除此之外,这似乎是正确的。

但这不是我的任何测试设备或模拟器上的默认“图片”文件夹。

我不知道你是如何确定这一点的。

我想知道是否有任何方法可以保存到此文件夹,同时还可以设置我自己的文件名。

从第一个示例开始,切换到DIRECTORY_PICTURES. 然后:

  • 已经outputStream成为一个FileOutputStream

  • outputStream.getFD().sync()之后flush()和之前调用close()

  • 使用MediaScannerConnection及其scanFile()方法来安排对MediaStore图像进行索引,因此可用于设备上的图库、桌面操作系统文件管理器等。