通过 Android Media Store 将图像存储在新文件夹中
Store Image via Android Media Store in new Folder
我正在使用以下内容将在我的应用程序中创建的图像存储在 Android 的图库中:
MediaStore.Images.Media.insertImage(contentResolver, bitmap, "SomeTitle", "Description");
这会将图像存储在图片设备文件夹中,并将它们添加到图库中。
我现在想为我的应用程序创建一个特定的图像文件夹,以便将图像存储在文件夹 "MyApp" 而不是 "Picture" 中。我该怎么做?
我找到了隐藏在这里的解决方案:
原题比较老,网友鲍磊的好回答排名比较靠后,这里引用一下。
在 API 29 (Android Q) 之前有几种不同的方法可以做到这一点,但所有方法都涉及一个或几个 API 被 Q 弃用的方法。在2019,这是一种向后和向前兼容的方法:
(因为现在是 2019 年所以我会用 Kotlin 写)
/// @param folderName can be your app's name
private fun saveImage(bitmap: Bitmap, context: Context, folderName: String) {
if (android.os.Build.VERSION.SDK_INT >= 29) {
val values = contentValues()
values.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/" + folderName)
values.put(MediaStore.Images.Media.IS_PENDING, true)
// RELATIVE_PATH and IS_PENDING are introduced in API 29.
val uri: Uri? = context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
if (uri != null) {
saveImageToStream(bitmap, context.contentResolver.openOutputStream(uri))
values.put(MediaStore.Images.Media.IS_PENDING, false)
context.contentResolver.update(uri, values, null, null)
}
} else {
val directory = File(Environment.getExternalStorageDirectory().toString() + separator + folderName)
// getExternalStorageDirectory is deprecated in API 29
if (!directory.exists()) {
directory.mkdirs()
}
val fileName = System.currentTimeMillis().toString() + ".png"
val file = File(directory, fileName)
saveImageToStream(bitmap, FileOutputStream(file))
if (file.absolutePath != null) {
val values = contentValues()
values.put(MediaStore.Images.Media.DATA, file.absolutePath)
// .DATA is deprecated in API 29
context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
}
}
}
private fun contentValues() : ContentValues {
val values = ContentValues()
values.put(MediaStore.Images.Media.MIME_TYPE, "image/png")
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
return values
}
private fun saveImageToStream(bitmap: Bitmap, outputStream: OutputStream?) {
if (outputStream != null) {
try {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
outputStream.close()
} catch (e: Exception) {
e.printStackTrace()
}
}
}
另外,在调用这个之前,你需要先有WRITE_EXTERNAL_STORAGE。
我正在使用以下内容将在我的应用程序中创建的图像存储在 Android 的图库中:
MediaStore.Images.Media.insertImage(contentResolver, bitmap, "SomeTitle", "Description");
这会将图像存储在图片设备文件夹中,并将它们添加到图库中。
我现在想为我的应用程序创建一个特定的图像文件夹,以便将图像存储在文件夹 "MyApp" 而不是 "Picture" 中。我该怎么做?
我找到了隐藏在这里的解决方案:
原题比较老,网友鲍磊的好回答排名比较靠后,这里引用一下。
在 API 29 (Android Q) 之前有几种不同的方法可以做到这一点,但所有方法都涉及一个或几个 API 被 Q 弃用的方法。在2019,这是一种向后和向前兼容的方法:
(因为现在是 2019 年所以我会用 Kotlin 写)
/// @param folderName can be your app's name
private fun saveImage(bitmap: Bitmap, context: Context, folderName: String) {
if (android.os.Build.VERSION.SDK_INT >= 29) {
val values = contentValues()
values.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/" + folderName)
values.put(MediaStore.Images.Media.IS_PENDING, true)
// RELATIVE_PATH and IS_PENDING are introduced in API 29.
val uri: Uri? = context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
if (uri != null) {
saveImageToStream(bitmap, context.contentResolver.openOutputStream(uri))
values.put(MediaStore.Images.Media.IS_PENDING, false)
context.contentResolver.update(uri, values, null, null)
}
} else {
val directory = File(Environment.getExternalStorageDirectory().toString() + separator + folderName)
// getExternalStorageDirectory is deprecated in API 29
if (!directory.exists()) {
directory.mkdirs()
}
val fileName = System.currentTimeMillis().toString() + ".png"
val file = File(directory, fileName)
saveImageToStream(bitmap, FileOutputStream(file))
if (file.absolutePath != null) {
val values = contentValues()
values.put(MediaStore.Images.Media.DATA, file.absolutePath)
// .DATA is deprecated in API 29
context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
}
}
}
private fun contentValues() : ContentValues {
val values = ContentValues()
values.put(MediaStore.Images.Media.MIME_TYPE, "image/png")
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
return values
}
private fun saveImageToStream(bitmap: Bitmap, outputStream: OutputStream?) {
if (outputStream != null) {
try {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
outputStream.close()
} catch (e: Exception) {
e.printStackTrace()
}
}
}
另外,在调用这个之前,你需要先有WRITE_EXTERNAL_STORAGE。