Open file in cache directory with ACTION_VIEW
android, android-intent, caching
Solution
I found out that I had to do things differently.
Instead of creating my own ContentProvider, the v4 support library offers a FileProvider class that can be used.
In `AndroidManifest.xml` add
<application ...>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="be.myapplication"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
The FILE_PROVIDER_PATHS is an xml file that describes which files can be read by other applications.
So I added a file_paths.xml file to the res/xml folder.
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path name="my_cache" path="." />
</paths>
And the only thing you have to do then is create and start the intent to show the file.
File file = new File(getCacheDir(), "test.pdf");
Uri uri = FileProvider.getUriForFile(context, "be.myapplication", file);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);
And actually that's it.
IMPORTANT: Please do not forget setting `FLAG_GRANT_READ_URI_PERMISSION` flags for the intent. Otherwise it will not work.
Problem
I have been searching for this for a while now but it I can't make this to work correctly. Let me explain. I have an android application that saves files (images, documents, ...) in the cache directory. At first I used to `getExternalCacheDir()` method and save them over there but because it should be cached on devices that do not have an SD-card, I have to use `getCacheDir()`. When I used to `getExternalCacheDir()` method, it was no problem to open those files in another application like this: ``` Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), mimetype); ``` But when using the `getCacheDir()`, those files are saved in the application sandbox and are not accessible from outside the application. So I googled it and came on the **ContentProvider. A ContentProvider makes it possible to open private files with external applications. But when I try to implement it, it doesn't work. I tried implementing the ContentProvider thanks to this post: How to open private files saved to the internal storage using Intent.ACTION_VIEW? but with no success. ``` package com.myapplication.providers; import java.io.File; import java.io.FileNotFoundException; import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.ParcelFileDescriptor; public class FileProvider extends ContentProvider { @Override public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { File privateFile = new File(getContext().getCacheDir(), uri.getPath()); return ParcelFileDescriptor.open(privateFile, ParcelFileDescriptor.MODE_READ_ONLY); } @Override public int delete(Uri arg0, String arg1, String[] arg2) { return 0; } @Override public String getType(Uri arg0) { return null; } @Override public Uri insert(Uri arg0, ContentValues arg1) { return null; } @Override public boolean onCreate() { return false; } @Override public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4) { return null; } @Override public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) { return 0; } } ``` Added this provider to the application manifest ``` <provider android:name="com.myapplication.providers.FileProvider" android:authorities="com.myapplication" android:exported="true" /> ``` And using this code to open the file: ``` Uri uri = Uri.parse("content://com.myapplication/" + filename); Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setDataAndType(uri, mimetype); ``` Thanks in advance!