Почему возникает ошибка «Файл не обнаружен» при создании XML в мобильном приложении 1С на Android и как её исправить?

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

Разработка для мобильных платформ часто преподносит сюрпризы, связанные с различиями в версиях операционных систем и архитектурой самой платформы 1С. Одной из распространенных проблем является внезапный отказ стабильно работавшего кода при переходе на новые устройства или обновлении версии Android. В этой статье мы подробно разберем ситуацию, когда мобильное приложение 1С выдает ошибку «Файл не обнаружен» при попытке создания XML-документа, проанализируем причины этого поведения и найдем эффективные способы решения.

Проблема: Код работает на одном устройстве, но выдает ошибку на другом

Рассмотрим типичную ситуацию. Имеется самописное мобильное приложение, в котором реализован механизм обмена данными через XML. Код для инициализации записи файла выглядит следующим образом:


ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
Попытка
    ЗаписьXML.ОткрытьФайл(ПутьОбмена + ИмяФайла);
Исключение
    ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Ошибка открытия файла для записи: " + ПутьОбмена + ИмяФайла);
КонецПопытки;

При выполнении этого фрагмента на планшете с Android 13 всё проходит успешно. Однако на телефоне с Android 10 приложение выбрасывает исключение с текстом: «К сожалению, возникла ошибка при работе с файлом. Файл не обнаружен '/data/user/0/(Идентификатор приложения)/cache/(имя файла)'». При этом все разрешения на доступ к памяти устройства в настройках телефона предоставлены. Проанализируем, почему стандартные пути, такие как КаталогДокументов() или КаталогВременныхФайлов(), перестают работать в определенных условиях.

Причина 1: Виртуализация контекстов «Клиент» и «Сервер»

Для начала выясним важную особенность мобильной платформы 1С:Предприятие. Несмотря на то что приложение работает на одном физическом устройстве, платформа эмулирует разделение на клиентскую и серверную части.

Проанализируем разницу:

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

Причина 2: Особенности Scoped Storage в Android 10+

Разберем технические изменения в безопасности Android. Начиная с 10-й версии (API 29), компания Google ввела механизм Scoped Storage (изолированное хранилище). Теперь приложения имеют жестко ограниченный доступ к файловой системе:

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

Когда мы используем метод КаталогВременныхФайлов(), мы получаем путь вида /data/user/0/.../cache/. Если попытка записи по этому адресу происходит в серверном контексте мобильной платформы, система безопасности Android может не распознать этот запрос как легитимный запрос от владельца папки.

Решение №1: Перенос логики на сторону клиента

Самым простым и эффективным решением, как показала практика, является перенос процедур работы с файлами в клиентский контекст. Рассмотрим, как изменить структуру кода. Вместо того чтобы формировать файл на сервере, мы делаем это &НаКлиенте.

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


&НаКлиенте
Процедура ВыполнитьЭкспортДанных()
    
    ПутьОбмена = КаталогВременныхФайлов();
    ИмяФайла = "export.xml";
    ПолныйПуть = ПутьОбмена + ИмяФайла;
    
    ЗаписьXML = Новый ЗаписьXML;
    Попытка
        // На клиенте доступ к файловой системе наиболее стабилен
        ЗаписьXML.ОткрытьФайл(ПолныйПуть);
        // Здесь логика записи данных в XML
        ЗаписьXML.ЗаписатьОбъявлениеXML();
        // ... заполнение данными ...
        ЗаписьXML.Закрыть();
        Сообщить("Файл успешно создан: " + ПолныйПуть);
    Исключение
        Сообщить("Ошибка при создании файла: " + ОписаниеОшибки());
    КонецПопытки;
    
КонецПроцедуры

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

Решение №2: Использование временного хранилища и двоичных данных

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

Выполним следующие шаги:

  1. На сервере создаем объект ЗаписьXML.
  2. Используем метод ЗаписьXML.УстановитьСтроку() вместо открытия файла.
  3. Записываем все необходимые данные.
  4. Получаем строку методом ЗаписьXML.Закрыть().
  5. Преобразуем строку в ДвоичныеДанные и передаем их на клиент.
  6. На клиенте вызываем метод ДвоичныеДанные.Записать().

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


&НаСервере
Функция СформироватьXMLНаСервере()
    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.УстановитьСтроку("UTF-8");
    // Логика формирования XML
    // ...
    СтрокаXML = ЗаписьXML.Закрыть();
    
    // Помещаем данные во временное хранилище или возвращаем как двоичные данные
    Возврат Новый ДвоичныеДанные(СтрокаXML); // Внимание: проверьте кодировку при преобразовании
КонецФункции

&НаКлиенте
Процедура СохранитьФайл()
    ДанныеФайла = СформироватьXMLНаСервере();
    ПутьСохранения = КаталогДокументов() + "data_exchange.xml";
    ДанныеФайла.Записать(ПутьСохранения);
КонецПроцедуры

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

Выясним основные правила, которые помогут избежать ошибок в будущем:

Проанализировав ситуацию, мы видим, что проблема «Файл не обнаружен» в мобильном приложении часто является не отсутствием самого файла, а невозможностью его создания из-за ограничений серверного потока. Следуя принципу разделения подготовки данных (на сервере) и записи в файловую систему (на клиенте), вы обеспечите стабильную работу вашего приложения на любых версиях Android.

← На главную