Отправка E-Mail средствами Android

Привет хабр и привет всем!

В данной статье я покажу как реализуется отправка писем средствами самого Android, а также ещё один более интересный способ, но уже с применением внешней библиотеки, которая позволяет нам отсылать письма более приемлимыми для программиста способами.

Часть 1. Mail, просто Mail


Как это делается: обычно в программу встраивается дополнительная Activity, которая представляет собой окошко с несколькими полями: Кому, Тема и Текст. Далее данные с этих полей передаются как экстра содержимое:
  • android.content.Intent.EXTRA_EMAIL
  • android.content.Intent.EXTRA_SUBJECT
  • android.content.Intent.EXTRA_TEXT
Специальному Intent-у: android.content.Intent.ACTION_SEND.
Сам код файла SimpleEMail.java
  1. public class SimpleEMail extends Activity {
  2.   Button send;
  3.   EditText address, subject, emailtext;
  4.   
  5.   @Override
  6.   public void onCreate(Bundle savedInstanceState) {
  7.     super.onCreate(savedInstanceState);
  8.     setContentView(R.layout.simple_email);
  9.  
  10.     // Наши поля и кнопка
  11.     send = (Button) findViewById(R.id.emailsendbutton);
  12.     address = (EditText) findViewById(R.id.emailaddress);
  13.     subject = (EditText) findViewById(R.id.emailsubject);
  14.     emailtext = (EditText) findViewById(R.id.emailtext);
  15.  
  16.     send.setOnClickListener(new OnClickListener() {
  17.  
  18.       @Override
  19.       public void onClick(View v) {
  20.  
  21.         final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
  22.  
  23.         emailIntent.setType("plain/text");
  24.         // Кому
  25.         emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
  26.             new String[] { address.getText().toString() });
  27.         // Зачем
  28.         emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,
  29.             subject.getText().toString());
  30.         // О чём
  31.         emailIntent.putExtra(android.content.Intent.EXTRA_TEXT,
  32.             emailtext.getText().toString());
  33.         // С чем
  34.         emailIntent.putExtra(
  35.             android.content.Intent.EXTRA_STREAM,
  36.             Uri.parse("file://"
  37.                 + Environment.getExternalStorageDirectory()
  38.                 + "/Клипы/SOTY_ATHD.mp4"));
  39.         
  40.         emailIntent.setType("text/video");
  41.         // Поехали!
  42.         SimpleEMail.this.startActivity(Intent.createChooser(emailIntent,
  43.             "Отправка письма..."));
  44.       }
  45.     });
  46.   }
  47. }
* This source code was highlighted with Source Code Highlighter.
Вот, код до безобразия прост. Правда можно еще проще: если нам лень создавать дополнительное Activity для ввода наших полей, то можно было бы просто запустить наш Intent.

Плюсы: Простая реализация, достаточно удобно для обратной связи.
Минусы: У пользователя должна быть настроенная программа приёма-передачи почтовых сообщений, без неё обрабатывать данный Intent будет некому.

Часть 2. Mail, анонимус Mail


Данный метод я использовал в своём проекте, обозначим для начала плюсы:
  • Не требует от пользователя настроенного клиента
  • Может быть полностью анонимным
  • Можно передавать все (в пределах разумного, конечно)
Для работы необходимы дополнительные библиотеки javamail-android.
Качаем их, и встраиваем в проект: Контекстное меню проекта > «Build Path» > «Add External Archives...» > «Наши файлы additional, mail, activation»

Для настройки нам также понадобится почтовый ящик зарегистрированный на gmail.com (или любом другом yandex, mail и.т.п.) настройки вы можете посмотреть здесь. В данном случае он будет выступать в виде шлюза через которые будут проходить наши письма.

Начинаем настраивать:
MailSenderClass.java
В данном классе записаны настройки того сервера, через который будет передаваться ваше сообщение. Здесь у нас есть несколько методов:
  • public MailSenderClass(String user, String password) — Конструктор. В качестве аргументов передаются логин и пароль от нашего промежуточного ящика на gmail.com. Здесь же прописываются параметры smtp-подключения к серверу.
  • protected PasswordAuthentication getPasswordAuthentication() — Аутентификация для сервера.
  • public synchronized void sendMail(String subject, String body, String sender, String recipients, String filename) — Основной метод, в который передаются наши данные для отправки.

