Why I can't open downloaded file on Android Q

Viewed 1615

I have a simple functionality in my application, user can download the file and then open it or share using any other installed application. Before android Q I hadn't any trouble with this, but with new privacy changes, I don't know how to do this correctly. I need to do the next two steps:

  1. Download file, using DownloadManager, in the common device Downloads folder (not in the application downloads folder)
  2. Open this file or share this file (using intent)

To download the file to common Downloads folder I use next code

val request = DownloadManager.Request(config.uri)
    .setTitle(title)
    .setDescription(config.description)
    .setNotificationVisibility(notificationVisibility)
    .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "filename.pdf")
val downloadId = downloadManager.enqueue(request)

and after downloading done I getting downloaded file Uri like this

val query = DownloadManager.Query().setFilterById(downloadId)
val cursor = downloadManager.query(query)
val fileUriStr = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI))
val fileUri = Uri.parse(fileUriStr)

In the end, when user click on button "Open", I creating next intent

val mime = context.contentResolver.getType(fileUri)
val intent = Intent()
    .setAction(Intent.ACTION_VIEW)
    .setDataAndType(uri, mime)
    .addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
    .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)

All these solutions work properly until Android Q. On android Q after Intent start I see the dialog to chose target application, when I pick target application I get error that this application cant access the file (I use Adobe Reader as target application).

So, the question is how to do this operation correctly on Android 10?

P/S/ Sorry for my bad English

1 Answers

I had a same problem. I used DownloadManager.getUriForDownloadedFile() instead of the Uri returned from query and the problem solved! I don't know what exactly causes the problem but I found that this solution doesn't work on lower versions. So I ended up with this line:

var fileUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) downloadManager.getUriForDownloadedFile(requestId) else Uri.parse(fileUriStr)

Also I get the mime type from here:

val mime = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_MEDIA_TYPE))

And it works on all versions.

Related