如何保存图像 Android Q 通过 MediaStore?

这是一个新的链接
https://developer.android.com/ ... orage
行动 Android Q.

根据
https://android-developers.goo ... .html
,
storing shared media files

/这是我的案子/ 必须使用
https://developer.android.com/ ... Store
在文件中吸烟,我找不到适当的功能。

这是我的审判 Kotlin 年:


val bitmap = getImageBitmap// // I have a bitmap from a function or callback or whatever
val name = "example.png" // I have a name

val picturesDirectory = getExternalFilesDir/Environment.DIRECTORY_PICTURES/!!

// Make sure the directory "Android/data/com.mypackage.etc/files/Pictures" exists
if /!picturesDirectory.exists/// {
picturesDirectory.mkdirs//
}

try {
val out = FileOutputStream/File/picturesDirectory, name//
bitmap.compress/Bitmap.CompressFormat.PNG, 100, out/

out.flush//
out.close//

} catch/e: Exception/ {
// handle the error
}


结果,我的图像在此处保存。
Android/data/com.mypackage.etc/files/Pictures/example.png

, 如博客所述 Best Practices 作为
Storing app-internal files


我的问题是:

如何使用拍摄图像 MediaStore API?

答案B. Java 同样可接受的。

先感谢您!

EDIT

谢谢 PerracoLabs

它真的有帮助!

但仍然存在 3 观点。

这是我的代码:


val name = "Myimage"
val relativeLocation = Environment.DIRECTORY_PICTURES + File.pathSeparator + "AppName"

val contentValues = ContentValues//.apply {
put/MediaStore.Images.ImageColumns.DISPLAY_NAME, name/
put/MediaStore.MediaColumns.MIME_TYPE, "image/png"/

// without this part causes "Failed to create new MediaStore record" exception to be invoked /uri is null below/
if /Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q/ {
put/MediaStore.Images.ImageColumns.RELATIVE_PATH, relativeLocation/
}
}

val contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
var stream: OutputStream? = null
var uri: Uri? = null

try {
uri = contentResolver.insert/contentUri, contentValues/
if /uri == null/
{
throw IOException/"Failed to create new MediaStore record."/
}

stream = contentResolver.openOutputStream/uri/

if /stream == null/
{
throw IOException/"Failed to get output stream."/
}

if /!bitmap.compress/Bitmap.CompressFormat.PNG, 100, stream//
{
throw IOException/"Failed to save bitmap."/
}


Snackbar.make/mCoordinator, R.string.image_saved_success, Snackbar.LENGTH_INDEFINITE/.setAction/"Open"/ {
val intent = Intent//
intent.type = "image/*"
intent.action = Intent.ACTION_VIEW
intent.data = contentUri
startActivity/Intent.createChooser/intent, "Select Gallery App"//
}.show//

} catch/e: IOException/ {
if /uri != null/
{
contentResolver.delete/uri, null, null/
}

throw IOException/e/

}
finally {
stream?.close//
}


1 - 保存的图像未收到其正确的名称。 "Myimage.png"

我试着用 "Myimage" 和 "Myimage.PNG", 但既不是一个也没有其他工作。

图像始终获得由此类数字组成的名称:


1563468625314.jpg


是什么让我们到第二个问题:

2 - 图像已保存为
jpg

, 虽然我挤压 bitmap 格式化
png

.

不是那么大问题。 只是好奇为什么。

3 - 页 relativeLocation 导致设备更少的例外 Android Q.
在环境之后。 "Android Version Check" if statement 图像直接保存在根文件夹中。
Pictures

.

另一个谢谢。

EDIT 2

变成:


uri = contentResolver.insert/contentUri, contentValues/
if /uri == null/
{
throw IOException/"Failed to create new MediaStore record."/
}

val cursor = contentResolver.query/uri, null, null, null, null/
DatabaseUtils.dumpCursor/cursor/
cursor!!.close//

stream = contentResolver.openOutputStream/uri/


这些是这些杂志


