gpt4 book ai didi

android - 保存位图 Android 8 时图像名称和类型错误

转载 作者:行者123 更新时间:2023-12-04 16:40:09 26 4
gpt4 key购买 nike

我有一个乐趣,将位图保存为 PNG 或 JPG(均无效),但似乎使用的内容值无法按预期工作。

  1. 文件名不正确。
  2. 文件类型不正确。

我错过了什么?适用于 Android 10,但不适用于 Android 8

fun Bitmap.save(context: Context) {
val contentResolver = context.contentResolver

val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, "test.png")
put(MediaStore.MediaColumns.TITLE, "test")
put(MediaStore.MediaColumns.MIME_TYPE, "image/png")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
put(MediaStore.MediaColumns.IS_PENDING, 1)
}
}

val contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
val uri = contentResolver.insert(contentUri, contentValues)
if (uri != null) {
try {
contentResolver.openFileDescriptor(uri, "w", null)?.use {
if (it.fileDescriptor != null) {
with(FileOutputStream(it.fileDescriptor)) {
compress(
Bitmap.CompressFormat.PNG,
DEFAULT_IMAGE_QUALITY,
this
)
flush()
close()
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
contentValues.clear()
contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0)
contentResolver.update(uri, contentValues, null, null)
}

MediaScannerConnection.scanFile(context, arrayOf(uri.toString()), null, null)
}
recycle()
}

实际文件名是1592205828045(一些时间戳)

实际文件类型是 jpg0B - 因为它没有正确保存?

最佳答案

您必须采用 2 种不同的方式将图像保存到共享存储中。这个post很好地涵盖了它。在旧手机中使用 Media Store API 会导致您描述的问题。一些代码示例(在 Android 8、10 和 11 中测试)。

将这些添加到您的 list 中

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<!-- File save functions handles this -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28"
tools:ignore="ScopedStorage" />

为您的应用添加权限检查(未提供代码)

当您准备好使用位图时,调用这些函数中的任何一个(取决于应用当前运行的手机的 SDK 版本)

    //TODO - bitmap needs null check
val bitmap = BitmapFactory.decodeFile(bitmapFile.canonicalPath)

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q)
{
saveBitmapPreQ(bitmap)
} else {
saveBitmapPostQ(bitmap)
}

最后这些是saveBitmapPreQsaveBitmapPostQ

的实现
@Suppress("DEPRECATION") // Check is preformed on function call
private fun saveBitmapPreQ(thisBitmap: Bitmap){
Log.d("HOME_4", "in pre Q")
val pictureDirectory =
File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"MyFolder")

if (!pictureDirectory.exists()){
pictureDirectory.mkdir()
}

val dateTimeStamp = SimpleDateFormat("yyyyMMddHHmmss").format(Date())
val name = "Image_$dateTimeStamp"

val bitmapFile = File(pictureDirectory, "$name.png")

try {
val fileOutputStream = bitmapFile.outputStream()
thisBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)
fileOutputStream.flush()
fileOutputStream.close()
} catch (e: Exception) {
Log.d("HOME_5", "Pre Q error $e")
}

}

private fun saveBitmapPostQ(thisBitmap: Bitmap){
Log.d("HOME_6", "in post Q")
val dateTimeStamp = SimpleDateFormat("yyyyMMddHHmmss").format(Date())
val name = "Image_$dateTimeStamp"
val relativePath = Environment.DIRECTORY_PICTURES + File.separator + "MyFolder"


val contentValues = ContentValues().apply {
put(MediaStore.Images.ImageColumns.DISPLAY_NAME, name)

put(MediaStore.MediaColumns.MIME_TYPE, "image/png")
put(MediaStore.MediaColumns.TITLE, name)
put(MediaStore.Images.ImageColumns.RELATIVE_PATH, relativePath)
}

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

try {
uri = contentResolver.insert(contentUri, contentValues)

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

outputStream = contentResolver.openOutputStream(uri)

if (outputStream == null){
throw IOException("Failed to get output stream.")
}

if (!thisBitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)){
throw IOException("Failed to save bitmap.")
}
} catch (e: IOException){
if (uri != null)
{
contentResolver.delete(uri, null, null)
}

throw IOException(e)
}

finally {
outputStream?.close()
}
}

我在其中留下了日志消息以帮助您了解流程。在 saveBitmapPostQ 函数中,我采用了一些捷径。请阅读 post创建新文件标题下,了解如何进一步改进该功能。

关于android - 保存位图 Android 8 时图像名称和类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62383342/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com