You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用通过邮件发送图片提示文件不存在或权限错误

Android发送带图片附件邮件无附件/报错问题修复方案

问题根源

  • 静态申请的存储权限未适配Android系统版本要求:Android 6.0及以上需要动态申请读写存储权限,Android 10及以上已禁止直接访问公共外部存储根目录,原代码case1使用Environment.getExternalStorageDirectory()会直接报错
  • 存储路径逻辑错误:使用getCacheDir()时重复创建系统已存在的缓存目录,默认生成的私有目录文件第三方邮件应用无权限访问
  • Uri构造错误:case1的Uri拼写错误,缺少file://中的冒号;Android 7.0及以上禁止直接向外部暴露file://类型的Uri,会抛出FileUriExposedException
  • Intent配置错误:MIME类型设置错误,变量名、方法名存在笔误(mailIntent和emailIntent混用、gtartActivity应为startActivity)

修复步骤

1. 配置FileProvider适配跨应用Uri访问

首先在AndroidManifest.xml的<application>标签内添加Provider配置:

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

在res/xml目录下新建file_paths.xml文件,配置允许共享的路径:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 允许共享应用缓存目录下的文件 -->
    <cache-path name="cache_attachments" path="." />
</paths>

2. 适配动态权限申请

Android 6.0及以上版本,在调用发送邮件逻辑前,先动态申请READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE权限,权限申请通过后再执行后续逻辑。如果仅使用应用专属缓存目录存储附件,可不需要申请外部存储权限。

3. 修正图片存储逻辑

修改storeImage方法,使用应用专属缓存目录存储图片,避免权限问题:

private File storeImage(Bitmap image) {
    String filename = "pic.png";
    File pic = null;
    try {
        // 应用专属缓存目录,无需外部存储权限,可通过FileProvider共享给其他应用
        File cacheDir = getCacheDir();
        pic = new File(cacheDir, filename);
        FileOutputStream out = new FileOutputStream(pic);
        boolean compressSuccess = image.compress(Bitmap.CompressFormat.PNG, 100, out);
        out.flush();
        out.close();
        if (!compressSuccess) {
            pic = null;
        }
    } catch (Exception e) {
        Log.e("BROKEN", "图片存储失败: " + e.getMessage(), e);
        pic = null;
    }
    return pic;
}

4. 修正邮件发送逻辑

String msgtext = "#22 Please warn/fine/terminate the user \n\n";
Bitmap photo = (Bitmap) data.getExtras().get("data");
File fileThing = storeImage(photo);

// 先校验文件是否有效
if (fileThing != null && fileThing.exists() && fileThing.length() > 0) {
    Intent emailIntent = new Intent(Intent.ACTION_SEND);
    // 正确设置MIME类型
    emailIntent.setType("image/png");
    String[] recipient = new String[]{"roySpin@royweil.com", "roysoin2@royweil.com"};
    emailIntent.putExtra(Intent.EXTRA_EMAIL, recipient);
    emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Scooter Illegaly Parked");
    emailIntent.putExtra(Intent.EXTRA_TEXT, msgtext);
    // 通过FileProvider生成可跨应用访问的Uri
    Uri pngUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", fileThing);
    emailIntent.putExtra(Intent.EXTRA_STREAM, pngUri);
    // 授予邮件应用读取附件的权限
    emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    // 调用系统选择器避免崩溃
    startActivity(Intent.createChooser(emailIntent, "选择邮件应用发送"));
} else {
    Log.e("BROKEN", "附件文件无效,无法发送");
}

内容的提问来源于stack exchange,提问作者Roy Weil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 22:06:02