При разработке мобильных приложений на платформе 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:// не является путем, который можно просто «открыть» методом НачатьПомещениеФайла.
Разберем способы, которые помогут нам продвинуться в решении:
content URI напрямую, отсутствие прав гарантированно блокирует любые попытки работы с хранилищем.content URI. Если же выбрать этот же файл через файловый менеджер из конкретной папки (например, WhatsApp/Media), система может вернуть более «понятный» для 1С путь. Попробуйте направить пользователя к выбору файла через структуру папок, а не через быстрый доступ.content:// — это не файл, а поток данных, стандартных средств 1С бывает недостаточно. Нативная компонента на Java/Kotlin может использовать ContentResolver для открытия InputStream по URI. Получив поток, компонента может передать его в 1С в виде Base64 или сразу сохранить во временный файл, путь к которому 1С уже сможет прочитать.После того как мы получили путь, необходимо правильно обработать его в процедуре завершения выбора. Рассмотрим стандартный подход:
&НаКлиенте
Процедура ОбработатьВыборФайла(Результат, ДополнительныеПараметры) Экспорт
Если Результат = Неопределено Тогда
Возврат;
КонецЕсли;
// Попытка помещения файла во временное хранилище
Оповещение = Новый ОписаниеОповещения("ОбработатьПомещениеФайла", ЭтотОбъект);
НачатьПомещениеФайла(Оповещение, , Результат, Ложь, УникальныйИдентификатор);
КонецПроцедуры
Если на этапе НачатьПомещениеФайла вы получаете ошибку «Файл не обнаружен», это означает, что внутренняя реализация вашей версии платформы 1С не поддерживает данный тип URI для данной операции. В таком случае, если обновление платформы до актуальной версии не помогает, единственным верным решением для бизнес-задач остается создание внешней компоненты, которая берет на себя роль посредника между ContentProvider Android и средой 1С.
Мы выяснили, что проблема не является ошибкой в коде, а обусловлена архитектурными изменениями безопасности Android. Рекомендуем начать с проверки прав и попытки выбора файла из «физических» папок устройства, а в случае неудачи — планировать разработку мобильной компоненты.