Skip to content

Commit

Permalink
优化文件类型获取
Browse files Browse the repository at this point in the history
  • Loading branch information
shhu committed Feb 16, 2022
1 parent c203853 commit f6f0002
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 23 deletions.
1 change: 1 addition & 0 deletions .idea/.name

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 39 additions & 23 deletions app/src/main/java/com/dede/mediastoredemo/ImageExt.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@file:JvmName("ImageExt")
@file:Suppress("unused")

package com.dede.mediastoredemo

Expand All @@ -17,13 +18,8 @@ import java.io.OutputStream

private const val TAG = "ImageExt"

const val MIME_PNG = "image/png"
const val MIME_JPG = "image/jpg"
private val ALBUM_DIR = Environment.DIRECTORY_PICTURES

/**
* 用于Q以下系统获取图片文件大小来更新[MediaStore.Images.Media.SIZE]
*/
private class OutputFileTaker(var file: File? = null)

/**
Expand All @@ -33,7 +29,7 @@ private class OutputFileTaker(var file: File? = null)
* @param fileName 文件名。 需要携带后缀
* @param relativePath 相对于Pictures的路径
*/
fun File.copyToAlbum(context: Context, fileName: String, relativePath: String? = null): Uri? {
fun File.copyToAlbum(context: Context, fileName: String, relativePath: String?): Uri? {
if (!this.canRead() || !this.exists()) {
Log.w(TAG, "check: read file error: $this")
return null
Expand All @@ -50,11 +46,7 @@ fun File.copyToAlbum(context: Context, fileName: String, relativePath: String? =
* @param fileName 文件名。 需要携带后缀
* @param relativePath 相对于Pictures的路径
*/
fun InputStream.saveToAlbum(
context: Context,
fileName: String,
relativePath: String? = null
): Uri? {
fun InputStream.saveToAlbum(context: Context, fileName: String, relativePath: String?): Uri? {
val resolver = context.contentResolver
val outputFile = OutputFileTaker()
val imageUri = resolver.insertMediaImage(fileName, relativePath, outputFile)
Expand Down Expand Up @@ -86,7 +78,7 @@ fun Bitmap.saveToAlbum(
context: Context,
fileName: String,
relativePath: String? = null,
quality: Int = 75
quality: Int = 75,
): Uri? {
// 插入图片信息
val resolver = context.contentResolver
Expand All @@ -99,8 +91,7 @@ fun Bitmap.saveToAlbum(

// 保存图片
(imageUri.outputStream(resolver) ?: return null).use {
val format =
if (fileName.endsWith(".png")) Bitmap.CompressFormat.PNG else Bitmap.CompressFormat.JPEG
val format = fileName.getBitmapFormat()
this@saveToAlbum.compress(format, quality, it)
imageUri.finishPending(context, resolver, outputFile.file)
}
Expand All @@ -119,7 +110,7 @@ private fun Uri.outputStream(resolver: ContentResolver): OutputStream? {
private fun Uri.finishPending(
context: Context,
resolver: ContentResolver,
outputFile: File?
outputFile: File?,
) {
val imageValues = ContentValues()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
Expand All @@ -128,7 +119,7 @@ private fun Uri.finishPending(
}
resolver.update(this, imageValues, null, null)
// 通知媒体库更新
val intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, this)
val intent = Intent(@Suppress("DEPRECATION") Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, this)
context.sendBroadcast(intent)
} else {
// Android Q添加了IS_PENDING状态,为0时其他应用才可见
Expand All @@ -137,18 +128,42 @@ private fun Uri.finishPending(
}
}

private fun String.getBitmapFormat(): Bitmap.CompressFormat {
val fileName = this.lowercase()
return when {
fileName.endsWith(".png") -> Bitmap.CompressFormat.PNG
fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") -> Bitmap.CompressFormat.JPEG
fileName.endsWith(".webp") -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
Bitmap.CompressFormat.WEBP_LOSSLESS else Bitmap.CompressFormat.WEBP
else -> Bitmap.CompressFormat.PNG
}
}

private fun String.getMimeType(): String? {
val fileName = this.lowercase()
return when {
fileName.endsWith(".png") -> "image/png"
fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") -> "image/jpeg"
fileName.endsWith(".webp") -> "image/webp"
fileName.endsWith(".gif") -> "image/gif"
else -> null
}
}

/**
* 插入图片到媒体库
*/
private fun ContentResolver.insertMediaImage(
fileName: String,
relativePath: String?,
outputFileTaker: OutputFileTaker? = null
outputFileTaker: OutputFileTaker? = null,
): Uri? {
// 图片信息
val imageValues = ContentValues().apply {
val mimeType = if (fileName.endsWith(".png")) MIME_PNG else MIME_JPG
put(MediaStore.Images.Media.MIME_TYPE, mimeType)
val mimeType = fileName.getMimeType()
if (mimeType != null) {
put(MediaStore.Images.Media.MIME_TYPE, mimeType)
}
val date = System.currentTimeMillis() / 1000
put(MediaStore.Images.Media.DATE_ADDED, date)
put(MediaStore.Images.Media.DATE_MODIFIED, date)
Expand All @@ -166,7 +181,8 @@ private fun ContentResolver.insertMediaImage(
// 高版本不用查重直接插入,会自动重命名
} else {
// 老版本
val pictures = Environment.getExternalStoragePublicDirectory(ALBUM_DIR)
val pictures =
@Suppress("DEPRECATION") Environment.getExternalStoragePublicDirectory(ALBUM_DIR)
val saveDir = if (relativePath != null) File(pictures, relativePath) else pictures

if (!saveDir.exists() && !saveDir.mkdirs()) {
Expand All @@ -192,7 +208,7 @@ private fun ContentResolver.insertMediaImage(
// 保存路径
val imagePath = imageFile.absolutePath
Log.v(TAG, "save file: $imagePath")
put(MediaStore.Images.Media.DATA, imagePath)
put(@Suppress("DEPRECATION") MediaStore.Images.Media.DATA, imagePath)
}
outputFileTaker?.file = imageFile// 回传文件路径,用于设置文件大小
collection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
Expand Down Expand Up @@ -220,8 +236,8 @@ private fun ContentResolver.queryMediaImage28(imagePath: String): Uri? {
// 查询是否已经存在相同图片
val query = this.query(
collection,
arrayOf(MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA),
"${MediaStore.Images.Media.DATA} == ?",
arrayOf(MediaStore.Images.Media._ID, @Suppress("DEPRECATION") MediaStore.Images.Media.DATA),
"${@Suppress("DEPRECATION") MediaStore.Images.Media.DATA} == ?",
arrayOf(imagePath), null
)
query?.use {
Expand Down

0 comments on commit f6f0002

Please sign in to comment.