Внешняя компонента для мобильного приложения

Публикация № 1544296 02.11.21

Разработка - Разработка внешних компонент

внешняя компонента Android sqlite zlib сжатие архивация распознавание штрихкод файл каталог http-сервер геоданные координаты модель SMB samba QR-code генератор regex

Внешняя компонента для дополнения мобильной платформы некоторыми функциями.

ВК имеет следующие функции:

1. Перехват широковещательных сообщений ОС андроид по заданному фильтру и ключу данных (extras).
2. Получать ИД устройства (с 10 версии ОС это не аппаратный ИД - https://developer.android.com/training/articles/user-data-ids).
3. Получать архитектуру процессора устройства (ABI - в терминологии ОС Android).
4. Сжимать (и разжимать обратно:)) двоичные данные (Deflate).
5. Сжимать файлы (Deflate).
6. Распознавать штрихкод с картинки (zxing).
7. Изменять разрешение и качество картинки.
8. Работать с файловой системой средствами ядра linux.
8.1. Возвращать массив объектов в заданной директории
8.2. Проверять, директория-ли объект файловой системы
8.3. Удалять объект файловой системы
8.4. Создавать файл
8.5. Создавать директорию
8.6. Писать двоичные данные в файл
8.7. Читать двоичные данные из файла
8.8. Переименовывать объект файловой системы
8.9. Проверять на существование объекта файловой системы
9. HTTP - сервер. (Прием входящих POST и PUT запросов и обработка запросов на стороне 1с (через внешнее событие). Ответ на запрос формируется в коде 1с).
10. Отображать производителя и модель устройства.
11. Получать геоданные устройства.
12.Работать с внешней СУБД sqlite3
13. Получать состав каталога по smb-протоколу (aka linux samba)
14. Получать содержимое файлов в двоичном виде по smb-протоколу (aka linux samba)
15. Записывать файлы в сетевой каталог по smb-протоколу
16. Работа с regEx. Пытается сопоставить регулярное выражение с последовательностью символов (regex_match). Подгруппы тоже ищутся и выводятся в массив результата.
17. Работа с regEx. Заменяет вхождения регулярного выражения форматированным замещающим текстом (regex_replace).
18. QR-code генератор. Функция поглощает строку и длину стороны картинки (квадрат), а выдает BASE64-строку, в которой завернуты двоичные данные картинки QR-кода. См. пример.
19.JSON-валидатор.

Тестирование производилось на платформах 8.3.19.51, 8.3.18.60, 8.3.20.40.

Работа компоненты на версиях OS и архитектурах:

ARM >=API 22
x86 >=API 22
ARM64 >=API 22
x86_64 >=API 22

 

Описание функций.

//--------Установка компоненты--------//
УстановитьВнешнююКомпоненту("ОбщийМакет.TestPro");
ПодключитьВнешнююКомпоненту("ОбщийМакет.TestPro", "Component", ТипВнешнейКомпоненты.Native);
ВК = Новый("AddIn.Component.Hermes");
//---------------------------------------------------------------------------//
//ЗапуститьПерехватБроадкастов//
//Может перехватывать любой броадкаст с известным фильтром и ключом данных   //
//---------------------------------------------------------------------------//
Процедура Запустить()
    м = новый массив;
    М.Добавить(новый структура("filter, extra",
    "com.xcheng.scanner.action.BARCODE_DECODING_BROADCAST",
    "EXTRA_BARCODE_DECODING_DATA"));
    
    ЗаписьJSON = Новый ЗаписьJSON;    
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON(ЗаписьJSON, М);
    Джейсон = ЗаписьJSON.Закрыть();
    Рез = ВК.ЗапуститьПерехватБроадкастов(Джейсон);
    Если Рез = "ok_en" тогда
        Предупреждение("Перехват установлен")
    иначе
        Предупреждение(Рез);
    КонецЕсли;
КонецПроцедуры
    
Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
    Если стрСравнить(СокрЛП(Источник),"Hermes") = 0 тогда
        Если стрСравнить(СокрЛП(Событие),"BroadcastCatched") = 0 тогда
            Попытка
                
                локДанные = РазобратьJSON(Данные);
                
                action     = Неопределено;
                _key     = Неопределено;
                Data    = Неопределено;
                
                локДанные.Свойство("action",action);
                локДанные.Свойство("key",_key);
                локДанные.Свойство("Data",Data);
                
                Если стрСравнить(сокрлп(action),"com.xcheng.scanner.action.BARCODE_DECODING_BROADCAST") = 0 тогда
                    Если стрСравнить(сокрлп(_key),"EXTRA_BARCODE_DECODING_DATA") = 0 тогда
                        Оповестить(Событие, новый структура("Данные, Тип", СокрЛП(Data), "hell_sighn"), Источник);
                    КонецЕсли;
                КонецЕсли;
            исключение
                ОШ = ОписаниеОшибки();
                Предупреждение(ОШ);
            КонецПопытки;
        иначеЕсли СтрСравнить(СокрЛП(Событие), "http_request") = 0 тогда
            
            J = РазобратьJSON(СокрЛП(Данные));
            J.data = "qwerqwerqwerqwer";
            
            ВК.HTTPСервер_Ответить(СформироватьJSON_(J)); 
                        
        КонецЕсли;
        Возврат;
    КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Данные, Источник)
    Если стрСравнить(Источник,"TestPro")=0 тогда
        Если стрСравнить(ИмяСобытия,"BroadcastCatched")=0 Тогда
            Если СтрСравнить(Данные.тип,"hell_sighn")=0 тогда
                штрихкод = Данные.Данные;
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;

КонецПроцедуры
    
//---------------------------------------------------------------------------//

 

//---------------------------------------------------------------------------//
//ОстановитьПерехватБроадкастов//
//---------------------------------------------------------------------------//

    Рез = ВК.ОстановитьПерехватБроадкастов();
    Если Рез = "ok_en" тогда
        Предупреждение("Перехват снят")
    иначе
        Предупреждение(Рез);
    КонецЕсли;
//---------------------------------------------------------------------------//

 

//---------------------------------------------------------------------------//
//=============================ИДУстройства==================================//
//Это не настоящий DeviceID, а некий синтетический идентификатор, выдаваемый //
//ОС вызывающему приложению  при вызове метода                               //
//Settings.Secure.getString(m_Activity.getContentResolver(),                 //
//Settings.Secure.ANDROID_ID),                                               //
//преобразованный к формату GUID                                             //
//(Начиная с 10 Андроида доступ "обычных" приложений к аппаратным            //
//идентификаторам устройства ограничен.)                                     //
//---------------------------------------------------------------------------//
    ИД = ВК.ИДУстройства();
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//АндроидИД//
//То-же самое, что и ИДУстройства, только передаваемый в 1с "как есть",      //
//т.е. без приведения к виду GUID                                            //
//---------------------------------------------------------------------------//
    ИД = ВК.АндроидИД();
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//Архитектура//
//Возвращает архитектуру процессора устройства (ABI - в терминологии Андроид)//
//---------------------------------------------------------------------------//
    Арх = ВК.Архитектура();
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//HTTPСервер_Запустить//
//---------------------------------------------------------------------------//
//Запускает локальный http-сервер на базе Nano, который принимает входящие   //
//POST/PUT-запросы. Каждый запрос обрабатывается в своем потоке и ему        //
//(запросу)присваевается ThreadID. После этого поток синхронно отправляет    //
//данные запроса в 1с - как внешнее событие. 1с должна в течение 60 секунд   //
//обработать запрос и вернуть ответ в компоненту.                            //
//Если ответ 1с'ом не возвращен, то клиент получит 500 ответ с описанием     //
//ошибки =  "SERVER INTERNAL ERROR: превышено ожидаемое время обработки      //
//запроса на стороне 1с."                                                    //
//Есть нюанс работы: если сервер долго не принимает запросов, а приложение, в//
//контексте которого он запущен, свернуто, то ОС через некоторое время       //
//останавливает поток сервера и его приходится перезапускать                 //
//---------------------------------------------------------------------------//
    Порт = 8086;
    Ответ = ВК.HTTPСервер_Запустить(Порт);
    Если СтрСравнить(сокрЛП(Ответ),"ok_en") = 0 тогда
        Предупреждение("HTTP сервер запущен на порту: " + Строка(Порт));
    иначе
        Предупреждение("Ошибка: " + ответ);
    КонецЕсли;
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//HTTPСервер_Остановить//
//---------------------------------------------------------------------------//
//Останавливает локальный http-сервер                                         //
//---------------------------------------------------------------------------//
    Ответ = ВК.HTTPСервер_Остановить();
    Если СтрСравнить(сокрЛП(Ответ),"ok_en") <> 0 тогда
        Предупреждение(Ответ);
    иначе
        Предупреждение("HTTP сервер остановлен");
    КонецЕсли;
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//HTTPСервер_Ответить//
//---------------------------------------------------------------------------//
//Выполняется в контексте обработчика внешнего события глобального модуля.   //
//Возвращает в http-сервер ответ, котрый будет переправлен клиенту.          //
//---------------------------------------------------------------------------//
Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
    Если стрСравнить(СокрЛП(Источник),"Hermes") = 0 тогда
        Если стрСравнить(СокрЛП(Событие),"BroadcastCatched") = 0 тогда
            Попытка
                
                локДанные = РазобратьJSON(Данные);
                
                action     = Неопределено;
                _key     = Неопределено;
                Data    = Неопределено;
                
                локДанные.Свойство("action",action);
                локДанные.Свойство("key",_key);
                локДанные.Свойство("Data",Data);
                
                Если стрСравнить(сокрлп(action),"com.xcheng.scanner.action.BARCODE_DECODING_BROADCAST") = 0 тогда
                    Если стрСравнить(сокрлп(_key),"EXTRA_BARCODE_DECODING_DATA") = 0 тогда
                        Оповестить(Событие, новый структура("Данные, Тип", СокрЛП(Data), "hell_sighn"), Источник);
                    КонецЕсли;
                КонецЕсли;
            исключение
                ОШ = ОписаниеОшибки();
                Предупреждение(ОШ);
            КонецПопытки;
        иначеЕсли СтрСравнить(СокрЛП(Событие), "http_request") = 0 тогда
            
            J = РазобратьJSON(СокрЛП(Данные));
            J.data = "qwerqwerqwerqwer";
            
            ВК.HTTPСервер_Ответить(СформироватьJSON_(J)); 
                        
        КонецЕсли;
        Возврат;
    КонецЕсли;

КонецПроцедуры

