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

Android Studio中无法附加Drawable矢量图至邮件:空文件错误

解决Android Studio中无法附加Drawable矢量图到邮件的问题

嘿,我来帮你搞定这个问题!你遇到的「无法附加空文件」错误,核心原因是直接把Drawable资源当成设备文件系统里的独立文件来处理是行不通的——Drawable资源是打包在APK内部的,并不是存储在设备的文件系统中,所以你通过Uri.parse("android.resource://...")创建的File对象其实指向了一个不存在的路径,自然会被判定为空文件。

下面是具体的解决步骤和修正后的代码:

核心思路

我们需要先把APK里的Drawable资源读取出来,写入到设备的临时文件中,再把这个临时文件的Uri附加到邮件Intent里。同时要适配Android 7.0及以上的版本,避免FileUriExposedException异常,推荐使用FileProvider来生成安全的文件Uri。

修正后的实现代码

首先,确保你在AndroidManifest.xml中注册了FileProvider:

<application ...>
    <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>
</application>

然后在res/xml目录下创建file_paths.xml文件(如果没有xml目录就新建一个):

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="cache_images" path="images/" />
</paths>

最后修改你的enviarCorreu方法:

public void enviarCorreu(View view) {
    EditText t = findViewById(R.id.editText);
    String email = t.getText().toString();
    Context context = this;

    // 1. 获取Drawable资源的输入流
    InputStream inputStream = getResources().openRawResource(R.drawable.face);
    File tempFile = null;

    try {
        // 2. 在缓存目录创建临时文件
        tempFile = new File(getCacheDir() + "/images/", "face.png");
        // 确保父目录存在
        if (!tempFile.getParentFile().exists()) {
            tempFile.getParentFile().mkdirs();
        }

        // 3. 将资源流写入临时文件
        FileOutputStream outputStream = new FileOutputStream(tempFile);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) > 0) {
            outputStream.write(buffer, 0, length);
        }
        outputStream.close();
        inputStream.close();

        // 4. 生成安全的文件Uri(适配Android 7.0+)
        Uri fileUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", tempFile);

        // 5. 构建邮件Intent
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.putExtra(Intent.EXTRA_EMAIL, new String[]{email});
        intent.setType("image/png"); // 指定图片类型,更精准
        intent.putExtra(Intent.EXTRA_SUBJECT, "邮件主题"); // 可自定义主题,原代码用email当主题可按需调整
        intent.putExtra(Intent.EXTRA_TEXT, "Missatge enviat de la imatge");
        // 授予Uri读取权限
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.putExtra(Intent.EXTRA_STREAM, fileUri);

        startActivity(Intent.createChooser(intent, "Enviant Correu ... "));

    } catch (IOException e) {
        e.printStackTrace();
        // 处理异常,给用户友好提示
        Toast.makeText(context, "无法准备图片,请重试", Toast.LENGTH_SHORT).show();
    } finally {
        // 可选:临时文件可在发送后删除,或依赖系统自动清理缓存
        // if (tempFile != null && tempFile.exists()) {
        //     tempFile.delete();
        // }
    }
}

关键要点说明

  • 资源转临时文件:通过openRawResource读取Drawable资源的输入流,写入到应用缓存目录的临时文件中,无需申请外部存储权限。
  • FileProvider适配:Android 7.0及以上禁止直接暴露文件Uri,使用FileProvider生成符合规范的Uri,同时添加FLAG_GRANT_READ_URI_PERMISSION授予邮件应用读取权限。
  • 异常处理:添加了IO异常捕获,避免应用崩溃,同时给用户清晰的操作反馈。

内容的提问来源于stack exchange,提问作者Gerard Zafra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:51:51