【问题标题】:How to send emails from my app using a Gmail account?如何使用 Gmail 帐户从我的应用程序发送电子邮件?
【发布时间】:2019-04-05 14:27:54
【问题描述】:

我正在尝试从应用程序发送电子邮件。

问题是由于位置不寻常,Gmail 不允许我进行身份验证 - 当然,每个应用程序都安装在其他位置。

我的代码(使用 Javax):

    Properties props = new Properties();
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.starttls.enable", "true");
    props.put("mail.smtp.host", SMTP_SERVER);
    props.put("mail.smtp.port", PORT);

    Session session = Session.getInstance(props,
            new javax.mail.Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(USERNAME, new StringBuilder(PASSWORD).toString());
                }
            });

该代码在我的测试设备上运行良好,但在其他使用我的应用程序时崩溃。

我得到的错误: javax.mail.AuthenticationFailedException: 534-5.7.14 请通过 534-5.7.14 登录您的网络浏览器,然后重试。 534-5.7.14 了解更多信息,请致电 534 5.7.14 https://support.google.com/mail/answer/78754l9-v6sm11531942wrf.4 - gsmtp

我尝试了所有找到的解决方案,但无济于事。

“允许不太安全的应用”和“解锁显示卡”的解决方案 - 没有帮助

我也尝试打开 2FA 并使用从谷歌生成的 AppPassword 进行身份验证 - 没有帮助。

有什么线索吗?

