Разработка под мобильные платформы в среде 1С:Предприятие имеет ряд существенных отличий от работы с классическим «толстым» или «тонким» клиентом. Одной из наиболее распространенных проблем, с которой сталкиваются разработчики, является попытка использовать стандартный объект ДиалогВыбораФайла в режиме сохранения. На мобильных устройствах под управлением Android такой подход вызывает ошибку: «ДиалогВыбораФайла не работает в режиме "Сохранение"».
В этой статье мы подробно разберем, почему возникает эта проблема, и рассмотрим правильные механизмы работы с файловой системой Android из мобильного приложения 1С.
Для начала проанализируем ситуацию. В операционной системе Android приложения работают в так называемых «песочницах» (sandboxes). Это означает, что приложение по умолчанию не имеет прямого доступа к файловой системе устройства, кроме своих собственных внутренних папок. Традиционный метод ДиалогВыбораФайла с параметром РежимДиалогаВыбораФайла.Сохранение, к которому мы привыкли в Windows, требует прямого взаимодействия с деревом каталогов ОС, что запрещено или сильно ограничено в мобильной среде.
Платформа 1С в мобильном клиенте и мобильном приложении блокирует этот метод, предлагая использовать альтернативные, асинхронные способы взаимодействия с пользователем.
Наиболее правильный способ реализации диалога сохранения файла, который рекомендует сама платформа в тексте ошибки, — это использование метода НачатьПолучениеФайла (или его современного аналога ПолучитьФайлИнтерактивно в более свежих версиях платформы). Этот метод инициирует системный механизм Android для работы с документами (Storage Access Framework).
Рассмотрим по шагам, как это реализовать. Сначала нам нужно подготовить данные, поместить их во временное хранилище, а затем вызвать диалог сохранения.
Шаг 1: Подготовка данных и вызов диалога
&НаКлиенте
Процедура СохранитьФайлНаУстройстве()
// Формируем текстовые данные для сохранения
ТекстДляСохранения = "Это содержимое нашего файла, сформированное в мобильном приложении.";
// Сохраняем во временный файл на мобильном устройстве
ИмяВременногоФайла = КаталогВременныхФайлов() + "document.txt";
Запись = Новый ЗаписьТекста(ИмяВременногоФайла, КодировкаТекста.UTF8);
Запись.ЗаписатьСтроку(ТекстДляСохранения);
Запись.Закрыть();
// Помещаем сформированный файл во временное хранилище
Описание = Новый ОписаниеОповещения("ПослеПомещенияФайла", ЭтаФорма);
НачатьПомещениеФайла(Описание, , ИмяВременногоФайла, Ложь, УникальныйИдентификатор);
КонецПроцедуры
Шаг 2: Обработка результата и вызов системного диалога сохранения
После того как файл оказался во временном хранилище, мы вызываем метод НачатьПолучениеФайла. Обратите внимание на параметр Истина в конце — именно он отвечает за интерактивность (показ диалога выбора места сохранения пользователю).
&НаКлиенте
Процедура ПослеПомещенияФайла(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
Если Результат Тогда
// Параметры метода:
// 1. Описание оповещения после завершения
// 2. Адрес во временном хранилище
// 3. Предлагаемое имя файла
// 4. Интерактивно (Истина - покажет диалог Android)
ОповещениеЗавершения = Новый ОписаниеОповещения("ЗавершитьСохранение", ЭтаФорма);
НачатьПолучениеФайла(ОповещениеЗавершения, Адрес, "МойДокумент.txt", Истина);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ЗавершитьСохранение(ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
Если ЗначениеЗаполнено(ВыбранноеИмяФайла) Тогда
Сообщить("Файл успешно сохранен: " + ВыбранноеИмяФайла);
КонецЕсли;
КонецПроцедуры
Иногда требуется сохранить файл «тихо», без участия пользователя. В мобильной платформе 1С есть предопределенные функции для получения путей к папкам, доступ к которым разрешен приложению.
Рассмотрим использование функции КаталогДокументов(). Это внутренняя папка приложения, файлы в которой будут доступны пользователю через системные файловые менеджеры (обычно по пути /Android/data/имя.пакета/files/Documents/).
&НаКлиенте
Процедура СохранитьПрограммно()
ПутьКПапке = КаталогДокументов();
ПолноеИмяФайла = ПутьКПапке + "internal_data.txt";
Запись = Новый ЗаписьТекста(ПолноеИмяФайла, КодировкаТекста.UTF8);
Запись.ЗаписатьСтроку("Данные сохранены программно без участия пользователя.");
Запись.Закрыть();
Сообщить("Файл записан в: " + ПолноеИмяФайла);
КонецПроцедуры
Важный нюанс: Начиная с Android 10 и выше, введена концепция Scoped Storage. Это означает, что даже при наличии прав на запись во внешнюю память, ваше приложение «видит» только свои папки. Использование КаталогДокументов() гарантирует, что запись пройдет успешно без запроса дополнительных разрешений.
На мобильных устройствах пользователи часто предпочитают не просто сохранять файл в папку, а сразу отправлять его в мессенджеры, почту или облачные хранилища. Мы можем реализовать это с помощью объекта ЗапускПриложенияМобильногоУстройства.
Проанализируем пример кода для вызова системного меню «Поделиться»:
&НаКлиенте
Процедура ОтправитьФайлЧерезСистему()
ИмяФайла = КаталогВременныхФайлов() + "Report.txt";
// Предварительно создаем файл через ЗаписьТекста...
Запуск = Новый ЗапускПриложенияМобильногоУстройства();
Запуск.Действие = "android.intent.action.SEND";
Запуск.Тип = "text/plain";
Запуск.ДополнительныеДанные.Добавить("android.intent.extra.STREAM", "file://" + ИмяФайла);
// Для Android 7+ требуется специальная обработка путей через FileProvider,
// но платформа 1С обычно берет это на себя при использовании правильных методов.
Запуск.Запустить(Ложь);
КонецПроцедуры
Выясним причину, по которой даже правильный код может не сработать. Если вы пытаетесь записать файл в общедоступные папки (например, в корень SD-карты), вам необходимо запросить разрешение у пользователя в явном виде. В 1С это делается через СредстваМультимедиа.
&НаКлиенте
Процедура ЗапроситьПраваИЗаписать()
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеЗапросаРазрешения", ЭтаФорма);
СредстваМультимедиа.ЗапроситьРазрешение(РазрешениеПриложения.ЗаписьВоВнешнееХранилище, ОписаниеОповещения);
КонецПроцедуры
&НаКлиенте
Процедура ПослеЗапросаРазрешения(Результат, ДополнительныеПараметры) Экспорт
Если Результат Тогда
// Права получены, можно выполнять запись
Сообщить("Доступ к памяти разрешен");
Иначе
Сообщить("Доступ запрещен. Невозможно сохранить файл.");
КонецЕсли;
КонецПроцедуры
Подведем итог нашему анализу работы с файлами на Android в 1С:
ДиалогВыбораФайла в режиме сохранения. Он предназначен для десктопных систем и не поддерживается мобильной платформой.НачатьПомещениеФайла -> НачатьПолучениеФайла(..., Истина). Это вызовет системный проводник Android, где пользователь сам выберет папку (Загрузки, Google Диск и т.д.).КаталогДокументов().Следуя этим правилам, вы сможете обойти ограничения Android и обеспечить стабильную работу вашего мобильного приложения при выгрузке текстовых документов, отчетов или любых других файлов.