Разработка приложения для обработки события MobileOperatorNotification
В этом разделе объясняется, как разработать мобильное широкополосное приложение, которое обрабатывает событие MobileOperatorNotification .
Рекомендации
Для обработки фоновых событий следует использовать следующие рекомендации:
Не регистрируйте фоновые события, с которыми невозможно выполнить действия. При обработке этих событий будет использоваться квота приложения.
Не выполняйте большие объемы обработки при получении фонового события.
Рассмотрите возможность отложить обработку до следующего запуска приложения.
Рассмотрите возможность отображения всплывающего уведомления и обновления плитки в ответ на фоновое событие. Мобильное широкополосное приложение может обрабатывать полезные данные фоновых событий.
Шаг 1. Объявление контракта фоновой задачи
Чтобы Windows распознала фоновые задачи, предоставляемые мобильным широкополосным приложением, приложение должно объявить, что оно предоставляет расширение для функциональных возможностей системы.
Чтобы сделать объявление в файле package.appxmanifest для проекта Visual Studio, выполните следующие действия:
Объявление контракта фоновой задачи
В Обозреватель решений дважды щелкните файл package.appxmanifest для проекта.
На вкладке Объявления в разделе Доступные объявления выберите Фоновые задачи и нажмите кнопку Добавить.
В разделе Свойства введите следующие сведения о приложении:
В поле Начальная страница в разделе Параметры приложения для мобильного широкополосного приложения, использующего JavaScript и HTML, введите имя файла, обрабатывающего фоновую задачу в приложении (например, backgroundtask.js).
В разделе Поддерживаемые типы задач щелкните поле Системное событие проверка.
Если это сделано правильно, в файле package.appxmanifest должен быть элемент расширения, аналогичный приведенному ниже.
<Extension Category="windows.backgroundTasks" StartPage="backgroundtask.js">
<BackgroundTasks>
<Task Type="systemEvent" />
</BackgroundTasks>
</Extension>
Шаг 2. Обработчик фоновой задачи
Если приложение предоставляет объявление уведомлений мобильного оператора, оно должно предоставить обработчик для активации фоновой задачи. Обработчик получит идентификатор сетевой учетной записи оператора мобильной связи и данные о событиях из Windows.Networking.NetworkOperators.NetworkOperatorNotificationEventDetails.
Так как фоновая задача поддерживает только пользовательский интерфейс Toast, обработчик фоновой задачи может отображать всплывающее уведомление или сохранять NetworkOperatorNotificationEventDetails в локальном хранилище.
В следующих примерах кода показана фоновая задача, предназначенная для выполнения при получении нового административного SMS-уведомления.
C#
using Windows.Networking.NetworkOperators;
namespace MNOMessageBackground
{
public sealed class MNOBackgroundTask : IBackgroundTask
{
public void Run(Windows.ApplicationModel.Background.IBackgroundTaskInstance taskInstance)
{
NetworkOperatorNotificationEventDetails notifyData = (NetworkOperatorNotificationEventDetails)taskInstance.TriggerDetails;
//The network account ID is stored in notifyData.NetworkAccountId
switch (notifyData.NotificationType)
{
case NetworkOperatorEventMessageType.Gsm: // 0
break;
case NetworkOperatorEventMessageType.Cdma: // 1
break;
case NetworkOperatorEventMessageType.Ussd: // 2
break;
case NetworkOperatorEventMessageType.DataPlanThresholdReached: // 3
break;
case NetworkOperatorEventMessageType.DataPlanReset: //4
break;
case NetworkOperatorEventMessageType.DataPlanDeleted: //5
break;
case NetworkOperatorEventMessageType.ProfileConnected: //6
break;
case NetworkOperatorEventMessageType.ProfileDisconnected: //7
break;
case NetworkOperatorEventMessageType.RegisteredRoaming: //8
break;
case NetworkOperatorEventMessageType.RegisteredHome: ///9
break;
case NetworkOperatorEventMessageType.TetheringEntitlementCheck: //10
break;
default:
break;
}
// Add code to save the message to app local storage, and optionally show toast notification and tile updates.
}
}
}
JavaScript
(function () {
"use strict";
//
// The background task instance's activation parameters are available via
// Windows.UI.WebUI.WebUIBackgroundTaskInstance.current.
//
var backgroundTaskInstance = Windows.UI.WebUI.WebUIBackgroundTaskInstance.current,
networkOperatorEventType = Windows.Networking.NetworkOperators.NetworkOperatorEventMessageType,
key = null,
settings = Windows.Storage.ApplicationData.current.localSettings;
try {
var details = backgroundTaskInstance.triggerDetails;
// The network account ID is stored in details.networkAccountId.
switch (details.notificationType) {
case networkOperatorEventType.gsm:
showToast("Mobile Broadband message", details.message);
break;
case networkOperatorEventType.cdma:
showToast("Mobile Broadband message", details.message);
break;
case networkOperatorEventType.ussd:
showToast("Mobile Broadband message", details.message);
break;
case networkOperatorEventType.dataPlanThresholdReached:
showToast("Mobile Broadband message", "Data plan threshold reached");
break;
case networkOperatorEventType.dataPlanReset:
showToast("Mobile Broadband message", "Data plan reset");
break;
case networkOperatorEventType.dataPlanDeleted:
showToast("Mobile Broadband message", "Data plan deleted");
break;
case networkOperatorEventType.profileConnected:
showToast("Mobile Broadband message", "Profile connected");
break;
case networkOperatorEventType.profileDisconnected:
showToast("Mobile Broadband message", "Profile disconnected");
break;
case networkOperatorEventType.registeredRoaming:
showToast("Mobile Broadband message", "Registered roaming");
break;
case networkOperatorEventType.registeredHome:
showToast("Mobile Broadband message", "Registered home");
break;
case networkOperatorEventType.tetheringEntitlementCheck:
showToast("Mobile Broadband message", "Entitlement check completed");
break;
default:
showToast("Mobile Broadband message", "Unknown message");
break;
}
//
// A JavaScript background task must call close when it is done.
//
close();
}
catch (exception) {
// Display error message.
close();
}
Отображение плиток и всплывающих уведомлений
Мы рекомендуем отображать всплывающие и мозаичное уведомления в мобильном широкополосном приложении, так как пользователь может пропустить всплывающее уведомление из-за его временной природы. Рекомендации по проектированию всплывающих уведомлений и обновлений плиток см. в статье Проектирование пользовательского интерфейса мобильного широкополосного приложения.
Включение всплывающих уведомлений
В Обозреватель решений дважды щелкните файл package.appxmanifest для проекта.
На вкладке Пользовательский интерфейс приложения под заголовком Уведомления установите для параметра Поддержка всплывающих уведомлений значение Да.
Если это сделано правильно, в файле package.appxmanifest должен быть элемент расширения, аналогичный приведенному ниже.
<VisualElements … ToastCapable="true"… />
В следующем коде показано, как отобразить всплывающее уведомление в дескрипторе фоновой задачи:
JavaScript
function showToast(title, body) {
var notifications = Windows.UI.Notifications;
var toastNotificationManager = Windows.UI.Notifications.ToastNotificationManager;
var toastXml = toastNotificationManager.getTemplateContent(notifications.ToastTemplateType.toastText02);
var temp = "the parameter will pass to app when app activated from tap Toast ";
toastXml.selectSingleNode("/toast").setAttribute("launch", temp);
var textNodes = toastXml.getElementsByTagName("text");
textNodes[0].appendChild(toastXml.createTextNode(title));
textNodes[1].appendChild(toastXml.createTextNode(body));
var toast = new notifications.ToastNotification(toastXml);
toastNotificationManager.createToastNotifier().show(toast);
}
Получение SMS-сообщения
Если фоновая задача была активирована входящим SMS-сообщением, сведения о фоновой задаче будут содержать объект SMS в полезных данных.
JavaScript
(function () {
"use strict";
//
// The background task instance's activation parameters are available via
// Windows.UI.WebUI.WebUIBackgroundTaskInstance.current.
//
var backgroundTaskInstance = Windows.UI.WebUI.WebUIBackgroundTaskInstance.current,
try {
var details = backgroundTaskInstance.triggerDetails;
if (details.notificationType === networkOperatorEventType.gsm
|| details.notificationType === networkOperatorEventType.cdma)
{
var textMessage = new Windows.Devices.Sms.SmsTextMessage.fromBinaryMessage(details.smsMessage);
// textMessage can be used to get other SmsMessage properties
// like sender number, timestamp, message part count etc.
showToast("From: " + textMessage.from + "; TimeStamp: " + textMessage.timestamp, details.message);
}
Использование локального хранилища
Фоновая задача может использовать локальное хранилище для сохранения сообщения, полученного от фонового события, чтобы приложение пользовалось этой информацией позже.
JavaScript
//
// Save the message
//
var settings = Windows.Storage.ApplicationData.current.localSettings;
var keyMessage = "BA5857FA-DE2C-4A4A-BEF2-49D8B4130A39";
//
// The background task instance's activation parameters are available via
// Windows.UI.WebUI.WebUIBackgroundTaskInstance.current
//
var backgroundTaskInstance = Windows.UI.WebUI.WebUIBackgroundTaskInstance.current;
var details = backgroundTaskInstance.triggerDetails;
settings.values[keyMessage] = details.message;
В следующем коде показано, как получить сообщение, хранящееся обработчиком фоновых задач в приложении:
JavaScript
var settings = Windows.Storage.ApplicationData.current.localSettings;
var keyMessage = "BA5857FA-DE2C-4A4A-BEF2-49D8B4130A39";
var operatorMessage = settings.values[keyMessage];
Шаг 3. Обработка события активации
Если всплывающее уведомление задает параметр, оно будет передано приложению через detail.arguments.
В JavaScript или C# вы обрабатываете событие WinJS.Application.onactivated , а затем проверяете аргументы события, передаваемые обработчику событий. Активация из всплывающего уведомления передает аргумент события типа Windows.UI.WebUI.WebUILaunchActivatedEventArgs. Если свойство аргумента события detail.kind имеет значение Windows.ApplicationModel.Activation.ctivationKind. При запуске приложение предоставляет либо начальный интерфейс, либо интерфейс уведомления в зависимости от того, задано ли для свойства аргумента события detail.argumentзначение NULL.
JavaScript
WinJS.Application.addEventListener("activated", activated; false);
function activated(eventArgs)
{
if (eventArgs.detail.kind == Windows.ApplicationModel.Activation.ActivationKind.launch)
{
if (!eventArgs.detail.arguments)
{
// Initialize logic for the Start experience here.
}
else
{
// Initialize logic for the Notification experience here.
}
}
}
Шаг 4. Обработка обработчиков завершения фоновых задач
Приложение переднего плана также может зарегистрировать обработчик завершения, чтобы получать уведомления о завершении фоновой задачи. Состояние завершения или любое исключение, возникающее в методе Run фоновой задачи, передается обработчику завершения в приложении переднего плана. Если приложение было приостановлено по завершении задачи, оно получает уведомление о завершении в следующий раз при возобновлении работы приложения. Если приложение находилось в состоянии Завершено , оно не получает уведомление о завершении. Если фоновая задача должна сохранить сведения, которые она успешно выполнила, она должна сохранить эти сведения с помощью диспетчера состояний или других средств, таких как файл, который приложение может прочитать при возвращении в состояние Выполняется .
Важно Хотя фоновое событие оператора мобильной связи автоматически регистрируется системой в приложении, приложение по-прежнему должно запускаться хотя бы один раз, чтобы зарегистрироваться в обработчиках фонового завершения или хода выполнения.
C#
foreach (var cur in BackgroundTaskRegistration.AllTasks)
{
if(cur.Value.Name == “MobileOperatorNotificationHandler”)
{
cur.Value.Progress += new BackgroundTaskProgressEventHandler(OnProgress);
cur.Value.Completed += new BackgroundTaskCompletedEventHandler(OnCompleted);
}
}
//
// Handle background task completion.
private void OnCompleted(IBackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs e)
{
var taskCompletion = task as IBackgroundTaskRegistration;
var completionArgs = args.Context as BackgroundTaskCompletedEventArgs;
//
// If the background task threw an exception, display the exception in the error text box.
if (completionArgs.Status != null)
{
throw completionArgs.Status;
}
}
// Handle background task progress.
private void OnProgress(IBackgroundTaskRegistration sender, BackgroundTaskProgressEventArgs e)
{
var taskRegistration = task as IBackgroundTaskRegistration;
var progressArgs = args.Context as BackgroundTaskProgressEventArgs;
// progressArgs.Progress has the progress percentage
}
JavaScript
var iter = Windows.ApplicationModel.Background.BackgroundTaskRegistration.allTasks.first();
var hascur = iter.hasCurrent;
while (hascur) {
var cur = iter.current.value;
if (cur.name === “MobileOperatorNotificationHandler”) {
cur.addEventListener("progress", new ProgressHandler(cur).onProgress);
cur.addEventListener("completed", new CompleteHandler(cur).onCompleted);
}
hascur = iter.moveNext();
}
//
// Handle background task progress.
//
function ProgressHandler(task) {
this.onProgress = function (args) {
try {
var progress = "Progress: " + args.progress + "%";
} catch (ex) {
displayError(ex);
}
};
}
//
// Handle background task completion.
//
function CompleteHandler(task) {
this.onCompleted = function (args) {
try {
var key = task.taskId;
} catch (ex) {
displayError(ex);
}
};
}
Устранение неполадок
Используйте эти разделы для устранения неполадок, которые могут возникнуть.
Активация синтаксического анализа метаданных для регистрации фоновых задач
Пользователи, когда мобильное широкополосное устройство подключено, Windows 8, Windows 8.1 и Windows 10 автоматически устанавливает мобильное широкополосное приложение и связанные метаданные службы и регистрирует фоновые задачи, определенные в метаданных службы. Однако в Windows 8.1 приложение не закрепляется на начальном экране автоматически.
Разработчики могут вручную активировать Windows 8, Windows 8.1 и Windows 10 для анализа метаданных службы и регистрации фоновых задач, нажав клавишу F5 (или щелкните правой кнопкой мыши и выберите Обновить) в окне Устройства и принтеры на рабочем столе. Регистрация фоновой задачи с помощью анализа метаданных службы выполняется только при развертывании приложения.
Проверка правильности регистрации фоновых задач
Разработчики могут убедиться, что диспетчер установки устройств (DSM) правильно анализировал метаданные службы, просмотрев журналы событий в разделе Журналы приложений и служб\Microsoft\Windows\DeviceSetupManager.
Откройте средство просмотра событий.
На вкладке Меню выберите Вид, а затем — Показать журналы аналитики и отладки.
Перейдите в журналы приложений и служб\Microsoft\Windows\DeviceSetupManager.
К интересующим событиям относятся событие с идентификатором 220, которое указывает, что DSM успешно зарегистрировала фоновую задачу для события MobileOperatorNotification , и событие с идентификатором 7900, которое указывает на все ошибки, обнаруженные в пакете метаданных.
Убедитесь, что метаданные подготовки успешно применены
При применении метаданных подготовки убедитесь, что параметр ProvisionFromXmlDocumentResults.AllElementsProvisioned имеет значение true. Если нет, проверка ProvisionResultsXml для получения дополнительных сведений об ошибке. Ниже перечислены распространенные ошибки мобильного широкополосного подключения.
Несоответствие между SIM-картой на компьютере и файлом подготовки (сбой профиля с ERROR_NOT_FOUND).
Несоответствие между Идентификатором CarrierId в файле подготовки и номером службы в метаданных интерфейса.
Убедитесь, что фоновые задачи выполняются брокером системных событий
Вы можете убедиться, что Windows создает событие MobileOperatorNotification и что фоновая задача приложения выполняется брокером событий, проверив Просмотр событий. Ведение журнала для этих событий по умолчанию отключено, и его можно включить, выполнив следующие действия.
Откройте средство просмотра событий.
На вкладке Меню выберите Вид, а затем — Показать журналы аналитики и отладки.
Перейдите в журналы приложений и служб\Microsoft\Windows\BackgroundTaskInfrastructure.
Щелкните правой кнопкой мыши журнал диагностики и выберите Включить журнал.
После включения журналов успешное выполнение фоновой задачи приводит к событию Идентификатор события = 1 со следующим описанием: "Экземпляр фоновой задачи с точкой <входа background_task_namespace_name>.<> background_task_class_name и имя MobileOperatorNotificationHandler были созданы в сеансе 1 и получили идентификатор {11111111-1111-1111-1111-111111111111}.
Если фоновая задача не выполняется, сначала убедитесь, что имена фоновых задач, указанные в метаданных службы, совпадают с именами в AppXManifest.xml файле пакета. Убедитесь, что после развертывания приложения активируется анализ метаданных службы и вставляется мобильное широкополосное устройство.
Убедитесь, что Windows получает УВЕДОМЛЕНИЯ SMS и USSD.
Вы можете убедиться, что Windows получает уведомления SMS и USSD, проверив наличие событий SmsRouter в Просмотр событий.
В Просмотр событий в разделе Журналы приложений и служб\Microsoft\Windows \Mobile-Broadband-Experience-SmsRouter\Microsoft-Windows-SMSRouter находятся такие записи, как "SmsRouter получил sms-уведомление оператора" и "SmsRouter получил текстовое сообщение". В разделе Журналы приложений и служб\Microsoft\Windows \Mobile-Broadband-Experience-SmsApi\SMSApi есть такие записи, как "Приложение: Microsoft.SDKSamples.SmsSendReceive, отправленное sms-сообщение на мобильном широкополосном устройстве: {11111111-1111-1111-1111-111111111111}".
Полученные SMS-сообщения не обнаруживаются как уведомления оператора
Если полученные SMS не обнаруживаются как уведомления оператора, проверьте настраиваемые правила фильтрации административных SMS-уведомлений в метаданных подготовки учетной записи. Дополнительные сведения о подготовке метаданных см. в статье Подготовка учетных записей.
В частности, если в метаданных подготовки учетной записи указан номер телефона отправителя, с помощью API-интерфейсов SMS убедитесь, что указанное форматирование номеров соответствует указанному в полученном сообщении. Чтобы убедиться, что это соответствие правильно, временно измените шаблон на [^]\* для сопоставления всех сообщений от этого отправителя.
Пример файла backgroundtask.js
//
// A JavaScript background task runs a specified JavaScript file.
//
(function () {
"use strict";
//
// The background task instance's activation parameters are available via Windows.UI.WebUI.WebUIBackgroundTaskInstance.current.
//
var backgroundTaskInstance = Windows.UI.WebUI.WebUIBackgroundTaskInstance.current,
networkOperatorEventType = Windows.Networking.NetworkOperators.NetworkOperatorEventMessageType,
key = null,
settings = Windows.Storage.ApplicationData.current.localSettings;
try {
var details = backgroundTaskInstance.triggerDetails;
switch (details.notificationType) {
case networkOperatorEventType.gsm:
var textMessage = new Windows.Devices.Sms.SmsTextMessage.fromBinaryMessage(details.smsMessage);
showToast("Gsm Msg From: " + textMessage.from + "; TimeStamp: " + textMessage.timestamp, details.message);
break;
case networkOperatorEventType.cdma:
showToast("Mobile Broadband message", details.message);
break;
case networkOperatorEventType.ussd:
showToast("Mobile Broadband message", details.message);
break;
case networkOperatorEventType.dataPlanThresholdReached:
showToast("Mobile Broadband message", "Data plan threshold reached");
break;
case networkOperatorEventType.dataPlanReset:
showToast("Mobile Broadband message", "Data plan reset");
break;
case networkOperatorEventType.dataPlanDeleted:
showToast("Mobile Broadband message", "Data plan deleted");
break;
case networkOperatorEventType.profileConnected:
showToast("Mobile Broadband message", "Profile connected");
break;
case networkOperatorEventType.profileDisconnected:
showToast("Mobile Broadband message", "Profile disconnected");
break;
case networkOperatorEventType.registeredRoaming:
showToast("Mobile Broadband message", "Registered roaming");
break;
case networkOperatorEventType.registeredHome:
showToast("Mobile Broadband message", "Registered home");
break;
case networkOperatorEventType.tetheringEntitlementCheck:
showToast("Mobile Broadband message", "Entitlement check completed");
break;
default:
showToast("Mobile Broadband message", "Unknown message");
break;
}
taskSucceeded();
}
catch (exception) {
taskFailed();
}
function showToast(title, body) {
var notifications = Windows.UI.Notifications;
var toastNotificationManager = Windows.UI.Notifications.ToastNotificationManager;
var toastXml = toastNotificationManager.getTemplateContent(notifications.ToastTemplateType.toastText02);
//
// Pass to app through eventArguments.arguments.
//
var temp = "\"Title\"" + ":" + "\"" + title + "\"" + "," + "\"Message\"" + ":" + "\"" + body + "\"";
if (temp.length > 251) {
temp = temp.substring(0, 251);
}
toastXml.selectSingleNode("/toast").setAttribute("launch", "'{" + temp + "}'");
var textNodes = toastXml.getElementsByTagName("text");
textNodes[0].appendChild(toastXml.createTextNode(title));
textNodes[1].appendChild(toastXml.createTextNode(body));
var toast = new notifications.ToastNotification(toastXml);
toastNotificationManager.createToastNotifier().show(toast);
}
//
// This function is called when the background task is completed successfully.
//
function taskSucceeded() {
//
// Use the succeeded property to indicate that this background task completed successfully.
//
backgroundTaskInstance.succeeded = true;
backgroundTask.taskInstance.progress = 100;
console.log("Background " + backgroundTask.taskInstance.task.name + " Completed");
//
// Write to localSettings to indicate that this background task completed.
//
key = backgroundTaskInstance.task.taskId.toString();
settings.values[key] = "Completed";
//
// A JavaScript background task must call close when it is done.
//
close();
}
//
// If the task was canceled or failed, stop the background task.
//
function taskFailed() {
console.log("Background " + backgroundTask.taskInstance.task.name + " Failed");
backgroundTaskInstance.succeeded = false;
key = backgroundTaskInstance.task.taskId.toString();
settings.values[key] = "Failed";
close();
}
})();
Связанные темы
Включение уведомлений оператора мобильной связи и системных событий
Создание и настройка возможностей общего доступа к Интернету