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

Публикация № 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(р);
	
	В ответ приходит структура с массивом объектов в указанном сетевом каталоге
	
КонецПроцедуры

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

	буфОбщий = новый БуферДвоичныхДанных(0);
	ДД  = ПолучитьДвоичныеДанныеИзСтроки("1");
	Прочитано = -1;
	Читать = 10;
	Поз = 0;
	ОбщийТекст = "";
	Пока истина цикл
		//smb://[<username>@]<host.domain(домен не обязателен)>[:<port(не обязателен)>]/<share>/<path>
		р = Гермес.SMB_ПолучитьФайл("smb://Ivanov@MyHomeComputer/temp/J_fails_20220906.txt", паруль, Читать, Поз, ДД);
		
		//В структуре возвращается состояние успеха/провала чтения файла и объем прочитанных байт.
		стк = JSON.РазобратьJSON(р);
		
		
		Прочитано = стк.Data.size;
		буфОбщий = буфОбщий.Соединить(ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(ДД));
		Поз = Поз + Прочитано;
		
		Если Прочитано < Читать тогда прервать КонецЕсли;
	КонецЦикла;
	стр = ПолучитьСтрокуИзДвоичныхДанных(ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(буфОбщий));
		
	
	//Либо, если файлик не больше 16 мегабайт, то его можно прочитать сразу весь - указав соответствующий РазмерБуффераДвоичныхДанных.
	//Входной буфер двоичных данных (здесь - "ДД") при вызове функции SMB_ПолучитьФайл каждый раз переопределяется и заполняется полученными данными.
	//Т.е. его размер при вызове функции - значения не имеет. По сути, это просто указатель.
	
	
КонецПроцедуры

&НаКлиенте
Процедура ЗаписатьФайл(Команда)
	стр = "арбадакарба";
	ДД  = ПолучитьДвоичныеДанныеИзСтроки(стр);
	
	//smb://[<username>@]<host.domain(домен не обязателен)>[:<port(не обязателен)>]/<share>/<path>
	р = Гермес.SMB_ЗаписатьФайл("smb://Ivanov@MyHomeComputer/temp/temp/111.txt", паруль, ДД);
	стк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.

Вариант ВК для Винды: //soft.crimea.com/public/1786101/.

Исходники:

https://github.com/KotVezdehod/Hermes

https://github.com/KotVezdehod/dreamcatcher_gith

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

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

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

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

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

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. sadiv 21 08.11.21 13:26 Сейчас в теме
Доброе время суток! Скажите, при распаковке zip-файлов каталоги восстанавливаются?
3. Prometeus2011 178 08.11.21 16:44 Сейчас в теме
(1) Архивация каталогов не поддерживается. Допускается сжимать только каждый файл по-отдельности.
2. SinglCOOLer 216 08.11.21 13:44 Сейчас в теме
1. Перехват широковещательных сообщений ОС андроид по заданному фильтру и ключу данных
Наивно полагал, что моб платформа уже научилась это делать
4. Prometeus2011 178 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 178 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 178 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 178 13.12.21 10:23 Сейчас в теме
(9)Там это есть уже. Реализовано только не через функцию, а через свойство "ОписаниеУстройства" ("DeviceInfo") компоненты. Его можно увидеть в отладчике.

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

