Android: FileUriExposedException? How does it happen with your application?

Leo N
2 min readJun 12, 2019

--

The exception that is thrown when an application exposes a file:// Uri to another app. This exposure is discouraged since the receiving app may not have access to the shared path. For example, the receiving app may not have requested the Manifest.permission.READ_EXTERNAL_STORAGE runtime permission, or the platform may be sharing the Uri across user profile boundaries. Instead, apps should use content:// Uris so the platform can extend temporary permission for the receiving app to access the resource.This is only thrown for applications targeting Build.VERSION_CODES#N or higher. Applications targeting earlier SDK versions are allowed to share file:// Uri, but it's strongly discouraged.

If you have an app that shares files with other apps using a Uri, you may have encountered this error on API 24+.

This error occurs when you try to share a file:// Uri in an Intent broadcast to share data with other apps. Using file:// Uri’s are discouraged in this scenario because it makes some assumptions about the destination app. For one thing, we assume that the destination app has READ_EXTERNAL_PERMISSIONwhich may not be the case. If the destination app does not have READ_EXTERNAL_PERMISSION, this may result in unexpected behaviour at best or at worst, result in a crash.

As of Android N, in order to work around this issue, you need to use the FileProvider API.

Step 1: Manifest Entry

<manifest ...>
<application ...>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
</application>
</manifest>

Step 2: Create XML file res/xml/provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>

Step 3: Code changes

File file = ...;
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
Uri apkURI = FileProvider.getUriForFile(
context,
context.getApplicationContext()
.getPackageName() + ".provider", file);
install.setDataAndType(apkURI, mimeType);
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(install);

That should do it!

Thanks for:

  1. https://medium.com/@ali.muzaffar/what-is-android-os-fileuriexposedexception-and-what-you-can-do-about-it-70b9eb17c6d0

--

--

Leo N

🎓 “A person who never made a mistake never tried anything new.” — Albert Einstein