"Внешнее событие" и мобильная платформа 1С

Внешние компоненты в Android для Мобильной Платформы 1С или как вызвать внешнее событие, когда его нет.

Предыстория

В компанию был куплен аппарат CipherLab RS30, ТСД на базе ОС Android 4.4.2 cо встроенным сканером штрихкода. Было решено разработать приложение для работы с этим чудом техники на базе Мобильной Платформы 1С. Для примера была взята конфигурация «Мобильная Касса», в которой была уже реализована работа со штрихсканером, с помощью внешних компонент (Стандартная от 1С, вторая от компании ScanCode).  

После опытов оказалось, что штрихкод считывается во внешнем окне, которое загораживает весь интерфейс, плюс для каждого считывания штрихкода нужно нажимать кнопку для вызова этого окна, что было совершенно неприемлемо. Было принято решение разработать собственную внешнюю компоненту для считывания штрихкода и передачи его в 1С, без дополнительных окон и нажатий лишних кнопок.

И тут началось, оказывается, что в Мобильном Приложение 1С нет предопределенной процедуры ВнешнееСобытие, зато есть объект «ДоставляемыеУведомления», с помощью которого можно отправить локальное сообщение и принять его с помощью обработчика уведомлений. Казалось, что вот оно, решение всех бед, но и тут мы потерпели фиаско, 1С может отправлять и принимать сообщения только от самой себя. После чего была неделя непрерывных поисков решения, информации в интернете не оказалось, а все, на что мы натыкались, говорило о том, что это невозможно.

Пришлось декомпилировать платформу, изучить весь внутренний код, но все попытки заканчивались неудачей. И вот настал день, когда надо было окончательно решить, каким способом организовать работу с этим аппаратом, и мы было уже отказались от идеи внешней компоненты и подумывали запустить всю систему через RDP, как, о чудо, после еще одной отчаянной попытки решение было найдено.

А теперь самое главное.

Ограничения: Данный способ подходит только для приложений, собранных с помощью Конфигурации «Сборщик мобильных приложений», также способ подразумевает небольшое вмешательство в исходные файлы мобильной платформы.

Дано:

1. CipherLab RS30

2. SDK для вашего сканера

3. Сборщик мобильных приложений

4. Сама мобильная платформа

5. Android Studio

А теперь начинается магия:

1. Распаковываем файлы платформы

2. Нас интересует Androidprjandroid-arminpermissions.xml этот файл

Этот файл используется при сборке приложений и добавляет в AndroidManifest разрешения, которые указаны в конфигурации.

3. Нас интересует секция <LocalNotification>, которая добавляется, если установлена отметка Локальные Уведомления в требуемых разрешениях мобильного приложения. По умолчанию она выглядит так.

    <LocalNotification>
<uses-permission android:name="android.permission.VIBRATE"/>
<target xpath="/manifest/application" >
<receiver
android:name="com.e1c.mobile.LocalNotificationReceiver"
android:enabled="true" >
</receiver>
</target>
</LocalNotification>

4. Здесь нас интересует секция <receiver>,  com.e1c.mobile.LocalNotificationReceiver является потомком класса BroadcastReceiver, который как раз нам и нужен. Первое, что нам нужно сделать, это добавить атрибут android:exported=»true» это позволит принимать сообщения из внешней программы.

5.  Дальше нам нужно добавить фильтр, который будет указывать, какое событие может принять наш receiver, его-то мы и будем передавать из нашей компоненты.

<intent-filter>
<action android:name="ru.dewersia.barcodeDLL.TRUSTCONNECT" />
</intent-filter>

Теперь наша секция должна выглядеть так

    <LocalNotification>
<uses-permission android:name="android.permission.VIBRATE"/>
<target xpath="/manifest/application" >
<receiver
android:name="com.e1c.mobile.LocalNotificationReceiver"
android:enabled="true" android:exported="true">

<intent-filter>
<action android:name=" ru.dewersia.barcodeDLL.TRUSTCONNECT " />
</intent-filter>

</receiver>
</target>
</LocalNotification>

6. Теперь запаковываем все обратно, наша мобильная платформа готова.

7. Дальше можно приступать и к разработке в 1С, создаем обработчик локальных уведомлений

