Разработчики мобильных приложений на платформе 1С часто сталкиваются с крайне неприятной проблемой: при подключении внешнего Bluetooth-сканера или использовании встроенного сканера ТСД в режиме эмуляции клавиатуры (режим HID) данные штрихкода «улетают в никуда». Чтобы штрихкод считался корректно, поле ввода на форме обязательно должно быть активным — в нем должен стоять курсор. Однако стандартные методы вроде АктивизироватьПоУмолчанию или прямое присвоение через ТекущийЭлемент в мобильной платформе (начиная с версий 8.3.5) часто работают нестабильно или не работают вовсе из-за особенностей оптимизации интерфейса мобильной операционной системы.
В рамках этой статьи мы подробно разберем, почему возникает эта проблема, рассмотрим несколько работающих способов программной активации полей ввода, научимся бороться с нежелательным всплытием экранной клавиатуры, а также разберем наиболее надежный и современный подход к сканированию — работу через широковещательные сообщения Android (Broadcast Intents) в обход использования фокуса полей ввода.
Начиная с версии мобильной платформы 8.3.5, разработчики 1С существенно переработали механизмы фокусировки элементов и вызова клавиатуры. В десктопной версии 1С установка свойства ТекущийЭлемент мгновенно активизирует поле. На мобильных устройствах простое позиционирование на элементе не гарантирует, что операционная система Android посчитает это поле готовым к вводу текста. Для ОС ввод текста ассоциируется с вызовом виртуальной клавиатуры. Если клавиатура не открыта, то и фокуса ввода в привычном понимании «физической клавиатуры» для поля не существует. Ситуация усложняется тем, что HID-сканеры определяются мобильным устройством как физическая клавиатура, из-за чего операционная система может принудительно скрывать экранную клавиатуру, сбрасывая при этом фокус с поля ввода.
Ниже мы разберем по шагам все варианты решения этой проблемы — от простых обходных путей в коде 1С до перевода сканера в профессиональный режим работы.
Начиная с версии мобильной платформы 8.3.9, разработчики получили официальный и стабильный метод для принудительного перевода поля в режим ввода текста — НачатьРедактированиеЭлемента(). Этот метод заставляет платформу не просто передать фокус элементу, но и запустить весь цикл ожидания ввода.
Рассмотрим пример кода, который активирует поле при открытии формы. Из-за особенностей инициализации интерфейса мобильного приложения прямой вызов метода в обработчике ПриОткрытии может не сработать, так как форма еще не успела полностью отрисоваться на экране смартфона или ТСД. Поэтому наиболее надежным решением является запуск активации через обработчик ожидания с минимальной задержкой.
Проанализируем программный код реализации этого механизма:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// Подключаем однократный обработчик ожидания с задержкой в 0.1 секунды
ПодключитьОбработчикОжидания("АктивизироватьПолеВводаШтрихкода", 0.1, Истина);
КонецПроцедуры
&НаКлиенте
Процедура АктивизироватьПолеВводаШтрихкода()
// Устанавливаем фокус на элемент формы
ЭлементДляФокуса = Элементы.ПолеВводаШтрихкода;
ТекущийЭлемент = ЭлементДляФокуса;
// Принудительно запускаем режим редактирования
НачатьРедактированиеЭлемента(ЭлементДляФокуса);
КонецПроцедуры
Использование этого метода гарантирует, что курсор встанет в поле ввода, и считанный со сканера штрихкод попадет именно туда. Однако у этого способа есть побочный эффект: при активации редактирования на экране устройства мгновенно всплывает виртуальная клавиатура Android, которая перекрывает половину экрана и мешает пользователю видеть данные формы.
Если вы используете сканирование через эмуляцию клавиатуры (HID), вам необходимо сделать так, чтобы поле ввода было активным, но экранная клавиатура при этом не мешала работе. Разберем три практических способа борьбы с этой проблемой:
&НаКлиенте
Процедура ПолеВводаШтрихкодаПриИзменении(Элемент)
// Обрабатываем полученный штрихкод
Штрихкод = Объект.ПолеВводаШтрихкода;
ОбработатьШтрихкод(Штрихкод);
// Очищаем поле для следующего сканирования
Объект.ПолеВводаШтрихкода = "";
// Переносим фокус на нередактируемый элемент (например, кнопку или декорацию)
// Это заставит систему скрыть экранную клавиатуру
ТекущийЭлемент = Элементы.КнопкаВыхода;
// Снова подключаем обработчик ожидания для подготовки поля к следующему сканированию
ПодключитьОбработчикОжидания("АктивизироватьПолеВводаШтрихкода", 0.5, Истина);
КонецПроцедуры
Работа со сканером в режиме эмуляции клавиатуры (HID) имеет фундаментальные недостатки: усечение символов при быстрой передаче (баг платформы 8.3.7), зависимость от фокуса и постоянные проблемы с экранной клавиатурой. Профессиональным стандартом автоматизации на мобильных устройствах является использование режима Broadcast (широковещательные сообщения Android).
При таком подходе сканер ТСД отправляет считанные данные напрямую в операционную систему в виде системного намерения (Intent). Мобильное приложение 1С перехватывает это событие. При этом на форме вообще не нужно держать активных полей ввода — сканирование успешно отработает, даже если на экране открыта пустая форма.
Для реализации этого сценария выполним следующие шаги:
В операционной системе вашего ТСД найдите встроенную утилиту настройки сканера (она может называться Scanner Settings, ScanWedge или Barcode Utility) и переведите режим сканирования из Keyboard Emulation в Intent Output (или Broadcast). В параметрах утилиты укажите:
com.1c.mobile.barcodebarcode_valueФирма 1С поставляет сертифицированные драйверы в составе БПО для мобильной платформы (например, драйвер Драйвер1СУстройствоВводаNative). Подключите этот драйвер в вашей конфигурации. В параметрах подключения укажите те же значения Action и Extra, которые вы настроили в системной утилите ТСД.
Вся обработка сканирования теперь будет происходить асинхронно через перехват внешнего события платформы. Разберем пример реализации в модуле управляемой формы:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// Подключаем сканер штрихкодов через стандартные механизмы БПО
ПодключитьСканерШтрихкодов();
КонецПроцедуры
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
// Перехватываем событие сканирования от БПО
Если ИмяСобытия = "Штрихкод" Тогда
Штрихкод = Параметр.Значение;
// Обрабатываем полученные данные напрямую без использования полей ввода!
ОбработатьШтрихкод(Штрихкод);
КонецЕсли;
КонецПроцедуры
Этот подход полностью избавляет разработчика от необходимости следить за активным элементом формы, гарантирует стопроцентную точность передачи всех символов штрихкода любой длины и полностью решает проблему всплывающей экранной клавиатуры, обеспечивая максимальное удобство и скорость работы кладовщиков и операторов ТСД.