среда, 23 ноября 2016 г.

Отправка письма с html кодом через Интент

Задача:
Отправить Email содержащий html код через Intent.
  • Получателей может быть более 1.
  • Сообщение может содержать как обычный текст, так и html, например:
'Hello! How are you?
<a href="https://www.google.com/">Google</a>'
Внимание. Код из заметки не гарантирует корректную работу со всеми почтовыми клиентами. Протестировано на GMail.

Update 20.03.17. Все способы отправки HTML перестали работать в GMail начиная с версии 6.11.2 по текущую 7.2.26. Ходит информация, что Google выпилил данный функционал из приложения.


Начнём с общих шагов.
Нам необходимо создать интент в котором указать Получателей, Тему сообщения, Сообщение. Далее, на основе созданного интента вызвать диалог выбора приложения для отправки сообщения.


Константы для определения типа действия:

ACTION_SEND — позволяет подобрать приложения на основе MIME-типа
Обязательно указываем MIME-тип. Для почтовых сообщений он может быть таким: 'text/plain', '*/*'

ACTION_SENDTO — позволяет подобрать приложения, которые поддерживают определённую схему данных
Обязательно указываем схему данных. Для почтовых сообщений это: 'mailto:'

Самая главная подзадача: Встроить html код в сообщение. Возможно кто-то уже полез в справку и нашёл там константу EXTRA_HTML_TEXT. К сожалению, у меня она не заработала. Приложения просто игнорировали связанный с ней текст. Так что мы пойдём другим путём, через класс HTML.


Общие юниты:
uses
  Androidapi.JNI.JavaTypes, FMX.Helpers.Android, Androidapi.JNI.GraphicsContentViewText,
  Androidapi.Helpers, Androidapi.JNI.text.Html, Androidapi.JNI.Net, Androidapi.JNI.App;


Как видите, в uses есть нестандартный модуль "Androidapi.JNI.text.Html". Утилита для генерации обёрток косячная, поэтому пришлось вносить правки самостоятельно. Файл есть в архиве с исходниками, действителен для АПИ 19.

Общее описание кода:
1) Создаём Интент
2) Указываем тип или схему данных
3) Указываем «Получателей» (EXTRA_EMAIL)
4) Указываем «Тему Сообщения» (EXTRA_SUBJECT)
5) Указываем «Текст Сообщения» (EXTRA_TEXT) пропустив через функцию fromHtml
6) Вызываем диалог выбора приложения (можно задать заголовок диалога, в данном случае я написал 'Send Email').

Как обычно исходники в конце заметки.

Вот так выглядит моё тестовое приложение:



ACTION_SEND или ищем все подходящие приложения.
procedure TForm2.Button1Click(Sender: TObject);
var
  Addresses: string;
  MessageSubject, MessageBody: JString;
  EmailIntent: JIntent;
  EmailHtmlText: JSpanned;
begin
  Addresses := Edit1.text;
  MessageSubject := StringToJString(Edit2.text);
  MessageBody := StringToJString(Memo1.text);

  EmailIntent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_SEND);
  EmailIntent.setType(StringToJString('text/plain'));

  EmailIntent.putExtra(TJIntent.JavaClass.EXTRA_EMAIL, CreateJavaStringArray([Addresses]));
  EmailIntent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, MessageSubject);

  EmailHtmlText := TJHtml.JavaClass.fromHtml(MessageBody);
  EmailIntent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, EmailHtmlText);

  TAndroidHelper.Activity.startActivity(TJIntent.JavaClass.createChooser(EmailIntent,
    StrToJCharSequence('Send Email')));
end;

Результат работы:


ACTION_SENDTO или ищем все почтовые приложения
procedure TForm2.Button2Click(Sender: TObject);
var
  Addresses: string;
  MessageSubject, MessageBody: JString;
  EmailIntent: JIntent;
  EmailHtmlText: JSpanned;
begin
  Addresses := Edit1.text;
  MessageSubject := StringToJString(Edit2.text);
  MessageBody := StringToJString(Memo1.text);

  EmailIntent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_SENDTO);
  EmailIntent.setData(StrToJURI('mailto:'));

  EmailIntent.putExtra(TJIntent.JavaClass.EXTRA_EMAIL, CreateJavaStringArray([Addresses]));
  EmailIntent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, MessageSubject);

  EmailHtmlText := TJHtml.JavaClass.fromHtml(MessageBody);
  EmailIntent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, EmailHtmlText);

  TAndroidHelper.Activity.startActivity(TJIntent.JavaClass.createChooser(EmailIntent,
    StrToJCharSequence('Send Email')));
end;

Результат работы:


После выбора Gmail:

Вот и всё.

Исходники: Скачать с Google Drive

1 комментарий:

  1. Собственно как создать ТОЛЬКО сервис и запустить на андроиде? при попытке запуска:install_failed_dexopt
    Т.е. необходимо создать только сервис, а не приложение, которое будет запускать сервис
    Почему-то не создается файл classes.dex
    Или как хотя бы использовать создание приложения через JAVA,MainActivity, т.к. он удовлетворяет моим условиям(не создаёт иконки,формы и тп и тд)
    //Delphi Xe 10

    ОтветитьУдалить