Как отправлять электронные письма из моего приложения, используя учетную запись Gmail? - PullRequest
0 голосов
/ 01 ноября 2018

Я пытаюсь отправить электронную почту из приложения.

Проблема в том, что 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/78754 l9-v6sm11531942wrf.4 - gsmtp

Я попробовал все найденные решения, но безрезультатно.

Решение с «Разрешить менее безопасные приложения» и «Разблокировать дисплей catcha» - не помогло

Также я попытался включить 2FA и аутентификацию с помощью AppPassword, сгенерированного из Google - не помогло.

Есть подсказка?

Ответы [ 3 ]

0 голосов
/ 01 ноября 2018

Вы должны использовать 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();
        }

    }

создайте Java-файл с именем GMailSender и вставьте

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;

                    }

                });

    }

}  

если я что-то забыл, скажи мне.

0 голосов
/ 21 декабря 2018

Для всех, кто не заинтересован, решение не работает. Gmail просто отказался разрешить вход в разные места из-за дополнительной безопасности (без возможности отключить это). Я переехал, чтобы использовать другой поставщик электронной почты. Больше нет проблем с тем же кодом.

0 голосов
/ 01 ноября 2018

Вместо использования свойств используйте Intents в вашем коде

  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");

Я использовал этот код год назад, просто зацените

...