Получите информацию об изображениях после их сохранения с помощью MediaStore в Android 10 и выше - PullRequest
0 голосов
/ 05 августа 2020

В своем приложении я использую приведенный ниже код, позволяющий пользователям выбирать несколько изображений.

val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
        addCategory(Intent.CATEGORY_OPENABLE)
        type = "image/*"
    }

startActivityForResult(intent, SELECT_IMAGE_REQUEST_CODE)

В onActivityResult() я получаю список URI, которые преобразуются в список файлов. Я сжимаю эти файлы и сохраняю растровое изображение, используя приведенный ниже код.

private fun saveImage(bitmap: Bitmap?) {
    val imageName = "image_${UUID.randomUUID().toString().substring(0, 5)}"
    var uri: Uri? = null

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        val relativeLocation =
            Environment.DIRECTORY_PICTURES + File.separator + getString(R.string.app_name)
        val contentValues = ContentValues().apply {
            put(MediaStore.MediaColumns.DISPLAY_NAME, imageName)
            put(MediaStore.MediaColumns.MIME_TYPE, "image/png")
            put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation)
        }
        val contentResolver = context?.contentResolver
        var stream: OutputStream? = null
        try {
            val contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
            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) == false) {
                throw IOException("Failed to save bitmap.")
            }
        } catch (e: IOException) {
            if (uri != null) {
                contentResolver?.delete(uri, null, null)
            }
            throw e
        } finally {
            stream?.close()
        }
        contentValues.clear()
        contentValues.put(MediaStore.Images.Media.IS_PENDING, 0)
        contentResolver?.update(uri!!, contentValues, null, null)
    } else {
        var stream: OutputStream? = null
        try {
            val savePath =
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
                    .toString() + File.separator + getString(R.string.app_name)
            val file = File(savePath)

            if (!file.exists()) file.mkdir()
            val imageFile = File(savePath, "$imageName.png")
            stream = FileOutputStream(imageFile)
            bitmap?.compress(Bitmap.CompressFormat.PNG, 100, stream)
        } catch (e: IOException) {
            throw e
        } finally {
            stream?.close()
        }
    }
}

После завершения сжатия я показываю пользователю список сжатых изображений вместе с их размером до и после сжатия.

Проблема в том, что поскольку я получаю File ниже Android Q, я могу легко извлечь такую ​​информацию, как имя и размер сжатого изображения. Однако в Android Q и выше у меня нет доступа к файлу, поскольку растровое изображение сохраняется с помощью MediaStore. Есть ли простой и быстрый способ получить имя и размер сохраненного растрового изображения с помощью MediaStore?

...