Recently, I have been struggling with this problem, and I would like to share the solution that I found using FileProvider from the support library. its Content Provider extension, which effectively solves this problem without work, and doesn't work too much.
As explained in the link, to activate the content provider: in your manifest, write:
<application .... <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.youdomain.yourapp.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> ...
metadata should indicate the xml file in the res / xml folder (I named it file_paths.xml):
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <files-path path="" name="document"/> </paths>
The path is empty if you use a folder with internal files, but if for a more general location (now we are talking about the internal storage path), you should use other paths. the name you write will be used for the URL provided by the content provider with the file provided.
and now you can create a new world-readable URL just by using:
Uri contentUri = FileProvider.getUriForFile(context, "com.yourdomain.yourapp.fileprovider", file);
in any file from the path in the res / xml / file_paths.xml metadata.
and now just use:
Intent mailIntent = new Intent(Intent.ACTION_SEND); mailIntent.setType("message/rfc822"); mailIntent.putExtra(Intent.EXTRA_EMAIL, recipients); mailIntent.putExtra(Intent.EXTRA_SUBJECT, subject); mailIntent.putExtra(Intent.EXTRA_TEXT, body); mailIntent.putExtra(Intent.EXTRA_STREAM, contentUri); try { startActivity(Intent.createChooser(mailIntent, "Send email..")); } catch (android.content.ActivityNotFoundException ex) { Toast.makeText(this, R.string.Message_No_Email_Service, Toast.LENGTH_SHORT).show(); }
you do not need to give permission, you do this automatically when you attach the url to the file.
and you don’t need to make your MODE_WORLD_READABLE file, this mode is now outdated, make it MODE_PRIVATE, the content provider will create a new URL for the same file available to other applications.
I should note that I only tested it on an emulator with Gmail.