java.lang.IllegalArgumentException: неизвестный URI при попытке открыть загруженное изображение

#android #android-download-manager #android-11

#Android #android-download-manager #android-11

Вопрос:

Я не могу открыть изображение DownloadManager , загруженное при нажатии на уведомление.

Вот как это воспроизводимо:
я загружаю изображение из сети, используя DownloadManager .
Затем, когда я нажимаю на уведомление об этой загрузке, и ОС показывает мне диалоговое окно, в котором я могу выбрать приложение для открытия загруженного изображения, но когда я выбираю любое приложение, ни одно из них не работает.
Например, при открытии с помощью Google Photos я вижу эту ошибку в Logcat.

 E/DatabaseUtils: Writing exception to parcel
    java.lang.IllegalArgumentException: Unknown URI: content://downloads/public_downloads/12322
        at com.android.providers.downloads.DownloadProvider.query(DownloadProvider.java:1298)
        at android.content.ContentProvider.query(ContentProvider.java:1379)
        at android.content.ContentProvider.query(ContentProvider.java:1475)
        at android.content.ContentProvider$Transport.query(ContentProvider.java:278)
        at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:106)
        at android.os.Binder.execTransactInternal(Binder.java:1154)
        at android.os.Binder.execTransact(Binder.java:1123)
  

Это воспроизводится на Android 11, в предыдущей версии все работает хорошо.
При проверке файловой системы изображение находится в Downloads папке

Я использую этот код для загрузки изображений

 val downloadService: DownloadManager = activity.getSystemService(DOWNLOAD_SERVICE) as val downloadService: DownloadManager = activity.getSystemService(DOWNLOAD_SERVICE) as DownloadManager
downloadService.enqueue(DownloadManager.Request(attachment.getAttachmentUri())
        .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE)
        .setAllowedOverRoaming(false)
        .setTitle(title)
        .setDescription("Downloading attachments")
        .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, title)
        .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
)
  

Протестировано на Pixel3a Android 11
targetSdkVersion 30
compileSdkVersion 30

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

1. @blackapps: «поставщик отсутствует» — если под «поставщиком» вы подразумеваете «полномочия», полномочия есть downloads . Некоторые из действительно старых системных провайдеров не используют пространства имен.

2. Вы предполагаете, что a Uri , возвращенный вашему приложению через DownloadManager , может использоваться любым другим приложением на устройстве . Это небезопасное предположение, особенно на Android 10 и выше. И DownloadManager будет все более странным в мире ограниченного хранилища, поскольку доступ к внешнему хранилищу предоставляется для каждого приложения, а поставщик загрузок отличается от вашего. Если у вас есть доступ к файловой системе к загруженному файлу, используйте FileProvider и getUriForFile() , чтобы сделать его доступным для других приложений.

3. Спасибо @CommonsWare за разъяснения, но дело в том, что я не справляюсь Uri . Когда я ставлю загрузку в очередь, DownloadManager пользователю отображается уведомление, а при нажатии на эту систему уведомлений отображается всплывающее окно, в котором я могу выбрать, с помощью какого приложения открыть это намерение. Мне интересно, могу ли я как-то изменить это поведение.

4. I'm wondering if I can alter this behavior somehow. ДА. Вы можете обойтись без этого уведомления и использовать широковещательный приемник для получения информации о завершении загрузки. Затем используйте FileProvider и ACTION_VIEW. But… все не должно быть необходимым.

5. «DownloadManager показывает пользователю уведомление, а при нажатии на эту систему уведомлений появляется всплывающее окно, в котором я могу выбрать, с помощью какого приложения открыть это намерение» — о, извините, я не понял, что это DownloadManager уведомление, предоставленное пользователем. Это похоже на ошибку в Android. Кроме самостоятельной загрузки содержимого или, по крайней мере, самостоятельного отображения уведомления, я не знаю решения. Я не использовал DownloadManager годами, поэтому могут быть варианты, которые я забываю.