1

I download file with downloadManager:

private fun downloadFile(exportModel: Export, i: Int) {
    val request: DownloadManager.Request = DownloadManager.Request(Uri.parse(exportModel.data.path + exportModel.data.files[i].filename))
            .setTitle(exportModel.data.files[i].filename)
            .setDescription("Downloading")
            .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
            .setAllowedOverMetered(true)
            .setAllowedOverRoaming(true)
            .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, exportModel.data.files[i].filename)
    val downloadManager = activity?.getSystemService(DOWNLOAD_SERVICE) as DownloadManager
    val downloadID = downloadManager.enqueue(request) // enqueue puts the download request in the queue.
}

Download completes (it can be opened from device file explorer in AS) and then i try to share it (e.g. i have file named "Export File.pdf", exists() returns true):

 val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "Export File.pdf")
        val fileUri = getUriForFile(requireContext(), "com.thirdframestudios.android.expensoor.cache_directory_provider", file);

        val shareIntent: Intent = Intent().apply {
            setDataAndType(fileUri, context!!.contentResolver.getType(fileUri))
            action = Intent.ACTION_SEND
            putExtra(Intent.EXTRA_STREAM, fileUri)
            flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
        }
        
        startActivity(shareIntent)

Debug values:

file = /storage/emulated/0/Download/Export File.pdf
fileUri=content://com.thirdframestudios.android.expensoor.cache_directory_provider/Download/Export%20File.pdf

Share sheet is shown (tested on emulator api 29), but when i select some app (e.g. g. drive, i get error when it tries to upload file). Similiar thing happens if i try to open file with ACTION_VIEW (pdf viewer is opened for a brief moment and then closes). I get error when trying to open file with ACTION_VIEW:

2020-10-21 12:58:32.183 18445-18496/? E/DisplayData: openFd: java.io.FileNotFoundException: open failed: EACCES (Permission denied)
2020-10-21 12:58:32.183 18445-18496/? E/PdfLoader: Can't load file (doesn't open)  Display Data [PDF : Export File.pdf] +ContentOpenable, uri: content://com.thirdframestudios.android.expensoor.cache_directory_provider/Download/Export%20File.pdf

My file provider:

  <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="com.thirdframestudios.android.expensoor.cache_directory_provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>

My file_paths.xml file:

<!-- used for support cache -->
<cache-path
    name="support_cache"
    path="."/>

<!-- Based on default Glide operation, see InternalCacheDiskCacheFactory instantiated from GlideBuilder.createGlide() -->
<cache-path
    name="share"
    path="image_manager_disk_cache"
    tools:path="DiskCache.Factory.DEFAULT_DISK_CACHE_DIR" />

<!-- used for sharing export files -->
<external-path
    name="Download"
    path="Download/" />
DixieFlatline
  • 7,895
  • 24
  • 95
  • 147
  • `DownloadManager` does its downloads via another app. AFAIK, your app does not have read access to what `DownloadManager` downloads on Android 10+, even if your app was the one that requested the download. Try [downloading the content yourself](https://stackoverflow.com/a/29012988/115145) and see if you have better luck. – CommonsWare Oct 21 '20 at 12:34
  • I downloded it myself i cannot save it to "Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)". If i download it to context!!.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) it works (can be opened and shared). If i get this right, there is no way to dll it to public download directory and share it from there? What options do i have because i want my users to see downloaded files in file managers app (and files to remain on the phone after my app is e.g. deleted)? – DixieFlatline Oct 22 '20 at 11:07
  • The best thing that I can offer you right now is [Google's documentation for storage use cases](https://developer.android.com/training/data-storage/use-cases). – CommonsWare Oct 22 '20 at 11:14
  • @CommonsWare same issue facing now. Any proven solution, we have now? TIA. – Shihab Uddin Apr 11 '21 at 10:29

2 Answers2

0

Register a broadcast receiver to inform you when download manager is ready.

You can obtain an uri for the downloaded file then from the download manager which you can use in ACTION_VIEW.

Or download to getExternalFilesDir() using setDestinationInExternalFilesDir().

blackapps
  • 8,011
  • 2
  • 11
  • 25
0

After searching for several hours, I find a solution like that. Just remove the directory setting from making the Download request. below line. Tested on Android 11.

setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, exportModel.data.files[i].filename) 

// remove above line. Finally download request looks like :>

val request = DownloadManager.Request(Uri.parse(url))
        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE or DownloadManager.Request.NETWORK_WIFI)
        request.setTitle(requireContext().getString(R.string.downloaded))
        request.setDescription(keyValue)
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
        manager.enqueue(request)
Shihab Uddin
  • 6,699
  • 2
  • 59
  • 74