Как передать файл с мобильного клиента на сервер в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке функциональности для мобильного клиента 1С часто возникает задача передачи файлов (фотографий, документов, вложений) с мобильного устройства на основной сервер базы данных. Однако стандартный подход, привычный для настольного тонкого клиента через НачатьПомещениеФайла и объект ДиалогВыбораФайла, на мобильных устройствах под управлением Android может приводить к ошибкам.

Проанализируем типичную ситуацию: пользователь выбирает файл в системном диалоге мобильного устройства, но вместо привычного пути к файлу в операционной системе возвращается ссылка вида content://media/external/images/media/20. При этом файл не отправляется на сервер, либо код падает при попытке разобрать имя и расширение через объект Файл. Разберем причины такого поведения и рассмотрим надежные способы решения задачи.

Выясним причину проблемы с путями вида content://

В операционной системе Android (в частности, в рамках модели Scoped Storage) системный проводник или галерея возвращают не абсолютный путь файловой системы (например, /storage/emulated/0/...), а так называемый Content URI. Попытка инициализировать стандартный объект 1С конструкцией Новый Файл(ПутьСФлешки) по такой ссылке приводит к ошибке: методы парсинга строки пути не находят расширения (свойство Расширение возвращает пустую строку, а Имя содержит лишь цифровой идентификатор контента).

Кроме того, устаревший метод НачатьПомещениеФайла не всегда корректно взаимодействует с Android ContentResolver для открытия прямого потока байтов, из-за чего передача данных прерывается либо возвращает признак неудачного завершения (Результат = Ложь).

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

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

Разберем по шагам реализацию этого механизма:

  1. Настроим диалог выбора файла с учетом специфики мобильного приложения, ограничив каталог стандартной библиотекой картинок устройства.
  2. Создадим объект Картинка по выбранному локальному ресурсу и извлечем ДвоичныеДанные.
  3. Поместим данные во временное хранилище сеанса и передадим адрес серверной процедуре.
  4. На сервере получим данные из временного хранилища и сохраним их на диск или в базу данных.

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


&НаКлиенте
Функция ВыбратьИПоместитьФайлВоВременноеХранилище()
    ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    
    #Если МобильноеПриложениеКлиент Тогда
        ВыборФайла.Каталог = КаталогБиблиотекиМобильногоУстройства(ПредопределенноеЗначение("ТипКаталогаБиблиотекиМобильногоУстройства.Картинки"));
    #КонецЕсли
    
    Если ВыборФайла.Выбрать() Тогда
        // Создаем картинку по ссылке на ресурс устройства
        ВыбранноеФото = Новый Картинка(ВыборФайла.ПолноеИмяФайла, Ложь);
        ТекущееФото = ВыбранноеФото.ПолучитьДвоичныеДанные();
        
        // Помещаем двоичные данные во временное хранилище
        СсылкаНаХранилище = ПоместитьВоВременноеХранилище(ТекущееФото, УникальныйИдентификатор);
    Иначе
        СсылкаНаХранилище = "";
    КонецЕсли;
    
    Возврат СсылкаНаХранилище;
КонецФункции

Для сохранения файла на стороне сервера используем следующую функцию:


&НаСервере
Функция СохранитьФайлНаСервере(Знач АдресВХранилище, Знач Расширение)
    Если ПустаяСтрока(АдресВХранилище) Тогда
        Возврат "";
    КонецЕсли;
    
    ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(АдресВХранилище);
    
    ПутьНаСервере = "C:\FileStorage\uploaded_file" + Расширение;
    ДвоичныеДанныеФайла.Записать(ПутьНаСервере);
    
    // Очищаем временное хранилище после сохранения
    УдалитьИзВременногоХранилища(АдресВХранилище);
    
    Возврат ПутьНаСервере;
КонецФункции

Способ 2. Использование современных унифицированных методов помещения файлов

Рассмотрим современный стандарт разработки в платформе 1С:Предприятие 8.3. Начиная с версии 8.3.15, вместо устаревшей функции НачатьПомещениеФайла рекомендуется использовать метод НачатьПомещениеФайлаНаСервер, а в более поздних релизах — асинхронную конструкцию ПоместитьФайлНаСерверАсинх.

Преимущество этого подхода заключается в том, что платформа внутри мобильного клиента самостоятельно взаимодействует с системными провайдерами контента Android. При этом возвращаемый объект типа ОписаниеПомещенногоФайла автоматически заполняет валидное имя, расширение и помещает данные во временное хранилище.

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


&НаКлиенте
Асинх Процедура ЗагрузитьФайлНаСерверАсинх(Команда)
    ПараметрыДиалога = Новый ПараметрыДиалогаПомещенияФайлов;
    ПараметрыДиалога.Заголовок = "Выберите файл для загрузки";
    ПараметрыДиалога.МножественныйВыбор = Ложь;
    
    // Вызываем асинхронный метод помещения файла
    ПомещенныйФайл = Ждать ПоместитьФайлНаСерверАсинх(,,, ПараметрыДиалога, УникальныйИдентификатор);
    
    Если ПомещенныйФайл <> Неопределено Тогда
        АдресВХранилище = ПомещенныйФайл.Адрес;
        ИмяФайла = ПомещенныйФайл.СсылкаНаФайл.Имя;
        Расширение = ПомещенныйФайл.СсылкаНаФайл.Расширение;
        
        // Передаем данные на сервер
        СохранитьФайлВБазеНаСервере(АдресВХранилище, ИмяФайла, Расширение);
    КонецЕсли;
КонецПроцедуры

Способ 3. Работа с мультимедиа через средства платформы

Если задача заключается исключительно в получении снимков с камеры или файлов из галереи мобильного устройства, эффективнее использовать глобальный объект СредстваМультимедиа. Он разработан специально для мобильных платформ и мобильных клиентов, что исключает конфликт с файловыми путями.

Проанализируем работу с объектом СредстваМультимедиа:

  1. Метод СделатьФотоснимок или выбор мультимедиа возвращает объект ДанныеМультимедиа.
  2. У этого объекта напрямую вызывается метод ПолучитьДвоичныеДанные(), а также доступно свойство РасширениеФайла.
  3. Полученные данные сразу пригодны для помещения во временное хранилище и передачи на сервер.

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

← На главную