МенеджерДоставляемыхУведомлений.ОтключитьОбработчикУведомлений

Методы · DetachNotificationHandler

Отключает вызов указанной процедуры.

Синтаксис

ОтключитьОбработчикУведомлений(<Процедура>)
Полное описание, параметры и ограничения

МенеджерДоставляемыхУведомлений.ОтключитьОбработчикУведомлений (DeliverableNotificationManager.DetachNotificationHandler)

МенеджерДоставляемыхУведомлений (DeliverableNotificationManager)

ОтключитьОбработчикУведомлений (DetachNotificationHandler)

Доступен, начиная с версии 8.3.6.

Синтаксис:
ОтключитьОбработчикУведомлений(<Процедура>)
Параметры:

<Процедура> (необязательный)
Тип: ОписаниеОповещения, Строка.
Имя процедуры, которую необходимо исключить из обработки уведомления.
Описание:

Отключает вызов указанной процедуры.

Доступность:

Мобильный клиент, мобильное приложение (клиент).

Использование в версии:

Доступен, начиная с версии 8.3.6.

Методическая информация

Практические примеры

Свой локальный Android пакет750: настоящий callback формы и осознанная общая отмена

Передайте две собственные строки через native локальное уведомление, проверьте реальный четырехпараметрический callback своей формы и отдельно изучите широкую отмену отложенного опыта.

Где и как запускать

Своя новая Android ARM64 developer лаборатория/CF. MAIN клиентские процедуры: только МобильноеПриложениеКлиент>=8.3.18; own scalar identity/UTC helpers: только МобильноеПриложениеСервер. Настоящие form command и Description callbacks, без push/SDK/личных данных/реальных операций сейчас.

