Resolving android.os.FileUriExposedException on Android Nougat and Above

Resolving android.os.FileUriExposedException on Android Nougat and Above

22 May 2024 Stephan Petzl Leave a comment Tech-Help

Are you encountering the dreaded android.os.FileUriExposedException when trying to open a file on Android Nougat and above? This issue typically arises when your app targets Android SDK version 24 or higher and attempts to use file URIs. This guide will walk you through the solution to this problem using the FileProvider class.

Understanding the Issue

The FileUriExposedException is thrown because, starting with Android Nougat, the platform restricts the use of file URIs to improve security. Instead, it mandates the use of content URIs. Here’s a sample code that might be causing the issue:

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

Solution: Using FileProvider

To resolve this issue, you need to use the FileProvider class to share files securely. Follow these steps:

1. Add FileProvider to AndroidManifest.xml

In your AndroidManifest.xml, add a provider tag under the application tag:

<provider
    android:name="androidx.core.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>

2. Define File Paths in provider_paths.xml

Create a file named provider_paths.xml in the res/xml directory. This file specifies which directories the FileProvider can share:

<paths>
    <external-path name="external_files" path="." />
</paths>

3. Update Your Code to Use FileProvider

Modify your code to use FileProvider.getUriForFile instead of Uri.fromFile:

File file = new File("/storage/emulated/0/test.txt");
Uri fileUri = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", file);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(fileUri, "text/*");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // Add this line
startActivity(intent);

Additional Tips

Ensure that you add the FLAG_GRANT_READ_URI_PERMISSION flag to the intent, which grants temporary read access to the content URI. This is crucial for the receiving app to read the file.

Conclusion

By following the above steps, you can resolve the FileUriExposedException and ensure your app remains compliant with Android’s security policies. For more detailed information on handling file permissions and intents, refer to our advanced testing techniques documentation.

Streamlining Your Testing with Repeato

While addressing issues like FileUriExposedException is essential, it’s equally important to ensure your app remains robust through comprehensive testing. Repeato, our no-code test automation tool for iOS and Android, can help you create, run, and maintain automated tests efficiently. Leveraging computer vision and AI, Repeato allows developers to focus on enhancing their apps rather than getting bogged down by testing intricacies. This tool is particularly beneficial for mobile developers who want to delegate test automation tasks to non-technical colleagues or QA teams.

Like this article? there’s more where that came from!