I'm trying to open a file that I've downloaded on one app, in another viewer, such as the stock gallery or a PDF viewer. Here is how I save the file:
FileOutputStream fos = null;
try {
fos = from.openFileOutput(name, Context.MODE_WORLD_READABLE);
fos.write(data); //data is my byte[]
fos.flush();
fos.close();
}catch...
// at this point the file IS written to the path. I can SFTP to my [rooted] device
// and can download the file, it's valid, it opens on my computer.
File outputFile = new File(from.getFilesDir().getAbsolutePath() + "/" + name);
if(!outputFile.exists()){
//show some error message
//we are NOT entering here, just a programmatic check that it exists.
return;
}
String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension("." + extension.toUpperCase()); //extension is file extension as String
//if it doesn't work, I set it manually to some valid one by looking at the extension myself.
Intent intent = new Intent();
intent.setDataAndType(Uri.parse(outputFile.getAbsolutePath()), mime);
intent.setAction(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
I can see the open dialog (and it's correct, e.g. gallery is displayed for a PNG file, or Adobe Reader if it's PDF etc), and the activity opens correctly. However, they can't access the file. Why can't they access the file?
The official way of sharing streams with third-party apps, where those streams come from internal storage of your app, is via FileProvider
. FileProvider
is an implementation of ContentProvider
that handles sharing these streams for you.
FileProvider
will work with most well-written Android apps. Sometimes, the app you share or send the content will fail with FileProvider
, as the people who wrote that app were lazy and assumed that everything came from MediaStore
and you can always map a Uri
to a file. That's not the case. To help with compatibility with those broken clients, I have a LegacyCompatCursorWrapper
that you can blend into your FileProvider
, that provides a canned implementation of Stefan Rusek's solution for this problem.