Разработка под мобильные платформы в экосистеме 1С:Предприятие имеет множество нюансов, связанных с жизненным циклом мобильного приложения, управлением памятью и спецификой работы временного хранилища. Одной из часто встречающихся проблем является ситуация, когда камера успешно открывается, снимок делается, но после завершения процесса фотография не отображается в поле картинки на форме документа. Рассмотрим подробнее, почему это происходит и как правильно организовать работу с мультимедиа.
Проанализируем типовую ситуацию. Разработчик создает функционал для захвата изображения: камера активируется, пользователь делает снимок, и программа должна сохранить его в реквизит. В представленном коде используется стандартная схема: получение данных снимка, помещение их во временное хранилище и присвоение адреса реквизиту Объект.Фотография. Однако интерфейс остается пустым.
Выясним причину такого поведения. Основная проблема кроется в синхронизации данных между клиентом и сервером. Когда мы присваиваем адрес временного хранилища реквизиту, который входит в состав Объект (реквизит самого документа), мобильная платформа инициирует процессы обновления состояния объекта. На мобильных устройствах это часто приводит к тому, что навигационная ссылка на временное хранилище «протухает» или очищается в момент передачи управления обратно форме. Система считает данные объекта приоритетными, и при малейшей неявной серверной активности временный адрес в строковом реквизите объекта может стать невалидным.
Как показала практика, самым эффективным и быстрым решением является вынос строкового реквизита, предназначенного для отображения картинки, из состава Объект непосредственно в Реквизиты формы. Рассмотрим по шагам, почему это работает:
Разберем, как должен выглядеть модифицированный код для захвата изображения:
&НаКлиенте
Процедура СделатьФотоКлиент()
// АдресФото теперь записывается в реквизит формы ФотографияНаФорме (Тип: Строка)
АдресФото = СделатьИПоместитьФото();
Если АдресФото = Неопределено Тогда
Возврат;
КонецЕсли;
// Вместо Объект.Фотография используем реквизит формы
ЭтаФорма.ФотографияНаФорме = АдресФото;
ЭтаФорма.Модифицированность = Истина;
// Принудительно обновляем отображение, чтобы поле картинки перечитало адрес
ЭтаФорма.ОбновитьОтображениеДанных();
КонецПроцедуры
Проанализируем еще один важный момент — использование УникальныйИдентификатор. В исходном коде автора использовался Новый УникальныйИдентификатор. Это создает новый контекст хранения, который может быть очищен системой при нехватке памяти или завершении вызова. Правильнее привязывать данные к идентификатору текущей формы. Это гарантирует, что данные будут «жить» столько же, сколько открыто окно документа.
Посмотрим на исправленную функцию помещения файла:
&НаКлиенте
Функция СделатьИПоместитьФото()
Если Не МожноСделатьФото() Тогда
Возврат Неопределено;
КонецЕсли;
ДанныеФото = ПолучитьДанныеСнимка();
Если ДанныеФото = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ТекущееФотоДвоичныеДанные = ДанныеФото.ПолучитьДвоичныеДанные();
// Привязываем адрес к УникальномуИдентификатору текущей формы
Адрес = ПоместитьВоВременноеХранилище(ТекущееФотоДвоичныеДанные, ЭтаФорма.УникальныйИдентификатор);
Возврат Адрес;
КонецФункции
Современные стандарты разработки 1С (особенно для мобильных платформ) настоятельно рекомендуют отказываться от синхронных методов, таких как СредстваМультимедиа.СделатьФотоснимок(). На мобильных устройствах Android и iOS выполнение кода блокируется до закрытия камеры, что может вызвать сбои в отрисовке интерфейса или даже аварийное завершение приложения при нехватке ресурсов.
Рассмотрим, как реализовать асинхронное получение снимка. Разберем этот процесс по шагам:
НачатьПолучениеСнимка().
&НаКлиенте
Процедура СделатьФотоАсинхронно(Команда)
Оповещение = Новый ОписаниеОповещения("ОбработатьФотографию", ЭтотОбъект);
СредстваМультимедиа.НачатьПолучениеСнимка(Оповещение, ТипКамерыУстройства.Задняя);
КонецПроцедуры
&НаКлиенте
Процедура ОбработатьФотографию(Результат, ДополнительныеПараметры) Экспорт
Если Результат = Неопределено Тогда
Возврат; // Пользователь отменил съемку
КонецЕсли;
ДанныеДвоичные = Результат.ПолучитьДвоичныеДанные();
Адрес = ПоместитьВоВременноеХранилище(ДанныеДвоичные, ЭтаФорма.УникальныйИдентификатор);
// Записываем в реквизит формы
ЭтаФорма.ФотографияНаФорме = Адрес;
ЭтаФорма.Модифицированность = Истина;
КонецПроцедуры
Часто причиной «пустого экрана» является попытка мобильного устройства отобразить слишком тяжелое изображение. Если камера делает снимок в разрешении 12 или 48 мегапикселей, мобильный клиент 1С может просто не справиться с рендерингом такого объекта в Поле картинки.
Проанализируем ситуацию: для предпросмотра на форме документа достаточно разрешения 1024x768. Рекомендуется программно ограничивать разрешение снимка. Для этого используем метод СредстваМультимедиа.ПолучитьПоддерживаемыеРазрешенияКамеры() и выбираем из списка среднее значение, вместо того чтобы брать первый (самый качественный) элемент массива.
Важные моменты для запоминания:
ЭтаФорма.ОбновитьОтображениеДанных() после программного изменения адреса картинки.ЭтаФорма.УникальныйИдентификатор.ПередЗаписьюНаСервере.Соблюдение этих правил позволит избежать проблем с «пропадающими» фотографиями и обеспечит стабильную работу мобильного приложения на любых устройствах, где также может быть реализована генерация QR и штрихкодов.