Подготовка

  1. Это будущий ручной опыт только в новой полностью собственной Android ARM64 developer лаборатории/эмуляторе, с одной новой CF. Не личный телефон, рабочая ИБ, старое приложение или стенд с чужими уведомлениями. Лаборатория должна целиком принадлежать вам: ниже есть общая отмена, не фильтр одного nonce. Техническая приватность/изоляция здесь не обещана; сейчас устройство/1С/ОС не запускались.

  2. Создайте пустую CF УчебныеУведомления85, версия = 3b362d96-3be0-49b5-84b8-9f69770d28fb, совместимость Не использовать. Общие → Общие формы: ровно одна управляемая Уведомления85 в рабочей области начальной страницы. Весь MAIN вставьте в модуль этой формы; событие ПриОткрытии свяжите с реальным ПриОткрытии(Отказ), не вызывайте вручную. Общий модуль/APP строковый handler не нужны.

  3. Реквизиты формы: СогласенНаУведомление85 и СогласенНаОбщуюОтмену85 (Булево, исходно Ложь, два отдельных ручных флажка); ВерсияRuntime85/Состояние85 (Строка); ОтветПолучен85/ПоказаноОС85 (Булево); Сумма85 (Число15,2). Поля наблюдения ТолькоПросмотр=Да. Начальные false/0 не являются результатом callback — отдельно смотрите ОтветПолучен85.

  4. Создайте четыре команды формы: ОтправитьСвойПакет85, ОтключитьСвойОбработчик85, ПодготовитьОбщуюОтмену85, ОтменитьОтложенные85. Для каждой назначьте одноименный настоящий обработчик с параметром Команда; добавьте собственные кнопки с соответствующим ИмяКоманды. ПолученСвойПакет85 — отдельная экспортная процедура с четырьмя параметрами, не действие кнопки и не вручную вызываемый пример.

  5. У своей CF установите назначение Приложение для мобильной платформы. Проверьте конфигурацию для мобильного приложения клиент/сервер, целостность и неподдерживаемые функции: при ошибке STOP. Конфигурация → Мобильное приложение → Публиковать…: только свой новый виртуальный каталог OwnLocalNotification85_<ownGUID> и собственная новая папка своей Windows-VM/IIS. Это публикация конфигурации, не сборка APK; рабочую ИБ не подключайте.

  6. Вручную подготовьте на собственном отдельном Android ARM64 стенде официальную developer mobile platform1cem-arm64.apk из своего фактически полученного дистрибутива, не client/standalone. В пустом списке developer приложений: + → Address = реальный URL своей private VM/IIS с точным именем публикации → Load → свое имя УчебныеУведомления85 → OK/Done → открыть новое приложение. Не localhost телефона/придуманный URL/публичный или рабочий сервер. Только собственная лабораторная загрузка, никаких push-сервисов/FCM/APNs/магазина/внешнего SDK. Здесь ничего не скачивается/устанавливается/публикуется.

  7. Официальные инструкции будущей ручной подготовки: https://1c-dn.com/library/publishing_of_1c_mobile_application/ ; https://1c-dn.com/library/tutorials/1c_enterprise_development_tools_user_guide/ ; https://1c-dn.com/library/tutorials/first_application_mobile_platform/ . Их наличие не подтверждает вашу установку/runtime. Windows8.5.1.1343 не доказывает версию APK: реальная ВерсияRuntime85 должна быть не ниже8.3.18.

  8. ПоддерживаетсяФункциональностьМобильногоПриложения проверяет включенную при сборке функциональность ЛокальныеУведомления, а не OS grant или гарантированную доставку. Ложь/неизвестный тип → STOP до подключения/Add; desktop/mobile-client fallback не предусмотрен. Реальные настройки/разрешения ОС на своем стенде проверяются вами вручную, без обхода ограничений.

  9. Фаза A: прочитайте опыт, отдельно установите СогласенНаУведомление85 и нажмите ОтправитьСвойПакет85. Этот экземпляр потребляет согласие один раз. Создаются nonce и две собственные строки A:2×250=500, B:1×250=250. В JSON сохраняются полная версия, nonce, фаза, строки и итог750. Никакие существующие сообщения/получатели/идентификаторы подписчика не читаются.

  10. ОписаниеОповещения содержит имя экспортной процедуры именно этой формы, native ЭтотОбъект формы и непустой собственный state. Родной ctor и readonly ДополнительныеПараметры явно добавляют state последним аргументом: три native поля уведомления плюс четвертый ownstate. Это не String→APP resolver и не CommonModule.ЭтотОбъект. Состояние ожидания установлено ДО Attach/Add; код после Add не перезаписывает пришедший немедленно callback.

  11. Дождитесь только настоящего callback. Он сначала требует Локальное=Истина и фактический Bool Показано, затем проверяет все поля четвертого параметра/consumed consent, только native Текст/Данные, целый JSON и повторный расчет750. Точный класс первого native объекта не объявлен: нет fake cast; его Заголовок/Дата/Получатели/Наклейка после доставки не читаются, поскольку native обещает заполненными лишь Текст/Данные. ПоказаноОС85 — фактический флаг callback, не чтение текущего центра ОС.

  12. После ОтветПолучен85=Истина и Сумма85=750 нажмите ОтключитьСвойОбработчик85. Native Detach получает сохраненный ТОТ ЖЕ Description явным аргументом. Параметр optional в native, но здесь не опускается: не отключаем неизвестные handlers. Никакая автоматическая отмена/уборка не выполняется.

  13. Фаза B необязательна для ручного запуска: только на полностью собственной НОВОЙ лаборатории без чужих pending уведомлений. Прочитайте широкую область действия и отдельно установите СогласенНаОбщуюОтмену85. ПодготовитьОбщуюОтмену85 потребляет второе согласие и создает новый nonce/отложенный опыт. Настоящий сервер собственной CF возвращает scalar UTC дату, на клиенте к ней прибавляются180 секунд; ИнтервалПовтора=0. Это wall-clock, не точный таймер и не monotonic clock.

  14. Нажмите отдельную ОтменитьОтложенные85 до прихода delayed callback. Native cancel0 отменяет все отложенные локальные уведомления, которые еще не выведены: нет nonce/ID/фильтра. У процедуры нет результата Bool/ID или queue-readback. Наблюдение лишь «запрос общей отмены без синхронного исключения», не «очередь пуста»/«данное уведомление точно отменено». Отсутствие callback не доказательство. В конце отдельной кнопкой отключите свой Description; это также не проверяет очередь.

  15. Если delayed callback пришел раньше общей отмены, его реальные данные/четвертый state проверяются, затем опыт STOP: не переименовывайте уже доставленное уведомление в успешно отмененное. Любая ошибка/unknown/повтор/чужой nonce/changed version дает sticky STOP этого экземпляра без retry, rollback, cancel-cleanup или восстановления prior state. Повтор возможен лишь новой явной ручной подготовкой собственной лаборатории/формы; блокировка не обещана сохраняющейся между экземплярами. Здесь нет доказанного Android GUI/runtime успеха.

