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?
Just paste the below code in activity onCreate()
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build());
It will ignore URI exposure
Happy coding :-)
Xamarin.Android
Note: The path xml/provider_paths.xml (.axml) couldn't be resolved, even after making the xml folder under Resources (maybe it can be put in an existing location like Values, didn't try), so I resorted to this which works for now. Testing showed that it only needs to be called once per application run (which makes sense being that it changes the operational state of the host VM).
Note: xml needs to be capitalized, so Resources/Xml/provider_paths.xml
My Solution was to 'Uri.parse' the File Path as String, instead of using Uri.fromFile().
Seems that fromFile() uses A file pointer, which I suppose could be insecure when memory addresses are exposed to all apps. But A file path String never hurt anybody, so it works without throwing FileUriExposedException.
Tested on API levels 9 to 26! Does not require FileProvider, nor the Android Support Library at all.
In my case I got rid of the exception by replacing
SetDataAndType
with justSetData
.If your
targetSdkVersion
is 24 or higher, you can not usefile:
Uri
values inIntents
on Android 7.0+ devices.Your choices are:
Drop your
targetSdkVersion
to 23 or lower, orPut your content on internal storage, then use
FileProvider
to make it available selectively to other appsFor example:
(from this sample project)
Using the fileProvider is the way to go. But you can use this simple workaround:
replace:
by