I/System.out: >>>>> Dumping cursor android.content.ContentResolver$CursorWrapperInner@76da9d1
I/System.out: 0 {
I/System.out: _id=25417
I/System.out: _data=/storage/emulated/0/Pictures/1563640732667.jpg
I/System.out: _size=null
I/System.out: _display_name=Myimage
I/System.out: mime_type=image/png
I/System.out: title=1563640732667
I/System.out: date_added=1563640732
I/System.out: is_hdr=null
I/System.out: date_modified=null
I/System.out: description=null
I/System.out: picasa_id=null
I/System.out: isprivate=null
I/System.out: latitude=null
I/System.out: longitude=null
I/System.out: datetaken=null
I/System.out: orientation=null
I/System.out: mini_thumb_magic=null
I/System.out: bucket_id=-1617409521
I/System.out: bucket_display_name=Pictures
I/System.out: width=null
I/System.out: height=null
I/System.out: is_hw_privacy=null
I/System.out: hw_voice_offset=null
I/System.out: is_hw_favorite=null
I/System.out: hw_image_refocus=null
I/System.out: album_sort_index=null
I/System.out: bucket_display_name_alias=null
I/System.out: is_hw_burst=0
I/System.out: hw_rectify_offset=null
I/System.out: special_file_type=0
I/System.out: special_file_offset=null
I/System.out: cam_perception=null
I/System.out: cam_exif_flag=null
I/System.out: }
I/System.out: <<<<<


我注意到了
title

符合名称,所以我试图添加:


put/MediaStore.Images.ImageColumns.TITLE, name/


它仍然没有工作,这里是新杂志:


I/System.out: >>>>> Dumping cursor android.content.ContentResolver$CursorWrapperInner@51021a5
I/System.out: 0 {
I/System.out: _id=25418
I/System.out: _data=/storage/emulated/0/Pictures/1563640934803.jpg
I/System.out: _size=null
I/System.out: _display_name=Myimage
I/System.out: mime_type=image/png
I/System.out: title=Myimage
I/System.out: date_added=1563640934
I/System.out: is_hdr=null
I/System.out: date_modified=null
I/System.out: description=null
I/System.out: picasa_id=null
I/System.out: isprivate=null
I/System.out: latitude=null
I/System.out: longitude=null
I/System.out: datetaken=null
I/System.out: orientation=null
I/System.out: mini_thumb_magic=null
I/System.out: bucket_id=-1617409521
I/System.out: bucket_display_name=Pictures
I/System.out: width=null
I/System.out: height=null
I/System.out: is_hw_privacy=null
I/System.out: hw_voice_offset=null
I/System.out: is_hw_favorite=null
I/System.out: hw_image_refocus=null
I/System.out: album_sort_index=null
I/System.out: bucket_display_name_alias=null
I/System.out: is_hw_burst=0
I/System.out: hw_rectify_offset=null
I/System.out: special_file_type=0
I/System.out: special_file_offset=null
I/System.out: cam_perception=null
I/System.out: cam_exif_flag=null
I/System.out: }
I/System.out: <<<<<


而且我无法改变
date_added

解决。


MediaStore.MediaColumns.DATA

它已经过时了。

先感谢您!
已邀请:

小明明

赞同来自:

尝试以下方法。 Android Q 如果它们不存在,已经负责创建文件夹。 该示例刚性地编程为输出到文件夹。 Pictures. 如果您需要子文件夹,请按如下方式添加子文件夹名称:


final String relativeLocation = Environment.DIRECTORY_PICTURES + File.separator + “YourSubforderName”;


请注意,压缩格式必须与类型参数关联 mime. 例如,当压缩格式 JPEG 一种 mime 将 "image/jpeg", 等等。


