При разработке мобильных решений на платформе 1С часто возникает задача сбора геоданных курьеров, торговых представителей или сервисных инженеров. Однако при обращении к спутниковому модулю разработчики регулярно сталкиваются с ситуацией, когда обработчики координат просто не срабатывают или вызывают системные ошибки. Выясним причину такого поведения, разберем штатные механизмы платформы для проверки состояния геолокации и научимся безошибочно настраивать отслеживание местоположения устройства.
Рассмотрим типовую ошибку, с которой сталкиваются при вызове метода ПодключитьОбработчикИзмененияМестоположения глобального объекта СредстваГеопозиционирования. Нередко в коде пытаются передать имя экспортной процедуры в виде обычной строки:
// Ошибочный вариант вызова:
СредстваГеопозиционирования.ПодключитьОбработчикИзмененияМестоположения("ПериодическийОтловГПСДанных", "gps", , 30);
При выполнении такой конструкции мобильное приложение падает с ошибкой: «Недопустимое значение параметра (параметр номер 1)». В управляемом интерфейсе мобильной платформы 1С первым параметром метода обязательно должен выступать объект ОписаниеОповещения, а не строковый литерал.
Вторая распространенная проблема заключается в несоответствии сигнатуры вызываемой процедуры. Экспортная процедура, обрабатывающая новые координаты, не может быть процедурой без параметров. Платформа передает в нее данные о текущих координатах и контекст выполнения. Если объявить процедуру без аргументов, среда выполнения не сможет ее вызвать, и обработчик будет проигнорирован.
Третья скрытая проблема — физическое состояние служб геолокации на устройстве Android. Если модуль GPS отключен пользователем в шторке быстрых настроек смартфона, обработчик местоположения подключается без исключений, однако события обновления координат никогда не поступят в приложение.
Разберем, как проверить доступность геолокации до запуска механизмов слежения, чтобы вовремя уведомить пользователя о необходимости включить датчик. В платформе 1С предусмотрено несколько встроенных механизмов:
ИспользованиеДанныхГеопозиционированияВключено(). Возвращает значение типа Булево. Позволяет мгновенно узнать, включена ли общая служба геолокации в операционной системе смартфона.ПолучитьПровайдера("gps", Истина) возвращает объект ИнформацияПровайдераГеопозиционирования, только если аппаратный модуль GPS действительно активен. Если модуль отключен, метод вернет Неопределено.Доступен. У любого полученного объекта провайдера можно проверить булево свойство Доступен, отражающее его готовность к работе в данный момент.Посмотрим на пример комплексной функции, которая выполняет корректную проверку перед началом работы:
&НаКлиенте
Функция МодульGPSВключен() Экспорт
#Если МобильноеПриложениеКлиент Тогда
// 1. Проверяем, включены ли службы геолокации в системе в целом
Если Не СредстваГеопозиционирования.ИспользованиеДанныхГеопозиционированияВключено() Тогда
Возврат Ложь;
КонецЕсли;
// 2. Проверяем доступность именно аппаратного провайдера GPS
ПровайдерGPS = СредстваГеопозиционирования.ПолучитьПровайдера("gps", Истина);
Если ПровайдерGPS = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Возврат ПровайдерGPS.Доступен;
#Иначе
Возврат Ложь;
#КонецЕсли
КонецФункции
Политики безопасности мобильной операционной системы Android запрещают сторонним приложениям принудительно и скрытно активировать модуль спутниковой навигации. Если проверка показала, что геолокация отключена, правильным решением будет открыть системное окно настроек местоположения с помощью специального намерения (Intent).
Проанализируем пример кода с использованием объекта ЗапускПриложенияМобильногоУстройства:
&НаКлиенте
Процедура ПредложитьВключитьГеолокацию()
#Если МобильноеПриложениеКлиент Тогда
ПоказатьПредупреждение(, "Для корректной работы приложения необходимо включить GPS в настройках устройства.");
// Открываем системный раздел настроек местоположения Android
ЗапускНастроек = Новый ЗапускПриложенияМобильногоУстройства("android.settings.LOCATION_SOURCE_SETTINGS");
Если ЗапускНастроек.Поддерживается() Тогда
ЗапускНастроек.Запустить();
КонецЕсли;
#КонецЕсли
КонецПроцедуры
Разберем по шагам реализацию обработчика местоположения в форме мобильного приложения. Учтем правильную инициализацию ОписаниеОповещения и корректный прием входящих параметров с координатами.
&НаКлиенте
Процедура ПриОткрытии(Отказ)
#Если МобильноеПриложениеКлиент Тогда
Если Не МодульGPSВключен() Тогда
ПредложитьВключитьГеолокацию();
Возврат;
КонецЕсли;
// Назначаем обработчик с интервалом обновления в 30 секунд
ОповещениеКоординат = Новый ОписаниеОповещения("ОбработкаИзмененияКоординат", ЭтотОбъект);
// Параметры: Оповещение, ИмяПровайдера, Расстояние (м), Период (сек)
СредстваГеопозиционирования.ПодключитьОбработчикИзмененияМестоположения(
ОповещениеКоординат,
"gps",
1,
30
);
#КонецЕсли
КонецПроцедуры
&НаКлиенте
Процедура ОбработкаИзмененияКоординат(Местоположение, ДополнительныеПараметры) Экспорт
#Если МобильноеПриложениеКлиент Тогда
Если Местоположение = Неопределено Тогда
Возврат;
КонецЕсли;
// Получаем параметры геопозиции
Широта = Местоположение.Координаты.Широта;
Долгота = Местоположение.Координаты.Долгота;
Точность = Местоположение.Координаты.Точность;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = СтрШаблон("Получены координаты: %1, %2 (погрешность: %3 м)", Широта, Долгота, Точность);
Сообщение.Сообщить();
#КонецЕсли
КонецПроцедуры
&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)
#Если МобильноеПриложениеКлиент Тогда
// Обязательно отключаем обработчик при выходе из формы для экономии заряда батареи
СредстваГеопозиционирования.ОтключитьОбработчикИзмененияМестоположения();
#КонецЕсли
КонецПроцедуры
Пользователь может включить или выключить геопозиционирование прямо во время работы с мобильным клиентом через верхнюю панель уведомлений. Чтобы интерфейс динамически реагировал на эти действия без перезапуска формы, подключим специальный обработчик доступности провайдеров:
&НаКлиенте
Процедура ПодключитьМониторингСтатусаПровайдеров()
#Если МобильноеПриложениеКлиент Тогда
ОповещениеСтатуса = Новый ОписаниеОповещения("ОбработкаИзмененияДоступностиПровайдеров", ЭтотОбъект);
СредстваГеопозиционирования.ПодключитьОбработчикИзмененияДоступностиПровайдеров(ОповещениеСтатуса);
#КонецЕсли
КонецПроцедуры
&НаКлиенте
Процедура ОбработкаИзмененияДоступностиПровайдеров(ИмяПровайдера, Доступен, ДополнительныеПараметры) Экспорт
#Если МобильноеПриложениеКлиент Тогда
Если ИмяПровайдера = "gps" И Не Доступен Тогда
ПоказатьОповещениеПользователя("Внимание", , "Спутниковый модуль GPS отключен! Запись трека приостановлена.");
КонецЕсли;
#КонецЕсли
КонецПроцедуры
ОбновитьМестоположение("gps", ...) с коротким таймаутом гарантированно завершится неудачей."network" (определение по вышкам сотовой связи и точкам Wi-Fi) либо считывать кэш с помощью метода ПолучитьПоследнееМестоположение().ОтключитьОбработчикИзмененияМестоположения(), когда форма закрывается или сбор трека больше не требуется.