感谢您贡献iCantC on
第 2 步:以 Q 样式保存图像。
我在 Android Studio 中遇到了一些内存使用问题,我不得不打开 Sublime 来修复。要修复此错误:
e: java.lang.OutOfMemoryError: Java heap space
这是我使用的代码,因为我的用例是用于 PNG 图像,bitmap.compress 小于 100 的任何值都可能没有用。
以前的版本不适用于 API 30,所以我将 contentValues RELATIVE_PATH 更新为 DIRECTORY_DCIM 和 contentResolver.insert(EXTERNAL_CONTENT_URI, ...
private val dateFormatter = SimpleDateFormat(
"yyyy.MM.dd 'at' HH:mm:ss z", Locale.getDefault()
)
private val legacyOrQ: (Bitmap) -> Uri = { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
saveImageInQ(it) else legacySave(it) }
private fun saveImageInQ(bitmap: Bitmap): Uri {
val filename = "${title}_of_${dateFormatter.format(Date())}.png"
val fos: OutputStream?
val contentValues = ContentValues().apply {
put(DISPLAY_NAME, filename)
put(MIME_TYPE, "image/png")
put(RELATIVE_PATH, DIRECTORY_DCIM)
put(IS_PENDING, 1)
}
//use application context to get contentResolver
val contentResolver = applicationContext.contentResolver
val uri = contentResolver.insert(EXTERNAL_CONTENT_URI, contentValues)
uri?.let { contentResolver.openOutputStream(it) }.also { fos = it }
fos?.use { bitmap.compress(Bitmap.CompressFormat.PNG, 100, it) }
fos?.flush()
fos?.close()
contentValues.clear()
contentValues.put(IS_PENDING, 0)
uri?.let {
contentResolver.update(it, contentValues, null, null)
}
return uri!!
}
第 3 步:如果不在 Q 上,则以旧样式保存图像
private fun legacySave(bitmap: Bitmap): Uri {
val appContext = applicationContext
val filename = "${title}_of_${dateFormatter.format(Date())}.png"
val directory = getExternalStoragePublicDirectory(DIRECTORY_PICTURES)
val file = File(directory, filename)
val outStream = FileOutputStream(file)
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream)
outStream.flush()
outStream.close()
MediaScannerConnection.scanFile(appContext, arrayOf(file.absolutePath),
null, null)
return FileProvider.getUriForFile(appContext, "${appContext.packageName}.provider",
file)
}
第 4 步:创建自定义 FileProvider
package com.example.background.workers.provider
import androidx.core.content.FileProvider
class WorkerFileProvider : FileProvider() {
}
第 5 步:更新您的 AndroidManifest.xml
变化
<activity android:name=".MyActivity" />
到
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.PICK"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.OPENABLE"/>
<data android:mimeType="image/png"/>
</intent-filter>
</activity>
<provider
android:name=".workers.provider.WorkerFileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true"
android:permission="android.permission.MANAGE_DOCUMENTS">
<intent-filter>
<action android:name="android.content.action.DOCUMENTS_PROVIDER"/>
</intent-filter>
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
第 6 步:在 xml 下为 FILE_PROVIDER_PATHS 添加资源
就我而言,我需要图片文件夹
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="pictures" path="Pictures"/>
</paths>