Рассмотрим код последнего метода чуть ближе:
  1. public synchronized void sendMail(String subject, String body, String sender, String recipients, String filename) throws Exception {
  2.     try {
  3.       MimeMessage message = new MimeMessage(session);
  4.       
  5.       // Кто
  6.       message.setSender(new InternetAddress(sender));
  7.       // О чем
  8.       message.setSubject(subject);
  9.       // Кому
  10.       if (recipients.indexOf(',') > 0)
  11.         message.setRecipients(Message.RecipientType.TO,
  12.             InternetAddress.parse(recipients));
  13.       else
  14.         message.setRecipient(Message.RecipientType.TO,
  15.             new InternetAddress(recipients));
  16.       
  17.       // Хочет сказать
  18.       BodyPart messageBodyPart = new MimeBodyPart();
  19.       messageBodyPart.setText(body);
  20.       _multipart.addBodyPart(messageBodyPart);
  21.       
  22.       // И что показать
  23.       if (!filename.equalsIgnoreCase("")) {
  24.         BodyPart attachBodyPart = new MimeBodyPart();
  25.         DataSource source = new FileDataSource(filename);
  26.         attachBodyPart.setDataHandler(new DataHandler(source));
  27.         attachBodyPart.setFileName(filename);
  28.   
  29.         _multipart.addBodyPart(attachBodyPart);
  30.       }
  31.       
  32.       message.setContent(_multipart);
  33.       
  34.       Transport.send(message);
  35.     } catch (Exception e) {
  36.       Log.e("sendMail","Ошибка отправки функцией sendMail! ");
  37.     }
  38.   }
* This source code was highlighted with Source Code Highlighter.
Метод также прост. Используя объект класса MimeMessage составляем наше письмо и для отправки передаём методу send, класса Transport.

JSSEProvider.java
Провайдер протокола безопасности для нашей почты. Линк.

VideoSelect.java
Код был взят из ApiDemos, которые поставляются в комплекте с Android SDK, и был чуть подправлен для выполнения с помощью метода startActivityForResult.
После выполнения возвращается строка, содержащая путь к файлу на карте памяти. Код можно будет посмотреть в проекте, он в конце статьи.

ExtendedMail.java
Основной метод отправления сообщения выполняется в функции sitv_sender_mail_async, представляющей класс AsyncTask:
  1. private class sender_mail_async extends AsyncTask<Object, String, Boolean> {
  2.  ProgressDialog WaitingDialog;
  3.  @Override
  4.  protected void onPreExecute() {
  5.   // Выводим пользователю процесс загрузки
  6.   WaitingDialog = ProgressDialog.show(ExtendedMail.this, "Отправка данных", "Отправляем сообщение...", true);
  7.  }
  8.   
  9.  @Override
  10.  protected void onPostExecute(Boolean result) {
  11.   // Прячем процесс загрузки
  12.   WaitingDialog.dismiss();
  13.   Toast.makeText(mainContext, "Отправка завершена!!!", Toast.LENGTH_LONG).show();
  14.   ((Activity)mainContext).finish();
  15.  }
  16.  @Override
  17.  protected Boolean doInBackground(Object... params) {
  18.   try {
  19.    // Получаем данные с наших полей
  20.    title = ((EditText)findViewById(R.id.screen_sendnews_et_title)).getText().toString();
  21.    text = ((EditText)findViewById(R.id.screen_sendnews_et_text)).getText().toString();
  22.    
  23.    from = "from_post_msg@gmail.com";
  24.    where = "where_post_msg@yandex.ru";
  25.    
  26.    // Вызываем конструктор и передаём в него наши логин и пароль от ящика на gmail.com
  27.    MailSenderClass sender = new MailSenderClass("mypostmail@gmail.com", "password");
  28.    
  29.    // И вызываем наш метод отправки
  30.    sender.sendMail(title, text, from, where, attach);
  31.   } catch (Exception e) {
  32.    Toast.makeText(mainContext, "Ошибка отправки сообщения!", Toast.LENGTH_SHORT).show();
  33.   }
  34.   return false;
  35.  }
  36. }