&НаКлиенте
Перем Остановка85, Этап85, ВерсияЗапуска85, НомерОпыта85, ВидОпыта85;
&НаКлиенте
Перем СогласиеИспользовано85, СогласиеОтменыИспользовано85, Пакет85, Описание85;

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    Если СогласиеИспользовано85 <> Неопределено Тогда
        Отказ = Истина;
        Возврат;
    КонецЕсли;
    Остановка85 = Истина;
    СогласиеИспользовано85 = Ложь;
    СогласиеОтменыИспользовано85 = Ложь;
    СогласенНаУведомление85 = Ложь;
    СогласенНаОбщуюОтмену85 = Ложь;
    ОтветПолучен85 = Ложь;
    ПоказаноОС85 = Ложь;
    Сумма85 = 0;
    Попытка
        ВерсияЗапуска85 = ПроверитьСреду85();
        ВерсияRuntime85 = ВерсияЗапуска85;
        Этап85 = "Готов";
        Остановка85 = Ложь;
        Состояние85 = "Прочитайте опыт. Согласие на одно свое уведомление пока не дано";
    Исключение
        Остановить85(ОписаниеОшибки());
        Отказ = Истина;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура Остановить85(Причина)
    Остановка85 = Истина;
    Этап85 = "STOP";
    СогласенНаУведомление85 = Ложь;
    СогласенНаОбщуюОтмену85 = Ложь;
    Состояние85 = "STOP этого экземпляра. Без повторов и автоматической уборки. " + Причина;
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьКоманду85(Команда, Имя, НужныйЭтап)
    Если Остановка85 <> Ложь Или Этап85 <> НужныйЭтап
        Или ТипЗнч(Команда) <> Тип("КомандаФормы") Или Команда <> Команды.Найти(Имя)
        Или ВерсияЗапуска85 <> ПроверитьСреду85() Тогда
        ВызватьИсключение "Не совпала своя команда, фаза или мобильная среда";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ОтправитьСвойПакет85(Команда)
    Попытка
        ПроверитьКоманду85(Команда, "ОтправитьСвойПакет85", "Готов");
        Если СогласиеИспользовано85 <> Ложь Или СогласенНаУведомление85 <> Истина Тогда
            ВызватьИсключение "Нужно отдельное согласие на собственный учебный пакет";
        КонецЕсли;
        СогласиеИспользовано85 = Истина;
        СогласенНаУведомление85 = Ложь;
        НачатьСвойОпыт85("СЕЙЧАС", Неопределено);
    Исключение
        Остановить85(ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура ПодготовитьОбщуюОтмену85(Команда)
    Попытка
        ПроверитьКоманду85(Команда, "ПодготовитьОбщуюОтмену85", "ГотовКОтмене");
        Если СогласиеОтменыИспользовано85 <> Ложь Или СогласенНаОбщуюОтмену85 <> Истина Тогда
            ВызватьИсключение "Нужно новое отдельное согласие: отмена всех отложенных уведомлений своей новой лаборатории";
        КонецЕсли;
        СогласиеОтменыИспользовано85 = Истина;
        СогласенНаОбщуюОтмену85 = Ложь;
        UTC = ПолучитьСвоюUTC85();
        Если ТипЗнч(UTC) <> Тип("Дата") Тогда
            ВызватьИсключение "Свой сервер не вернул фактическую UTC дату";
        КонецЕсли;
        НачатьСвойОпыт85("ОТЛОЖЕННО", UTC + 180);
    Исключение
        Остановить85(ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура НачатьСвойОпыт85(Вид, UTCСрабатывания)
    Если Остановка85 <> Ложь Тогда
        ВызватьИсключение "Остановленный экземпляр не начинает новый опыт";
    КонецЕсли;
    ВидОпыта85 = Вид;
    НомерОпыта85 = Строка(Новый УникальныйИдентификатор);
    Если СтрДлина(НомерОпыта85) <> 36 Или НомерОпыта85 = "00000000-0000-0000-0000-000000000000" Тогда
        ВызватьИсключение "Нет собственного ненулевого номера опыта";
    КонецЕсли;
    Строки = Новый Массив;
    Строки.Добавить(Новый Структура("Item,Qty,Price", "A", 2, 250));
    Строки.Добавить(Новый Структура("Item,Qty,Price", "B", 1, 250));
    Источник = Новый Структура("Version,Nonce,Phase,Rows,Total",
        ВерсияЗапуска85, НомерОпыта85, ВидОпыта85, Строки, 750);
    Запись = Новый ЗаписьJSON;
    Запись.УстановитьСтроку();
    ЗаписатьJSON(Запись, Источник);
    Пакет85 = Запись.Закрыть();
    Если ПроверитьПакет85(Пакет85) <> 750 Тогда
        ВызватьИсключение "Свой исходный пакет не дал 750";
    КонецЕсли;
    СвоеСостояние = Новый Структура("Nonce,Phase,Version,SourcePacket,Consent",
        НомерОпыта85, ВидОпыта85, ВерсияЗапуска85, Пакет85, Истина);
    Описание85 = Новый ОписаниеОповещения("ПолученСвойПакет85", ЭтотОбъект, СвоеСостояние);
    ПроверитьОписание85();
    Уведомление = Новый ДоставляемоеУведомление;
    Уведомление.Заголовок = "Учебный пакет 750";
    Уведомление.Текст = "Свой расчет 750. Опыт " + НомерОпыта85;
    Уведомление.Данные = Пакет85;
    Уведомление.ИнтервалПовтора = 0;
    Если ВидОпыта85 = "ОТЛОЖЕННО" Тогда
        Если ТипЗнч(UTCСрабатывания) <> Тип("Дата") Или UTCСрабатывания <= ПолучитьСвоюUTC85() Тогда
            ВызватьИсключение "Нет собственной будущей UTC даты";
        КонецЕсли;
        Если Остановка85 <> Ложь Тогда
            ВызватьИсключение "Не продолжаем после неизвестного исхода во время проверки UTC";
        КонецЕсли;
        Уведомление.ДатаПоявленияУниверсальноеВремя = UTCСрабатывания;
        Этап85 = "ЖдемОтмены";
        Состояние85 = "Создается свой отложенный опыт. Затем нажмите отдельную общую отмену";
    ИначеЕсли ВидОпыта85 = "СЕЙЧАС" И UTCСрабатывания = Неопределено Тогда
        Этап85 = "Ждем";
        Состояние85 = "Ожидается настоящий callback; отсутствие ответа не означает успех";
    Иначе
        ВызватьИсключение "Неизвестный собственный вид опыта";
    КонецЕсли;
    ОтветПолучен85 = Ложь;
    Менеджер = ПолучитьМенеджер85();
    Менеджер.ПодключитьОбработчикУведомлений(Описание85);
    Если Остановка85 <> Ложь Или (Этап85 <> "Ждем" И Этап85 <> "ЖдемОтмены") Тогда
        ВызватьИсключение "Во время подключения возник неизвестный исход";
    КонецЕсли;
    Менеджер.ДобавитьЛокальноеУведомление(Уведомление);
КонецПроцедуры

&НаКлиенте
Процедура ПолученСвойПакет85(Уведомление, Локальное, Показано, СостояниеОпыта85) Экспорт
    Попытка
        Если Остановка85 <> Ложь Или (Этап85 <> "Ждем" И Этап85 <> "ЖдемОтмены")
            Или ВерсияЗапуска85 <> ПроверитьСреду85()
            Или ТипЗнч(Локальное) <> Тип("Булево") Или Локальное <> Истина
            Или ТипЗнч(Показано) <> Тип("Булево") Тогда
            ВызватьИсключение "Не свой локальный callback, фаза или тип native флага; чужие данные не читаются";
        КонецЕсли;
        ПроверитьСостояние85(СостояниеОпыта85);
        Текст = Уведомление.Текст;
        Данные = Уведомление.Данные;
        Если ТипЗнч(Текст) <> Тип("Строка") Или Текст <> "Свой расчет 750. Опыт " + НомерОпыта85
            Или ТипЗнч(Данные) <> Тип("Строка") Или Данные <> СостояниеОпыта85.SourcePacket Тогда
            ВызватьИсключение "Native Text/Data не совпали с целым своим пакетом";
        КонецЕсли;
        Сумма85 = ПроверитьПакет85(Данные);
        ОтветПолучен85 = Истина;
        ПоказаноОС85 = Показано;
        Если ВидОпыта85 <> "СЕЙЧАС" Тогда
            ВызватьИсключение "Отложенный callback уже пришел. Не объявляйте последующую отмену успешной";
        КонецЕсли;
        Этап85 = "Доставлено";
        Состояние85 = "Настоящий свой callback: сумма 750. Флаг ОС показан отдельно. Отключите свой handler отдельной кнопкой";
    Исключение
        Остановить85(ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура ОтменитьОтложенные85(Команда)
    Попытка
        ПроверитьКоманду85(Команда, "ОтменитьОтложенные85", "ЖдемОтмены");
        ПроверитьОписание85();
        Если ВидОпыта85 <> "ОТЛОЖЕННО" Или СогласиеОтменыИспользовано85 <> Истина Тогда
            ВызватьИсключение "Нет своего отложенного опыта с использованным отдельным согласием";
        КонецЕсли;
        Менеджер = ПолучитьМенеджер85();
        Менеджер.ОтменитьЛокальныеУведомления();
        Если Остановка85 <> Ложь Или Этап85 <> "ЖдемОтмены" Тогда
            ВызватьИсключение "Не перезаписываем исход callback во время запроса отмены";
        КонецЕсли;
        Этап85 = "ОтменаЗапрошена";
        Состояние85 = "Запрос ОБЩЕЙ отмены выполнен без синхронного исключения. Пустая очередь и точная отмена не доказаны";
    Исключение
        Остановить85(ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура ОтключитьСвойОбработчик85(Команда)
    Попытка
        Если Этап85 <> "Доставлено" И Этап85 <> "ОтменаЗапрошена" Тогда
            ВызватьИсключение "Нет законченной ручной фазы для отключения своего handler";
        КонецЕсли;
        ПроверитьКоманду85(Команда, "ОтключитьСвойОбработчик85", Этап85);
        ПроверитьОписание85();
        Менеджер = ПолучитьМенеджер85();
        Менеджер.ОтключитьОбработчикУведомлений(Описание85);
        Если Остановка85 <> Ложь Или (Этап85 <> "Доставлено" И Этап85 <> "ОтменаЗапрошена") Тогда
            ВызватьИсключение "Не перезаписываем неизвестный исход во время отключения";
        КонецЕсли;
        Если ВидОпыта85 = "СЕЙЧАС" Тогда
            Этап85 = "ГотовКОтмене";
        Иначе
            Этап85 = "Завершено";
        КонецЕсли;
        Состояние85 = "Явно отключен свой сохраненный Description. Это не очистка уведомлений и не подтверждение очереди";
    Исключение
        Остановить85(ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьОписание85()
    Если ТипЗнч(Описание85) <> Тип("ОписаниеОповещения")
        Или Описание85.ИмяПроцедуры <> "ПолученСвойПакет85" Или Описание85.Модуль <> ЭтотОбъект Тогда
        ВызватьИсключение "Подменен native Description или контекст собственной формы";
    КонецЕсли;
    ПроверитьСостояние85(Описание85.ДополнительныеПараметры);
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьСостояние85(Состояние)
    Если ТипЗнч(Состояние) <> Тип("Структура") Или Состояние.Количество() <> 5
        Или Не Состояние.Свойство("Nonce") Или Не Состояние.Свойство("Phase")
        Или Не Состояние.Свойство("Version") Или Не Состояние.Свойство("SourcePacket")
        Или Не Состояние.Свойство("Consent") Тогда
        ВызватьИсключение "Не совпали поля собственного четвертого параметра";
    КонецЕсли;
    Если ТипЗнч(Состояние.Nonce) <> Тип("Строка") Или Состояние.Nonce <> НомерОпыта85
        Или ТипЗнч(Состояние.Phase) <> Тип("Строка") Или Состояние.Phase <> ВидОпыта85
        Или ТипЗнч(Состояние.Version) <> Тип("Строка") Или Состояние.Version <> ВерсияЗапуска85
        Или ТипЗнч(Состояние.SourcePacket) <> Тип("Строка") Или Состояние.SourcePacket <> Пакет85
        Или ТипЗнч(Состояние.Consent) <> Тип("Булево") Или Состояние.Consent <> Истина
        Или (ВидОпыта85 = "СЕЙЧАС" И СогласиеИспользовано85 <> Истина)
        Или (ВидОпыта85 = "ОТЛОЖЕННО" И СогласиеОтменыИспользовано85 <> Истина)
        Или ПроверитьПакет85(Состояние.SourcePacket) <> 750 Тогда
        ВызватьИсключение "Не совпал own nonce, фаза, версия, полный пакет или использованное согласие";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Функция ПроверитьПакет85(JSON)
    Если ТипЗнч(JSON) <> Тип("Строка") Или JSON = "" Тогда
        ВызватьИсключение "Нет целого JSON пакета";
    КонецЕсли;
    Чтение = Новый ЧтениеJSON;
    Чтение.УстановитьСтроку(JSON);
    Попытка
        Пакет = ПрочитатьJSON(Чтение);
        Чтение.Закрыть();
    Исключение
        Чтение.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Если ТипЗнч(Пакет) <> Тип("Структура") Или Пакет.Количество() <> 5
        Или Не Пакет.Свойство("Version") Или Не Пакет.Свойство("Nonce")
        Или Не Пакет.Свойство("Phase") Или Не Пакет.Свойство("Rows") Или Не Пакет.Свойство("Total") Тогда
        ВызватьИсключение "Не совпали все поля пакета";
    КонецЕсли;
    Если ТипЗнч(Пакет.Version) <> Тип("Строка") Или Пакет.Version <> ВерсияЗапуска85
        Или ТипЗнч(Пакет.Nonce) <> Тип("Строка") Или Пакет.Nonce <> НомерОпыта85
        Или ТипЗнч(Пакет.Phase) <> Тип("Строка") Или Пакет.Phase <> ВидОпыта85
        Или ТипЗнч(Пакет.Rows) <> Тип("Массив") Или Пакет.Rows.Количество() <> 2
        Или ТипЗнч(Пакет.Total) <> Тип("Число") Или Пакет.Total <> 750 Тогда
        ВызватьИсключение "Не свой пакет, типы или количество строк";
    КонецЕсли;
    Итог = 0;
    Для Индекс = 0 По 1 Цикл
        СтрокаПакета = Пакет.Rows[Индекс];
        Если ТипЗнч(СтрокаПакета) <> Тип("Структура") Или СтрокаПакета.Количество() <> 3
            Или Не СтрокаПакета.Свойство("Item") Или Не СтрокаПакета.Свойство("Qty")
            Или Не СтрокаПакета.Свойство("Price") Тогда
            ВызватьИсключение "Не совпали все поля строки";
        КонецЕсли;
        Если ТипЗнч(СтрокаПакета.Item) <> Тип("Строка") Или ТипЗнч(СтрокаПакета.Qty) <> Тип("Число")
            Или ТипЗнч(СтрокаПакета.Price) <> Тип("Число") Или СтрокаПакета.Price <> 250
            Или (Индекс = 0 И (СтрокаПакета.Item <> "A" Или СтрокаПакета.Qty <> 2))
            Или (Индекс = 1 И (СтрокаПакета.Item <> "B" Или СтрокаПакета.Qty <> 1)) Тогда
            ВызватьИсключение "Подменены собственные две строки, числовые типы, порядок или цены";
        КонецЕсли;
        Итог = Итог + СтрокаПакета.Qty * СтрокаПакета.Price;
    КонецЦикла;
    Если Итог <> Пакет.Total Тогда
        ВызватьИсключение "500 + 250 не совпало с заявленным итогом";
    КонецЕсли;
    Возврат Итог;
КонецФункции

&НаКлиенте
Функция ПолучитьМенеджер85()
    Менеджер = ДоставляемыеУведомления;
    Если ТипЗнч(Менеджер) <> Тип("МенеджерДоставляемыхУведомлений") Тогда
        ВызватьИсключение "Не получен настоящий global менеджер";
    КонецЕсли;
    Возврат Менеджер;
КонецФункции

&НаКлиенте
Функция ПроверитьСреду85()
    #Если МобильноеПриложениеКлиент Тогда
        Информация = Новый СистемнаяИнформация;
        Версия = Информация.ВерсияПриложения;
        Если ПодтвердитьСвойПакет85() <> Истина Тогда
            ВызватьИсключение "Нужно собственное мобильное приложение не ниже 8.3.18";
        КонецЕсли;
        Поддержка = ПоддерживаетсяФункциональностьМобильногоПриложения(ФункциональностьМобильногоПриложения.ЛокальныеУведомления);
        Если ТипЗнч(Поддержка) <> Тип("Булево") Или Поддержка <> Истина Тогда
            ВызватьИсключение "Функциональность не включена. Это проверка сборки, не разрешение ОС";
        КонецЕсли;
        Возврат Версия;
    #Иначе
        ВызватьИсключение "Только свое мобильное приложение; desktop/mobile-client fallback запрещен";
    #КонецЕсли
КонецФункции

&НаСервереБезКонтекста
Функция ПодтвердитьСвойПакет85()
    #Если МобильноеПриложениеСервер Тогда
        Если Метаданные.ОбщиеФормы.Количество() <> 1 Или Метаданные.ОбщиеФормы.Найти("Уведомления85") = Неопределено Тогда
            ВызватьИсключение "Не совпала своя новая мобильная CF и единственная форма";
        КонецЕсли;
        Возврат Истина;
    #Иначе
        ВызватьИсключение "Нужен сервер своего мобильного приложения";
    #КонецЕсли
КонецФункции

&НаСервереБезКонтекста
Функция ПолучитьСвоюUTC85()
    #Если МобильноеПриложениеСервер Тогда
        Если ПодтвердитьСвойПакет85() <> Истина Тогда
            ВызватьИсключение "Нет своего сервера";
        КонецЕсли;
        UTC = ТекущаяУниверсальнаяДата();
        Если ТипЗнч(UTC) <> Тип("Дата") Тогда
            ВызватьИсключение "Нет native UTC даты";
        КонецЕсли;
        Возврат UTC;
    #Иначе
        ВызватьИсключение "UTC берется на сервере, не прямым mobile-client вызовом";
    #КонецЕсли
КонецФункции

Разбор по шагам

  1. Подготовьте свою новую CF/единственную форму/четыре реальные команды и actual Android developer runtime. Открытие только проверяет свою среду.

  2. Дайте первое отдельное согласие и запустите фазу A. Native global manager получает настоящий DTO, собственный Description и пакет A500+B250=750.

  3. Настоящий callback проверяет свои четвертые параметры, local/shown Bool и целый native Text/Data; после повторного расчета наблюдайте ОтветПолучен85,750 и actual ПоказаноОС85.

  4. Реальной кнопкой явно отключите тот же свой Description, без optional omission/массового отключения.

  5. Только в новой полностью своей лаборатории дайте второе отдельное согласие. Native серверная UTC дата+180 готовит delayed опыт с новым nonce и interval0.

  6. Отдельная ручная cancel0 запрашивает широкую отмену без success/ID/empty-queue обещания. После этого отдельной кнопкой отключите свой handler; early delayed callback дает STOP.

Как проверить результат

  1. Все6 PRIMARY входят в реальный единый producer→consumer: readonly global manager, native DTO/Add, реальный formDescription callback4, явный savedDescription Detach и отдельный delayed cancel0.

  2. Четвертый callback formal документирован constructor/AdditionalParameters и целиком потребляется по полям nonce/phase/version/sourcepayload/consent; первые3 native аргумента также потребляются.

  3. Source пакет и принятый packet проверяются полностью: exact fields/types/2rows/order/A2×250/B1×250/total750. Unknown/foreign данные не становятся успешным результатом.

  4. Оба согласия отдельные, исходноFalse и потребляются только настоящими командами; waiting установлен до Attach/Add, немедленный callback не затирается.

  5. UTC native call находится только в actual mobile-server helper собственной формы, возвращает safe scalar Дата; native void procedures не присваиваются выдуманному результату.

  6. Нет автоматических повторов/cleanup/ручных callbacks, caller-owned ИсходныйОбъект, push-ID или dummy coverage вызовов; runtimeVerified остаетсяFalse.

Ожидаемый результат

Будущая ручная проверка: actual callback дает750 и собственный факт BoolПоказано. Вторая фаза показывает только запрос общей отмены без синхронного исключения. Настоящие Android OS/UI/доставка здесь не проверены.

На что обратить внимание

  1. Attach rawHTML ошибочно помещает ОписаниеОповещения/Строка под «Значение по умолчанию». Description route подтвержден отдельным native ctor/AdditionalParameters/Module и реальным конфигурационным caller; source ошибку не переписываем.

  2. CommonModule.ЭтотОбъект имеет иной native список доступности; не переносим его на mobile APPclient. Здесь используется только прямо документированный native ЭтотОбъект собственной managedформы.

  3. Точный класс callback Уведомление native не указан; onlyText/Data не означает сохранение остальных полей DTO. Actual LocalFalse не читается как свой payload.

  4. Cancel0 широкая, не адресная и не гарантированный rollback. Возвращаемого Bool/ID, чтения очереди и доказательства по отсутствию callback нет.

  5. Мин8.3.18 относится capability guard; фактический APK/runtime отдельно от установленной Windows платформы. OS grant/точный alarm/изоляция/атомарность не обещаны.

  6. STOP относится текущему экземпляру формы. Исключение после Attach/Add/Cancel оставляет неизвестный исход без автоматической уборки; реальный новый опыт требует новой явной ручной подготовки.

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

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.