Android сохранить МЕДИА в галерею MediaStoreApi

#android #gallery #media #mediastore

#Android #Галерея #Медиафайлы #медиастор #mediastore

Вопрос:

Я использую этот код для сохранения файла в галерею с помощью MediaStoreApi. Он хорошо работает на 29-м уровне API Android и выше, но не работает на 28-м уровне API Android и ниже. Есть ли решение с использованием MediaStoreApi в более низких версиях? Заранее спасибо!

 val values = ContentValues().apply {
    val folderName = if (isVideo) {
        Environment.DIRECTORY_MOVIES
    } else {
        Environment.DIRECTORY_PICTURES
    }
    put(MediaStore.Images.Media.DISPLAY_NAME, fileName)
    put(MediaStore.Images.Media.MIME_TYPE, MimeUtils.guessMimeTypeFromExtension(getExtension(fileName)))
        put(MediaStore.Images.Media.RELATIVE_PATH, folderName   "/${context.getString(R.string.app_name)}/")
        put(MediaStore.Images.Media.IS_PENDING, 1)
}

val collection = if (isVideo) {
    MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
} else {
    MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
}
val fileUri = context.contentResolver.insert(collection, values) ?: return

if (isVideo) {
    context.contentResolver.openFileDescriptor(fileUri, "w").use { descriptor ->
        descriptor?.let {
            FileOutputStream(descriptor.fileDescriptor).use { out ->
                val videoFile = File(filePath)
                FileInputStream(videoFile).use { inputStream ->
                    val buf = ByteArray(8192)
                    while (true) {
                        val sz = inputStream.read(buf)
                        if (sz <= 0) break
                        out.write(buf, 0, sz)
                    }
                }
            }
        }
    }
} else {
    context.contentResolver.openOutputStream(fileUri).use { out ->
        val bmOptions = BitmapFactory.Options()
        val bmp = BitmapFactory.decodeFile(filePath, bmOptions)
        bmp.compress(Bitmap.CompressFormat.JPEG, 90, out)
        bmp.recycle()
    }
}
values.clear()
values.put(if (isVideo) MediaStore.Video.Media.IS_PENDING else MediaStore.Images.Media.IS_PENDING, 0)
context.contentResolver.update(fileUri, values, null, null)
  

Комментарии:

1. Ниже 29 вы не можете использовать .RELATIVE. Столбец ПУТИ. Тогда вы получите предупреждения / исключения для этого. Используйте . Вместо этого укажите столбец ДАННЫХ и укажите полный путь. И не используйте IS_PENDING.

2. Я проверил наличие этих полей, но, в любом случае, это выдает мне java.lang.UnsupportedOperationException: Unknown URI: content://media/external_primary/images/media ошибку.

3. MediaStore.VOLUME_EXTERNAL_PRIMARY также добавлена на уровне API 29.

4. Затем выберите другой. Android Studio IDE расскажет вам несколько, если вы введете MediaStore. и дождитесь появления окна. Попробуйте MediaStore.VOLUME_EXTERNAL.

5. Ох… вы также не можете использовать .getContentUri().