Разработка мобильных приложений на платформе 1С:Предприятие часто сталкивается с проблемой долгого определения координат. Пользователи жалуются, что при вызове функции получения местоположения программа «задумывается» на 1–2 минуты, пока мобильное устройство пытается «поймать» спутники. Это происходит из-за так называемого «холодного старта» GPS-приемника, который отключается операционной системой для экономии энергии сразу после выполнения запроса.
В этой статье мы подробно разберем, как реализовать механизм, при котором служба геопозиционирования будет работать в фоновом режиме постоянно. Это позволит приложению всегда иметь актуальные координаты «под рукой» и мгновенно возвращать их пользователю без раздражающих пауз.
Для начала выясним причину, по которой стандартный метод СредстваГеопозиционирования.ОбновитьМестоположение() вызывает зависание интерфейса. Этот метод является синхронным (или условно-синхронным с таймаутом): он принудительно активирует датчик и ждет ответа от провайдера. Если датчик был выключен, устройству требуется время на поиск спутников и расчет дистанции.
Правильный путь для мобильной платформы — переход от опроса (polling) к подписке на события. Вместо того чтобы просить координаты «здесь и сейчас», мы скажем операционной системе: «сообщай нам каждый раз, когда координаты изменятся». Для этого в 1С используется метод СредстваГеопозиционирования.ПодключитьОбработчикИзмененияМестоположения().
Чтобы сбор координат начинался сразу после запуска приложения, нам необходимо прописать вызов соответствующей процедуры в модуле управляемого приложения. Рассмотрим, как это сделать правильно, чтобы не нагружать систему лишними вызовами на стационарных ПК.
// В модуле управляемого приложения
Процедура ПриНачалеРаботыСистемы()
#Если МобильноеПриложениеКлиент Тогда
ГеопозиционированиеКлиент.ЗапуститьМониторинг();
#КонецЕсли
КонецПроцедуры
Здесь мы используем директиву препроцессора #Если МобильноеПриложениеКлиент, так как методы работы с датчиками доступны только на мобильных устройствах. Мы вызываем метод общего модуля, который возьмет на себя настройку датчиков.
Проанализируем ситуацию с провайдерами данных. В мобильных устройствах их обычно несколько: gps (высокая точность, спутники), network (средняя точность, по вышкам сотовой связи и Wi-Fi) и passive (получение координат, которые запросили другие приложения). Для стабильной работы лучше всего подключать обработчики сразу к нескольким провайдерам.
Разберем программный код в общем модуле ГеопозиционированиеКлиент (свойство «Клиент (управляемое приложение)»):
Процедура ЗапуститьМониторинг() Экспорт
СекундыНаОбновление = 30; // Интервал опроса (оптимально для автотранспорта)
МассивПровайдеров = СредстваГеопозиционирования.ПолучитьПровайдеров();
Инд = 0;
Для Каждого ТекущийПровайдер Из МассивПровайдеров Цикл
// Пассивный провайдер не требует отдельной активации в данном контексте
Если ТекущийПровайдер.Имя = "passive" Тогда
Продолжить;
КонецЕсли;
// Устанавливаем небольшое смещение времени для разных провайдеров,
// чтобы события не приходили в одну миллисекунду
ЧастотаОбновления = СекундыНаОбновление + Инд;
ОписаниеОповещения = Новый ОписаниеОповещения("ОпросКоординатЗавершение", ГеопозиционированиеКлиент);
СредстваГеопозиционирования.ПодключитьОбработчикИзмененияМестоположения(
ОписаниеОповещения,
ТекущийПровайдер.Имя,
10, // Минимальное расстояние в метрах (не слать точки, если стоим)
ЧастотаОбновления // Интервал в секундах
);
Инд = Инд + 1;
КонецЦикла;
КонецПроцедуры
Важный момент: Обратите внимание на инкремент переменной Инд. Мы добавляем её к интервалу обновления. Это делается для того, чтобы процедуры обработки данных от GPS и сети запускались асинхронно и не вызывали конфликтов при одновременной попытке записи данных в базу.
Когда устройство зафиксирует изменение координат, платформа 1С автоматически вызовет процедуру, которую мы указали в ОписаниеОповещения. Рассмотрим, что должно происходить внутри этой процедуры.
Процедура ОпросКоординатЗавершение(ИмяПровайдера, ДанныеМестоположения, ДополнительныеДанные) Экспорт
// Проверяем валидность данных
Если ДанныеМестоположения = Неопределено Тогда
Возврат;
КонецЕсли;
// Передаем данные на сервер для записи в регистр или документ
ГеопозиционированиеСервер.ЗаписатьКоординату(
ДанныеМестоположения.Широта,
ДанныеМестоположения.Долгота,
ДанныеМестоположения.Дата,
ИмяПровайдера
);
КонецПроцедуры
Поскольку процедура ОпросКоординатЗавершение выполняется на клиенте, мы должны вызвать серверный метод для сохранения данных. Рекомендуется записывать координаты в Регистр Сведений с периодичностью или в специальную таблицу для последующей отправки в центральную базу.
Проанализируем технические сложности, которые могут возникнуть на актуальных версиях Android (10+) и iOS. Даже если ваш код в 1С написан идеально, операционная система может «убить» процесс или отключить GPS при сворачивании приложения.
Для обеспечения стабильной работы в фоне придерживайтесь следующих правил:
Постоянно работающий GPS сильно расходует заряд батареи. Выясним, как сбалансировать точность и энергозатраты:
МинимальноеРасстояние в методе ПодключитьОбработчикИзмененияМестоположения. Если установить значение 50 или 100 метров, приложение не будет просыпаться и дергать сервер, пока курьер или водитель стоят на месте.Применяя данные подходы, мы добьемся того, что при повторном обращении к геоданным (например, при нажатии кнопки «Заполнить координаты» в документе), приложение мгновенно получит последнюю зафиксированную точку из памяти, не заставляя пользователя ждать завершения «холодного старта» GPS.