Разработка для мобильных устройств на платформе 1С требует понимания специфики работы операционных систем Android и iOS. Одной из часто возникающих проблем в релизах ветки 8.3.6 является работа с механизмом локальных уведомлений. Разберем подробно, почему уведомления могут не появляться, как правильно настроить часовые пояса и какие нюансы следует учитывать при написании кода.
Для начала проанализируем ситуацию: разработчики часто сталкиваются с тем, что код, успешно работавший в одном релизе, перестает функционировать в следующем. В мобильной платформе 1С объект ДоставляемоеУведомление предназначен для создания сообщений, которые отображаются пользователю непосредственно на мобильном устройстве без участия внешнего Push-сервера. Основная сложность заключается в том, что платформа предъявляет строгие требования к формату даты появления уведомления и состоянию самого приложения.
Одной из главных причин отсутствия уведомлений является некорректная установка времени срабатывания. Мобильная платформа 1С ожидает, что в свойство ДатаПоявленияУниверсальноеВремя будет передано время в формате UTC (Universal Time Coordinated). Если вы передаете текущее время устройства, которое отличается от UTC на несколько часов, система может посчитать, что уведомление должно было сработать «в прошлом», и проигнорирует его.
Рассмотрим правильный подход к формированию даты срабатывания. Нам необходимо вычислить разницу между локальным временем и UTC. Посмотрим на пример кода, который решает эту задачу:
&НаКлиенте
Процедура ОтправитьУведомление()
#Если МобильноеПриложениеКлиент Тогда
Уведомление = Новый ДоставляемоеУведомление;
Уведомление.Заголовок = "Напоминание";
Уведомление.Текст = "Проверьте новые заявки в системе";
// Используем встроенную функцию для получения UTC
ДатаПоявленияУТВ = УниверсальноеВремя(ТекущаяДата());
Уведомление.ДатаПоявленияУниверсальноеВремя = ДатаПоявленияУТВ;
Уведомление.ЗвуковоеОповещение = ЗвуковоеОповещение.ПоУмолчанию;
ДоставляемыеУведомления.ДобавитьЛокальноеУведомление(Уведомление);
#КонецЕсли
КонецПроцедуры
В некоторых случаях, особенно в старых релизах, функция УниверсальноеВремя на клиенте может работать нестабильно. Рекомендуем вычислять это значение на стороне сервера. Проанализируем следующий пример:
&НаСервере
Функция ПолучитьДатаПоявленияУниверсальноеВремяНаСервере(Срок)
Возврат УниверсальноеВремя(Срок);
КонецФункции
&НаКлиенте
Процедура СоздатьУведомление(Заголовок, Текст)
Уведомление = Новый ДоставляемоеУведомление;
Уведомление.Заголовок = Заголовок;
Уведомление.Текст = Текст;
// Получаем корректное время с сервера
Уведомление.ДатаПоявленияУниверсальноеВремя = ПолучитьДатаПоявленияУниверсальноеВремяНаСервере(ТекущаяДата());
Уведомление.ЗвуковоеОповещение = ЗвуковоеОповещение.ПоУмолчанию;
ДоставляемыеУведомления.ДобавитьЛокальноеУведомление(Уведомление);
КонецПроцедуры
Важно понимать фундаментальное ограничение: если мобильное приложение 1С открыто и является активным в данный момент, системное уведомление в «шторке» (трее) мобильного устройства не появится. Это штатное поведение платформы. В этом случае срабатывает событие модуля управляемого приложения ПриПолученииУведомления.
Чтобы пользователь увидел уведомление, необходимо либо свернуть приложение, либо программно обработать его получение внутри 1С. Разберем, как это реализовать в модуле управляемого приложения:
Процедура ПриПолученииУведомления(Уведомление, Локальное, Показано) Экспорт
Если Локальное Тогда
// Если приложение активно, просто выводим сообщение пользователю
ПоказатьОповещениеПользователя("Новое событие", , Уведомление.Текст);
КонецЕсли;
КонецПроцедуры
Важный момент: если вы тестируете уведомления, обязательно сворачивайте приложение кнопкой "Home" сразу после вызова кода добавления уведомления. Только тогда вы увидите стандартный баннер операционной системы.
При необходимости отправить несколько уведомлений подряд (например, по списку новых задач), разработчики сталкиваются с тем, что доходит только одно или уведомления пропадают вовсе. Это связано с тем, что операционная система Android может группировать или перезаписывать уведомления, если они поступают слишком быстро с одинаковыми параметрами.
Выясним причину: в старых версиях платформы 8.3.6 отсутствовала возможность явно задать уникальный идентификатор для каждого уведомления. В качестве обходного пути можно использовать небольшую задержку в цикле, хотя это и не является «чистым» решением. Рассмотрим пример реализации такой паузы:
Для Каждого СтрокаТЧ Из ТаблицаЗадач Цикл
#Если МобильноеПриложениеКлиент Тогда
Текст = "Задача: " + СтрокаТЧ.Наименование;
ДатаУведомления = УниверсальноеВремя(ТекущаяДата());
Уведомление = Новый ДоставляемоеУведомление;
Уведомление.Текст = Текст;
Уведомление.ДатаПоявленияУниверсальноеВремя = ДатаУведомления;
ДоставляемыеУведомления.ДобавитьЛокальноеУведомление(Уведомление);
// Искусственная пауза для корректной регистрации в ОС
КонДата = ТекущаяДата() + 1; // Задержка в 1 секунду
Пока ТекущаяДата() < КонДата Цикл
// Пустой цикл ожидания
КонецЦикла;
#КонецЕсли
КонецЦикла;
В релизе 8.3.6.182 пользователи часто жаловались на работу в Android 5.0 (Lollipop). Это связано с изменением политики безопасности Google. Для того чтобы уведомления приходили стабильно, проверьте следующие настройки:
Подведем итог нашему анализу. Чтобы локальные уведомления в 1С работали гарантированно, придерживайтесь следующих правил:
УниверсальноеВремя() для установки даты появления.ПриПолученииУведомления в модуле управляемого приложения.AlarmManager.Используя предложенные методы, вы сможете настроить надежную систему оповещения пользователей в вашем мобильном приложении на базе 1С:Предприятие.