我最近一直在努力解决这个问题,我想分享我从支持库中使用FileProvider找到的解决方案。它是内容提供商的扩展,无需解决即可很好地解决此问题,并且没有太多的工作。
如链接中所述,要激活内容提供程序:在清单中,请写下:
<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>
...
元数据应该指示 res/xml 文件夹中的 xml 文件(我将其命名为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>
当您使用内部文件文件夹时,路径为空,但是如果对于更一般的位置(我们现在谈论的是内部存储路径),则应使用其他路径。您编写的名称将用于内容提供商提供给文件的 URL。
现在,您只需使用以下命令即可生成一个新的,世界可读的URL:
Uri contentUri = FileProvider.getUriForFile(context, "com.yourdomain.yourapp.fileprovider", file);
来自 res/xml/file_paths.xml 元数据中路径的任何文件。
现在只需使用:
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();
}
您不需要授予权限,当您将URL附加到文件时,会自动执行此操作。
并且您不需要使您的文件MODE_WORLD_READABLE,此模式现已弃用,使其MODE_PRIVATE,内容提供商为其他应用程序可访问的同一文件创建新的URL。
我应该注意,我只是在带有Gmail的模拟器上测试了它。