The app is crashing when I'm trying to open a file. It works below Android Nougat, but on Android Nougat it crashes. It only crashes when I try to open a file from the SD card, not from the system partition. Some permission problem?
Sample code:
File file = new File("/storage/emulated/0/test.txt");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "text/*");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent); // Crashes on this line
Log:
android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()
Edit:
When targeting Android Nougat, file://
URIs are not allowed anymore. We should use content://
URIs instead. However, my app needs to open files in root directories. Any ideas?
Besides the solution using the
FileProvider
, there is another way to work around this. Simply putin
Application.onCreate()
. In this way the VM ignores the fileURI
exposure.Method
enables the file exposure check, which is also the default behavior if we don't setup a VmPolicy.
I encountered a problem that if I use a
content://
URI
to send something, some apps just can't understand it. And downgrading thetarget SDK
version is not allowed. In this case my solution is useful.Update:
As mentioned in the comment, StrictMode is diagnostic tool, and is not supposed to be used for this problem. When I posted this answer a year ago, many apps can only receive File uris. They just crash when I tried to send a FileProvider uri to them. This is fixed in most apps now, so we should go with the FileProvider solution.
First you need to add a provider to your AndroidManifest
now create a file in xml resource folder (if using android studio you can hit Alt + Enter after highlighting file_paths and select create a xml resource option)
Next in the file_paths file enter
This example is for external-path you can refere here for more options. This will allow you to share files which are in that folder and its sub-folder.
Now all that's left is to create the intent as follows:
EDIT: I added the root folder of the sd card in the file_paths. I have tested this code and it does work.
I used Palash's answer given above but it was somewhat incomplete, I had to provide permission like this
If
targetSdkVersion
is higher than 24, then FileProvider is used to grant access.Create an xml file(Path: res\xml) provider_paths.xml
Add a Provider in AndroidManifest.xml
and replace
to
and you are good to go. Hope it helps.
For downloading pdf from server , add below code in your service class. Hope this is helpful for you.
And yes , don't forget to add permissions and provider in your manifest.