* This source code was highlighted with Source Code Highlighter.
Все просто, создали экземпляр класса MailSenderClass, передали конструктору наши логин и пароль. Далее вызов метода отправки sendMail с нашими параметрами.
Асинхронный процесс состоит из трех методов onPreExecute(), doInBackground() и onPostExecute(), которые выполняются в написанной последовательности.
Для тех, кто забыл как им пользоваться вот код:
  1. public void onClick(View v) {
  2.  sender_mail_async async_sending = new sender_mail_async();
  3.  async_sending.execute();
  4. }
* This source code was highlighted with Source Code Highlighter.

Таким образом создав небольшой класс-поток, можно спокойно слать необходимую информацию от клиента к себе на ящик.

Исходный код приложения можно скачать тут.
Поделиться публикацией

Комментарии 11

    +5
    Вы шутите, да? Код на Андроиде легко декомпилируется, надёжно спрятать пароль невозможно (в конечном счёте он нужен в явном виде). Это если сниффер не сработает.

    Первый кому взбредёт это в голову зайдёт в gmail под вашим же паролем и поменяет его.
      0
      Если бы шифровать канал, да и пароль хранить в виде хэша…
      –3
      В принципе — да, если отправка сообщений прямо стоит как пунктик в меню, если же пользователю ничего не сообщать, что чего-то шлётся, да и к тому же программа бесплатная — то не факт, что и полезет. Ну и в целом ящик на gmail.com используется просто как промежуточное звено, в котором всё равно ничего нету.
      • НЛО прилетело и опубликовало эту надпись здесь
          +2
          +1 – это дает гораздо более гибкую настройку того, что вы хотите сделать. Кроме того, в подавляющем большинстве случаев вам захочется представить эту информацию в какой-то более удобной для чтения форме – например, отчет на веб-странице. Это нам как бы намекает по буквам слово х-т-т-п ;-)
            0
            Да, согласен. Насчет защиты я немного не подумал, вариант с сервером был бы более примелим в таком случае.
            0
            Как-то заголовок «Организация обратной связи с пользователем» слишком громко звучит. В статье-то рассказывается реализация отправки почты крайне сомнительным путем…
              0
              В заголовке стоило бы добавить, что отправление идет без участия серверного кода, и с этой точки раскрывать идею. А так пример будет полезен, как туториал для новичка, при изучении Андроида.
                0
                Главным образом статья рассказывает о 2-х способах программной отправки е-мейлов в Андроид. Так что более точным названием было бы что то типа «Отправка E-Mail средствами Android».
                Вот пару каментариев к статье:
                • Что же касается обратной связи, то в Андроид начиная с версии 2.2 появился стандарный механизм уведомления разработчика в случае ошибки в программе — Error Reporting:

                  Данное окно с предложением выслать репорт разработчику появляется в случае если программа выполнила недопустимую операцию или не отвечала продолжительное время.
                  Расширяя идею ручного составления письма разработчику, неплохо было бы притачить Exception Stack Trace,
                  0
                  Ctrl+Enter сработал не вовремя :(
                  продолжаю…
                  • Автоматическая скрытая отсылка е-мейлов разработчику — довольно спорный момент.
                    Скажем программа выполняет функции калькулятора, и ни интернет, ни электронная почта ей не нужны, что же видит юзер в пермишенах перед установкой программы — полный доступ к интернет, а если не дай бог еще и логи увидит — без его ведома программа отослала в фоне какой-то е-мейл — это однозначный гневный отзыв в каментах, а то и в саппорт Android Market
                  • в первую очередь, обратная связь — это каменты к вашей программе на маркете (благо в на дев страничке маркета теперь есть возможность оперативно видеть все комментарии на всех языках), во-вторых, если юзерам что то понравилось или нет, будьте уверены, письма на указанный вами е-мейл в описании программы будут идти сплошным потоком ;)
                    P.S.
                    А вот с точки зрения руководства по отсылке е-мейлов, к статье вообще никаких претензий.
                    Спасибо автору.
                    0
                    Ну сейчас в калькуляторы пихают всякую рекламу так что наличие связи с интернетом вполне нормально.
                    Название статьи сменил, наверно да, «Отправка E-Mail средствами Android» всё-таки ближе.

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое