Android: отдать картинку пользователю

Загружаю по сети изображение и хочу отдать его пользователю, чтобы он мог сохранить его себе или поставить на обои. Пока догуглился до такого:

val result = MediaStore.Images.Media.insertImage(
    activity!!.contentResolver,
    bitmap,
    "title",
    "desc",
)
val intent = Intent(Intent.ACTION_ATTACH_DATA)
intent.setDataAndType(Uri.parse(result), "image/*")
activity?.startActivity(
    Intent.createChooser(
        intent,
        "Download",
    ),
    Bundle()
)

Работает, но

  • insertImage() deprecated и чем его заменить не понимаю
  • можно ли обойтись без битмапа? я скачал png и пользователь себе сохранит его, скорее всего, как png, обязательно ли в промежутке разворачивать его в bitmap, который в десять раз тяжелее? Может памяти не хватить

Ответы (1 шт):

Автор решения: Дмитрий

Пример демонстрирующий скачивания картинки по url и её сохранением на устройство, далее можешь юзать файл и предлагать пользователю что с ним делать. У меня deprecate не возникает api 21 .. 30.

suspend fun saveImage(name: String, url: String) {
    withContext(Dispatchers.IO) {
        val imageUri = getUriSaveImage(name)
        downloadImage(url, imageUri)
    }
}

//Сохраняем на устройство
private fun getUriSaveImage(name: String): Uri {
    val volume = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        MediaStore.VOLUME_EXTERNAL_PRIMARY
    } else {
        MediaStore.VOLUME_EXTERNAL
    }

    val imageCollectionUri = MediaStore.Images.Media.getContentUri(volume)
    val imageDetails = ContentValues().apply {
        put(MediaStore.Images.Media.DISPLAY_NAME, name)
        put(MediaStore.Images.Media.MIME_TYPE, "image/*")
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            put(MediaStore.Images.Media.IS_PENDING, 1)
        }
    }

    return context.contentResolver.insert(imageCollectionUri, imageDetails)!!
}

//Скачиваем файл (картинку) при помощи retrofit с API по url
private suspend fun downloadImage(url: String, uri: Uri) {
    context.contentResolver.openOutputStream(uri)?.use { outputStream ->
        Networking.api
            .getFile(url)
            .byteStream()
            .use { inputStream ->
                inputStream.copyTo(outputStream)
            }
    }
}

/*
interface Api {
    @GET 
    suspend fun getFile(@Url url: String): ResponseBody
} 
*/
→ Ссылка