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


๐ฑ Android Nougat Crash: FileUriExposedException Explained! ๐ฑ
Are you encountering a dreading ๐ crash while trying to open a file in your Android app? Does it work smoothly on older versions but tumbles ๐คน on Android Nougat? Are you wondering if it's a permission problem? ๐ค Don't worry! You've come to the right place! ๐
What's Happening? ๐คทโโ๏ธ
Let's break it down! ๐ต๏ธโโ๏ธ
When you try to open a file from the SD card using the Intent.ACTION_VIEW
action, you might encounter the android.os.FileUriExposedException
. This exception occurs because starting from Android Nougat (API level 24), file:// URIs are not allowed anymore. They are considered insecure as they expose sensitive data to other apps. ๐ซ
The Sample Code ๐
Here's a snippet of the sample code where the crash occurs:
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
How to Fix It? ๐ ๏ธ
To fix the FileUriExposedException
, we need to use content://
URIs instead of file://
URIs. However, there's a catch! Your app needs to open files in root directories. ๐ฎ Don't worry; I've got a solution for you! ๐
First, we need to make use of the File Provider ๐๏ธ class provided by Android.
Add the following snippet to your AndroidManifest.xml file within the
<application>
tags:<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.myfileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
In the above snippet, replace
${applicationId}
with your actual application id.
Create a new XML file in the
res/xml
directory namedfile_paths.xml
(create thexml
directory if it doesn't exist) and add the following code:<paths xmlns:android="http://schemas.android.com/apk/res/android"> <root-path name="root" path="/" /> </paths>
This configuration allows your app to access files in root directories.
Now, let's modify the previous code snippet to use
content://
URIs through the File Provider:File file = new File("/storage/emulated/0/test.txt"); Uri contentUri = FileProvider.getUriForFile(this, "${applicationId}.myfileprovider", file); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(contentUri, "text/*"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(intent);
Replace
${applicationId}
with your actual application id, just like in the manifest.
We also need to update the file's
FileProvider
path in thefile_paths.xml
file. Add the following code inside the<paths>
tag:<root-path name="external_files" path="."/>
With this, the File Provider will have access to the root directory of your files.
Wrap Up and Engage! ๐
Hurray! ๐ You've just solved the FileUriExposedException problem on Android Nougat and still manage to access files in root directories! ๐
Remember, targeting newer Android versions requires adapting to their security measures. But don't worry, we've got your back! ๐
If you found this blog post helpful, comment below and let me know how it worked for you. ๐ฃ๏ธ Share this article with your fellow developers who might be facing a similar issue. Together, we can conquer any Android obstacle! ๐
Take Your Tech Career to the Next Level
Our application tracking tool helps you manage your job search effectively. Stay organized, track your progress, and land your dream tech job faster.
