exposed beyond app through intent getdata

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?

android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()

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?

If your targetSdkVersion >= 24 , then we have to use FileProvider class to give access to the particular file or folder to make them accessible for other apps. We create our own class inheriting FileProvider in order to make sure our FileProvider doesn’t conflict with FileProviders declared in imported dependencies as described here.

Steps to replace file:// URI with content:// URI:

Add a class extending FileProvider

Add a FileProvider

The final step is to change the line of code below in

Edit: If you’re using an intent to make the system open your file, you may need to add the following line of code:

Please refer, full code and solution has been explained here.

Besides the solution using the FileProvider , there is another way to work around this. Simply put

in Application.onCreate() . In this way the VM ignores the file URI exposure.

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 the target SDK version is not allowed. In this case my solution is useful.

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.

If your app targets API 24+, and you still want/need to use file:// intents, you can use hacky way to disable the runtime check:

Method StrictMode.disableDeathOnFileUriExposure is hidden and documented as:

Problem is that my app is not lame, but rather doesn’t want to be crippled by using content:// intents which are not understood by many apps out there. For example, opening mp3 file with content:// scheme offers much fewer apps than when opening same over file:// scheme. I don’t want to pay for Google’s design faults by limiting my app’s functionality.

Google wants developers to use content scheme, but the system is not prepared for this, for years apps were made to use Files not «content», files can be edited and saved back, while files served over content scheme can’t be (can they?).

If targetSdkVersion is higher than 24, then FileProvider is used to grant access.

Create an xml file(Path: resxml) provider_paths.xml

Add a Provider in AndroidManifest.xml

and you are good to go. Hope it helps.

If your targetSdkVersion is 24 or higher, you can not use file: Uri values in Intents on Android 7.0+ devices.

Your choices are:

Drop your targetSdkVersion to 23 or lower, or

Put your content on internal storage, then use FileProvider to make it available selectively to other apps

(from this sample project)

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.

@palash k answer is correct and worked for internal storage files, but in my case I want to open files from external storage also, my app crashed when open file from external storage like sdcard and usb, but I manage to solve the issue by modifying provider_paths.xml from the accepted answer

change the provider_paths.xml like below

and in java class(No change as the accepted answer just a small edit)

This help me to fix the crash for files from external storages, Hope this will help some one having same issue as mine 🙂

Using the fileProvider is the way to go. But you can use this simple workaround:

WARNING: It will be fixed in next Android release — https://issuetracker.google.com/issues/37122890#comment4

Just paste the below code in activity onCreate()

It will ignore URI exposure

I used Palash’s answer given above but it was somewhat incomplete, I had to provide permission like this

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.

I don’t know why, I did everything exactly the same as Pkosta (https://stackoverflow.com/a/38858040 ) but kept getting error:

java.lang.SecurityException: Permission Denial: opening provider redacted from ProcessRecord (redacted) that is not exported from uid redacted

I wasted hours on this issue. The culprit? Kotlin.

intent was actually setting getIntent().addFlags instead of operating on my newly declared playIntent.

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.

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

https://stackoverflow.com/a/38858040/395097 this answer is complete.

This answer is for — you already have an app which was targeting below 24, and now you are upgrading to targetSDKVersion >= 24.

In Android N, only the file uri exposed to 3rd party app is changed. (Not the way we were using it before). So change only the places where you are sharing the path with 3rd party app (Camera in my case)

In our app we were sending uri to Camera app, in that location we are expecting the camera app to store the captured image.

  1. For android N, we generate new Content:// uri based url pointing to file.
  2. We generate usual File api based path for the same (using older method).

Now we have 2 different uri for same file. #1 is shared with Camera app. If the camera intent is success, we can access the image from #2.

Hope this helps.

In my case I got rid of the exception by replacing SetDataAndType with just SetData .

Android7.0 failed to open a local file:

android.os.FileUriExposedException: file:///storage/emulated/0/BE641B.xls exposed beyond app through Intent.getData().

It’s caused by Android7.0 privilege mechanism changed.

First add in the configuration file is as follows: filepaths.xml of the package name and XML resources, create if not exist.

Note: need to add the following flags in intent, I tried not to add this sentence, no error but can not open the file.

add the read and write permissions. that’s it.

Posted by easydw in Android at Apr 12, 2017 — 1:38 PM

Comments

Copy link Quote reply

xiaozhicheng commented May 14, 2017 •

This comment has been minimized.

Copy link Quote reply

wkh237 commented May 14, 2017

@xiaozhicheng , please provide more detailed information about this issue, thanks.

This comment has been minimized.

Copy link Quote reply

xiaozhicheng commented May 14, 2017

The problem occurred on the Android 7 model,
installing Apk times wrong: android.os.FileUriExposedException:, file://xxxxx.apk, exposed, beyond, app, through, Intent.getData ()

This comment has been minimized.

Copy link Quote reply

sagar-teallabs commented Sep 12, 2017

This comment has been minimized.

Copy link Quote reply

dantman commented Sep 16, 2017

This could be a result of how RNFB uses PathResolver.getRealPathFromURI and the new File API to read files from common filesystem document providers instead of using getContentResolver().openInputStream(uri) .

This comment has been minimized.

Copy link Quote reply

lll000111 commented Sep 17, 2017 •

@wkh237 In this context, is it possible this function is wrong?

but if I see this right it should be

That change also satisfies Android studio, which complains about that method. It also complains about the empty onNewIntent just below («Method does not override method from its superclass»).

I don’t want to change anything in the «fetch» part of the code, I only do filesystem (fs.methods).

This comment has been minimized.

Copy link Quote reply

parthgandhi7 commented Nov 7, 2017

I am just doing android.actionViewIntent(res.path(), ‘image/png’) ( where res.path() returns ‘/storage/emulated/0/Download/CatHat1.jpg’ ) and it is giving me this error . Full stack trace of error :

Is any workaround or any kind of solution to this problem possible? If yes then please tell me as and when possible. I just want to open the downloaded file in its default file opener.

This comment has been minimized.

Copy link Quote reply

parthgandhi7 commented Nov 7, 2017

Update , This is not working on android N(7.0) only. It worked fine in 6.0. So i think whatever @sagar-teallabs and @dantman have written is the ultimate problem . Does anyone have a workaround or solution to this?

Оцените статью