//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//ZLIB_Архивировать//
//Архивирует двоичные данные алгоритмом Deflate
//---------------------------------------------------------------------------//
    масМарки = новый массив;
    джМарки = JSON.СформироватьJSON(масМарки);
    
    ДД = ПолучитьДвоичныеДанныеИзСтроки(джМарки);
    
    ДДАрх = ВК.ZLIB_Архивировать(ДД);
    Если ТипЗнч(ДДАрх) = Тип("ДвоичныеДанные") тогда
        ДДРазарх = ВК.ZLIB_Разархивировать(ДДАрх, ДД.Размер());
    КонецЕсли;
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//ZLIB_Разархивировать//
//Разархивирует двоичные данные, заархивированные алгоритмом Deflate
//---------------------------------------------------------------------------//
    масМарки = новый массив;
    джМарки = JSON.СформироватьJSON(масМарки);
    
    ДД = ПолучитьДвоичныеДанныеИзСтроки(джМарки);
    
    ДДАрх = ВК.ZLIB_Архивировать(ДД);
    Если ТипЗнч(ДДАрх) = Тип("ДвоичныеДанные") тогда
        ДДРазарх = ВК.ZLIB_Разархивировать(ДДАрх, ДД.Размер());
    КонецЕсли;
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//ZLIB_АрхивироватьФайл//
//Архивирует файл алгоритмом Deflate
//---------------------------------------------------------------------------//
    ДДист = ПолучитьДвоичныеДанныеИзСтроки("Какие-нибудь данные");
    ИВФИст = ПолучитьИмяВременногоФайла("dat");
    ИВФНазн = ПолучитьИмяВременногоФайла("dat");
    ДДист.Записать(ИВФИст);
    Р = ВК.ZLIB_АрхивироватьФайл(ИВФИст, ИВФНазн);
    ДДАрх = новый ДвоичныеДанные(ИВФНазн);
    УдалитьФайлы(ИВФИст);
    Р1 = ВК.ZLIB_РазархивироватьФайл(ИВФНазн, ИВФИст);
    ДД1 = новый ДвоичныеДанные(ИВФИст);
    УдалитьФайлы(ИВФИст);
    УдалитьФайлы(ИВФНазн);
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//ZLIB_РазархивироватьФайл//
//Разархивирует файл, сжатый алгоритмом Deflate
//---------------------------------------------------------------------------//
    ДДист = ПолучитьДвоичныеДанныеИзСтроки("Какие-нибудь данные");
    ИВФИст = ПолучитьИмяВременногоФайла("dat");
    ИВФНазн = ПолучитьИмяВременногоФайла("dat");
    ДДист.Записать(ИВФИст);
    Р = ВК.ZLIB_АрхивироватьФайл(ИВФИст, ИВФНазн);
    ДДАрх = новый ДвоичныеДанные(ИВФНазн);
    УдалитьФайлы(ИВФИст);
    Р1 = ВК.ZLIB_РазархивироватьФайл(ИВФНазн, ИВФИст);
    ДД1 = новый ДвоичныеДанные(ИВФИст);
    УдалитьФайлы(ИВФИст);
    УдалитьФайлы(ИВФНазн);
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//PHOTO_ИзменитьКартинку//
//Изменяет разрешение и качество картинки. Под качеством подразумевается      //
//величина, обратная степени сжатия картинки алгоритмом JPEG                 //
//---------------------------------------------------------------------------//
    ФайлКартинки = КаталогДокументов()+"MobileFoto.jpg";
    ФайлКартинки = СтрЗаменить(ФайлКартинки,"\","/");
    ФайлКартинки = "file://" + ФайлКартинки; 
    НовВз = Новый ЗапускПриложенияМобильногоУстройства(
    "android.media.action.IMAGE_CAPTURE");
    
    НовВз.ДополнительныеДанные.Добавить("output",ФайлКартинки,"Uri");
    Если НовВз.Запустить(Истина) <> 0 Тогда
        ИВФВых = ПолучитьИмяВременногоФайла("jpg");
        
        Р = ВК.PHOTO_ИзменитьКартинку(ФайлКартинки,
        ИВФВых,
        ЭтаФорма.РазрешениеХ, 
        ЭтаФорма.РазрешениеУ, 
        ЭтаФорма.Какчество);
        
        ДД = новый ДвоичныеДанные(ИВФВых);
        ОтобразитьКартинку(ДД);
    КонецЕсли;
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//Версия//
//Возвращает версию компоненты
//---------------------------------------------------------------------------//
    Сообщить(ВК.Версия());
//---------------------------------------------------------------------------//
//-----------------------------------------------------------------------------//
//ZXING_РаспознатьШтрихкод//
//Пытается прочитать любой 1- и 2-мерный штрихкод.
//Функция имеет 2 перегрузки:                                                  //
//1. в качестве параметра принимается строка - имя файла картинки с штрихкодом //
//2. в качестве параметра принимаются двоичные данные картинки                 //
//-----------------------------------------------------------------------------//
    &НаКлиенте
    Процедура РаспознатьQRCodeСКартинки(Команда)
        //1.Вариант с чтением картинки из файла
        Картинка = ЗаписатьКартинкуВФайл(КаталогДокументов());
        стр = ВК.ZXING_РаспознатьШтрихкод(Картинка);
        стк = JSON.РазобратьJSON(стр);
        Если стк.status тогда
            УдалитьФайлы(Картинка);
            Предупреждение(стк.data);
        иначе
            Предупреждение(стк.description);
        КонецЕсли;
        
        
        //2.Вариант с чтением картинки из ДД
        стр = ВК.ZXING_РаспознатьШтрихкод(ПолучитьДДКартинки());
        стк = JSON.РазобратьJSON(стр);
        Если стк.status тогда
            Предупреждение(стк.data);
        иначе
            Предупреждение(стк.description);
        КонецЕсли;
        
        
        Данные = СредстваМультимедиа.СделатьФотоснимок(ТипКамерыУстройства.Задняя, 
        новый РазрешениеКамерыУстройства(800, 600), 
        100,
        ,
        ТипПодсветкиКамеры.Выключена);
        
        Если Данные <> неопределено тогда
            стр = ВК.ZXING_РаспознатьШтрихкод(Данные.ПолучитьДвоичныеДанные());
            стк = JSON.РазобратьJSON(стр);
            Если стк.status тогда
                Предупреждение(стк.data);
            иначе
                Предупреждение(стк.description);
            КонецЕсли;
        КонецЕсли;
    КонецПроцедуры
    
    &НаСервере
    Функция ЗаписатьКартинкуВФайл(КаталогДокументов)
        ИВФ = КаталогДокументов + "MobileFoto.png";
        ПолучитьДДКартинки().Записать(ИВФ);
        ИВФ = СтрЗаменить(ИВФ,"\","/");
        ИВФ = "file://" + ИВФ; 
        Возврат ИВФ;
    КонецФункции
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//ФС_ПрочитатьКаталог//
//Возвращает массив объектов каталога файловой системы - если у приложения   //
//в этот каталог есть соответствующий доступ.                                //
//---------------------------------------------------------------------------//
    &НаКлиенте
    Функция УдалитьФсеФСОРекурсивно(вхКаталог, ВК)
        Если РазобратьJSON(ВК.ФС_ОбъектФССуществует(вхКаталог)).Status тогда
            сткРез = РазобратьJSON(ВК.ФС_ПрочитатьКаталог(вхКаталог));
            Если сткРез.Status тогда
                сткРез0 = РазобратьJSON(сткРез.Data);
                Для каждого эстк из сткРез0 Цикл
                    Если эстк.Значение = ".." или эстк.Значение = "." тогда 
                        продолжить 
                    КонецЕсли;
                    
                    П = вхКаталог + ?(прав(вхКаталог,1)="/","","/") + 
                    эстк.Значение;
                    сткЭтоДиректорияСтатус = 
                    РазобратьJSON(ВК.ФС_ЭтоДиректория(П));
                    
                    Если сткЭтоДиректорияСтатус.Status тогда
                        Если РазобратьJSON(сткЭтоДиректорияСтатус.Data).
                        IsDirectory тогда
                            УдалитьФсеФСОРекурсивно(П, ВК);
                        КонецЕсли;
                    КонецЕсли;
                    ВК.ФС_УдалитьФайлИлиКаталог(П);
                КонецЦикла;
            КонецЕсли;
        КонецЕсли;
        ВК.ФС_УдалитьФайлИлиКаталог(?(прав(вхКаталог,1)="/", 
        Лев(вхКаталог,стрДлина(вхКаталог)-1), вхКаталог));
    КонецФункции
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//ФС_ЭтоДиректория//
//Проверяет: объект файловой системы - директория или файл.
//---------------------------------------------------------------------------//
    сткЭтоДиректорияСтатус = РазобратьJSON(ВК.ФС_ЭтоДиректория(П));
    Если сткЭтоДиректорияСтатус.Status тогда
        Если РазобратьJSON(сткЭтоДиректорияСтатус.Data).IsDirectory тогда
            УдалитьФсеФСОРекурсивно(П, ВК);
        КонецЕсли;
    КонецЕсли;
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//ФС_УдалитьФайлИлиКаталог//
//Удаляет объект файловой системы.
//---------------------------------------------------------------------------//
    Ответ = ВК.ФС_УдалитьФайлИлиКаталог(
    "/data/data/com.e1c.mobile/files/1C/1cem/test/test.txt");
    
    стк = РазобратьJSON(Ответ);    
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//ФС_СоздатьФайл//
//Создает файл
//---------------------------------------------------------------------------//
    Ответ = ВК.ФС_СоздатьФайл(
    "/data/data/com.e1c.mobile/files/1C/1cem/test/test.txt");
    
    стк = РазобратьJSON(Ответ);
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//ФС_СоздатьКаталог//
//Создает каталог
//---------------------------------------------------------------------------//
    Ответ = ВК.ФС_СоздатьКаталог(
    "/data/data/com.e1c.mobile/files/1C/1cem/test", 511);
    стк = РазобратьJSON(Ответ);
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//ФС_ПереименоватьФайлИлиКаталог//
//переименовывает файл или каталог
//---------------------------------------------------------------------------//
    
    Ответ = ВК.ФС_ПереименоватьФайлИлиКаталог(
    "/data/data/com.e1c.mobile/files/1C/1cem/test/test.txt",
    "/data/data/com.e1c.mobile/files/1C/1cem/test/test1.txt");
    
    стк = РазобратьJSON(Ответ);    
    Если стк.Status тогда
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//ФС_ЗаписатьДанныеВФайл//
//Пишет двоичные данные в файл                                               //
//---------------------------------------------------------------------------//
    Ответ = ВК.ФС_ЗаписатьДанныеВФайл(
    "/data/data/com.e1c.mobile/files/1C/1cem/test/test.txt", 
    ПолучитьДвоичныеДанныеИзСтроки("СтрокаДляДД"));
    стк = РазобратьJSON(Ответ);    
    Если стк.Status тогда
        Ответ = ВК.ФС_ПрочитатьДанныеИзФайла(
        "/data/data/com.e1c.mobile/files/1C/1cem/test/test.txt");
        Если ТипЗнч(Ответ) = тип("ДвоичныеДанные") тогда
            стр = ПолучитьСтрокуИзДвоичныхДанных(Ответ);
        КонецЕсли;
    КонецЕсли;
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//ФС_ПрочитатьДанныеИзФайл//
//---------------------------------------------------------------------------//
    Ответ = ВК.ФС_ЗаписатьДанныеВФайл(
    "/data/data/com.e1c.mobile/files/1C/1cem/test/test.txt", 
    ПолучитьДвоичныеДанныеИзСтроки("СтрокаДляДД"));
    
    стк = РазобратьJSON(Ответ);    
    Если стк.Status тогда
        
        Ответ = ВК.ФС_ПрочитатьДанныеИзФайла(
        "/data/data/com.e1c.mobile/files/1C/1cem/test/test.txt");
        
        Если ТипЗнч(Ответ) = тип("ДвоичныеДанные") тогда
            стр = ПолучитьСтрокуИзДвоичныхДанных(Ответ);
        КонецЕсли;
    КонецЕсли;
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//ФС_ОбъектФССуществует//
//Проверяет: существует-ли каталог или файл                                  //
//---------------------------------------------------------------------------//
    Ответ = ВК.ФС_ОбъектФССуществует(
    "/data/data/com.e1c.mobile/files/1C/1cem/test");
    
    стк = РазобратьJSON(Ответ);
    КаталогСуществует = ложь;
    Если стк.Status тогда
        КаталогСуществует = истина;
    КонецЕсли;
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//Общий пример для работы с файловой системой: удаляет все файлы внешних     //
//компонент из каталога ExtCompT мобильной платформы.                        //
//---------------------------------------------------------------------------//
    &НаКлиенте
    Процедура СканироватьФайловуюСистему(Команда)
        
        //stat.h
        //#define S_IRWXU 00700
        //#define S_IRUSR 00400
        //#define S_IWUSR 00200
        //#define S_IXUSR 00100
        //#define S_IRWXG 00070
        //#define S_IRGRP 00040
        //#define S_IWGRP 00020
        //#define S_IXGRP 00010
        //#define S_IRWXO 00007
        //#define S_IROTH 00004
        //#define S_IWOTH 00002
        //#define S_IXOTH 00001
        
        
        БазовыйКаталог = "";
        
        Ответ = ВК.ФС_ОбъектФССуществует(
        "/data/data/com.yourapp.tsd/files/1C/1cem");
        
        стк = РазобратьJSON(Ответ);
        Если стк.Status тогда
            БазовыйКаталог = "/data/data/com.yourapp.tsd/files/1C/1cem";
        иначе
            Ответ = ВК.ФС_ОбъектФССуществует(
            "/data/data/com.e1c.mobile/files/1C/1cem");
            
            стк = РазобратьJSON(Ответ);
            Если стк.Status тогда
                БазовыйКаталог = "/data/data/com.e1c.mobile/files/1C/1cem";
            КонецЕсли;
        КонецЕсли;
        
        Если БазовыйКаталог <> "" тогда
            Ответ = ВК.ФС_ПрочитатьДанныеИзФайла(БазовыйКаталог + 
            "/ibases.v8i");
            
            Если ТипЗнч(Ответ) = тип("ДвоичныеДанные") тогда
                стр = ПолучитьСтрокуИзДвоичныхДанных(Ответ);
                
                Попытка
                    ИВФ = ПолучитьИмяВременногоФайла("txt");
                    ЗаписьТекста = новый ЗаписьТекста(ИВФ);
                    ЗаписьТекста.ЗаписатьСтроку(стр);
                    ЗаписьТекста.Закрыть();
                    
                    ЧтениеТекста = новый ЧтениеТекста(ИВФ);
                    стр = "";
                    Пока стр<>Неопределено Цикл
                        стр = ЧтениеТекста.ПрочитатьСтроку();
                        Если СтрНачинаетсяС(стр,"[Tsd test]") тогда
                            стр = "";
                            Пока стр<>Неопределено Цикл
                                стр = ЧтениеТекста.ПрочитатьСтроку();
                                Если стрСравнить(Лев(стр,стрДлина("Connect=File=")),"Connect=File=")=0 тогда
                                    масСтр = СтрРазделить(стр,"/1cem/");
                                    Если масСтр.Количество()>1 тогда
                                        сткРез0 = РазобратьJSON(ВК.ФС_ПрочитатьКаталог(БазовыйКаталог + масСтр[1]));
                                        Если сткРез0.Status тогда
                                            сткРез1 = РазобратьJSON(сткРез0.Data);
                                            Для каждого эстк из сткРез1 Цикл
                                                Если эстк.Значение = ".." или эстк.Значение = "." тогда продолжить КонецЕсли;
                                                П = БазовыйКаталог + масСтр[1] + ?(прав(БазовыйКаталог + масСтр[1],1)="/","","/")+эстк.Значение;
                                                сткЭтоДиректорияСтатус = РазобратьJSON(ВК.ФС_ЭтоДиректория(П));
                                                Если сткЭтоДиректорияСтатус.Status тогда
                                                    Если РазобратьJSON(сткЭтоДиректорияСтатус.Data).IsDirectory тогда
                                                        Р = УдалитьФсеФСОРекурсивно(П + "/ExtCompT",ВК);
                                                        Если ЗначениеЗаполнено(Р) тогда
                                                            Попытка 
                                                                ВызватьИсключение "Не удалось зачистить кэш: "+Р;
                                                            исключение
                                                                Ош = ОписаниеОшибки();
                                                                //ДИАГНОСТИКА
                                                            КонецПопытки;
                                                        КонецЕсли;
                                                    КонецЕсли;
                                                КонецЕсли;
                                            КонецЦикла;
                                        КонецЕсли;
                                    КонецЕсли;
                                    Прервать;
                                КонецЕсли;
                            КонецЦикла;
                            прервать;
                        КонецЕсли;
                    КонецЦикла;
                    
                исключение
                    Ош = ОписаниеОшибки();
                    //ДИАГНОСТИКА - 
                КонецПопытки;
                
                Попытка
                    УдалитьФайлы(ИВФ);
                исключение
                    Ош = ОписаниеОшибки();
                    //ДИАГНОСТИКА - ошибка удаления ВФ
                КонецПопытки;
                
            КонецЕсли;    
        иначе
            Попытка 
                ВызватьИсключение стк.Description;
            исключение
                Ош = ОписаниеОшибки();
                //ДИАГНОСТИКА
            КонецПопытки;
        КонецЕсли;
        
        
        //Ответ = ВК.ФС_ОбъектФССуществует("/data/data/com.e1c.mobile/files/1C/1cem/test");
        //стк = РазобратьJSON(Ответ);
        //КаталогСуществует = ложь;
        //Если стк.Status тогда
        //    КаталогСуществует = истина;
        //иначе
        //    Ответ = ВК.ФС_СоздатьКаталог("/data/data/com.e1c.mobile/files/1C/1cem/test", 511);
        //    стк = РазобратьJSON(Ответ);
        //    Если стк.Status тогда
        //        КаталогСуществует = истина;
        //    КонецЕсли;
        //КонецЕсли;
        //
        //Если КаталогСуществует тогда
        //    Ответ = ВК.ФС_СоздатьФайл("/data/data/com.e1c.mobile/files/1C/1cem/test/test.txt");
        //    стк = РазобратьJSON(Ответ);
        //    Если стк.Status тогда
        //        Ответ = ВК.ФС_ЗаписатьДанныеВФайл("/data/data/com.e1c.mobile/files/1C/1cem/test/test.txt", ПолучитьДвоичныеДанныеИзСтроки("СтрокаДляДД"));
        //        стк = РазобратьJSON(Ответ);    
        //        Если стк.Status тогда
        //            Ответ = ВК.ФС_ПрочитатьДанныеИзФайла("/data/data/com.e1c.mobile/files/1C/1cem/test/test.txt");
        //            Если ТипЗнч(Ответ) = тип("ДвоичныеДанные") тогда
        //                стр = ПолучитьСтрокуИзДвоичныхДанных(Ответ);
        //            КонецЕсли;
        //        КонецЕсли;
        //        
        //        Ответ = ВК.ФС_ПереименоватьФайлИлиКаталог("/data/data/com.e1c.mobile/files/1C/1cem/test/test.txt","/data/data/com.e1c.mobile/files/1C/1cem/test/test1.txt");
        //        стк = РазобратьJSON(Ответ);    
        //        Если стк.Status тогда
        //            Ответ = ВК.ФС_УдалитьФайлИлиКаталог("/data/data/com.e1c.mobile/files/1C/1cem/test/test1.txt");
        //            стк = РазобратьJSON(Ответ);    
        //        иначе
        //            Ответ = ВК.ФС_УдалитьФайлИлиКаталог("/data/data/com.e1c.mobile/files/1C/1cem/test/test.txt");
        //            стк = РазобратьJSON(Ответ);    
        //        КонецЕсли;
        //    КонецЕсли;
        //    
        //    Ответ = ВК.ФС_УдалитьФайлИлиКаталог("/data/data/com.e1c.mobile/files/1C/1cem/test");
        //    стк = РазобратьJSON(Ответ);
        //КонецЕсли;
        //
        //
        ////Для а = 0 по 10000 цикл
        //
        ////Ответ = ВК.ФС_ЭтоДиректория("/data/data/com.e1c.mobile/files/1C/1cem");
        ////стк = РазобратьJSON(Ответ);
        ////Если стк.Status тогда
        ////    стк0 = РазобратьJSON(стк.Data);
        ////    //Для каждого эстк из стк0 цикл
        ////    //    
        ////    //КонеЦЦикла;
        ////КонецЕсли;
        ////КонеЦЦИкла;
        
    КонецПроцедуры

    &НаКлиенте
    Функция УдалитьФсеФСОРекурсивно(вхКаталог, ВК)
        Если РазобратьJSON(ВК.ФС_ОбъектФССуществует(вхКаталог)).Status тогда
            сткРез = РазобратьJSON(ВК.ФС_ПрочитатьКаталог(вхКаталог));
            Если сткРез.Status тогда
                сткРез0 = РазобратьJSON(сткРез.Data);
                Для каждого эстк из сткРез0 Цикл
                    Если эстк.Значение = ".." или эстк.Значение = "." тогда продолжить КонецЕсли;
                    П = вхКаталог + ?(прав(вхКаталог,1)="/","","/")+эстк.Значение;
                    сткЭтоДиректорияСтатус = РазобратьJSON(ВК.ФС_ЭтоДиректория(П));
                    Если сткЭтоДиректорияСтатус.Status тогда
                        Если РазобратьJSON(сткЭтоДиректорияСтатус.Data).IsDirectory тогда
                            УдалитьФсеФСОРекурсивно(П, ВК);
                        КонецЕсли;
                    КонецЕсли;
                    ВК.ФС_УдалитьФайлИлиКаталог(П);
                КонецЦикла;
            КонецЕсли;
        КонецЕсли;
        ВК.ФС_УдалитьФайлИлиКаталог(?(прав(вхКаталог,1)="/", Лев(вхКаталог,стрДлина(вхКаталог)-1), вхКаталог));
    КонецФункции
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//ОписаниеУстройства//
//Свойство компоненты - показывает производителя и модель устройства         //
//---------------------------------------------------------------------------//
    стрПроизводительИМодель = ВК.ОписаниеУстройства;
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//Запустить получение геоданных//
//---------------------------------------------------------------------------//

//1й параметр - получать данные от провайдера GPS, 
//2й параметр - получать данные от провайдера NETWORKPROVIDER
//Данные от разных провайдеров приходят разными событиями
Р = ВК.ГЕО_НачатьПолучениеКоординат(истина, истина);

ВК.ГЕО_ОстановитьПолучениеКоординат();

//1й параметр - получать данные от провайдера GPS, 
//2й параметр - получать данные от провайдера NETWORKPROVIDER
//Данные от разных провайдеров приходят разными событиями
Р = ВК.ГЕО_ПолучитьСейчас(истина, истина);
    

Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
    Если стрСравнить(СокрЛП(Источник),"Hermes") = 0 тогда
        Если СтрСравнить(СокрЛП(Событие), "GEO_location") = 0 тогда

			//Что-то сделать с геоданными...
			
        КонецЕсли;
        Возврат;
    КонецЕсли;
КонецПроцедуры


//---------------------------------------------------------------------------//
Это JSON, который приходит во внешнем событии:

{
	"data": "",
	"description": "",
	"object": [
		{
			"accuracy": 603.0,
			"altitude": 0.0,
			"latitude": 37.4218964,
			"longitude": -122.0840582,
			"provider": "NETWORK",
			"speed": 0.0
		}
	],
	"status": true
}

Работа с СУБД sqlite3.

При начале тестирования работы МП на мобильном фреймворке 1с столкнулись с извечной проблемой этой платформы - ОЧЕНЬ НИЗКОЙ ПРОИЗВОДИТЕЛЬНОСТЬЮ.

Когда таблицы содержат более 500к строк, то время поиска соответствующих просканированному штрихкоду данных доходит до  4х секунд. Вынос этих данных в СУБД sqlite3 + некоторые другие нехитрые манипуляции (в целях загрузки файла БД sqlite3 на устройство) решают эту проблему. Разницу в производительности не замеряли, но субъективно sqlite3 работает шустрее примерно на 2-3 порядка.

//---------------------------------------------------------------------------//
//СКЛт_ОткрытьСоединение//
//Открывает новое подключение к файлу БД                                     //
//1й параметр - полный путь к файлу БД СУБД sqlite3                          //
//---------------------------------------------------------------------------//
    ИВФНазн = КаталогВременныхФайлов() + "test.db";
	УдалитьФайлы(ИВФНазн);

	джРез = ВК.СКЛт_ОткрытьСоединение(ИВФНазн);
	сткРез = JSON.РазобратьJSON(джРез);
	Если сткРез.status тогда
		локИДСоединения = сткРез.data.conn_id;
	КонецЕсли;

//---------------------------------------------------------------------------//
Ответ:
{
	"Data" : 
	{
		"conn_id" : 0
	},
	"Description" : "",
	"Status" : true
}

 

//---------------------------------------------------------------------------//
//СКЛт_ПолучитьДеталиПоБД//
//Открывает новое подключение к файлу БД                                     //
//1й параметр - ID подключения к БД                                          //
//---------------------------------------------------------------------------//
    ИВФНазн = КаталогВременныхФайлов() + "test.db";
	УдалитьФайлы(ИВФНазн);

	джРез = ВК.СКЛт_ОткрытьСоединение(ИВФНазн);
	сткРез = JSON.РазобратьJSON(джРез);
	Если сткРез.status тогда
		локИДСоединения = сткРез.data.conn_id;
	КонецЕсли;

    джРез = ВК.СКЛт_ПолучитьДеталиПоБД(локИДСоединения);

//---------------------------------------------------------------------------//
Ответ:
{
	"Data" : 
	{
		"Size" : 12288
	},
	"Description" : "",
	"Status" : true
}
//---------------------------------------------------------------------------//
//СКЛт_ВыполнитьСкрипт//
//Выполняет скрипт                                                           //
//1й параметр - ID подключения к БД                                          //
//2й параметр - текст скрипта                                                //
//---------------------------------------------------------------------------//
   ИВФНазн = КаталогВременныхФайлов() + "test.db";
	УдалитьФайлы(ИВФНазн);
		
	джРез = ВК.СКЛт_ОткрытьСоединение(ИВФНазн);
	сткРез = JSON.РазобратьJSON(джРез);
	Если сткРез.status тогда
		локИДСоединения = сткРез.data.conn_id;
	КонецЕсли;
	джРез = ВК.СКЛт_ПолучитьДеталиПоБД(локИДСоединения);
	
	скриптCreate = "CREATE TABLE IF NOT EXISTS МАРКИ (Марка TEXT NOT NULL UNIQUE, DocDate TEXT, ID TEXT, PRIMARY KEY(Марка))";
	джРез = ВК.СКЛт_ВыполнитьСкрипт(локИДСоединения,скриптCreate);
	
	скриптИнсерт = "INSERT INTO МАРКИ (Марка, DocDate, ID) 
	|VALUES('102400137351161018001T3XIKZ5WR2MEEAXXWN2JKZBEBEZCB5ZVMFPUTVXHNMXPUJCWQJXYV3FTR2TOLGZ3CNTYMOKGL3XTWDYZUVHCHJ7ZPOFMZDHUABQ66GMELE4LGAEGNEV4A7AL199999', 
	|'20220122', '99999')";
	джРез = ВК.СКЛт_ВыполнитьСкрипт(локИДСоединения,скриптИнсерт);
	
	скриптСелект = "select * from МАРКИ where Марка like '%8001T3XIKZ5WR2MEEAXXWN2JKZBEBEZCB5ZVMFPUTVXHNMXPUJCWQJ%'";
	джРез = ВК.СКЛт_ВыполнитьСкрипт(локИДСоединения,скриптСелект);
	
	
	джРез = ВК.СКЛт_ЗакрытьСоединение(локИДСоединения);
	УдалитьФайлы(ИВФНазн);


//---------------------------------------------------------------------------//
Ответ:
{
	"Data" : 
	{
		"rows" : 
		[
			{
				"DocDate" : "20220122",
				"ID" : "99999",
				"Марка" : "102400137351161018001T3XIKZ5WR2MEEAXXWN2JKZBEBEZCB5ZVMFPUTVXHNMXPUJCWQJXYV3FTR2TOLGZ3CNTYMOKGL3XTWDYZUVHCHJ7ZPOFMZDHUABQ66GMELE4LGAEGNEV4A7AL199999"
			}
		]
	},
	"Description" : "",
	"Status" : true
}

 

Работа с smb (samba) протоколом.

В состав компоненты введен функционал по работе с "сетевыми каталогами Windows".

Что это такое. 
https://ru.wikipedia.org/wiki/Server_Message_Block
Проще говоря: этот протокол используется для работы с сетевыми каталогами Windows.

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

Для работы со всеми этими ресурсами сети используется smb-протокол.
В ОС Windows работа с smb визуально реализована как работа с обычными объектами файловой системы.

Зачем это нужно.
Это очень быстро настраваемый способ обмена данными между мобильным приложением на 1с и любым компьютером на базе ОС Windows, работающем в той-же локальной сети, что и мобильное устройство.
Не нужны ни HTTP, ни FTP сервера.
Достаточно просто опубликовать сетевой каталог на любом из компьютеров, положить в него текстовый файлик с данными и этот файлик "станет" доступен на мобильном устройстве -
как на любом другом компьютере в той-же локальной сети.

Технические условия.
Те-же самые, что и для получения доступа к сетевому каталогу с настольного компьютера.
1. Компьютер, на котором опубликован сетевой каталог, должен быть в зоне сетевой доступности ТСД (из wi-fi сети, к которой подключено мобильное устройство).
2. На компьютере с публикацией сетевого каталога, не должно быть запрета на работу с протоколом SMB.
3. Если опубликованный каталог виден с другого компьютера сети, то в общем случае, он должен быть виден и для ТСД.

Реализация.
Использована достаточно известная open-sorce библиотека https://github.com/sahlberg/libsmb2.

Как работает из 1с.
Взаимодействие с сетевыми каталогами из 1с немного отличается от взаимодействия с ними из ОС Windows.

Если в Windows для доступа в каталог надо в УРЛ-строке написать что-то вроде "\\MyHomeComputer\temp\какой-то каталог", то библиотека libsmb2 кушает URL строку вида smb://[<username>@]<host>[:<port>]/<share>/<path>
и "\\MyHomeComputer\temp\какой-то каталог" превратится в "smb://Ivanov@MyHomeComputer/temp/какой-то каталог"
Также, для успешного проникновения в недру сетевого каталога - каждый раз при подключении следует указывать пароль локального (или доменного) пользователя компьютера, на котором расшарен каталог.

Вдаваться в описание всех членов URL не буду - его можно нагуглить, а лучше приведу код из 1с:

&НаКлиенте
Процедура Самба_Каталог(Команда)
	
	УстановитьВнешнююКомпоненту("ОбщийМакет.Hermes_gith");
	Р = ПодключитьВнешнююКомпоненту("ОбщийМакет.Hermes_gith", "Test", ТипВнешнейКомпоненты.Native);
	Гермес =  Новый("AddIn.Test.Hermes");
	
	//smb://[<username>@]<host.domain(домен не обязателен)>[:<port(не обязателен)>]/<share>/<path>
	р = Гермес.SMB_ПрочитатьКаталог("smb://Ivanov@MyHomeComputer/temp/kp", пароль_пользователя_на_компьютере);
	стк = JSON.РазобратьJSON(р);
	
	В ответ приходит структура с массивом объектов в указанном сетевом каталоге
	
КонецПроцедуры

&НаКлиенте
Процедура Самба_ПолучитьФайл(Команда)

	ДД = ПолучитьДвоичныеДанныеИзСтроки("1";);
	Прочитано = -1;
	Читать = 8388608;
	Поз = 0;
	ОбщийТекст = "";
	ИВФ = ПолучитьИмяВременногоФайла("cf";);

	Пока истина цикл
	//smb://[<username>@]<host.domain(домен не обязателен)>[:<port(не обязателен)>]/<share>/<path>
	р = Гермес.SMB_ПолучитьФайл("smb://username@host:445/temp/1cv8.cf", паруль, Читать, Поз, ДД);
	стк = JSON.РазобратьJSON(р);
	Если не стк.Status тогда
		ПоказатьПредупреждение(,стк.Description);
		Прервать;
	КонецЕсли;

	Прочитано = стк.Data.size;
	Поток = ФайловыеПотоки.Открыть(ИВФ, РежимОткрытияФайла.Дописать);
	Буф = ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(ДД);
	Поток.Записать(Буф,0,Буф.Размер);
	Поток.СброситьБуферы();
	Поток.Закрыть();

	Поз = Поз + Прочитано;
	Если Прочитано < Читать тогда прервать КонецЕсли;
	КонецЦикла;
		
	
	//Либо, если файлик не больше 8388608 байт, то его можно прочитать сразу весь - указав соответствующий РазмерБуффераДвоичныхДанных.
	//Входной буфер двоичных данных (здесь - "ДД") при вызове функции SMB_ПолучитьФайл каждый раз переопределяется и заполняется полученными данными.
	//Т.е. его размер при вызове функции - значения не имеет. По сути, это просто указатель.
	
	
КонецПроцедуры

&НаКлиенте
Процедура ЗаписатьФайл(Команда)

	//стр = "арбадакарба";
	//ДД = ПолучитьДвоичныеДанныеИзСтроки(стр);
	Буф = Новый БуферДвоичныхДанных(8388608);
	ДД = ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(Буф);

	//smb://[<username>@]<host.domain(домен не обязателен)>[:<port(не обязателен)>]/<share>/<path>
	р = Гермес.SMB_ЗаписатьФайл("smb://username@host:445/temp/111.txt", паруль, ДД, 0); // создает файл и открывает для записи. Если файл существует, то обрезает в ноль и открывает для записи
	р = Гермес.SMB_ЗаписатьФайл("smb://username@host:445/temp/111.txt", паруль, ДД, 1); // Открывает для записи и перемещает указатель в конец файла. (дозаписывает данные в конец файла).

	стк1 = JSON.РазобратьJSON(р);
	Сообщить(р);

КонецПроцедуры

Работа с regEx (используется встроенная в std библиотека (#include <regex>)).

&НаКлиенте
Процедура REX_match(Команда)
	р = Гермес.REX_Совпадения("0104603744393009215!&WLVz93BwZ5z310300100070032212030600", "^01(?:0{1,6}(\d{8,13}))21(.{6,7})(?:93.{4})z?(?:3103(\d{6}))(?:17|7003)(\d{6,10})$");
	Сообщить(р);
	стк = JSON.РазобратьJSON(р);
КонецПроцедуры

&НаКлиенте
Процедура REX_replace(Команда)
	р = Гермес.REX_Замена("0104603744393009215!&WLVz93BwZ5z310300100070032212030600", "^01(?:0{1,6}(\d{8,13}))21(.{6,7})(?:93.{4})z?(?:3103(\d{6}))(?:17|7003)(\d{6,10})$","[$1][$2][$3]");
	Сообщить(р);
	стк = JSON.РазобратьJSON(р);
КонецПроцедуры

QR-code генератор (используется com.github.kenglxn.QRGen:android:2.6.0).

&НаКлиенте
Процедура QRCodeGen(Команда)
	стрДжей = Гермес.QR_Сгенерировать("Some people, when confronted with a problem, think 
        								|""I know, I'll use regular expressions.""
        								|Now they have two problems... (https://en.cppreference.com/w/cpp/regex)", 250);
	сткРез = JSON.РазобратьJSON(стрДжей);
	
	Если не сткРез.Status тогда
		Возврат;
	КонецЕсли;
	
	ЭтаФорма.КартинкаШтрихкод = ПоместитьВоВременноеХранилище(новый картинка(Base64Значение(сткРез.data)),ЭтаФорма.УникальныйИдентификатор);
	
КонецПроцедуры

JSON-валидатор.

Что это такое: https://otus.ru/journal/schema-json-i-comments-chto-nuzhno-znat/ (в разделе "JSON Schema") или даже лучше: https://habr.com/ru/post/495766/.

Где может потребоваться: в тех ситуациях, когда нет уверенности, что придет JSON с тем составом и форматом полей или коллекций, который ожидается. Например, когда информация получается от неопределенного круга источников или когда нет уверенности в источнике.

Короче, согласно https://json-schema.org/, benefits такие:
1.Describes your existing data format(s).
2. Provides clear human- and machine- readable documentation.
3. Validates data which is useful for:
    3.1 Automated testing.
    3.2 Ensuring quality of client submitted data.

Пример использования:

&НаКлиенте
Процедура JVD_validate(Команда)
	
	Схема = "{
	|""$id"": ""tsdGoodsPosting"",
	|""description"": ""Данные о товаре, поступившем на точку в рамках маршрутного листа"",
	|""type"": ""object"",
	|""properties"": {
	|	""ДатаДок"": {
	|		""type"": ""string"",
	|		""pattern"": ""^20\\d{6}$""
	|	},
	|	""НомерДок"": {
	|		""type"": ""string""
	|	},
	|	""Товары"": {
	|		""type"": ""array"",
	|		""items"": {
	|			""$ref"": ""#/definitions/good""
	|		}
	|	}
	|},
	|""definitions"": {
	|	""good"": {
	|		""type"": ""object"",
	|		""required"": [
	|			""Товар_КодНСИ"",
	|			""ЕИ""
	|		],
	|		""properties"": {
	|			""Товар_КодНСИ"": {
	|				""type"": ""string"",
	|				""description"": """"
	|			},
	|			""ЕИ"": {
	|				""type"": ""string"",
	|				""description"": """"
	|			}
	|		}
	|	}
	|}
	|}";
	
	
	ДанныеОк = "
	|{
	|""ДатаДок"": ""20221125"",
	|""НомерДок"": ""005-00001315"",
	|""Товары"": [
	|	{
	|		""Товар_КодНСИ"": ""90000013"",
	|		""ЕИ"": """"
	|	},
	|	{
	|		""Товар_КодНСИ"": ""90012291"",
	|		""ЕИ"": """"
	|	}
	|]
	|}";
	
	стрДжей = Гермес.JVD_Проверить(Схема, ДанныеОк);
	
	стк = JSON.РазобратьJSON(стрДжей);
	
	ПоказатьПредупреждение(,стрДжей);
	
	ДанныеНЕОк = "
	|{
	|""ДатаДок"": ""30221125"",
	|""НомерДок"": ""005-00001315"",
	|""Товары"": [
	|	{
	|		""Товар_КодНСИ"": ""90000013"",
	|		""ЕИ"": """"
	|	},
	|	{
	|		""Товар_КодНСИ"": ""90012291""
	|	}
	|]
	|}";
	
	стрДжей = Гермес.JVD_Проверить(Схема, ДанныеНЕОк);
	
	стк = JSON.РазобратьJSON(стрДжей);
	
	ПоказатьПредупреждение(,стрДжей);
КонецПроцедуры

ОТВЕТЫ:
1. {"Data":"","Description":["OK"],"Status":true}
2. {"Data":"","Description":["Отсутствует обязательное поле 'ЕИ'. Объект: <root> --> [Товары] --> [1]","Провалена валидация значения на соответствие выражению RegEx. Объект: <root> --> [ДатаДок]"],"Status":false}

 

ИМХО: технология огонь. В среде 1с, она не слишком известна и востребована. Однако, быстрая валидация json по схемам очень будет полезной при обмене через rest+json.

P.S.
Библиотеки jsoncpp и valijson переведены мной на русский язык в одно лицо, так-что прошу прощения, если где-то перевод не слишком точен.

P.P.S.

Вариант ВК для Винды: //infostart.ru/public/1786101/.

Исходники:

https://github.com/KotVezdehod/Hermes

https://github.com/KotVezdehod/dreamcatcher_gith

Частично использован код из //infostart.ru/1c/articles/987286/

Скачать файлы

Наименование Файл Версия Размер
Внешняя компонента для мобильного приложения:

.zip 7,33Mb
3
.zip 7,33Mb 3 Скачать

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. sadiv 21 08.11.21 13:26 Сейчас в теме
Доброе время суток! Скажите, при распаковке zip-файлов каталоги восстанавливаются?
3. Prometeus2011 180 08.11.21 16:44 Сейчас в теме
(1) Архивация каталогов не поддерживается. Допускается сжимать только каждый файл по-отдельности.
2. SinglCOOLer 216 08.11.21 13:44 Сейчас в теме
1. Перехват широковещательных сообщений ОС андроид по заданному фильтру и ключу данных
Наивно полагал, что моб платформа уже научилась это делать
4. Prometeus2011 180 08.11.21 16:50 Сейчас в теме
(2) Согласен. Очень странно. Причем, в релизе 8.3.21 мобильной платформы был сделан анонс работы с zip-архивами (очевидно нашли в android-NDK библиотеку ZLIB ;)), но перехвата броадкастов так и нет). Забавно.
5. zaoproxy 35 11.11.21 15:02 Сейчас в теме
Хороший набор функций. Надо будет потестить.
Вопрос: если 1С свёрнута, т.е. не активна на текущий момент, будет ли продолжаться обработка внешних событий? будь то перехват широковещательных сообщений или входящих POST или PUT запросы?
6. Prometeus2011 180 12.11.21 10:07 Сейчас в теме
46. nick_e 2 11.01.23 06:21 Сейчас в теме
(6) что у вас в РазобратьJSON ? Хотел потестить компоненту, не увидел данной функции...
7. lion-killer 22 12.11.21 13:07 Сейчас в теме
Добрый день. Поддерживается ли перехват компонентой событий сканирования штрихкодов в терминалах сбора данных Cipherlab? Особенностью этих устройств является то что в поле Data они передают не строку, а двоичные данные.
8. Prometeus2011 180 12.11.21 15:29 Сейчас в теме
Добрый день!

Работа с бинарными данными в поле extra поддерживается.

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


extra = intent.getStringExtra(extra_key);
                                    if (extra == null) {
                                        b0 = intent.getByteArrayExtra(extra_key);
                                        if (b0 != null) {
                                            extra = new String(b0);
                                        }
                                    }
                                    if (extra == null || extra == "") {
                                        extra = "Доп. данные с ключом: '" + extra_key + "' не содержат данных!";
                                    }
Показать


Насчет получения данных из поля Data - сказать не могу, но столкнулся с ситуацией, когда метод getStringExtra возвращал null, при этом метод getByteArrayExtra() - работал нормально.
9. user790708 10.12.21 16:40 Сейчас в теме
Добрый день.
Можете добавить функцию для получения свойст системы (System.getProperty())?
Непосредственно интересует получение модели устройства и производителя (вот тут есть пример: https://stackoverflow.com/questions/1995439/get-android-phone-model-programmatically-how-to-get-device-name-and-model-prog), но и другие свойства могут пригодится.
10. Prometeus2011 180 13.12.21 10:23 Сейчас в теме
(9)Там это есть уже. Реализовано только не через функцию, а через свойство "ОписаниеУстройства" ("DeviceInfo") компоненты. Его можно увидеть в отладчике.

Свойство формируется конкатенацией из 2х полей: MANUFACTURER + MODEL.

wData = wManufacturer + L": " + wModel;
11. akR00b 21 21.01.22 13:07 Сейчас в теме
условия использования? можно ли в коммерческом проекте применять?
12. Prometeus2011 180 21.01.22 13:54 Сейчас в теме
13. Prometeus2011 180 21.01.22 17:17 Сейчас в теме
(11)Кстати, если будет идея насчет того, что можно еще добавить в компоненту, то пишите - добавлю.
14. akR00b 21 24.01.22 08:09 Сейчас в теме
(13)Хорошо, для полноты картины не хватает асинхронного снятия GPS координат, ну или просто метода для получения данных через внешние событие. Аналог тут https://infostart.ru/public/1497363/
15. Prometeus2011 180 24.01.22 09:45 Сейчас в теме
(14) Ок. Добавлю метод для получения координат и внешнее событие.
16. akR00b 21 24.01.22 10:55 Сейчас в теме
(15)Спасибо за оперативность! Ждем релиза;)
18. Prometeus2011 180 26.01.22 17:12 Сейчас в теме
(16)Добавил получение геоданных.
20. akR00b 21 27.01.22 12:54 Сейчас в теме
(18)а в архиве обработка с макетом компоненты или сразу собранное apk?
21. Prometeus2011 180 27.01.22 18:17 Сейчас в теме
(20)Архив, для целей моб платформы 1с - это макет типа внешняя компонента, выполненная по технологии Native. Чтобы ZIP-архив чудесным образом превратился в макет ВК, следует туда положить манифест, содержащий перечень файлов архива (библиотеки и apk-пакеты), а также указание разрядности и типа ОС, для которой предназначена конкретная библиотека или apk-пакет.
apk-пакет, содержащийся в архиве, выполняет одну единственную роль - служит контейнером для java-класса, который реализует в себе некоторые функции ВК (получение геоданных - в частности). В принципе, у него даже главной активити может не быть.
28. Prometeus2011 180 28.01.22 15:02 Сейчас в теме
(20)чего-то перечитал и понял, что написал много и не по делу. Архив из публикации - готовая внешняя компонента. Ее надо загрузить в общие макеты конфигурации и можно подключать, как подключаются все ВК native.
29. akR00b 21 01.02.22 09:26 Сейчас в теме
(28)Спасибо за подробный ответ, компоненту прикрутил, но я так понял что скачал старую версию. А новую с геоданными можно скачать только за новые SM?
Прикрепленные файлы:
17. user790708 26.01.22 16:39 Сейчас в теме
Сделал сервис, как описано в этой статье https://infostart.ru/public/1039819/

В сервисе передаю строку так:
Intent intent = new Intent();
intent.putExtra("KeyEvent", eventString);

В конфигурации настроил получение широковещательных сообщений с помощью вашей компоненты:
Интенты = Новый Массив;
Интенты.Добавить(Новый Структура("filter, extra", "com.example.SendBroadcast", "KeyEvent"));

В 1с вызывается событие по сообщению сервиса, но в данных пустая строка (заполнены только Источник и Событие).
Что это может быть?
19. Prometeus2011 180 26.01.22 17:29 Сейчас в теме
(17) Сложно так сказать. Вроде, тут все просто. Попробуйте использовать LogCat, чтобы увидеть, какие данные идут в вашем броадкасте.
Потом попробуйте реализовать собственный перехватчик вашего-же броадкаста. Возможно, это покажет изъян).
Вот кусок кода, который ищет данные в броадкасте. Может это поможет вам.
Этот код также можно посмотреть и в репозитории программы - на GitHub.

for (int i = 0; i < bk_filters.length(); i++) {
                        try {

                            intent_action = bk_filters.getJSONObject(i).getString("filter");
                            if (intent_action.equals(action)) {
                                extra_key = bk_filters.getJSONObject(i).getString("extra");
                                if (extra_key != "") {
                                    extra = intent.getStringExtra(extra_key);
                                    if (extra == null) {
                                        b0 = intent.getByteArrayExtra(extra_key);
                                        if (b0 != null) {
                                            extra = new String(b0);
                                        }
                                    }
                                    if (extra == null || extra == "") {
                                        extra = "Доп. данные с ключом: '" + extra_key + "' не содержат данных!";
                                    }

                                    cl_bk_result loc_ob = new cl_bk_result();
                                    loc_ob.action = intent_action;
                                    loc_ob.key = extra_key;
                                    loc_ob.Data = extra;

                                    OnBroadcastCatched(m_V8Object, gson.toJson(loc_ob));
                                } else {
                                    OnBroadcastCatched(m_V8Object, "ok_en");
                                }
                                break;
                            }
                        } catch (Exception ex) {
                        }
                    }


Показать
22. user790708 28.01.22 03:39 Сейчас в теме
(19)
Выяснил в 1С:
В процедуре ОбработкаВнешнегоСобытия в модуле формы данные приходят.
А в процедуре ОбработкаВнешнегоСобытия в модуле Приложения - Данные пустая строка.
Событие в модуле Приложения вызывается позже.
Можете подтвердить такое поведение?

Я использую обработку в модуле Приложения, так как в мобильном приложении если последовательно открыто несколько форм и в каждой форме есть Обработка внешних событий, то она будет вызвана в каждой форме, а не один раз.
В типовых конфах от 1с реализовано тоже через обработку в модуле Приложения.
23. Prometeus2011 180 28.01.22 10:51 Сейчас в теме
(22)Не подтверждаю. Что-то странное у вас происходит с платформой. Тестировалось все на платформах с 18 по 20ю.
Внешнее событие с данными приходит и в форму и в глобальный обработчик. Попробуйте использовать другу версию платформы.
Прикрепленные файлы:
2022-01-28_9-38-33.mp4
25. user790708 28.01.22 12:48 Сейчас в теме
(23)Понял. У меня мобильная платформа 8.3.16.142 выше использовать не могу, там финт с автообновлением конфы в приложении не работает.
26. user790708 28.01.22 13:23 Сейчас в теме
(23)Все работает. Спасибо!
Была ошибка в коде.
Prometeus2011; +1 Ответить
27. Prometeus2011 180 28.01.22 14:59 Сейчас в теме
30. user1759157 14.04.22 10:02 Сейчас в теме
(0)
Метод "ВК.ГЕО_ПолучитьСейчас(истина, истина);" возвращает строку: "{"data":"","description":"","object":[{"GPS":true,"NETWORK":true}],"status":true}" так и должно быть?
31. Prometeus2011 180 18.04.22 15:16 Сейчас в теме
32. user1759157 19.04.22 06:29 Сейчас в теме
33. AnDrU89 06.06.22 07:55 Сейчас в теме
Добрый день. Для iOS не планируется портировать?
34. Prometeus2011 180 07.06.22 11:50 Сейчас в теме
35. nkroshko 20.09.22 17:05 Сейчас в теме
Добрый день. Определение географических координат происходит через сервисGoogle или без его помощи? Это важно, т.к. на некоторых смартфонах Huawei / Honor сервисы Google отсутствуют
36. Prometeus2011 180 21.09.22 12:56 Сейчас в теме
(35) Здравствуйте!

Для получения координат используется функционал системного Android-сервиса "Context.LOCATION_SERVICE".

Код:

if (loc_manager == null) {

            loc_manager = (LocationManager) m_Activity.getSystemService(Context.LOCATION_SERVICE);

        }

        boolean isGpsProviderEnabled = false;
        boolean isNetworkProviderEnabled = false;

        if (gps_provider)
        {

            if (loc_manager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
                isGpsProviderEnabled = true;
            }
            if (isGpsProviderEnabled){
                if (gps_loc_listener == null) {
                    gps_loc_listener = new gpsLocListener();
                }
                if (loc_manager != null) {
                    Log.w("Hermes",LocationManager.GPS_PROVIDER);
                    loc_manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, gps_loc_listener, Looper.getMainLooper());

                }
            }
        }

        if (net_provider)
        {
            if (loc_manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
                isNetworkProviderEnabled = true;
            }
            if (isNetworkProviderEnabled){
                if (net_loc_listener == null) {
                    net_loc_listener = new netLocListener();
                }

                if (loc_manager != null) {
                    Log.w("Hermes",LocationManager.NETWORK_PROVIDER);
                    loc_manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, net_loc_listener,Looper.getMainLooper());
                }
            }
        }
Показать


Вероятно, следует уточнить, есть-ли на вашем устройстве такой системный сервис.
37. nkroshko 21.09.22 13:13 Сейчас в теме
38. nkroshko 29.09.22 15:20 Сейчас в теме
Добрый день,

еще вопрос:
При определении гео координат и вызове метода

Р = ВК.ГЕО_ПолучитьСейчас(истина, истина);

получаю в Р следующие данные:
{
"Data": ""
"Description": "JNI Error"
"Status": false
}

Разрешение на местоположение выдал, версия мобильной платформы 8.3.21.41. В чем может быть ошибка?
39. Prometeus2011 180 30.09.22 09:36 Сейчас в теме
(38)

1. Возможно, вы переименовали apk-пакет, когда собирали компоненту:
Расположенная в cpp классе "SendData" библиотеки "Hermes_ХХХ.so" константа
const wchar_t* CATCHER_CLASS_NAME = L"ru.somecompany.dreamcatcher.catcher";

определяет имя вашего пакета, который будет использоваться для вызова Android-методов.
Если по указанному в этой константе имени пакет найти не удается, то не создается и java-объект, из которого и вызывается метод "GetLocationNow".
Чтобы проверить гипотезу попробуйте ПОСЛЕ неудачного вызова ГЕО_ПолучитьСейчас() дернуть какой-нибудь другой метод, например, метод Архитектура(). Он тоже должен провалиться с такой-же ошибкой.
Для понимания, ошибка JNI генерится в методе GetLocationNow так:
void SendData::GetLocationNow(tVariant* paParams, tVariant* pvarRetValue)
{
	if (obj)
	{
		JNIEnv* env = getJniEnv();
		jmethodID methID = env->GetMethodID(cc, "GetLocationNow", "(ZZ)Ljava/lang/String;");
		jstring stringObject = static_cast<jstring>(env->CallObjectMethod(obj, methID, (&paParams[0])->bVal, (&paParams[1])->bVal));
		wstring std_wstr = ToWStringJni(stringObject);
		ToV8String(std_wstr.c_str(), pvarRetValue, loc_iMemoryManager);
		env->DeleteLocalRef(stringObject);

	}
	else
	{
		DiagToV8String(pvarRetValue, loc_iMemoryManager, false, L"JNI Error");
	}

	return;
}
Показать



2. Возможно, что-то с платформой. Каждый релиз мобильной платформы 1с сопровождается ворохом новых ошибок в самых неожиданных местах. Например, в платформах, начиная с версии 8.3.2х ВК в серверном контексте не работает.
В любом случае - проблема в том, что компонента по какой-то причине не может создать нужный ей для работы JAVA-объект на основании JAVA-класса из APK-пакета в составе компоненты.
Создается он в cpp классе "SendData":
void SendData::Initialize(IAddInDefBaseEx* cnn, IMemoryManager *in_iMemoryManager)
{
	loc_iMemoryManager = in_iMemoryManager;

	if (!obj)
	{
		helper = (IAndroidComponentHelper*)cnn->GetInterface(eIAndroidComponentHelper);
		if (helper)
		{
			WCHAR_T* className = nullptr;

                        convToShortWchar(&className, CATCHER_CLASS_NAME);

			jclass ccloc = helper->FindClass(className);             //ПОИСК JAVA-КЛАССА ИЗ ПАКЕТА - ДЛЯ СОЗДАНИЯ JAVA-ОБЪЕКТА

			delete[] className;

			className = nullptr;

			if (ccloc)
			{

				JNIEnv* env = getJniEnv();

				cc = static_cast<jclass>(env->NewGlobalRef(ccloc));

				env->DeleteLocalRef(ccloc);

				jobject activity = helper->GetActivity();

				// call of constructor for java class
				jmethodID methID = env->GetMethodID(cc, "<init>", "(Landroid/app/Activity;J)V");
				//jmethodID methID = env->GetMethodID(cc, "<init>", "(Landroidx.core.app.ActivityCompat;J)V");

				jobject objloc = env->NewObject(cc, methID, activity, (jlong)cnn);

				obj = static_cast<jobject>(env->NewGlobalRef(objloc));

				env->DeleteLocalRef(objloc);

				methID = env->GetMethodID(cc, "show", "()V");

				env->CallVoidMethod(obj, methID);

				env->DeleteLocalRef(activity);
			}
		}
	}
}
Показать
40. nkroshko 30.09.22 13:45 Сейчас в теме
(39)
Благодарю за ответ!

проверил, что возвращает метод Архитектура() - результат: JNI Error
Но не совсем понял, как я мог переименовать apk пакет при сборке компонеты.
Я подключил компоненту как макет в 1с конфигурацию, в сборщике мобильного приложения компонента выглядит так:
Прикрепленные файлы:
41. Prometeus2011 180 30.09.22 18:01 Сейчас в теме
(40)
Все проверил: это я допустил ошибку при сборке последнего релиза.
Прошу прощения...

Архив заменил.
Чтобы снова не скачивать компоненту, замените в архиве файлы:
- app-release.apk
- MANIFEST.XML
на прилагающиеся.
И... должно заработать.
Прикрепленные файлы:
app-release.apk
MANIFEST.XML
42. nkroshko 30.09.22 20:52 Сейчас в теме
(41)
Спасибо огромное!
Координаты передались в приложение во внешнем событии! )
43. nkroshko 28.10.22 20:01 Сейчас в теме
Здравствуйте,
А есть ли техническая возможность в эту компоненту добавить функционал определения режима подмены координат (fake gps)?
44. Prometeus2011 180 01.11.22 12:10 Сейчас в теме
(43) Здравствуйте!
Как реализуется подмена координат?
Если с помощью включения на устройстве отладочных функций разработчика и установкой специального софта, то там, кажется, это работает только с GPS-координатами.
Отсюда вывод - если не идут координаты от NETWORK_PROVIDER, то это подозрительно...
Можно просканировать устройство на наличие установленных пакетов программ обхода.
Для этого права системного приложения не нужны.

Код на java вот:

 public boolean isAppPackageInstalled(Context context)
    {
        List<ApplicationInfo> packages;
        PackageManager pm;

        pm = context.getPackageManager();
        packages = pm.getInstalledApplications(0);
        for (ApplicationInfo packageInfo : packages) {
            if(packageInfo.packageName.equals("ru.somecompany.someapp"))
                return true;
        }
        return false;
    }
Показать


Проблем с подгрузкой зависимостей и импортами нет.

Ответ - да, можно.
Нет, делать не буду).
Мы реализуем контроль наших 100500 устройств через сторонний софт и проблем с этим не возникает.
45. nkroshko 03.11.22 11:52 Сейчас в теме
Благодарю за ответ!

протестил несколько приложений для подмены координат, некоторые подменяют GPS провайдер только, а другие и NETWORK, поэтому проверять только провайдера, наверное, будет недостаточно... В общем буду искать решение)
Оставьте свое сообщение

См. также

Разработка внешней компоненты по технологии Native API. Мониторинг файловой системы в 1С

Разработка внешних компонент Платформа 1С v8.3 Россия Абонемент ($m)

Пример разработки внешней компоненты по технологии Native API для мониторинга выбранной папки файловой системы (изменение, переименование, удаление) файлов.

1 стартмани

12.03.2023    3146    2    binx    3    

41

Конвертор из PDF

Разработка внешних компонент Платформа 1С v8.3 Абонемент ($m)

Native компонента для рендеринга PDF в картинки, и (или) извлечения текста из PDF файлов.

2 стартмани

25.01.2023    1812    13    bmk74    8    

21

Внешняя компонента JSON-валидатор

Разработка внешних компонент Платформа 1С v8.3 Абонемент ($m)

Внешняя компонента под ОС семейства windows, реализующая функционал по проверке соответствия json-пакета заданной схеме ("Валидация").

1 стартмани

09.01.2023    1704    2    Prometeus2011    2    

16

Взаимодействие мобильного приложения 1С и центральной информационной базы с использованием http-сервиса

Мобильная разработка Платформа 1С v8.3 1С:Комплексная автоматизация 2.х Казахстан Абонемент ($m)

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

1 стартмани

07.06.2022    4104    17    3dice    8    

16

Пишем внешнюю компоненту для 1С, NativeAPI на С++, для ОС Linux, с использованием Qt Creator

Разработка внешних компонент Платформа 1С v8.3 Конфигурации 1cv8 Россия Абонемент ($m)

В статье рассмотрен процесс создания внешней компоненты для 1С в среде Qt Creator для операционной системы Linux (ubuntu, debian, mint и им подобных). На примере компоненты для сбора данных от внешней аппаратуры и сохранение их в базе, посредством 1С. В качестве внешней аппаратуры в данном примере будем использовать Arduino UNO.

1 стартмани

13.05.2022    7396    4    user1779098    34    

61

Программы для исполнения 54-ФЗ Промо

С 01.02.2017 контрольно-кассовая техника должна отправлять электронные версии чеков оператору фискальных данных - правила установлены в 54-ФЗ ст.2 п.2. Инфостарт предлагает подборку программ, связанных с применением 54-ФЗ, ККТ и электронных чеков.

Делаем табло в обозревателе из 1Ски с нуля за полчаса. Без бутстрапов, реактов и ангуляров. Жизнетрюки от kuzkov.info

Разработка внешних компонент WEB-интеграция Платформа 1С v8.3 Абонемент ($m)

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

1 стартмани

02.05.2022    8025    124    Steelvan    0    

66

Внешняя Native API компонента совместно с функционалом фреймворка Qt

Разработка внешних компонент Платформа 1С v8.3 Абонемент ($m)

В данном примере реализована интеграция внешней компоненты, написанной с использованием технологии Native API и фреймворка Qt.

1 стартмани

20.02.2022    5401    8    tav_74    2    

17

Внешняя компонента - универсальный, надежный перехватчик клавиатурных событий

Разработка внешних компонент Платформа 1С v8.3 Абонемент ($m)

Перехват нажатия клавиш в 1С реализован с привязкой к фокусу формы. Если форма (или главное окно процесса 1С) теряет фокус, то перехват перестает работать. Чтобы решить эту проблему, была разработана соответствующая внешняя компонента.

1 стартмани

29.11.2021    7621    19    Prometeus2011    14    

36

1Scan. Интеграция веб-клиента 1С с устройством Android (смартфон, планшет, ТСД)

Мобильная разработка WEB-интеграция Платформа 1С v8.3 Абонемент ($m)

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

1 стартмани

15.11.2021    9177    37    kild    33    

29

Программы для исполнения 488-ФЗ: Маркировка товаров Промо

1 января 2019 года вступил в силу ФЗ от 25.12.2018 № 488-ФЗ о единой информационной системе маркировки товаров с использованием контрольных (идентификационных) знаков, который позволяет проследить движение товара от производителя до конечного потребителя. Инфостарт предлагает подборку программ, связанных с применением 488-ФЗ и маркировкой товаров.

Распознавание речи в мобильном приложении 1С на Android

Мобильная разработка Разработка внешних компонент Мобильная платформа Абонемент ($m)

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

1 стартмани

15.07.2021    9046    8    salexdv    6    

35

Дневник времени. Простое мобильное приложение 1С для телефона на Андроид

Мобильная разработка Мобильная платформа Абонемент ($m)

Дневник времени. Для адептов тайм-менеджмента и всех тех, кто ценит свое время. Предназначен для ежедневных записей в телефоне расхода времени на различные задачи. Отчет по записям программы позволяет увидеть, сколько времени, на какие задачи расходовалось и проанализировать траты времени за месяц. Можно выгрузить записи в csv файл и анализировать на дескопном компьютере, например в Экселе. Можно составлять планы на день и отмечать, что удалось сделать, а что нет.

1 стартмани

12.03.2021    6557    6    pricec    1    

6

Мобильное приложение для 1C:Drive для фотоотчетов с сохранением фотографий в Microsoft Azure Blob storage

Мобильная разработка Мобильная платформа Абонемент ($m)

Пример реализации мобильного приложения, которое использует Microsoft Azure Blob storage для сохранения фотографий и передает сведения о сделанных фотографиях в 1C:Drive.

1 стартмани

26.02.2021    6710    6    keypax    4    

6

Авторизация в мобильном приложении 1С

Роли и права Мобильная разработка Платформа 1С v8.3 Мобильная платформа Конфигурации 1cv8 Абонемент ($m)

Реализация входа по паролю (личному коду) в мобильном приложении 1С.

10 стартмани

23.02.2021    11258    9    kaiman_fedor_yandex    0    

13

Работа с 1С:Аналитика Промо

Онлайн-курс предусматривает изучение возможностей системы “1С:Аналитика”, которая работает как составная часть платформы “1С:Предприятие” и обеспечивает оперативный просмотр и анализ необходимых данных.

4500 рублей

Внешняя компонента: Android tools

Мобильная разработка Разработка внешних компонент Платформа 1С v8.3 Мобильная платформа Абонемент ($m)

Несколько дополнительных функций для мобильного приложения\клиента под Android. Размер архива внешних компонент под архитектуры ARM и x86 - 390KB.

1 стартмани

12.01.2021    12954    36    KAV2    46    

15

Выбор документов на мобильном устройстве (iOS)

Мобильная разработка Мобильная платформа Абонемент ($m)

При внедрении мобильного приложения, имеющего в своём функционале работу с файлами, возникла необходимость прикреплять к документам не только фотографии из библиотеки мультимедиа или тут же созданные фотографии, а документы (pdf, doc, xlsx, и др.). В операционной системе iOS файловая система скрыта для пользователя и взаимодействие с файлами осуществляется средствами самого приложения и только с файлами, расположенными в директории приложения (контейнере приложения). Т.е. задачей было поместить файлы в директорию приложения и организовать взимодествие с этим каталогом.

1 стартмани

29.11.2020    7048    0    OlegK    0    

2

Использование встроенного сканера ТСД на Android в мобильном клиенте и мобильном приложении (драйвер сканера Android для 1С)

Разработка внешних компонент Мобильная разработка Платформа 1С v8.3 Абонемент ($m)

Используя данный драйвер, можно без единой строки кода, просто установив на ТСД мобильный клиент 1С, сразу начать подбирать товары в документах вашей учётной системы. А, адаптировав нужные формы под небольшой размер экрана ТСД, можно просто создать полноценное рабочее место для выполнения операций с помощью ТСД, не прибегая к стороннему софту. Если же на складе плохая связь (или её нет вовсе), то можно использовать возможности мобильного клиента в автономном режиме (потребуется доработка вашей конфигурации). Драйвер также можно использовать и для Android приложения на мобильной платформе. В результате чего можно обойтись без ненужных полей ввода и клавиатуры «на пол-экрана».

3 стартмани

09.10.2020    48674    356    ltfriend    211    

104

Видеокурс-практикум: как подготовить и написать ТЗ, ЗНР, ЧТЗ. Промо

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

3 500 рублей

Мобильная платформа. Штрихкоды в Android.

Разработка внешних компонент Мобильная разработка Сканер штрих-кода Мобильная платформа Абонемент ($m)

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

3 стартмани

14.09.2020    8359    5    kinan    19    

5

Внешняя компонента на C# для парсинга страниц через Phantom JS на сервере 1С х32,х64

Инструментарий разработчика Разработка внешних компонент WEB-интеграция Мессенджеры и боты Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

PhantomJS - это браузер без окна, используемый для автоматизации взаимодействия с веб-страницами. PhantomJS предоставляет JavaScript API, обеспечивающий автоматическую навигацию, снимки страницы, эмуляции поведение пользователя, что делает его распространенным инструментом, используемым для запуска модульных тестов на основе браузера в автономной системе, такой как среда непрерывной интеграции . PhantomJS основан на WebKit, что делает его похожей на Safari и Google Chrome средой просмотра. Это программное обеспечение с открытым исходным кодом, выпущенное под лицензией BSD.

1 стартмани

06.08.2020    11055    8    DrZombi    7    

22

Расширение "PUSH уведомления для мобильного клиента".

Мобильная разработка Мобильная платформа 1С:Комплексная автоматизация 1.х 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:CRM ПРОФ, КОРП Россия Абонемент ($m)

Расширение для отправки PUSH уведомлений в мобильный клиент на Android. Подходит для типовых конфигураций, протестирована на конфигурации КА 2.4.

1 стартмани

04.08.2020    10313    25    romanpolyashov@yandex.ru    0    

14

Универсальная обертка для использования NATIVE компонент на платформе 1С 7.7, 8.0 и 8.1

Разработка внешних компонент Платформа 1С v8.3 Абонемент ($m)

Используете 1С 7.7, 8.0 или 8.1 и вас раздражает, что под вашу 1С уже не выпускаются современные компоненты. А хотелось бы?

1 стартмани

07.07.2020    12012    10    karpik666    5    

15

Подборка решений для взаимодействия со ФГИС «Меркурий» Промо

С 1 июля 2019 года все компании, участвующие в обороте товаров животного происхождения, должны перейти на электронную ветеринарную сертификацию (ЭВС) через ФГИС «Меркурий». Инфостарт предлагает подборку программ, связанных с этим изменением.

Нано HTTP сервер - внешняя компонента для мобильного приложения 1C, на Android

Разработка внешних компонент Мобильная разработка Платформа 1С v8.3 Мобильная платформа Конфигурации 1cv8 Абонемент ($m)

Нано HTTP сервер на терминале сбора данных "ATOL Smart.Lite android 7.0". Работает только с GET и POST запросами. Аутентификация BASE64. Не поддерживает HTTPS и не передает файлы. В прикрепленном архиве исходники на компоненту (С++ и java для Android Studio 3.6.2), ЦФ - мобильного приложения и тестовая обработка.

1 стартмани

22.06.2020    12041    18    SanyMaga    23    

18

miniWms. Программное решение для автоматизации склада

Мобильная разработка Учет ТМЦ Платформа 1С v8.3 1С:Управление торговлей 11 Оптовая торговля, дистрибуция, логистика Управленческий учет Абонемент ($m)

Готовое Android приложение для автоматизации складских операций УТ 11. Доработка конфигурации не требуется. Навыки разработчика не требуются.

1 стартмани

16.06.2020    7956    9    Basili02    7    

12

Перехват сканирования Android Native API

Разработка внешних компонент Мобильная разработка Мобильная платформа Абонемент ($m)

Native компонента для перехвата сканирования шк и передачу в мобильную 1С.

1 стартмани

29.04.2020    18383    89    evgeny43    82    

18

Внешняя компонента Native API для управления окнами и буфером обмена, получения снимков окон Windows и Linux

Разработка внешних компонент Управляемые формы Россия Абонемент ($m)

Внешняя компонента Native API для Windows и Linux с исходными кодами на C++. Возможности компоненты: получение списка окон и списка процессов, управление размерами и положением окна, снимок окон и снимок экрана, доступ к данным буфера обмена, взаимодействие по протоколу WebSocket.

2 стартмани

16.04.2020    11469    24    kandr    13    

29

Готовые переносы данных из различных конфигураций 1C Промо

Рекомендуем готовые решения для переноса данных из различных конфигураций 1C. C техподдержкой от разработчиков и гарантией от Инфостарт.

Android Java и NativAPI C++ внешняя компонента для широковещательных сообщений (отправка и прием). Подключаем сканер ШК и клавиатуру к "1С мобильное приложение"

Оптовая торговля Розничная торговля Сканер штрих-кода Разработка внешних компонент Мобильная разработка Мобильная платформа Оптовая торговля, дистрибуция, логистика Абонемент ($m)

Подключаем сканер ШК и клавиатуру к "1С мобильное приложение", на терминале сбора данных "ATOL Smart.Lite android 7.0". Работаем с буфером обмена. В архиве к теме; 1. исходник компоненты (папка package готовый zip); 2. исходник "AccessibilityService" для перехвата клавиатуры (папка package готовый apk); 3. cf - тестовая конфигурация

1 стартмани

15.04.2020    17387    102    SanyMaga    102    

20

Получение фото с веб-камеры

Разработка внешних компонент Платформа 1С v8.3 Абонемент ($m)

Получение фото с веб-камеры без ActiveX. Внешняя компонента по технологии Native API.

1 стартмани

25.03.2020    19847    172    berezdetsky    51    

27

Обработка голосового ввода текста с использованием (intent)

Мобильная разработка Мобильная платформа Конфигурации 1cv8 Абонемент ($m)

Обработка для голосового ввода текста с использованием дополнительных возможностей ОС Android.

1 стартмани

26.02.2020    8803    5    algabas    7    

3

1СПАРК РИСКИ. Сервис оценки благонадежности контрагентов. Промо

СПАРК помогает предотвратить мошенничество со стороны компаний и предпринимателей, благодаря актуальным сведениям о компаниях и системе выявления факторов риска.Сервис позволяет управлять налоговыми рисками и комплексно оценивать благонадежность контрагентов.

Быстрая печать этикеток (ZPL, EPL, TSPL, EZPL, GEPL, TSPL-EZ)

Разработка внешних компонент Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Качественная и быстрая печать на внутреннем языке принтеров этикеток.

4 стартмани

02.02.2020    21619    76    Johny_v    19    

33

Наш путь к эффективной инвентаризации склада

Учет ТМЦ Розничная торговля Мобильная разработка Платформа 1С v8.3 Управленческий учет Абонемент ($m)

В работе любой торговой организации всегда остро стоит вопрос контроля остатков на складе. И здесь не обойтись без проведения инвентаризации товаров. В этой публикации рассмотрим наш путь и выбранное решение ее проведения.

8 стартмани

12.01.2020    12295    2    Johny_v    23    

13

Сканирование по TWAIN в 1С (обычные и управляемые формы)

Разработка внешних компонент Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Обработка показывает пример, как можно в 1С проводить сканирование с помощью компоненты TWAIN.

3 стартмани

03.01.2020    14713    48    Denr83    0    

20

Обмен данными с Android через USB

Мобильная разработка Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Обработка с примером обмена данными конфигурации 1С через USB. Без установки Web сервера и настройки WiFi.

1 стартмани

23.12.2019    10719    8    asdfgcom    3    

15

Simple UI: простой конструктор мобильных приложений для устройств на Android. Обновление от 15.03.23

Мобильная разработка Платформа 1С v8.3 Управленческий учет Абонемент ($m)

Simple UI – это полностью бесплатная платформа для создания мобильных рабочих мест на Android. Конструктор позволяет создавать мобильные клиенты для учетных систем и самостоятельные приложения на телефонах, ТСД (терминалах сбора данных), планшетах, электронных киосках и других устройствах. При этом не нужно разбираться в мобильной разработке, Android SDK ведь основная цель платформы – максимально упростить процесс разработки и поддержки, сделать его визуальным, собирать приложения из готовых блоков с минимумом кода. Причем код обработчиков можно писать на языке учетной системы либо задавать логику обработки событий с помощью команд REST, SQL и визуального конструктора. Проект постоянно развивается изыскивая новые способы упрощения разработки и повышения функционала и является пожалуй самым быстрым способом как создать MVP-проект так и продакшн-систему под конкретное внедрение или тиражный продукт.Тестировалось на 1С: Предприятие 8.3 релиз 8.3.13.1865.

1 стартмани

14.11.2019    45594    447    informa1555    249    

185