美文网首页
Android开发--调用系统邮件

Android开发--调用系统邮件

作者: 何先生与小花匠 | 来源:发表于2019-02-01 15:14 被阅读0次

    题前语

    Android系统的开源性使其在当前智能手机市场占据绝对优势,同时也产生了各种各样的机型和系统。这使得我们Android开发人员需要根据不同的机型和系统去做对应的适配。

    正文

    本篇所述需求为调用本地邮件客户端发送带有附件的邮件。

    第一种常规调用邮件

    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setData(Uri.parse("mailto:"));
    intent.putExtra(Intent.EXTRA_EMAIL, "");
    intent.setType("text/plain");
    intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
    startActivity(Intent.createChooser(intent, "分享一下"));
    

    加载效果如下:

    ACTION_SEND.png

    我们看到第一种情况,我们标识的邮件(mailto),但是实际执行却成了分享文件,虽然其中也有邮件客户端,但是却增加了用户的操作步骤,这样的情况是产品经理不可接受的,所以我们尝试第二种方法。

    第二种使用SENDTO来试试(网上多提倡此种方式)

      Intent intent = new Intent(Intent.ACTION_SENDTO);
      intent.setData(Uri.parse("mailto:"));
      intent.putExtra(Intent.EXTRA_EMAIL, "");
      intent.setType("text/plain");
      intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
      startActivity(Intent.createChooser(intent, "分享一下"));
    

    SENDTO代码加载如下:

    ACTION_SENDTO.png

    SENDTO确实能调用邮箱客户端,但是上面的截图是“没有应用可执行此操作”。为什么说确实能调用呢,因为在有的机型上确实可以调用,但是华为平板却没有调起来。我们是不是就可以推测华为把Android系统邮箱相关标识改了呢?有兴趣的同学可以去看看华为系统的源码。既然这样的方式不行,那么我们就继续探索还有没有其他的方法。

    第三种方式SEND_MULTIPLE多附件发送

    SENDTO是发送单个附件,而SEND_MULTIPLE却是携带多个附件进行发送,下面我们来试试这一段代码执行的情况

    Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
    intent.setData(Uri.parse("mailto:"));
    intent.putExtra(Intent.EXTRA_EMAIL, "");
    intent.setType("text/plain");
    intent.putExtra(Intent.EXTRA_STREAM, list);//Uri.fromFile(file)
    startActivity(Intent.createChooser(intent, "分享一下"));
    

    多附件执行截图如下:

    ACTION_SEND_MULTIPLE.png

    我们看到这个多附件的发送同第一种情况类似,调起了系统的所有邮件客户端和蓝牙,不过我们不需要调用这么多应用,那么我们就再试试其他的方式。

    第四种直接调用应用

    相信肯定有直接能够调用某个工具软件的方式,我们直接用这种方式会不会能够达到我们想要的效果呢?我们一起来试试

     Intent intent = new Intent(android.content.Intent.ACTION_SEND);
     intent.putExtra(Intent.EXTRA_EMAIL, "");
     intent.setType("text/plain");
     intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
     intent.setClassName("com.android.email","com.android.email.activity.MessageCompose");
     startActivity(Intent.createChooser(intent, "分享一下"));
    

    直接调用执行效果截图:

    最终效果图.png

    这样看我们是不是找几个不同型号不同系统的手机,获取对应的包名和Activity就可以达到我们想要的效果呢?答案是肯定的。并且经过试用小米、红米、三星、华为、荣耀、努比亚,发现可以实现需求。因为手上没有魅族的机器所以还没有在魅族的系统上尝试过,有条件的同学可以试试,顺便告知一下。我将万分感谢。

    最终代码

    奉上最终代码,因为一个类就可以解决了,就不在放Github了。

    package com.hewc.sendmail;
    
    import android.content.Context;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Build;
    import android.os.StrictMode;
    import android.support.annotation.RequiresApi;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.TextView;
    
    import java.io.File;
    
    public class MainActivity extends AppCompatActivity {
    
    private Context context;
    private String filePath = "/storage/emulated/0/20.txt";
    
    private static final String[] NARMAL_PHONE = {"com.android.email", "com.android.email.activity.MessageCompose"};
    private static final String[] MIUI_PHONE = {"com.android.email", "com.kingsoft.mail.compose.ComposeActivity"};
    private static final String[] SAMSUNG_PHONE = {"com.samsung.android.email.provider", "com.samsung.android.email.composer.activity.MessageCompose"};
    
    
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = this;
        setContentView(R.layout.activity_main);
        // android 7.0系统解决拍照的问题
        StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
        StrictMode.setVmPolicy(builder.build());
        builder.detectFileUriExposure();
    
        TextView tv = findViewById(R.id.tv);
        tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                File file = new File(filePath);
                try {
                    Intent intent = new Intent(android.content.Intent.ACTION_SEND);
                    intent.putExtra(Intent.EXTRA_EMAIL, "");
                    intent.setType("text/plain");
                    intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
                    if (getDeviceBrand().toUpperCase().contains("HONOR") || getDeviceBrand().toUpperCase().contains("HUAWEI") || getDeviceBrand().toUpperCase().contains("NUBIA")) {
                        intent.setClassName(NARMAL_PHONE[0], NARMAL_PHONE[1]);
                    } else if (getDeviceBrand().toUpperCase().contains("XIAOMI") || getDeviceBrand().toUpperCase().contains("XIAOMI")) {
                        intent.setClassName(MIUI_PHONE[0], MIUI_PHONE[1]);
                    } else if (getDeviceBrand().toUpperCase().contains("SAMSUNG")) {
                        intent.setClassName(SAMSUNG_PHONE[0], SAMSUNG_PHONE[1]);
                    }
                    startActivity(Intent.createChooser(intent, "分享一下"));
                } catch (Exception e) {
                    e.printStackTrace();
                    Intent intent = new Intent(Intent.ACTION_SEND);
                    intent.setData(Uri.parse("mailto:"));
                    intent.putExtra(Intent.EXTRA_EMAIL, "");
                    intent.setType("text/plain");
                    intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
                    startActivity(Intent.createChooser(intent, "分享一下"));
                }
    
            }
        });
    }
    
      /**
       * 获取手机厂商
       *
       * @return 手机厂商
       */
      public static String getDeviceBrand() {
          Log.e("--获取手机厂商--:", android.os.Build.BRAND);
          return android.os.Build.BRAND;
      }
    }
    

    关于获取第三方应用Activity名称的方法:
    adb shell dumpsys activity | findstr "mFocusedActivity"

    题后语

    第一次尝试写技术文档,难免会有瑕疵,希望同学们能够积极指正。能帮到你是我的荣幸。

    相关文章

      网友评论

          本文标题:Android开发--调用系统邮件

          本文链接:https://www.haomeiwen.com/subject/hdkmdqtx.html