Android 11如何通过FileProvider的content URI批量发送文件作为邮件附件
问题原因及解决方案
根因说明
- 你当前仅给Intent添加了
FLAG_GRANT_READ_URI_PERMISSION,但在ACTION_SEND_MULTIPLE场景下,该权限标记默认仅对Intent的data字段对应的Uri生效,放在EXTRA_STREAM中的批量附件Uri不会被自动授予读取权限,因此邮件应用访问文件时会触发安全异常。 - 额外的小问题:你当前设置的MIME类型有误,
text/plain仅适配纯文本内容,带附件的邮件需要使用对应的MIME类型,否则部分邮件应用会无法识别附件。
具体修复步骤
1. 修正MIME类型
将intent.setType("text/plain");修改为intent.setType("message/rfc822");,如果需要适配多种附件类型,可以使用更通用的intent.setType("*/*");。
2. 手动给所有附件Uri授予读取权限
Android 7.0及以上版本针对批量传递的Uri,需要手动给所有可接收该Intent的应用授予对应Uri的读取权限,代码需要添加在startActivity执行之前,示例如下:
// 查询所有支持ACTION_SEND_MULTIPLE的应用列表 List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); for (ResolveInfo resolveInfo : resInfoList) { String packageName = resolveInfo.activityInfo.packageName; for (Uri uri : uries) { // 给每个接收应用授予每个附件Uri的读取权限 grantUriPermission(packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); } }
3. 可选检查项
确认你存储在imageFiles列表中的Uri是合法的FileProvider content格式,如果你之前执行imageUri = photoURI.toString();后,存储的是字符串转Uri的结果,没有额外的截取、拼接操作,该部分就不存在问题。
修复后完整的邮件发送代码示例
Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE); // 修正MIME类型 intent.setType("message/rfc822"); intent.putExtra(Intent.EXTRA_EMAIL, new String[] { email }); intent.putExtra(Intent.EXTRA_SUBJECT, subject); LinkedList<Uri> uries = new LinkedList<Uri>(); if (imageFiles != null) { for(Uri file:imageFiles){ uries.add(file); } } intent.putExtra(Intent.EXTRA_STREAM, uries); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 新增权限授予逻辑 List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); for (ResolveInfo resolveInfo : resInfoList) { String packageName = resolveInfo.activityInfo.packageName; for (Uri uri : uries) { grantUriPermission(packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); } } startActivity(Intent.createChooser(intent, "Send email..."));
内容的提问来源于stack exchange,提问作者user3092760
相关产品推荐
相关产品推荐