【问题讨论】:

    标签: android authentication gmail jakarta-mail


    【解决方案1】:

    在你的代码中使用 Intent 代替属性

      Intent emailIntent = new Intent(Intent.ACTION_SEND);      
      emailIntent.setData(Uri.parse("mailto:"));
      emailIntent.setType("text/plain");
      emailIntent.putExtra(Intent.EXTRA_EMAIL, TO);
      emailIntent.putExtra(Intent.EXTRA_CC, CC);
      emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Your subject");
      emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message goes here");
    

    一年前我用过这个代码,看看这个

    【讨论】:

    • 但这不会从用户在其设备中注册的电子邮件帐户(如果有)发送电子邮件吗?我想使用我的 gmail 帐户发送电子邮件 - 运行我的应用程序的所有设备上的相同帐户。
    • 在您的应用中嵌入您的 Gmail 帐户凭据可能是个坏主意。
    【解决方案2】:

    您必须为此使用GMailSender

    将此添加到您要发送邮件的活动中

    我正在使用订阅,所以我把它放在AlertDialog

        @OnClick({R.id.btn_newsLetter_ok, R.id.btn_newsLetter_cancel})
        public void onClick(View view) {
            switch (view.getId()) {
                case R.id.btn_newsLetter_ok:
    
                    email = etNewsLetterEmail.getText().toString().trim();
                    if (email.isEmpty()|| !android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
                        Toast.makeText(context, "please enter a valid email address!!", Toast.LENGTH_SHORT).show();
    
                    }
                    else if(NetworkManager.isNetworkAvailable(context)){
                        try {
                            mailBody = mailBody.replace("@email",email);
    
    
                            sender = new GMailSender("yourEmail@gmail.com", "yourPassword");
    
                            StrictMode.setThreadPolicy(policy);
                            new MyAsyncClass().execute();
    
    
    
                        } catch (Exception ex) {
    
                            Toast.makeText(context, ex.toString(), Toast.LENGTH_SHORT).show();
    
                        }
                        dismiss();
                    }
                    break;
                case R.id.btn_newsLetter_cancel:
                    dismiss();
                    break;
            }
        }
    
        public class MyAsyncClass extends AsyncTask<Void, Void, Void> {
    
    
    
            ProgressDialog pDialog;
    
    
    
            @Override
    
            protected void onPreExecute() {
    
                super.onPreExecute();
    
    
    
                pDialog = new ProgressDialog(context);
    
                pDialog.setMessage("Please wait...");
    
                pDialog.show();
    
    
    
            }
    
    
    
            @Override
    
            protected Void doInBackground(Void... mApi) {
    
                try {
    
                    // Add subject, Body, your mail Id, and receiver mail Id.
    
    
                    sender.sendMail("hi kevin",  mailBody, "from@gmail.com", "to@gmail.com");
    
                }
    
    
    
                catch (Exception ex) {
    
    
    
                }
    
                return null;
    
            }
    
    
    
            @Override
    
            protected void onPostExecute(Void result) {
    
                super.onPostExecute(result);
    
                pDialog.cancel();
    
                Toast.makeText(context, "Email send", Toast.LENGTH_SHORT).show();
            }
    
        }
    

    创建一个名为 GMailSender 的 java 文件并粘贴它

    public class GMailSender extends javax.mail.Authenticator {
    
    private String mailhost = "smtp.gmail.com";
    
    private String user;
    
    private String password;
    
    private Session session;
    
    
    
    static {
    
        Security.addProvider(new JSSEProvider());
    
    }
    
    
    
        public GMailSender(final String user, final String password) {
    
            this.user = user;
    
            this.password = password;
    
    
    
            Properties props = new Properties();
    
            props.setProperty("mail.transport.protocol", "smtp");
    
            props.setProperty("mail.host", mailhost);
    
            props.put("mail.smtp.auth", "true");
    
            props.put("mail.smtp.port", "465");
    
            props.put("mail.smtp.socketFactory.port", "465");
    
            props.put("mail.smtp.socketFactory.class",
    
                    "javax.net.ssl.SSLSocketFactory");
    
            props.put("mail.smtp.socketFactory.fallback", "false");
    
            props.put("mail.smtp.starttls.enable", "true");
    
    
    
            props.setProperty("mail.smtp.quitwait", "false");
    
            session = Session.getInstance(props, new javax.mail.Authenticator() {
    
                protected PasswordAuthentication getPasswordAuthentication() {
    
                    return new PasswordAuthentication(user, password);
    
                }
    
            });
    
            session = Session.getDefaultInstance(props, this);
    
        }
    
    
    
        protected PasswordAuthentication getPasswordAuthentication() {
    
            return new PasswordAuthentication(user, password);
    
        }
    
    
    
        public synchronized void sendMail(String subject, String body,
    
                                          String sender, String recipients) throws Exception {
    
            MimeMessage message = new MimeMessage(session);
    
            DataHandler handler = new DataHandler(new ByteArrayDataSource(
    
                    body.getBytes(), "text/plain"));
    
            message.setSender(new InternetAddress(sender));
    
            message.setSubject(subject);
    
            message.setDataHandler(handler);
    
    
    
            if (recipients.indexOf(',') > 0)
    
                message.setRecipients(Message.RecipientType.TO,
    
                        InternetAddress.parse(recipients));
    
            else
    
                message.setRecipient(Message.RecipientType.TO, new InternetAddress(
    
                        recipients));
    
            Transport.send(message);
    
        }
    
    
    
        public class ByteArrayDataSource implements DataSource {
    
            private byte[] data;
    
            private String type;
    
    
    
            public ByteArrayDataSource(byte[] data, String type) {
    
                super();
    
                this.data = data;
    
                this.type = type;
    
            }
    
    
    
            public ByteArrayDataSource(byte[] data) {
    
                super();
    
                this.data = data;
    
            }
    
    
    
            public void setType(String type) {
    
                this.type = type;
    
            }
    
    
    
            public String getContentType() {
    
                if (type == null)
    
                    return "application/octet-stream";
    
                else
    
                    return type;
    
            }
    
    
    
            public InputStream getInputStream() throws IOException {
    
                return new ByteArrayInputStream(data);
    
            }
    
    
    
            public String getName() {
    
                return "ByteArrayDataSource";
    
            }
    
    
    
            public OutputStream getOutputStream() throws IOException {
    
                throw new IOException("Not Supported");
    
            }
    
        }
    
    }  
    

    创建另一个名为 JESSEProvider 的类并粘贴它

        public class JSSEProvider extends Provider {
    
        public JSSEProvider() {
    
            super("HarmonyJSSE", 1.0, "Harmony JSSE Provider");
    
            AccessController
    
                    .doPrivileged(new java.security.PrivilegedAction<Void>() {
    
                        public Void run() {
    
                            put("SSLContext.TLS","org.apache.harmony.xnet.provider.jsse.SSLContextImpl");
    
                            put("Alg.Alias.SSLContext.TLSv1", "TLS");
    
                            put("KeyManagerFactory.X509","org.apache.harmony.xnet.provider.jsse.KeyManagerFactoryImpl");
    
                            put("TrustManagerFactory.X509","org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl");
    
                            return null;
    
                        }
    
                    });
    
        }
    
    }  
    

    如果我忘记了什么,请告诉我。

    【讨论】:

      【解决方案3】:

      对于任何感兴趣的人,没有解决方案有效。由于额外的安全性(没有禁用此选项的选项),Gmail 只是拒绝允许不同的位置登录。 我转而使用其他电子邮件提供商。使用相同的代码不再有问题。

      【讨论】:

        猜你喜欢
        • 2012-03-30
        • 2012-05-25
        • 2011-03-08
        • 1970-01-01
        • 2017-08-05
        • 2013-03-24
        • 1970-01-01
        • 2019-06-21
        • 2014-02-02
        相关资源
        最近更新 更多