Здравствуйте, коллеги.
В 2017 году столкнулся с задачей передачи данных сканирования со сканера ТСД в мобильную платформу 1С. Пришлось начать изучать java программирование под андроид и благодаря теме //infostart.ru/public/587908/ (в этой теме пример готовой компоненты, но под мое по не подошло) и ее предшественнице смог реализовать свою компоненту, ссылку на которую можете найти в комментариях к этой (//infostart.ru/public/587908) теме (работает до версии мобильной платформы 8.3.11). Однако стабильность работы старых мобильных платформ 1с оставляла желать лучшего и на нашем производстве уже достаточно большой функционал перекочевал на ТСД ,а частые ошибки о крушении мобильной базы стали доставать ... К сожалению, на конференцию Инфостарт 2018 я не поехал, подумал, что там будет как на других IT конференциях - кучу информации обо всем кроме программирования, но я ошибался ... Где то с полгода назад я наткнулся на тему //infostart.ru/public/987286/ в которой описывался путь создания Native компоненты под мобильную платформу и уже тогда я начал задуматься о изучении данной технологии, но руки так и не доходили. Данная технология позволяет работать с мобильной платформой с 8.3.8 и выше, насколько я понял.
Сегодня хочу предоставить вам в помощь ту компоненту, которая у меня получилась, она подходит под ряд тсд :
- honeywell scanpal eda50k( таких у нас 2)
- mobilebase ds5 (основной тсд для работы )
- CipherLab 9700(таких 2 , на них очень хороший сканер шк для сканирования на 5 и более метра ) точную версию не помню в документации к тсд написано 97XX
- AТОЛ Smart.Droid (таких нет) -пользователь с Инфостарта просил добавить в старую версию компоненты , как работает на 100% не знаю, но вроде не жаловался.
Теперь перечислю интенты и поля со строковыми данными, которые отлавливает компонента:
- Интент : scan.rcv.message Поле:data - это под honeywell scanpal eda50k, но на нем нужно настроить такие интенты
- Интент : com.cipherlab.barcodebaseapi.GET_DATA Поле:BarcodeData - это чиперлаб по моему это по умолчанию событие и в поле BarcodeData не строка, а байты, которые я разбирал с помощью драйвера и инструкции по чиперлабам, превращая их в строку
- Интент : app.dsic.barcodetray.BARCODE_BR_DECODING_DATA Поле:EXTRA_BARCODE_DECODED_DATA это под DS5
- Интент : DATA_SCAN Поле:com.hht.emdk.datawedge.data_string это под AТОЛ Smart.Droid.
Все интенты вшиты гвоздями статически)))
Извините за такой подход, писал для себя.
Теперь кратко пробежимся по работе компоненты.
Компонента состоит из .so файлов - библиотека на C++ для работы с платформами 1с и apk файл, в котором вшита логика работы с андроид.
Вся эта прелесть находится в zip архиве в таком варианте и должна попасть в мобильную конфигурацию 1с.
Имя подключения компоненты :
AddInNativeBEN.
Свойства компоненты:
IsEnabled(Включен)(bool)-показывает подключено ли событие отлова сканирования шк .
Методы компоненты:
- StartGetScan(НачатьПолучатьСканирование)(void)-начать получать данные со сканера ТСД. Вызывает внешнее событие при получении данных.
- StopGetScan(ОстановитьПолучениеСканирования)(void)-остановить получение данных со сканера ТСД .
- GetDataTSD(ПолучитьДанныеОТСД)(String)-получает данных о серийном номере устройства модели и версии андроида работает как функция
- GetDataTSDevent(ПолучитьДанныеОТСДсобытие)-получает данных о серийном номере устройства модели и версии андроида. Вызывает внешнее событие
- GetDataTSD и GetDataTSDevent возвращает строку вида СерийныйНомер$Модель$ВерсияАдроидаEndDescription.
Данные внешнего события , которое инициализирует платформа:
Источник: ru.MyDLLForJava.CallAndWorkJava Событие:BarcodeDecodeData Данные: штрихкод
Источник: ru.MyDLLForJava.CallAndWorkJava Событие:DataTSD Данные: СерийныйНомер$Модель$ВерсияАдроидаEndDescription
Хочу заметить, что сам я конечно не проверял , но по описанию Native компонента живет только на клиенте.
Приведу пример кода из 1с :
Код формы рабочей области . т.е той формы, которая живет все время работы приложения.
&НаКлиенте
Перем Компонента;
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Попытка
ПодключитьВнешнююКомпоненту("ОбщийМакет.AddIn", "LibData", ТипВнешнейКомпоненты.Native);
Компонента = Новый("AddIn.LibData.AddInNativeBEN");
Компонента.StartGetScan();
Исключение
Сообщить("драйвер сканирования не смог создать подключения-- сканирование на текущем устройстве работать не будет");
КонецПопытки;
//28.04.2020 устаревший метод заменен на работу Native компоненты
//ПодключитьОбработчикОжидания("УстановкаДрайверов",0.1,Истина);
//
УстановкаПервоначальныхДанныхОТСД();
КонецПроцедуры
Далее подписаться на внешнее событие можно где угодно, но я подписался в модуле приложения:
Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
МодульМобильныхДивайсовКлиент.ОбработчикВнешнихСобытийМобильнойКомпоненты(Источник, Событие, Данные);
КонецПроцедуры
Код в модуле мобильный девайсов:
&НаКлиенте
Процедура ОбработчикВнешнихСобытийМобильнойКомпоненты(Источник, Событие, Данные)Экспорт
Если Событие="BarcodeDecodeData" тогда
ШК=Данные;
Оповестить("ОбработчикШтрихКода",ШК,"ОбработчикШтрихКода");
КонецЕсли;
КонецПроцедуры
В принципе можно было сделать во всех формах подписку на внешнее событие и не использовать оповещения, но механизм оповещения был написан для старой версии компоненты , и что бы не переписывать всю мобильную конфигурацию , я воспользовался таким методом .
Прошу обратить внимание на этот код.
&НаКлиенте
Перем Компонента;
Мы объявляем компоненту как глобальную переменную в форме , что бы сборщик мусора видел, что на нее есть указатель ,пока форма открыта нам будут приходить сообщения, но как только форма закроется указатель на нее исчезнет и сборщик мусора удалит компоненту из памяти, автоматические отработает метод StopGetScan(); и события перестанут приходить.
Сборщик мусора - понятие из таких языков как С++,С# и т.д если интересно почитайте.
Если я что-то написал неправильно - пишите, рад быть просвещенным.
Данная компонента протестирована на мобильной платформе 8.3.10.84, а так же 8.3.15.105 версия андроида 4.4.
Примечание: на 8.3.10.84 при первом запуске есть ошибка связанная скорее всего с неправильной последовательность записи и запуска компоненты. После получения ошибки запускаю еще раз и все отлично работает, даже после перезапуска базы.
02.07.2020 наконец то добрался до модернизации компоненты, как обещал сделал ее более универсальной -
появился новый метод StartMyGetScan("ИмяСобытия","ИмяПолеСоСтроковымиДаннымиШтрихКода").
StartMyGetScan останавливается тем же методом что и StartGetScan -StopGetScan.
Пример использования:
ПодключитьВнешнююКомпоненту("ОбщийМакет.AddIn", "LibData", ТипВнешнейКомпоненты.Native);
Компонента = Новый("AddIn.LibData.AddInNativeBEN");
Компонента.StartMyGetScan("app.dsic.barcodetray.BARCODE_BR_DECODING_DATA","EXTRA_BARCODE_DECODED_DATA");
//Компонента.StartGetScan();
Компонента.StartGetKeyEvent();
Если кто то обратил внимание, так же появился один не описанный новый метод StartGetKeyEvent() - этот метод начинает отлавливать сообщения нажатия физической клавиатуры на ТСД, если она имеется, но он не работает без установки апк из нового архива.
Конечно к этому методу идет второй в паре StopGetKeyEvent()- он останавливает передачу нажатия клавиатуры в 1с.
Событие которое вызывается в 1с после нажатия клавиатуры "KeyEventAndroid" источник тот же что и у события штрих-кода.
Если кому то все таки понадобится отлавливать события нажатия клавиш , то замечу, что после установки апк из архива на ТСД , в специальных возможностях его необходимо включить после установки он носит имя "getKeyboard".
Источник идеи перехвата клавиатуры : //infostart.ru/public/1039819/
10.11.2020
Для тех у кого ТСД M3 Mobile SL10, SL10К - один из пользователей , попросил добавить информацию в статью:
Событие ШК-com.android.server.scannerservice.broadcast;
Поле с данным ШК-m3scannerdata;
Компонента.StartMyGetScan("com.android.server.scannerservice.broadcast","m3scannerdata")