wData = wManufacturer + L": " + wModel;
11. akR00b 21.01.22 13:07 Сейчас в теме
условия использования? можно ли в коммерческом проекте применять?
12. Prometeus2011 178 21.01.22 13:54 Сейчас в теме
13. Prometeus2011 178 21.01.22 17:17 Сейчас в теме
(11)Кстати, если будет идея насчет того, что можно еще добавить в компоненту, то пишите - добавлю.
14. akR00b 24.01.22 08:09 Сейчас в теме
(13)Хорошо, для полноты картины не хватает асинхронного снятия GPS координат, ну или просто метода для получения данных через внешние событие. Аналог тут https://infostart.ru/public/1497363/
15. Prometeus2011 178 24.01.22 09:45 Сейчас в теме
(14) Ок. Добавлю метод для получения координат и внешнее событие.
16. akR00b 24.01.22 10:55 Сейчас в теме
(15)Спасибо за оперативность! Ждем релиза;)
18. Prometeus2011 178 26.01.22 17:12 Сейчас в теме
(16)Добавил получение геоданных.
20. akR00b 27.01.22 12:54 Сейчас в теме
(18)а в архиве обработка с макетом компоненты или сразу собранное apk?
21. Prometeus2011 178 27.01.22 18:17 Сейчас в теме
(20)Архив, для целей моб платформы 1с - это макет типа внешняя компонента, выполненная по технологии Native. Чтобы ZIP-архив чудесным образом превратился в макет ВК, следует туда положить манифест, содержащий перечень файлов архива (библиотеки и apk-пакеты), а также указание разрядности и типа ОС, для которой предназначена конкретная библиотека или apk-пакет.
apk-пакет, содержащийся в архиве, выполняет одну единственную роль - служит контейнером для java-класса, который реализует в себе некоторые функции ВК (получение геоданных - в частности). В принципе, у него даже главной активити может не быть.
28. Prometeus2011 178 28.01.22 15:02 Сейчас в теме
(20)чего-то перечитал и понял, что написал много и не по делу. Архив из публикации - готовая внешняя компонента. Ее надо загрузить в общие макеты конфигурации и можно подключать, как подключаются все ВК native.
29. akR00b 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 178 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 178 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 178 28.01.22 14:59 Сейчас в теме
30. user1759157 14.04.22 10:02 Сейчас в теме
(0)
Метод "ВК.ГЕО_ПолучитьСейчас(истина, истина);" возвращает строку: "{"data":"","description":"","object":[{"GPS":true,"NETWORK":true}],"status":true}" так и должно быть?
31. Prometeus2011 178 18.04.22 15:16 Сейчас в теме
32. user1759157 19.04.22 06:29 Сейчас в теме
33. AnDrU89 06.06.22 07:55 Сейчас в теме
Добрый день. Для iOS не планируется портировать?
34. Prometeus2011 178 07.06.22 11:50 Сейчас в теме
35. nkroshko 20.09.22 17:05 Сейчас в теме
Добрый день. Определение географических координат происходит через сервисGoogle или без его помощи? Это важно, т.к. на некоторых смартфонах Huawei / Honor сервисы Google отсутствуют
36. Prometeus2011 178 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 178 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 178 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 178 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, поэтому проверять только провайдера, наверное, будет недостаточно... В общем буду искать решение)
Оставьте свое сообщение

См. также

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

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

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

1 стартмани

12.03.2021    6176    6    pricec    1    

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

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

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

2 стартмани

25.01.2023    874    7    bmk74    6    

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

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

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

1 стартмани

09.01.2023    1138    1    Prometeus2011    2    

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

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

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

1 стартмани

07.06.2022    3291    14    3dice    8    

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

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

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

1 стартмани

12.01.2021    12172    33    KAV2    39    

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

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

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

1 стартмани

13.05.2022    6477    3    user1779098    34    

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

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

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

1 стартмани

02.05.2022    7030    124    Steelvan    0    

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

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

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

1 стартмани

20.02.2022    4837    7    tav_74    2    

Внешняя компонента для работы по Web-socket протоколу x32 x64 Промо

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

Кто когда-нибудь сталкивался с обменом данными по Web-Socket (wss) протоколу из 1С, тому известно, что в платформе отсутствуют данные механизмы (не путать с HTTP запросами и WebServices). Предлагается использовать внешнюю компоненту, написанную по технологии NativeAPI, для подключения и обмена с серверами из 1С-Предприятия, работающими по протоколу Web-Socket.

2 стартмани

30.03.2018    47066    115    Ditron    120    

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

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

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

1 стартмани

29.11.2021    6891    16    Prometeus2011    11    

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

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

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

1 стартмани

15.11.2021    8324    36    kild    33    

TextRadar - компонента нечеткого поиска Промо

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

Компонента предназначена для организации поиска в текстовых данных, решения задач сопоставления списков и т.д. Вычисляемый коэффициент релевантности (похожести) - нормированный, лежит в диапазоне между 0 и 1. В случае необходимости (опционально) формируются данные для отображения найденных фрагментов. Расчет коэффициентов происходит в многопоточном режиме (на уровне компоненты). Для 32 и 64 разрядных систем. Исходный код компоненты на языке C# может быть предоставлен по запросу.

1 стартмани

19.09.2018    30198    38    TSSV    19    

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

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

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

1 стартмани

15.07.2021    8490    7    salexdv    6    

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

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

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

1 стартмани

26.02.2021    6340    6    keypax    4    

Использование сборок .NET в 1С 7. и 8.x. Создание внешних Компонент. Промо

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

Данная разработка создана для использования сборок .Net в 1С через преобразование объектов и классов в COM-объекты, которые можно использовать в 1С. Достигается это путем создания класса, реализующего методы интерфейса IReflect public class AutoWrap: IReflect.

1 стартмани

28.11.2013    103163    319    Serginio    80    

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

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

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

1 стартмани

29.11.2020    6768    0    OlegK    0    

Приложение Android для идентификации/распознавания образов (с обучением с одного раза, One-Shot Learning) с возможностью работы с 1С через веб-сервис Промо

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

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

1 стартмани

19.06.2018    23664    5    informa1555    16    

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

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

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

3 стартмани

09.10.2020    45681    339    ltfriend    208    

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

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

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

3 стартмани

