AndroidQ DownloadManager.Request.setDestinationUri - PullRequest
1 голос
/ 07 июня 2019

В моем коде загрузки хранятся изображения, которые должны «выжить» для удаления приложения, я использовал getExternalStoragePublicDirectory, но теперь в Android Q этот API устарел, поэтому я изменил свой код для загрузки

val uri = Uri.fromFile(File(Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_PICTURES), "mysubdir"))
val request = DownloadManager.Request(Uri.parse(url))
.setDestinationUri(uri)

до

val uri = buildImageUri(context.contentResolver, fileName, fileName)
val request = DownloadManager.Request(Uri.parse(url))
    .setDestinationUri(uri)

////// Use MediaStore

    fun buildImageUri(
        cr: ContentResolver,
        title: String,
        description: String): Uri? {
        val values = ContentValues()
        values.put(MediaStore.Images.Media.TITLE, title)
        values.put(MediaStore.Images.Media.DISPLAY_NAME, title)
        values.put(MediaStore.Images.Media.DESCRIPTION, description)
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
        val buildTime = System.currentTimeMillis() / 1000
        values.put(MediaStore.Images.Media.DATE_ADDED, buildTime)
        values.put(MediaStore.Images.Media.DATE_MODIFIED, buildTime)

        return cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
    }

Но я получаю java.lang.IllegalArgumentException: Not a file URI: null, так как код должен быть написан, чтобы быть совместимым с Android Q и без использования эзотерических трюков, таких как поиск двоеточия в uri и разделенная строка?

Документация для setDestinationUri не обновляется и сообщает

Для приложений, ориентированных на Build.VERSION_CODES.Q или выше, пропущенный текст или путь в каталоге загрузок верхнего уровня (как возвращается Environment # getExternalStoragePublicDirectory (String) с Окружающая среда # DIRECTORY_DOWNLOADS)

1 Ответ

0 голосов
/ 09 июня 2019

DownloadManager все еще имеет давнее ограничение только на поддержку file: схем, а не content:. Я подал проблему , чтобы попытаться когда-нибудь исправить это.

Ваши варианты:

  • Используйте setDestinationInExternalFilesDir() на DownloadManager.Request, что соответствует getExternalFilesDir(), к которому ваше приложение имеет полный доступ. Если контент является тем, что должно пережить удаление приложения, вам нужно будет использовать его как временное местоположение и самостоятельно переместить содержимое в другое, более надежное место.

  • Используйте setDestinationInExternalPublicDir() на DownloadManager.Request. Хотя соответствующее местоположение (Environment.getExternalStoragePublicDirectory()) устарело, это не мешает вам использовать DownloadManager для него. Проблема может заключаться в том, что вы не сможете читать или записывать загруженный файл, поскольку у вас нет доступа к этому каталогу, когда ваше приложение использует хранилище с ограниченным объемом Android Q. Таким образом, это подходит только для «слепых» загрузок, когда ваше приложение загружает что-то по запросу пользователя, но только пользователь (не приложение) нуждается в доступе к загруженному контенту.

  • Используйте setDestinationUri() на DownloadManager.Request для некоторого file: Uri, представляющего другое полезное местоположение. Например, возможно (хотя и немного странно) хотеть скачать в getExternalCacheDir().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...