Как исправить ошибку в мобильном приложении 1С при повороте устройства во время фотосъемки

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

При разработке мобильных решений на платформе 1С:Предприятие разработчики часто сталкиваются со специфическим поведением системы на различных устройствах. Одной из самых неприятных проблем является критическая ошибка (падение приложения) при попытке сделать фотографию, если в процессе съемки пользователь решит повернуть планшет или телефон. Рассмотрим причины возникновения этой ошибки и разберем по шагам, как обеспечить стабильную работу мобильного клиента.

Почему происходит падение приложения при повороте?

Для начала проанализируем ситуацию с технической точки зрения ОС Android. Поворот экрана для системы — это не просто изменение картинки, а смена конфигурации устройства. Разберем основные факторы, которые приводят к сбою:

  1. Жизненный цикл Activity: В ОС Android по умолчанию поворот устройства приводит к полному уничтожению и повторному созданию текущего окна (Activity). Когда мобильный клиент 1С вызывает камеру, основное приложение переходит в фоновый режим. Если в этот момент происходит поворот, Android пытается перезапустить Activity 1С. Если платформа 1С в конкретной версии не успевает корректно восстановить состояние после возврата из интерфейса камеры, происходит обращение к пустой области памяти или NullPointerException, что и вызывает вылет.
  2. Low Memory Killer (Нехватка памяти): Планшеты часто имеют экраны с высоким разрешением, что требует значительных ресурсов оперативной памяти для обработки изображений. При повороте нагрузка на систему кратковременно возрастает. Если свободной памяти мало, Android может принудительно завершить фоновый процесс 1С, пока открыта камера. При попытке вернуться в приложение после снимка контекст оказывается утерян, и пользователь видит ошибку.
  3. Особенности мобильного клиента: В отличие от мобильного приложения, мобильный клиент постоянно поддерживает связь с сервером. При повороте экрана клиент может инициировать переподключение или перерисовку управляемой формы, что в сочетании с возвратом данных от камеры создает конфликт потоков.

Решение проблемы через использование Android Intent

Стандартный метод СредстваМультимедиа.СделатьФотоснимок является универсальным, но на некоторых прошивках и устройствах он работает нестабильно. Рассмотрим альтернативный вариант — использование объекта ЗапускПриложенияМобильногоУстройства для прямого обращения к системному интенту камеры android.media.action.IMAGE_CAPTURE. Это позволяет более гибко управлять процессом и минимизировать зависимость от внутренних механизмов платформы.

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


// Определяем путь к файлу на внешнем хранилище
ФайлКартинки = "file:///sdcard/Download/FotoTestFrom1C.jpg";

// Создаем объект для запуска системного интента камеры
НовВз = Новый ЗапускПриложенияМобильногоУстройства("android.media.action.IMAGE_CAPTURE");

// Обязательно указываем параметр "output", чтобы получить полноразмерное фото.
// Если этого не сделать, система вернет только миниатюру (preview) низкого качества.
НовВз.ДополнительныеДанные.Добавить("output", ФайлКартинки, "Uri");

// Запускаем приложение и ожидаем завершения (Истина)
РезультатЗапуска = НовВз.Запустить(Истина);

Если РезультатЗапуска <> 0 Тогда
    // Если фото успешно сделано, можно обработать файл
    // Например, открыть его для просмотра или загрузить в базу
    ЗапуститьПриложение(ФайлКартинки);
Иначе
    Сообщить("Фото не сделано или съемка была отменена пользователем!");
КонецЕсли;

Проанализируем этот код. Здесь мы используем ДополнительныеДанные с ключом output. Это критически важный момент: если его не указать, Android вернет результат в виде данных (data), которые часто обрезаются по качеству. Указывая прямой путь через Uri, мы заставляем камеру сохранить файл непосредственно на диск.

Важные ограничения для Android 7.0 и выше

Разберем нюанс, который может возникнуть на современных устройствах. Начиная с Android 7.0 (API 24), прямая передача путей через протокол file:// запрещена в целях безопасности. Это может вызвать ошибку FileUriExposedException. В полноценной разработке на Java/Kotlin это решается через FileProvider, но в рамках мобильной платформы 1С мы ограничены возможностями среды.

Если вы столкнулись с такой проблемой, попробуйте следующие шаги:

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

Оптимизация работы со стандартными средствами

Если вы все же хотите использовать СредстваМультимедиа, проанализируем ситуацию с параметрами съемки. Часто ошибка возникает из-за попытки передать слишком большой объем данных при возврате управления в 1С. Попробуем ограничить качество снимка:


// Ограничиваем качество до 60% для снижения нагрузки на память
Данные = СредстваМультимедиа.СделатьФотоснимок(ТипКамерыУстройства.Авто, , 60);

Также выясним причину влияния версии платформы. Выяснено, что в версиях 8.3.18 и выше механизмы обработки события onConfigurationChanged (смена ориентации) были существенно оптимизированы. Если ваше устройство позволяет, рекомендуется обновить мобильную платформу до версии 8.3.20 или выше. В этих релизах взаимодействие с нативными компонентами Android стало более стабильным.

Программная блокировка ориентации как обходной путь

Выясним еще один способ предотвратить падение — это запрет на сам поворот экрана во время выполнения функции. Хотя в мобильном клиенте 1С нет прямой команды "заблокировать экран", можно использовать свойства формы. Если перед вызовом камеры зафиксировать положение формы или использовать модальные окна, которые ограничивают перерисовку интерфейса, вероятность сбоя снизится.

Рекомендации по подаче баг-репортов

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

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

← На главную