Рассмотрим весьма распространенную ситуацию при разработке под мобильную платформу 1С. Допустим, в нашем мобильном приложении есть справочник сотрудников или контрагентов с контактной информацией. При нажатии на адрес электронной почты ранее штатно открывался установленный на телефоне почтовый клиент (например, Gmail или Яндекс.Почта), в котором уже был заполнен адрес получателя, и пользователю оставалось лишь ввести текст и нажать кнопку отправки. Однако, проанализируем ситуацию: после обновления смартфонов до версии Android 13 (или выше) этот функционал внезапно перестал работать.
При этом метод СредстваПочты.ПоддерживаетсяОтправка() возвращает значение Истина, платформа 1С не выдает никаких ошибок, но при вызове команды запуска почтовика в ответ мы получаем тишину — приложение никак не реагирует на нажатие. Выясним причину такого поведения и разберем по шагам несколько надежных способов решения данной проблемы.
Давайте посмотрим на классический код, который отлично работал на старых версиях операционной системы Android (до 11-12 версии):
#Если МобильноеПриложениеКлиент Тогда
Сообщение = Новый ИнтернетПочтовоеСообщение;
Сообщение.Тема = "Тема письма";
Сообщение.Получатели.Добавить("адрес_получателя@domain.com");
Текст = Сообщение.Тексты.Добавить("Текст письма");
Текст.ТипТекста = ТипТекстаПочтовогоСообщения.ПростойТекст;
Поддерживается = СредстваПочты.ПоддерживаетсяОтправка();
Сообщить("Поддерживается отправка: " + Поддерживается);
СредстваПочты.Послать(Сообщение);
#КонецЕсли
Проанализируем, почему этот код перестал функционировать. Проблема кроется не в самой мобильной платформе 1С, а в ужесточении политик безопасности операционной системы Android. Начиная с 11 версии, и особенно строго в 13-й, Google изменила механизмы видимости пакетов (Package Visibility) и обработки неявных намерений (Intents). Платформа 1С «думает», что функция отправки поддерживается, отправляет системный вызов (интент) на открытие почты, но операционная система блокирует его передачу сторонним приложениям без явных разрешений.
Кроме того, современные версии почтовых программ изменили логику обработки параметров. Если просто передать команду SENDTO, некоторые почтовики открываются, но игнорируют переданную тему и текст письма. Разберем несколько вариантов обхода этих ограничений.
Рассмотрим первый подход. Если наша задача состоит не в том, чтобы дать пользователю возможность редактировать письмо в интерфейсе почтовой программы смартфона, а просто отправить сформированные данные (например, отчет или выгрузку), мы можем вообще отказаться от взаимодействия с системным почтовым клиентом. Посмотрим на пример использования объекта ИнтернетПочта.
// Формируем сообщение
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тема = "Тема нашего письма";
Письмо.Отправитель = СтруктураПодключения.АдресОтправителя;
Письмо.ИмяОтправителя = СтруктураПодключения.ИмяПользователя;
Письмо.Кодировка = "UTF-8";
Письмо.Тексты.Добавить("Текст сообщения...");
// Добавляем вложения при необходимости
Письмо.Вложения.Добавить(ИмяФайла, ИмяФайлаДанных);
Письмо.Получатели.Добавить(СтруктураПодключения.АдресПолучателя);
// Подключаемся напрямую к SMTP-серверу и отправляем
Почта = Новый ИнтернетПочта;
Почта.Подключиться(СтруктураПодключения.Подключение); // Передаем ИнтернетПочтовыйПрофиль
Почта.Послать(Письмо);
Почта.Отключиться();
Преимущества: Полная независимость от версии Android и наличия настроенного почтового клиента на телефоне.
Недостатки: Необходимо где-то хранить учетные данные для отправки (логин, пароль, адреса серверов). Если у каждого пользователя должен быть свой адрес отправителя, потребуется разработать механизм хранения профилей электронной почты.
Если нам принципиально важно открыть именно приложение электронной почты, мы можем сформировать намерение (intent) вручную, используя объект ЗапускПриложенияМобильногоУстройства. Разберем по шагам, как это сделать, учитывая, что на старых ОС метод 1С работает нормально, а на новых — требует ручного вызова.
Проанализируем пример кода с определением версии операционной системы:
#Если МобильноеПриложениеКлиент Тогда
// Получаем информацию об устройстве
СИ = Новый СистемнаяИнформация();
ВерсияОС = СИ.ВерсияОС; // Пример: "Android 13"
// Извлекаем номер версии
НомерВерсии = СокрЛП(СтрЗаменить(ВерсияОС,"Android",""));
НомерВерсииЧисло = Число(НомерВерсии);
Если НомерВерсииЧисло >= 13 Тогда
// Ручной запуск через Intent для новых версий
НовВз = Новый ЗапускПриложенияМобильногоУстройства();
НовВз.Действие = "android.intent.action.SENDTO";
НовВз.Данные = "mailto:test@test.ru";
НовВз.ДополнительныеДанные.Добавить("android.intent.extra.SUBJECT", "Тема письма");
НовВз.ДополнительныеДанные.Добавить("android.intent.extra.TEXT", "Текст письма");
НовВз.Запустить(Истина);
Иначе
// Стандартный способ для старых версий
Сообщение = Новый ИнтернетПочтовоеСообщение;
Сообщение.Тема = "Тема письма";
Сообщение.Получатели.Добавить("test@test.ru");
Текст = Сообщение.Тексты.Добавить("Текст письма");
Текст.ТипТекста = ТипТекстаПочтовогоСообщения.ПростойТекст;
СредстваПочты.Послать(Сообщение);
КонецЕсли;
#КонецЕсли
В данном варианте мы используем действие android.intent.action.SENDTO и передаем схему mailto: в свойство Данные. ОС Android понимает, что мы хотим отправить письмо, и открывает нужную программу.
Разберем подробнее более надежный метод. Вышеописанный способ с проверкой версии имеет изъян: на некоторых устройствах с Android 12 действие SENDTO может терять тему и текст письма. Чтобы избежать ветвления кода и гарантированно открыть почтовый клиент со всеми заполненными данными, разработчики мобильной платформы рекомендуют использовать комбинированный паттерн.
Суть заключается в использовании основного действия отправки и специального «селектора», который жестко ограничивает выбор программ только почтовыми клиентами. Посмотрим на этот подход:
android.intent.action.SEND (или SEND_MULTIPLE для отправки с вложениями).SENDTO и схему данных.
Запуск = Новый ЗапускПриложенияМобильногоУстройства();
Запуск.Действие = "android.intent.action.SEND";
// Передаем тему и текст в основной интент
Запуск.ДополнительныеДанные.Добавить("android.intent.extra.SUBJECT", "Тема письма");
Запуск.ДополнительныеДанные.Добавить("android.intent.extra.TEXT", "Содержимое письма");
// Создаем селектор для фильтрации только почтовых приложений
ПараметрыВыбора = Новый ПараметрыВыбораЗапускаПриложенияМобильногоУстройства();
ПараметрыВыбора.Действие = "android.intent.action.SENDTO";
ПараметрыВыбора.Данные = "mailto:test@test.ru";
// Применяем селектор к основному запуску
Запуск.УстановитьПараметрыВыбораПриложения(ПараметрыВыбора);
Запуск.Запустить(Истина);
Этот способ является наиболее предпочтительным с точки зрения архитектуры Android. Селектор заставляет систему правильно определить намерения приложения 1С и без потерь пробросить все дополнительные данные (тему и текст) в открывшееся окно почтовика.
Если мы не хотим использовать сложную структуру с селекторами, рассмотрим альтернативный вариант работы с действием SEND. Чтобы при вызове намерения операционная система не предлагала отправить наш текст в мессенджеры (Telegram, WhatsApp) или по Bluetooth, мы должны явно указать формат данных.
Для сообщений электронной почты существует специальный MIME-тип. Проанализируем следующий код:
НовВз = Новый ЗапускПриложенияМобильногоУстройства();
НовВз.Действие = "android.intent.action.SEND";
НовВз.Тип = "message/rfc822"; // Строгое указание на e-mail формат
НовВз.ДополнительныеДанные.Добавить("android.intent.extra.EMAIL", "test@test.ru"); // Массив адресов или строка
НовВз.ДополнительныеДанные.Добавить("android.intent.extra.SUBJECT", "Тема письма");
НовВз.ДополнительныеДанные.Добавить("android.intent.extra.TEXT", "Текст сообщения");
НовВз.Запустить(Истина);
Указав свойство Тип как message/rfc822, мы даем Android четкую инструкцию отфильтровать меню выбора приложений ("Share menu") и оставить там исключительно почтовые программы.
В завершение разберем самый простой и лаконичный метод, который вообще не требует работы со структурой интентов и добавления свойства ДополнительныеДанные. Мы можем сформировать готовую ссылку формата mailto со всеми встроенными параметрами.
Посмотрим на пример использования глобальной процедуры ЗапуститьПриложение():
АдресПочты = "test@test.ru";
Тема = "Отчет_за_месяц";
ТекстПисьма = "Добрый_день_направляю_отчет";
СтрокаЗапуска = "mailto:" + АдресПочты + "?subject=" + Тема + "&body=" + ТекстПисьма;
ЗапуститьПриложение(СтрокаЗапуска);
Важный нюанс: В этом случае разбором (парсингом) темы и текста занимается не механизм платформы 1С, а само почтовое приложение, которому ОС передала строку URL. Этот способ считается крайне надежным на любых версиях ОС. Однако, обратите внимание на форматирование: при формировании такой строки необходимо следить за правильным URL-кодированием (UrlEncode). Пробелы, кириллица и специальные символы (например, знак переноса строки) в переменных Тема и ТекстПисьма должны быть переведены в безопасный URL-формат, иначе ссылка может обрезаться или отработать некорректно.
Мы проанализировали причины отказа метода СредстваПочты.Послать() в Android 13 и разобрали несколько эффективных рабочих решений. В зависимости от бизнес-логики вашей задачи, вы можете выбрать прямую отправку через SMTP API (если не нужно участие пользователя), использовать правильную комбинацию системных интентов с селекторами или применить простую генерацию mailto ссылки. Использование объекта ЗапускПриложенияМобильногоУстройства дает наибольшую гибкость и позволяет максимально прозрачно интегрировать мобильную 1С с экосистемой Android.