&НаКлиенте
Процедура ПриОткрытии(Отказ)
// Вставить содержимое обработчика.
Параметр = Неопределено;
ОП = Новый ОписаниеОповещения("КрутойОбработчик",ЭтаФорма,Параметр);
ДоставляемыеУведомления.ПодключитьОбработчикУведомлений(ОП);
былЗапуск = ЛОЖЬ;
КонецПроцедуры


&НаКлиенте
Процедура КрутойОбработчик(Уведомление,Локальное,Показано,ДопПараметры) Экспорт
Сообщить(Уведомление.Текст);
ШтрихКод = Уведомление.Текст;
КонецПроцедуры

8. Отправка сообщений в Android выглядит так:

    private void sendMessage(String title,String text) {
Intent intent = new Intent();
intent.setAction("ru.dewersia.barcodeDLL.TRUSTCONNECT");
intent.putExtra("text", text); //Основной текст сообщения
intent.putExtra("base", "");
intent.putExtra("title", title); //Будем использовать для определения действия
sendBroadcast(intent);
}

В параметры передаваемого сообщения добавляется значение с ключом base

 intent.putExtra(«base», «»);

Уважаемый DitriX в одном из своих комментариев писал, что туда должен передаваться ID базы, но на все попытки передать туда какое-либо значение из всех возможных, в сообщении появлялась надпись «Сообщение для неизвестной базы», при передаче пустого значения все отлично работает.

Всем большое спасибо за внимание, надеюсь, эта информация будет кому-нибудь полезна.

В результате был написан внешний сервис, работающий в фоновом режиме, который получает штрихкод со сканера и передает его в 1С.

