我正在尝试将用户创建的位图保存到默认的'图片'设备上的文件夹。我将从似乎是更常见的方法的选项开始:
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();
}
}
这应该保存到'图片'文件夹,但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();
}
}
这实际上保存到默认文件结构,显然如下所示:content://media/external/images/media/4282
。但似乎没有办法指定图像的文件名(Media.TITLE
只设置标题属性,而不是实际的文件名),它保存为(看似)随机数字串。我查看MediaStore.Images.Media
的{{3}},似乎没有任何其他变量可以设置文件名。根据{{3}},这似乎也不是正确的保存方式。我想知道是否有任何方法可以保存到此文件夹,同时还设置我自己的文件名。如果这种方法可以在其他设备上产生无法预料的问题。
修改 对于任何感兴趣的人,这是我目前的代码,基于@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);
}
答案 0 :(得分:3)
这应该保存到'图片'夹
Pictures/
会返回外部存储空间的根目录,而不是其中的某个位置(例如DCIM/
,Movies/
,Pictures/
)。
我也尝试过具有相同结果的Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
这将为您提供正确的目录,或者设备认为正确的目录(通常在外部存储中将11
命名为当前用户)。
但是Environment.getExternalStorageDirectory()。getAbsolutePath()似乎创建了一个像这个文件的新文件结构:// storage / emulated / 11 / Pictures /
getAbsolutePath()
有点不寻常,而file://
不会返回带有DIRECTORY_PICTURES
方案的内容,但除此之外似乎是正确的。
但这不是默认的'图片'我的任何测试设备或模拟器上的文件夹。
我不知道你是怎么决定的。
我想知道是否有任何方法可以保存到此文件夹,同时还可以设置我自己的文件名。
从第一个示例开始,切换到outputStream
。然后:
让FileOutputStream
成为outputStream.getFD().sync()
在flush()
之后和close()
之前致电MediaScannerConnection
使用scanFile()
及其MediaStore
方法安排searchEmail
索引图像,因此可供设备上的画廊,桌面操作系统文件管理器等使用
答案 1 :(得分:0)
使用Android 6.0 Marshmallow(API> = 23),Google引入了新的权限模型。
您必须在运行时请求权限:
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
requestPermissions(permissions, WRITE_REQUEST_CODE);
并在onRequestPermissionsResult(),
中处理结果File path = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File file = new File(path, "db.JPG");
try {
file.createNewFile();
}
catch (IOException e) {
Toast.makeText(this.getApplicationContext(),
"createNewFile:"+e.toString(),
Toast.LENGTH_LONG).show();
}
然后
if (Build.VERSION.SDK_INT < 19) {
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + filename)));
}
else {
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse("file://" + filename)));
}
在画廊中展示。