private void saveBitmap/@NonNull final Context context, @NonNull final Bitmap bitmap,
@NonNull final Bitmap.CompressFormat format, @NonNull final String mimeType,
@NonNull final String displayName/ throws IOException
{
final String relativeLocation = Environment.DIRECTORY_PICTURES;

final ContentValues contentValues = new ContentValues//;
contentValues.put/MediaStore.MediaColumns.DISPLAY_NAME, displayName/;
contentValues.put/MediaStore.MediaColumns.MIME_TYPE, mimeType/;
contentValues.put/MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation/;

final ContentResolver resolver = context.getContentResolver//;

OutputStream stream = null;
Uri uri = null;

try
{
final Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
uri = resolver.insert/contentUri, contentValues/;

if /uri == null/
{
throw new IOException/"Failed to create new MediaStore record."/;
}

stream = resolver.openOutputStream/uri/;

if /stream == null/
{
throw new IOException/"Failed to get output stream."/;
}

if /bitmap.compress/format, 95, stream/ == false/
{
throw new IOException/"Failed to save bitmap."/;
}
}
catch /IOException e/
{
if /uri != null/
{
// Don't leave an orphan entry in the MediaStore
resolver.delete/uri, null, null/;
}

throw e;
}
finally
{
if /stream != null/
{
stream.close//;
}
}
}

卫东

赞同来自:

private void saveImage/Bitmap bitmap, @NonNull String name/ throws IOException {
OutputStream fos;
if /Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q/ {
ContentResolver resolver = getContentResolver//;
ContentValues contentValues = new ContentValues//;
contentValues.put/MediaStore.MediaColumns.DISPLAY_NAME, name + ".jpg"/;
contentValues.put/MediaStore.MediaColumns.MIME_TYPE, "image/jpg"/;
contentValues.put/MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES/;
Uri imageUri = resolver.insert/MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues/;
fos = resolver.openOutputStream/Objects.requireNonNull/imageUri//;
} else {
String imagesDir = Environment.getExternalStoragePublicDirectory/Environment.DIRECTORY_PICTURES/.toString//;
File image = new File/imagesDir, name + ".jpg"/;
fos = new FileOutputStream/image/;
}
bitmap.compress/Bitmap.CompressFormat.JPEG, 100, fos/;
Objects.requireNonNull/fos/.close//;
}


图像将存储在文件夹中 Pictures @ root level

见B. live
https://youtu.be/695HqaiwzQ0
我创造了一个教科书

莫问

赞同来自:

这就是我总是使用的。 你可以试试。


private void saveImageToStorage// throws IOException {

OutputStream imageOutStream;
if /Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q/ {

ContentValues values = new ContentValues//;
values.put/MediaStore.Images.Media.DISPLAY_NAME, "image_screenshot.jpg"/;
values.put/MediaStore.Images.Media.MIME_TYPE, "image/jpeg"/;
values.put/MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES/;
Uri uri = getContentResolver//.insert/MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values/;

imageOutStream = getContentResolver//.openOutputStream/uri/;
} else {
String imagePath = Environment.getExternalStoragePublicDirectory/Environment.DIRECTORY_PICTURES/.toString//;
File image = new File/imagePath, "image_screenshotjpg"/;
imageOutStream = new FileOutputStream/image/;
}

try {
bitmapObject.compress/Bitmap.CompressFormat.JPEG, 100, imageOutStream/;
} finally {
imageOutStream.close//;
}

}

奔跑吧少年

赞同来自:

如果有人正在寻找如何在文件夹中保存照片 DCIM, 因此,将出现 Google 照片后面:
/基于:
https://github.com/yasirkula/U ... 3-L96
/


ContentValue values = new ContentValues//;
values.put/MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM/;
values.put/MediaStore.MediaColumns.DATE_TAKEN, System.currentTimeMillis///;
values.put/MediaStore.MediaColumns.IS_PENDING, true/;

Uri uri = context.getContentResolver//.insert/externalContentUri, values/;

if /uri != null/ {
try {
if /WriteFileToStream/originalFile, context.getContentResolver//.openOutputStream/uri/// {
values.put/MediaStore.MediaColumns.IS_PENDING, false/;
context.getContentResolver//.update/uri, values, null, null/;
}
} catch /Exception e/ {
context.getContentResolver//.delete/ uri, null, null /;
}
}


在哪里
WriteFileToStream

- 这是从文件到流的标准复制方法。

要回复问题请先登录注册