MobileOperatorNotification イベントを処理するアプリを開発する
このトピックでは、MobileOperatorNotification イベントを処理するモバイル ブロードバンド アプリを開発する方法について説明します。
ベスト プラクティス
バックグラウンド イベント処理の場合は、次のベスト プラクティスを使用する必要があります。
アクションを実行できないバックグラウンド イベントには登録しないでください。 これらのイベントを処理すると、アプリのクォータが不必要に消費されます。
バックグラウンド イベントの受信時に大量の処理を実行しないでください。
次にアプリを起動したときまで処理を延期することを検討してください。
トースト通知を表示し、バックグラウンド イベントに応答してタイルを更新することを検討してください。 モバイル ブロードバンド アプリでは、バックグラウンド イベント ペイロードを処理できます。
ステップ 1: バックグラウンド タスク コントラクト宣言
Windows がモバイル ブロードバンド アプリによって提供されるバックグラウンド タスク エクスペリエンスを認識するには、アプリがシステム機能に拡張機能を提供していることを宣言する必要があります。
Visual Studio プロジェクトの package.appxmanifest ファイルで宣言を行うには、次の手順を実行します。
バックグラウンド タスク コントラクトを宣言するには
ソリューション エクスプローラーで、プロジェクトの 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 からモバイル通信事業者のネットワーク アカウント ID とイベント データを取得します。
バックグラウンド タスクでサポートされている UI はトーストのみであるため、バックグラウンド タスク ハンドラーはトーストを表示したり、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 ファイルをダブルクリックします。
[アプリケーション UI] タブの [通知] 見出しで、[トースト対応] を [はい] に設定します。
これが正しく行われる場合は、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.launch である場合、イベント引数の detail.argument プロパティが null に設定されているかどうかに応じて、アプリによって Start エクスペリエンスまたは Notification エクスペリエンスが提供されます。
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 メソッドで発生する完了状態または例外は、フォアグラウンド アプリの完了ハンドラーに渡されます。 タスクの完了時にアプリが中断された場合は、次回アプリが再開されたときに完了通知を受け取ります。 アプリが終了状態であった場合は、完了通知が受信されません。 バックグラウンド タスクが正常に実行された情報を保持する必要がある場合は、State Manager または別の方法 (アプリが実行中の状態に戻ったときに読み取ることができるファイルなど) を使用して情報を保持する必要があります。
重要 モバイル通信事業者のバックグラウンド イベントはシステムによってアプリに自動的に登録されますが、バックグラウンド完了ハンドラーまたは進行状況ハンドラーに登録するには、アプリを少なくとも 1 回実行する必要があります。
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 キーを押し (または右クリックして [更新] を選択し)、サービス メタデータを解析し、バックグラウンド タスクを登録できます。 サービス メタデータ解析によるバックグラウンド タスクの登録は、アプリがデプロイされている場合にのみ成功します。
バックグラウンド タスクが正しく登録されていることを確認する
開発者は、Application and Services Logs\Microsoft\Windows\DeviceSetupManager の下のイベント ログを表示することで、デバイス セットアップ マネージャー (DSM) がサービス メタデータを適切に解析したことを確認できます。
イベント ビューアーを開きます。
[メニュー] タブで [表示] を選択し、[分析ログとデバッグ ログの表示] をクリックします。
Applications and Services Logs\Microsoft\Windows\DeviceSetupManager を参照します。
対象となるイベントには、DSM が MobileOperatorNotification イベントのバックグラウンド タスクを正常に登録したことを示すイベント ID 220 と、メタデータ パッケージで見つかったエラーを示すイベント ID 7900 が含まれます。
プロビジョニング メタデータが正常に適用されたことを確認する
プロビジョニング メタデータを適用する場合は、ProvisionFromXmlDocumentResults.AllElementsProvisioned が true であることを確認します。 そうでない場合は、ProvisionResultsXml をチェックして、エラーの詳細を確認します。 一般的なモバイル ブロードバンド エラーには、次のものがあります。
PC 内の SIM とプロビジョニング ファイルの間の不一致 (プロファイルは ERROR_NOT_FOUND で失敗します)。
プロビジョニング ファイル内の CarrierId とエクスペリエンス メタデータ内のサービス番号の不一致。
バックグラウンド タスクが System Event Broker によって実行されていることを確認する
Windows が MobileOperatorNotification イベントを生成していること、およびアプリのバックグラウンド タスクがイベント ブローカーによって実行されていることを確認するには、イベント ビューアーを確認します。 これらのイベントのログ記録は既定ではオフになっており、次の手順を実行して有効にすることができます。
イベント ビューアーを開きます。
[メニュー] タブで [表示] を選択し、[分析ログとデバッグ ログの表示] をクリックします。
Applications and Services Logs\Microsoft\Windows\BackgroundTaskInfrastructure を参照します。
[診断ログ] を右クリックし、[ログの有効化] を選択します。
ログを有効にした後、バックグラウンド タスクが正常に実行されると、Event ID = 1、“エントリ ポイント <background_task_namespace_name>.<background_task_class_name>、MobileOperatorNotificationHandler の名前のバックグラウンド タスクのインスタンスがセッション 1 で作成され、{11111111-1111-1111-1111-111111111111} の ID が付与されました” という説明のイベントが発生します。
バックグラウンド タスクが実行されていない場合は、まず、サービス メタデータで指定されているバックグラウンド タスクの名前が、パッケージの AppXManifest.xml ファイル内の名前と一致することを確認します。 アプリをデプロイした後、サービス メタデータの解析がトリガーされ、モバイル ブロードバンド デバイスが挿入されることを確認します。
Windows が SMS および USSD の通知を受信することを確認する
Windows が SMS および USSD の通知を受信していることを確認するには、イベント ビューアーで SmsRouter イベントを確認します。
イベント ビューアーの Application and Services Logs\Microsoft\Windows \Mobile-Broadband-Experience-SmsRouter\Microsoft-Windows-SMSRouter には、"SMSRouter が SMS 通信事業者通知メッセージを受信しました" や "SMSRouter がテキスト メッセージを受信しました" などのエントリがあります。 Application and Services Logs\Microsoft\Windows \Mobile-Broadband-Experience-SmsApi\SMSApi には、"アプリ: Microsoft.SDKSamples.SmsSendReceive が モバイル ブロードバンド デバイスに SMS テキスト メッセージを送信しました: {11111111-1111-1111-1111-111111111111}” などのエントリがあります。
受信した SMS メッセージが通信事業者通知として検出されない
受信した SMS が通信事業者通知として検出されない場合は、アカウント プロビジョニング メタデータの管理 SMS 通知のカスタム フィルター規則を確認します。 プロビジョニング メタデータの詳細については、「アカウント プロビジョニング」を参照してください。
特に、アカウント プロビジョニング メタデータで送信者の電話番号が指定されている場合は、SMS API を使用して、指定された番号の書式設定が受信メッセージ内の番号と一致することを確認します。 正しく一致していることを確認するには、一時的にパターンを [^]\* に変更して、この送信者のすべてのメッセージと照合します。
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();
}
})();