Android 无法通过Gmail以编程方式发送带有附件的电子邮件

Android 无法通过Gmail以编程方式发送带有附件的电子邮件,android,gmail,android-support-library,Android,Gmail,Android Support Library,我正在开发一个Android应用程序,它可以编写一封带有照片附件的电子邮件,并通过第三方应用程序发送 要以编程方式撰写电子邮件,我使用IntentBuilderclass /** * Helpers to compose and send emails with 3rd party apps. */ public final class MailUtils { /** * Creates {@link Intent} and fills data to send emai

我正在开发一个Android应用程序,它可以编写一封带有照片附件的电子邮件,并通过第三方应用程序发送

要以编程方式撰写电子邮件,我使用
IntentBuilder
class

/**
 * Helpers to compose and send emails with 3rd party apps.
 */
public final class MailUtils {

    /**
     * Creates {@link Intent} and fills data to send email with 3rd party application.
     *
     * @param activity
     * @param photoUris list of photo URIs which can be accessed with {@link android.support.v4.content.FileProvider}
     * @param requestCode to filter results in {@link Activity#onActivityResult(int, int, Intent)}
     */
    public static void sendMail(Activity activity, List<Uri> photoUris, int requestCode) {
        final ShareCompat.IntentBuilder intentBuilder = ShareCompat.IntentBuilder.from(activity)
                .setType("text/html")
                .setChooserTitle("Choose application to send email")
                .addEmailTo("someone@anywhere.com")
                .addEmailCc("someone.else@anywhere.com")
                .setSubject("This is subject")
                .setHtmlText("Hello, world!");
        if (photoUris != null) {
            for (Uri photoUri : photoUris) {
                intentBuilder.addStream(photoUri); // add photo attachment
            }
        }
        if (activity.getPackageManager().resolveActivity(intentBuilder.getIntent(), 0) != null) {
            final Intent intent = intentBuilder.createChooserIntent();
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            activity.startActivityForResult(intent, requestCode);
        } else {
            Toast.makeText(activity, "Email app not found", Toast.LENGTH_LONG).show();
        }
    }
}
/**
*使用第三方应用撰写和发送电子邮件的助手。
*/
公共最终类MailUtils{
/**
*创建{@link Intent}并填充数据以使用第三方应用程序发送电子邮件。
*
*@param活动
*@param photoUris可通过{@link android.support.v4.content.FileProvider}访问的照片URI列表
*@param requestCode在{@link Activity#onActivityResult(int,int,Intent)}中过滤结果
*/
公共静态void sendMail(活动、列表照片URI、int requestCode){
最终ShareCompat.IntentBuilder IntentBuilder=ShareCompat.IntentBuilder.from(活动)
.setType(“文本/html”)
.setChooserTitle(“选择要发送电子邮件的应用程序”)
.addEmailTo(”someone@anywhere.com")
.addEmailCc(“某人。else@anywhere.com")
.setSubject(“本主题”)
.setHtmlText(“你好,世界!”);
if(photoUris!=null){
for(Uri photoUri:photoUri){
intentBuilder.addStream(photoUri);//添加照片附件
}
}
if(activity.getPackageManager().resolveActivity(intentBuilder.getIntent(),0)!=null){
final-Intent=intentBuilder.createchooserentent();
intent.addFlags(intent.FLAG\授予\读取\ URI\权限);
addFlags(intent.FLAG\u GRANT\u WRITE\u URI\u权限);
activity.startActivityForResult(意图、请求代码);
}否则{
Toast.makeText(活动,“未找到电子邮件应用程序”,Toast.LENGTH_LONG.show();
}
}
}
错误通知

Gmail只发送电子邮件文本,但跳过附件。这个问题只在Gmail上存在。其他电子邮件应用程序(例如,OutlookYahoo)都能正常工作

注意:在我的案例中,照片附件的大小通常小于10MB

为了解决这个问题,我尝试将照片压缩到单个ZIP存档中,但结果几乎相同。它适用于5-10张压缩照片,但不适用于10张以上的照片

在设备上测试

  • LG Nexus 4(果冻豆
    4.2.2
    ,Gmail
    6.11.27…
  • LG Nexus 5X(牛轧糖
    7.1.2
    ,Gmail
    7.3.26…
  • 三星Galaxy Note 4(棉花糖
    6.0.1
    ,Gmail
    7.3.26…

当您附加文件时,需要一些时间才能用邮件附加,因此您必须使用AsyncTask执行操作。请尝试此代码,它适用于Gmail,也适用于7.0操作系统

private class attachMailProcess extends AsyncTask<Void, Void, Void>
{
    protected void onPreExecute()
    {
        // Progress visibility Visible
    }

    protected Void doInBackground(Void... param)
    {
        YourActivity.this.runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                File file = // Get your file here.
                if (file.exists()) {
                    Uri path = Uri.fromFile(file);
                    Intent i = new Intent(Intent.ACTION_SEND);
                    i.setType("message/rfc822");
                    i.putExtra(Intent.EXTRA_EMAIL, new String[]{"Your email"});
                    i.putExtra(Intent.EXTRA_SUBJECT, "Your Subject");
                    i.putExtra(Intent.EXTRA_TEXT, "Your body text");
                    i.putExtra(Intent.EXTRA_STREAM, path);
                    try {
                        startActivity(Intent.createChooser(i,"Email Chooser"));
                        // Progress visibility gone
                    } catch (android.content.ActivityNotFoundException ex) {
                        // Progress visibility gone
                        Toast.makeText(NewRoundActivity.this, "No Email client found", Toast.LENGTH_SHORT).show();
                    }
                } else {
                    //File not found
                }
            }
        });
        return null;
    }

    protected void onPostExecute(Void result) {
        // Progress visibility gone
    }
}
私有类attachMailProcess扩展异步任务
{
受保护的void onPreExecute()
{
//进度可见性可见
}
受保护的Void doInBackground(Void…参数)
{
YourActivity.this.rununuithread(new Runnable())
{
@凌驾
公开募捐
{
File=//在这里获取您的文件。
if(file.exists()){
Uri路径=Uri.fromFile(文件);
意向i=新意向(意向.行动\发送);
i、 setType(“消息/rfc822”);
i、 putExtra(Intent.EXTRA_EMAIL,新字符串[]{“您的电子邮件”});
i、 putExtra(Intent.EXTRA_SUBJECT,“您的主体”);
i、 putExtra(Intent.EXTRA_TEXT,“你的身体文本”);
i、 putExtra(Intent.EXTRA_流、路径);
试一试{
startActivity(Intent.createChooser(即“电子邮件选择器”);
//进度可见性消失
}捕获(android.content.ActivityNotFoundException ex){
//进度可见性消失
Toast.makeText(NewRoundActivity.this,“未找到电子邮件客户端”,Toast.LENGTH_SHORT.show();
}
}否则{
//找不到文件
}
}
});
返回null;
}
受保护的void onPostExecute(void结果){
//进度可见性消失
}
}

正如OP在评论中提到的,我认为这里的答案是使用文件提供者临时授予对要附加的文件的访问权限。可以在此处找到详细信息:


我还发现本教程很有用:。

这里也有同样的问题。你找到解决办法了吗?柏林方面的问候,Germany@RicoHerlt是的,我找到了解决办法。最初我使用
FileProvider
从应用程序目录(位于
context.getfiledir()
context.getCacheDir()
)附加照片。现在,所有照片都存储在设备的图库中,我在构建
意图时使用它的URI。希望能有帮助。