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

03.10.23

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

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

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

Наименование Файл Версия Размер
Внешняя компонента для мобильного приложения:
.zip 7,49Mb
10
.zip 7,49Mb 10 Скачать

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

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 не поддерживается 
x86_64 не поддерживается

 

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

//--------Установка компоненты--------//
УстановитьВнешнююКомпоненту("ОбщийМакет.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/

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

См. также

"Штрихкод-информер" - мобильный ТСД и прайс-чекер в смартфоне

Мобильная разработка Сканер штрих-кода Терминал сбора данных Управляемые формы Мобильная платформа 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Управленческий учет Платные (руб)

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

2880 руб.

03.12.2018    54623    137    102    

161

SALE! 25%

Что нам стоит бота построить? Нарисуем - будет жить! Графический конструктор телеграм-ботов/Telegram

Мобильная разработка Мессенджеры и боты Платформа 1С v8.3 Платные (руб)

Теперь создать telegram-бота - элементарно. Достаточно просто нарисовать блок-схему телеграм-бота, и он сразу заработает. Это возможно при использовании Графического конструктора телеграм-ботов. Это единственный конструктор ботов для telegram, чье качество и функционал подтверждены фирмой 1С, есть сертификат 1С:Совместимо. Расширение в интерактивном режиме, с помощью блок-схем, позволяет с минимальными трудозатратами создать телеграм-ботов в любой конфигурации, работающей на платформе «1С:Предприятие 8.3».

13200 9900 руб.

27.12.2021    33291    80    157    

174

"Мобильный ТСД" - инвентаризация и сбор штрихкодов для iOS и Android

Сканер штрих-кода Терминал сбора данных Мобильная разработка Монитор заказов Оптовая торговля Розничная торговля Ценообразование, анализ цен Платформа 1С v8.3 Мобильная платформа 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Розничная и сетевая торговля (FMCG) Оптовая торговля, дистрибуция, логистика Управленческий учет Платные (руб)

Простой мобильный терминал сбора данных для смартфонов на iOS и Android, не требующий сложных настроек и установки дополнительных программ. Обмен между Вашей 1С и мобильным приложением осуществляется через облачный сервис и расширение конфигурации. Работает с конфигурациями УТ 11, ERP, КА2, Розница 2, Розница 3, УНФ 1.6, УНФ 3.0. Полнофункциональный демо-доступ для своей конфигурации можно запросить в настройках мобильного приложения - все необходимое придет на почту автоматически.

2000 руб.

22.04.2019    91948    512    186    

293

Медиадисплей. Рекламный информационный монитор для покупателя.

Разработка внешних компонент POS терминал Рабочее место Розничная торговля Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Управление торговлей 10 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Розничная и сетевая торговля (FMCG) Рестораны, кафе и фаст-фуд Реклама, PR и маркетинг Управленческий учет Платные (руб)

Монитор покупателя может отображать текущую покупку на кассовом месте, показывать видеорекламу, баннеры, во время простоя разворачивать рекламу на весь экран. Можно использовать в качестве графического меню-борда в кафе и видеовывески. Управление выводом на телевизор через hdmi-приставку на базе Windows или Android. В качестве устройства отображения можно использовать Android-планшеты, фоторамки с Android, монитор любого Windows-компьютера, доступного по сети. Настраивается ЛЮБОЙ ДИЗАЙН экрана!

16800 руб.

30.05.2017    52106    34    69    

43

Магазин 15 - приемка товара по штрихкодам или инвентаризация в торговом зале

Логистика, склад и ТМЦ Мобильная разработка Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Розничная и сетевая торговля (FMCG) Россия Платные (руб)

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

12950 руб.

30.05.2023    3388    2    0    

4

Внешняя компонента для сканирования (замена TWAIN-компоненты БСП) (Native Win 32/64)

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

Внешняя компонента позволяет работать c TWAIN-совместимым оборудованием (сканерами, камерами) . Полностью совместима со стандартной TWAIN-компонентой из БСП и может применяться как ее замена без изменения вызовов, при этом может работать с 64-разрядной платформой, а так же имеет расширенную функциональность, например, сохранение результата непосредственно в PDF без использования сторонних утилит. Прекрасно работает на сервере, тонком клиенте и веб-клиенте (проверена работа в браузерах Google Chrome, Mozilla Firefox и Microsoft Internet Explorer).

2400 руб.

12.05.2020    26244    131    99    

83

Внешняя компонента для подключения 1С к телефонии Asterisk

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

Внешняя компонента выполнена по технологии Native API для 1С 8.х, обеспечивает доступ к программным АТС Asterisk (FreePBX, Elastix) через AMI интерфейс. Через него можно управлять многими функциями Asterisk (определение номеров, перевод звонков, набор телефона и т. д.)

2400 руб.

04.05.2018    44978    117    64    

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

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

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

Короче, угадать я вряд-ли сейчас смогу. Будет время на неделе - протестирую на 13 Андроиде. Только арм64 у меня нет. Попробуем методом исключения: если на 23 платформе и 13 Андроиде будет работать-значит дело в билде под арм64 процессор.

P.S. Если взлетит на AVD arm64 то это не значит, что будет работать на физическом устройстве.
50. Dream_kz 129 24.09.23 12:44 Сейчас в теме
(48) Запустил на 8.3.18.77, также 13-й андроид, ARM64, 32-битное приложение поставить не могу, они тут не работают. В процедуру ОбработкаВнешнегоСобытия не заходит, ВнешнееСобытие на форме аналогично. Запускаю код из модуля формы ПриОткрытии, так что вызов на клиенте.
Так что платформа тут скорее всего не причем, возможно причина в том, что 32 битные приложения не поддерживаются, попробую найти другое устройство.
49. Prometeus2011 210 23.09.23 09:45 Сейчас в теме
Можете и сами попробовать разные варианты комбинаций: платформа/ОС/процессор
51. Dream_kz 129 25.09.23 09:40 Сейчас в теме
(49) Android 13, ARM32, 8.3.23, тоже самое, приложение завершается
52. Prometeus2011 210 03.10.23 23:22 Сейчас в теме
Пересобрал с новым СДК. В общем, все, что не 32 бита - валится в момент вызова pAddIn->ExternalEvent(s_EventSource, s_EventName_GEO, WCHART) (внешнее событие).

Причем, валится даже с указателями на пустые строки в параметрах.
53. Dream_kz 129 04.10.23 13:49 Сейчас в теме
(52) Можно перекачивать, проверять заново?
54. Prometeus2011 210 04.10.23 14:48 Сейчас в теме
У меня пока не получилось решить проблему с работой на arm64. Такое ощущение, что указатель на объект 1с после возврата из callbac'а становится не валидным.
То-есть протестировал на версиях только до х86 11 Андроида - включительно.

Можно взять отсюда: https://github.com/KotVezdehod/Hermes
zip-архив.
Оставьте свое сообщение