Как получить двоичные данные файла, если 1С возвращает ссылку content:// на Android?

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

При разработке мобильных приложений на платформе 1С для ОС Android многие разработчики сталкиваются с тем, что стандартные методы выбора файлов начинают возвращать необычные пути, начинающиеся с content://media/external/.... Традиционные методы платформы, ожидающие путь вида file://, в такой ситуации выдают ошибку «Файл не найден». Давайте разберемся, почему это происходит и как нам решить эту задачу.

Понимаем причину возникновения проблемы

Начиная с Android 10 и выше, Google внедрил механизм Scoped Storage (Ограниченное хранилище). Это сделано для безопасности: приложения больше не имеют прямого доступа к файловой системе устройства. Вместо прямого пути к файлу file:// система предоставляет content URI — это специальный идентификатор, который ссылается на «контент-провайдер». Платформа 1С в текущих версиях не всегда умеет «на лету» превращать такой URI в привычный для нас объект ДвоичныеДанные, что и приводит к ошибкам при попытке обращения к файлу.

Рассматриваем варианты выбора файлов

Для начала проанализируем, как можно организовать выбор файла, чтобы минимизировать проблемы. Мы можем использовать как встроенный диалог 1С, так и системный вызов Android через ЗапускПриложенияМобильногоУстройства. Рассмотрим пример реализации выбора через системный диалог:


&НаКлиенте
Функция ВыбратьФото()
    НовВз = Новый ЗапускПриложенияМобильногоУстройства;
    НовВз.Действие = "android.intent.action.GET_CONTENT";
    НовВз.Тип = "image/*";
    // Указываем, что нас интересуют только локальные данные
    НовВз.ДополнительныеДанные.Добавить("android.intent.extra.LOCAL_ONLY", Истина);
    
    РезультатРаботы = НовВз.Запустить(Истина);
    Если НЕ РезультатРаботы Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    // Возвращаем полученный контент-путь
    Возврат НовВз.Данные;
КонецФункции

Этот способ позволяет получить URI через системные механизмы Android, которые имеют право на работу с медиафайлами. Однако, как мы выяснили, сама по себе строка content:// не является путем, который можно просто «открыть» методом НачатьПомещениеФайла.

Анализируем стратегии работы с файлами

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

  1. Проверка прав доступа: Прежде всего, убедитесь, что в манифесте приложения и в настройках мобильной платформы разрешен доступ к файлам. Хотя это не решит проблему с content URI напрямую, отсутствие прав гарантированно блокирует любые попытки работы с хранилищем.
  2. Выбор файлов из конкретных папок: Существует наблюдение, что если пользователь выбирает файл через раздел «Недавние» (Recent), он часто получает content URI. Если же выбрать этот же файл через файловый менеджер из конкретной папки (например, WhatsApp/Media), система может вернуть более «понятный» для 1С путь. Попробуйте направить пользователя к выбору файла через структуру папок, а не через быстрый доступ.
  3. Использование внешней компоненты: Это самый надежный, хоть и трудоемкий путь. Поскольку content:// — это не файл, а поток данных, стандартных средств 1С бывает недостаточно. Нативная компонента на Java/Kotlin может использовать ContentResolver для открытия InputStream по URI. Получив поток, компонента может передать его в 1С в виде Base64 или сразу сохранить во временный файл, путь к которому 1С уже сможет прочитать.

Разбираем процесс обработки выбора

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


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

Если на этапе НачатьПомещениеФайла вы получаете ошибку «Файл не обнаружен», это означает, что внутренняя реализация вашей версии платформы 1С не поддерживает данный тип URI для данной операции. В таком случае, если обновление платформы до актуальной версии не помогает, единственным верным решением для бизнес-задач остается создание внешней компоненты, которая берет на себя роль посредника между ContentProvider Android и средой 1С.

Мы выяснили, что проблема не является ошибкой в коде, а обусловлена архитектурными изменениями безопасности Android. Рекомендуем начать с проверки прав и попытки выбора файла из «физических» папок устройства, а в случае неудачи — планировать разработку мобильной компоненты.

← На главную