49 Comments

  1. gorevg

    Интересно. Сейчас мы тоже пишем мобильное приложение под ТСД. Надо иметь ввиду. Спасибо!

    Reply
  2. gorevg

    Возможно ли купить у вас получившийся внешний сервис? или выложите его…

    Reply
  3. bulpi

    Это здорово и очень полезно. Было бы, вот только «внешний сервис, работающий в фоновом режиме» для Андроида я не напишу 🙁 ибо я просто 1с-ник. И таких миллион.

    Reply
  4. Tahallus

    Это если можно сделать приложение на android которое будет это сообщение отправлять.

    А бывает что только активное приложение может работать с оборудованием.

    Тогда только потрошить платформу и внедрять код.

    Reply
  5. dewersia

    (2) gorevg, Добрый день, в воскресенье выложу сервис. Не стал этого делать так как достаточно специфичное решение под конкретный аппарат, под каждый аппарат придется его переделывать, использовать свои библиотеки и так далее. Основной задачей было рассказать как можно реализовать вызов внешнего события в Мобильной Платформе.

    Reply
  6. dewersia

    (3) bulpi, Исходники как уже писал выше, выложу в воскресенье, это как раз и есть сервис работающий в фоновом режиме, 1С запускает сервис, а дальше этот сервис отправляет ей сообщения.

    Reply
  7. dewersia

    (4) Tahallus, Хм, тогда встает вопрос если это отдельное приложение, которое работает с оборудованием, неужели оно никак не передает данные? А если приложение этого не делает то тогда для чего оно? Такое узкоспециализированное оборудование тогда никак не может быть внедрено в учетную систему компании. Поправьте меня если это не так.

    Reply
  8. Tahallus

    (7) проблема в том что только активное приложение может работать с СШК по serialport. можно сделать отдельное приложение которое будет работать и отправлять сообщение в 1с, но когда оно активно. Это как с аппаратными клавишами, их нажатие может ловить только активное приложение, если конечно прошивка не изменена.

    Reply
  9. DitriX

    Как тут все глубоко ошибаются 🙂

    На счет статьи — таки да, надо отправлять ID, чем это чревато? Создайте две базы в списке и увидите.

    Мы (я про фирму ACODE) сделали проще в своих терминалах — у нас не надо нарушать лицензионной соглашение 1С, что делает автор в данной статье 🙂

    Это конечно прикол, я не думаю что реально это будет кто-то проверять, но иди и знай 🙂

    Вопрос номер два — зачем вы выдумывали велосипед? Видь есть Acode Tools, которые не только умею работать с блютуз сканерами, но и умеют еще кучу всего, из без танцев с бубном, как сделали вы сейчас.

    З.Ы. Велосипед это хорошо, но все же — вы просто не знали про утилиты, или они вам чем-то не подошли?

    Reply
  10. dewersia

    (9) DitriX, Добрый день, насчет нескольких баз, в списке несколько баз доступно только в платформе для разработчика, которую кстати нельзя использовать для конечного приложения, поэтому в какой роли выступает ID для отдельного приложения не понятно. Я кстати описал это ограничение в статье. Ваши утилиты это круто, мы их тоже изучали, но я так понял считывание штрих кода все равно происходит в отдельном окне, а не внешним событием, что нас не устраивало. По поводу вмешательства в платформу, это спорный вопрос, ведь исходный код платформы не изменен, изменены только лишь разрешения, которые кстати говоря определяет сам разработчик.

    По поводу сканеров, у нас СШК встроенный и в его настройках можно выбрать не эмуляцию клавиатуры, а передачу данных BroadCast сообщением, для него есть SDK под андроид, что и дало возможность использование такого метода, с блютуз сканерами боюсь так действительно не получится, хотя наверное и тут все зависит от конкретной модели и ее возможностей.

    Ну и опять же я не пытался привязаться к конкретной задаче, просто работа с торговым и складским оборудованием это наилучший пример. Я хотел лишь показать как можно вызвать пресловутое внешнее событие из внешней компоненты или любого другого приложения на андроид.

    Reply
  11. dewersia

    (8) Tahallus, Тут согласен, но это как раз ограничение аппаратных средств, тут надо смотреть, может у производителя есть библиотеки для работы с этим аппаратом, изучать их возможности и если это становится не возможным тогда решать нужен вообще такой аппарат или нет, хотя я бы сказал что нет ничего не возможного, я не отношусь к гуру android программистов, но если бы у меня стояла такая задача я бы копал в сторону сервиса, который бы перехватывал нажатие клавиш, думаю что это вполне возможно. А ели можно перехватить нажатие клавиш тогда их обработка и передача это дело техники.

    Reply
  12. dewersia

    Как и обещал, исходники сервиса разместил.

    Reply
  13. DitriX

    (10) не смотрели вы утилиты, так как там именно через уведомления, неужели вы думали, что мы выпустим такой бред — сканирование в активное поле?

    Мало того, еще с 8.3.4, где не было уведомлений — мы эмулировали через смс 🙂 И даже в нескольких релизах 8.3.х — был баг с уведомлениями, они тупо не работали, так что при тестах — надо это учитывать, но мы выключивались тем, что было резервное — смс. Так что у нас там немерянно приколов было.

    А про утилиты — всеравно обратите внимание, ибо там куча функций, которые точно нужны на ТСД 🙂

    На счет сканера штрихкода — не понял до конца, наши утилиты поддерживают все сканеры штрихкодов, которые можно подключить по блютузу в SPP режиме, т.е. не в режиме эмуляции. И для этого не надо ковырять ничего.

    В вашем случае — я так понял что у вас именно тсд на андроид. Ну тут да, мы для своих тоже отдельные модули пишем, но они имеют обратную совместимость и таки опять — без ковыряния манифестов 🙂

    Ну в целом — да, статья ценная для тех, кому потребуется аналогичное решение проблем. 🙂

    Теперь будет куда отправлять народ с аналогичными вопросами 🙂

    Reply
  14. dewersia

    (13) DitriX, Тогда примите мои извинения, значит что-то я упустил. Мне почему-то показалось что сканирование происходит в отдельном окне. Правда один из вариантов, который я еще вижу это push- уведомления ), для которых можно поднять свой сервер и гонять их через него, а что делать если нет соединения с интернет и мобильной связи? Я конечно понимаю, что сейчас это звучит дико, но все же бывает всякое, как тогда быть?

    Reply
  15. shakmaev

    (9) DitriX, на сколько я понимаю, ваше решение — это решение только для ваших терминалов. Например, Chainway 2D Soft без SDK не будет ничего слать, кроме как Keyboard Emulator.

    В случае с параметром base, Дмитрий прав, 2 и более базы будут работать некорректно, но это не проблема.

    Чтобы подставить значение base, можно при старте системы прочитать его из файла bases.v8i, и передать интент в сервис, например.

    Вот так выглядит список файлов:

    https://yadi.sk/i/a-sooEt8v44tv

    Вот так читать например ПриОткрытии:

    /data/data/»+ПолныйИД+»/files/1C/1cem/ibases.v8i

    Reply
  16. dewersia

    (15) shakmaev, Добрый день, большое спасибо за подсказку по поводу ID. Я до него так и не докопался, да и в моем случае мне это было не нужно по крайне мере в текущей задаче.

    Reply
  17. DitriX

    (14) нет, опять не верно поняли, у нас механизм работает так же, как и вы свой описали, только мы дергаем строенны в 1с бродкасты, а вы их перименовываете.

    Так что никаких пушей и интрнетов не надо 🙂

    (15) я же вверху исправился, и сказал, что да — это для наших терминалов, но утилиты работают с любыми блютух сканерами по такому же принципу, т.е. аля «внещнее событие», и вот утилиты идут под все устройства. Конечно, в данном случае на ТСД они работать не будут 🙂

    Так ID вы не прочитаете, у вас 2 базы, и все. Какой ID брать? Правильней — получать путь временного каталога и из него вырезать конкретный ID 🙂

    Reply
  18. iliabvf

    (17) DitriX, как то пытался получить у вас информацию как работают утилиты, как подключить другой ТСД (не ACODE), предлагал доработать силами нашей команды взамен исходного когда, но вы так и не захотели ничего давать, в результате мы тоже начали разрабатывать свою утилиту. А тут человек дал дельное решение, спасибо ему.

    Reply
  19. romak78

    подскажите com.cipherlab.barcode где взять, у меня только com.cipherlab.clbarcodeservice есть в приложениях ?

    Reply
  20. DitriX

    (18) я ж не говорю что это плохо, это выход из ситуации. И мы никогда не скрывали используемой технологии, даже в коде вы могли наблюдать названия соответствующие (SMS и GCM), другое дело, что мы не разрабатываем ни для кого, и не потому что мы плохие или хорошие, а потому что с каждым релизом вылазят новые чудеса. И ваш бы комментарий мог звучать сейчас не так. что мы ничего не делаем, а так, что мы сделали и нифига теерь не работает 🙂

    Тем более что мы сейчас вообще переходим на внешние компоненты, так как такой способ нарушает лицензию 1с, и в более менее крупных внедрениях — руководство просто может не пойти на это, а самое страшное — если такое сделать и их не предупредить. Это чисто медвежья услуга.

    Поэтому еще раз повторюсь — механизм рабочий, конечно требует более детального подхода и изучения, не без этого. НО! Это подойдет для лавочников или компаний, которые готовы сэкономить, но при этом на свой страх нарушить лицензии.

    Выбирайте сами. Но я считаю важным предупредить про это, иначе поплнится в ряду тех, кто «не переваривает» мобильную 1С.

    Reply
  21. mental86

    Большое спасибо автору!

    Маленький нюанс при использовании такого подхода: нельзя использовать вариант отладки с Android Debug Bridge. Платформа, которую ставит конфигуратор, почему-то игнорирует изменения в манифесте. Файл с платформой указывается в настройках, но, видимо, конфигуратор просто использует готовый APK из архива. Этот же архив платформы при использовании со сборщиком работает в соответствии со статьей. Конфигуратор 8.3.9.1850.

    А вообще надеюсь, что коллеги из 1С в новых релизах исправят досадную необщительность мобильной платформы.

    Reply
  22. zavbak

    Отличная статья. Спасибо.

    Использую для сборки конфигурацию «Сборщик мобильных приложений». Соответственно она постоянно заменяет permissions.xml. Какими командами собрать приложение?

    И сейчас вроде появились внешние компоненты. Вы копали в эту сторону?

    Reply
  23. dewersia

    (22) Файл permissions.xml заменяется в файлах самой платформы, которая потом используется в сборщике и он не должен каждый раз изменяться. По поводу внешних компонент, как раз сейчас разбираюсь, но проблема состоит в том, что внешние компоненты появились, а вот обработчика «внешне событие» пока нет, по крайне мере на сколько мне известно.

    Reply
  24. d_sdr

    подскажите, в процедуре «ПриОткрытии» вызывается такая интересная вещь, как

    ДоставляемыеУведомления.ПодключитьОбработчикУведомлений(…)

    Что это за модуль — «ДоставляемыеУведомления» и где его достать? В типовых конфигурациях его не нашёл, в ACode Tools тоже нету.

    Reply
  25. d_sdr

    (24) Вопрос снят, разобрался

    Reply
  26. koks17v

    Автор, спасибо большое! Очень полезный материал!

    А бродкастить в 1С нажатие аппаратных кнопок вы не реализовывали?

    Reply
  27. dewersia

    (26) Добрый день. Не пробовал. Но думаю можно сделать по такому же принципу. Словить его в своем сервисе и перенаправить в 1С.

    Reply
  28. demONx7

    Да, материал действительно полезен.

    А по поводу этого:

    (26)

    А бродкастить в 1С нажатие аппаратных кнопок вы не реализовывали?

    Тоже очень интересен данный момент.

    Особенно хотелось бы отследить клавиши стрелок и F..

    Есть мысли как это можно сделать?

    Reply
  29. koks17v

    (28) Да. Решение почти готово. Для АТОЛ SmartDroid.

    Reply
  30. koks17v

    (28) Функциональные клавиши F… тоже перехватываем, а так же — цифры и стрелки.

    Reply
  31. demONx7

    (30) Я сейчас занимаюсь написанием конфигурации для ТСД. Весь функционал работает, но только сенсорно. Застрял на том, что не могу перехватить как раз таки эти клавиши(F.., стрелки и цифры). Нужно дорабатывать permissions или AndroidManifest? Или нужно вносить корректировки в драйвер ТСД для 1С?

    Можете подсказать как и где это допиливается? Буду очень признателен.

    Reply
  32. dewersia

    (31) Если честно мы не изучали данный вопрос ), у нас нет функциональных клавиш, ну кроме «Назад», «Домой» и список открытых приложений. Поэтому в данном случае, первое что мне приходит на ум дописать сервис и вставить туда перехват нажатия клавиш. Вот только здесь нужно более подробно изучать материал по работе Android, я вчера полистал для интереса интернет, с лету не нашел ничего подходящего, но думаю если углубиться, то можно что-то нарыть. Можно дописать permission и сделать свой сервис )

    Reply
  33. demONx7

    Я уже три дня не могу ничего подходящего найти). Приходит на ум тоже что и вам, изучать Android. Чем сейчас постепенно и занимаюсь.

    Но ведь должно же быть где-то решение.

    Reply
  34. koks17v

    У нас получилось разработать драйвер для АТОЛ SmartDroid.

    1. Получение штрихкода с аппаратного сканера в обход клавиатуры.

    2. Обработка нажатия аппаратных кнопок устройства.

    3. Получение и обработка всех данных в мобильном приложении 1С.

    Готовим публикацию.

    Reply
  35. demONx7

    Отлично. С нетерпением ждём.

    Reply
  36. andrey314

    Правильно я понял что, чтобы это работало нужно обязательно собирать мобильное приложение? Просто как конфигурация мобильной 1С не будет работать?

    Reply
  37. dewersia

    Да, все верно

    Reply
  38. gorevg

    (34) Не готова публикация?

    Reply
  39. dbachinsky

    (39) Скачал файлы из статьи. Что с ними делать? Думал там будет сервис в формате apk

    Reply
  40. rhtr

    Новое направление «1С Хацкеры».

    Reply
  41. KBNIKKB

    (41) Да что с ними делать?

    Reply
  42. dewersia

    (43) Добрый день. Это не готовый сервис, это исходники сервиса их можно открыть в android studio и собрать собственный apk. Идея статьи была не выложить готовый универсальный сервис, а описать способ реализации внешнего события.

    Reply
  43. KBNIKKB

    (44) Собственный

    BarcodeService ? или что маленько не понимаю

    Reply
  44. dewersia

    (45) Это исходники сервиса, который является прокладкой между аппаратным сканером штрихкода и 1с. Суть заключается в том, что сервис перехватывает считывание штрихкода и передает его в 1с.

    Reply
  45. McLer

    (34) сделали публикацию?

    Reply
  46. dewersia

    (47)

    (40)

    Вот выложил небольшое дополнение по поводу клавиш https://infostart.ru/public/1039819/

    Reply
  47. Rokstedi

    Скачал последнюю мобильную платформу, там нет файла permissions.xml

    Reply
  48. dewersia

    (49) Какая версия платформы? У меня сейчас используется 8.3.13.64, там все есть.

    Reply
  49. kinan

    В 8.3.15.59 нет

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *