I want to use Android's DownloadManager to download a pdf and then enable the user to open it using his pdf viewer app.
To do that I am saving initiating the download using the following:
public String downloadFile(String url, String name) {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setDescription("Downloading file: " + name);
request.setTitle("My app name");
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setMimeType("application/pdf");
Uri destinationUri = Uri.fromFile(new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), name+".pdf"));
request.setDestinationUri(destinationUri);
manager.enqueue(request);
return destinationUri.toString();
}
I am saving the Uri and use it to open the PDF using a PDF view app like this:
public void openDownloadedFile(String uri) {
Intent intent = new Intent(Intent.ACTION_VIEW);
File file = new File(uri);
Uri uriForFile = FileProvider.getUriForFile(context.getApplicationContext(), context.getString(R.string.my_file_authority), file);
intent.setDataAndType(uriForFile, "application/pdf");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(intent);
}
My application
's Manifest file contains the following provider:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="@string/my_file_authority"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
And I also have the following content in the provider_paths
:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path
name="my_pdfs"
path="."/>
<external-path
name="my_pdfs"
path="."/>
<files-path
name="my_pdfs"
path="."/>
</paths>
I know that there are 2 extra elements there but I just wanted to make sure I don't miss something out.
Unfortunately, this crashes with the following reason:
java.lang.IllegalArgumentException: Failed to find configured root that contains /file:/storage/emulated/0/Android/data/{my_app_id}/files/Download/filename_of_pdf.pdf
at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:738)
at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:417)
Some additional details:
minSdkVersion 21
targetSdkVersion 27
I am testing on a Samsung S8 and Android emulator with Android O.
Can someone please give me a clue about why is this happening? How can I know that Android is considering my provider_paths?
Thank you!
PS:
File file = new File(uri);
A Uri
is not a file.
java.lang.IllegalArgumentException: Failed to find configured root that contains /file:/storage/emulated/0/Android/data/{my_app_id}/files/Download/filename_of_pdf.pdf
/file:/storage/emulated/0/Android/data/{my_app_id}/files/Download/filename_of_pdf.pdf
is not a filesystem path on Android (nor, AFAIK, for any other operating system).
To fix this:
Hold onto the result of new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), name+".pdf")
from your destinationUri
instantiation as a File
Use that File
with getUriForFile()