如何使用MediaStore在Android Q中保存图像?

这是新的Android Q 范围存储的链接。

根据此Android开发者最佳实践博客,storing shared media

files(这是我的情况)应使用MediaStore

API完成。

深入研究文档,我找不到相关功能。

这是我在科特林的审判:

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按照最佳做法博客中的描述,我的图像保存在此处为Storing

app-internal files


我的问题是:

如何使用MediaStore API保存图像?


用Java回答同样可以接受。

提前致谢!


感谢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即使我以的格式压缩位图,图像也会保存为png

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

3-relativeLocation位在小于Android Q的设备上导致异常。用“ Android Version Check”

if语句括起来后,图像直接保存在Pictures文件夹的根目录中。

另一个谢谢你。


变成:

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-type参数相关。例如,对于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();

}

}

}

以上是 如何使用MediaStore在Android Q中保存图像? 的全部内容, 来源链接: utcz.com/qa/424815.html

回到顶部