14.09.2020    7990    5    kinan    19    

Мобильное приложение "Отчет по проделанной работе" Промо

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

Приложение выполняет фиксацию рабочего времени у клиентов, а также заявок на работы, пригодится как шаблон для разработки своего или как готовое решение для работников в сфере услуг, которые фиксируют время у клиентов. В приложении 2 документа: первый "отчет за день", второй "заявка" и полезный инструмент "Отчет задачи", который в свою очередь создан для просмотра, анализа и закрытия заявок. Тестировал на Iphone 6s.

10 стартмани

01.12.2017    33931    11    olejnikov_m    6    

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

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

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

1 стартмани

06.08.2020    10433    7    DrZombi    7    

NativeDraw: Компонента рисования для 1С [V2.6.2] Промо

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

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

3 стартмани

13.07.2015    60162    484    ПерваяСистема    154    

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

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

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

1 стартмани

07.07.2020    11538    9    karpik666    5    

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

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

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

1 стартмани

22.06.2020    11435    18    SanyMaga    23    

Компоненты распознавания и печати штрих-кодов Промо

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

Комплект программного обеспечения для реализации функций оптического распознавания штрих-кодов различных систем при помощи обычной web-камеры, а также их отображения в печатных формах. Программы могут работать в составе конфигураций, созданных на базе платформ «1С-Предприятие» версий 7.7, 8.2, 8.3. Компонент чтения кодов реализован в виде внешней компоненты 1С с COM-интерфейсом. Компонент отображения создан по стандартной технологии ActiveX для Windows, и может быть встроен в любое приложение, поддерживающее встраивание ActiveX элементов управления, например в документ Word или Excel, или форму VBA. P.S. Добавлена новая версия программы распознавания. Новые функции: обработка видео в реальном режиме (а не по таймеру, как раньше), добавлена возможность распознавания штрих-кодов из графических файлов JPEG, PNG, GIF, BMP, а также передавать для распознавания картинки из 1С, теперь можно получить в 1С захваченное с камеры или файла изображение, как с выделением мест, содержащих коды, так и без, а также отдельные фрагменты изображений, содержащие код. Добавлены новые свойства и методы для программирования. Обновлена документация.

10 стартмани

10.07.2015    85962    98    igorberezhnov    122    

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

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

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

1 стартмани

29.04.2020    17582    86    evgeny43    80    

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

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

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

2 стартмани

16.04.2020    11100    23    kandr    13    

7 причин, почему интеграция стала приятной. Не упускайте ряд потрясающих возможностей Промо

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

В статье показаны примеры получения данных без программирования на стороне «1С:Предприятие 8». Вам нужно проверить гипотезу и проанализировать данные, почему бы не интегрироваться с Excel? Используете технологии .NET и «1С:Предприятие 8», процесс связывания систем движется катастрофически медленно? Хотите native Android приложение с вашими данными всегда под рукой?

1 стартмани

01.10.2015    68804    55    pbazeliuk    23    

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

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

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

1 стартмани

15.04.2020    16636    97    SanyMaga    102    

Мобильная платформа. Реакция на внешнее событие в Android при помощи внешней компоненты

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

Внешняя компонента для мобильной платформы на Android. Пришиваем платформе уши, чтобы лучше слышать.

3 стартмани

06.04.2020    13086    20    kinan    29    

Давайте подружим 1С и Android. Часть 1 - постановка задачи и подход к решению Промо

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

Серия уроков по созданию простейшего приложения на платформе Android для взаимодействия с 1С.

1 стартмани

29.02.2016    39556    43    solarisman    32    

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

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

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

1 стартмани

25.03.2020    18946    165    berezdetsky    51    

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

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

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

1 стартмани

26.02.2020    8477    5    algabas    7    

Снимок экрана для 1С Промо

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

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

1 стартмани

08.02.2016    36751    35    linkforget    11    

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

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

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

8 стартмани

12.01.2020    11866    2    Johny_v    23    

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

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

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

3 стартмани

03.01.2020    14159    46    Denr83    0    

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

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

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

1 стартмани

23.12.2019    10317    8    asdfgcom    3    

Native API компонента для использования установленного в системе интерпретатора Python Промо

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

Компонента позволяет подключать к платформе 1С python-модули, оформленные в стиле внешней компоненты. Кроме этого, она позволяет запускать небольшие фрагменты python-кода прямо из модулей 1С. На данный момент поддерживаются платформы 8.2 — 8.3 x86 Windows.

1 стартмани

14.05.2013    55634    110    Принт    31    

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

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

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

1 стартмани

14.11.2019    44184    439    informa1555    249    

Получение AndroidID в мобильном приложении

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

Получаем Android DeviceID в мобильном приложении/клиенте, используя стороннее приложение.

1 стартмани

05.11.2019    15620    12    sam441    13