Share via


MobileOperatorNotification 이벤트를 처리하는 앱 개발

이 항목에서는 MobileOperatorNotification 이벤트를 처리하는 모바일 광대역 앱을 개발하는 방법을 설명합니다.

모범 사례

백그라운드 이벤트 처리의 경우 다음 모범 사례를 사용해야 합니다.

  • 작업을 수행할 수 없는 백그라운드 이벤트에 등록하지 마세요. 이러한 이벤트를 처리하면 앱 할당량이 불필요하게 소비됩니다.

  • 백그라운드 이벤트를 수신할 때 많은 양의 처리를 수행하지 마세요.

  • 다음 번에 앱을 시작할 때까지 처리를 지연하는 것이 좋습니다.

  • 백그라운드 이벤트에 대한 응답으로 알림 메시지를 표시하고 타일을 업데이트하는 것이 좋습니다. 모바일 광대역 앱은 백그라운드 이벤트 페이로드를 처리할 수 있습니다.

1단계: 백그라운드 작업 계약 선언

Windows가 모바일 광대역 앱에서 제공하는 백그라운드 작업 환경을 인식하려면 앱이 시스템 기능에 대한 확장을 제공하고 있음을 선언해야 합니다.

Visual Studio 프로젝트의 package.appxmanifest 파일에서 선언을 수행하려면 다음 단계를 수행합니다.

백그라운드 작업 계약을 선언하려면

  1. 솔루션 탐색기 프로젝트의 package.appxmanifest 파일을 두 번 클릭합니다.

  2. 선언 탭의 사용 가능한 선언에서 백그라운드 작업을 선택한 다음 추가를 클릭합니다.

  3. 속성 제목 아래에 다음 앱 정보를 입력합니다.

    • 앱 설정 아래의 시작 페이지 상자에 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();
    }

타일 및 알림 메시지 표시

일시적인 특성으로 인해 사용자가 알림 메시지를 놓칠 수 있으므로 모바일 광대역 앱에 알림 메시지와 타일 알림을 모두 표시하는 것이 좋습니다. 알림 메시지 및 타일 업데이트 환경 디자인 지침은 모바일 광대역 앱의 사용자 환경 디자인을 참조하세요.

알림 메시지를 사용하도록 설정하려면

  1. 솔루션 탐색기 프로젝트의 package.appxmanifest 파일을 두 번 클릭합니다.

  2. 애플리케이션 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인 경우 시작, 앱은 이벤트 인수의 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 앱은 시작 화면에 자동으로 고정되지 않습니다.

개발자는 데스크톱의 디바이스 및 프린터 창에서 F5 키를 누르거나 마우스 오른쪽 단추로 클릭하고 새로 고침을 선택하여 서비스 메타데이터를 구문 분석하고 백그라운드 작업을 등록하기 위해 Windows 8, Windows 8.1 및 Windows 10 수동으로 트리거할 수 있습니다. 서비스 메타데이터 구문 분석을 통한 백그라운드 작업 등록은 앱이 배포된 경우에만 성공합니다.

백그라운드 작업이 올바르게 등록되었는지 확인

개발자는 애플리케이션 및 서비스 로그\Microsoft\Windows\DeviceSetupManager에서 이벤트 로그를 확인하여 DSM(Device Setup Manager)이 서비스 메타데이터를 제대로 구문 분석했는지 확인할 수 있습니다.

  1. 이벤트 뷰어를 엽니다.

  2. 메뉴 탭에서 보기를 선택한 다음 분석 및 디버그 로그 표시를 클릭합니다.

  3. 애플리케이션 및 서비스 로그\Microsoft\Windows\DeviceSetupManager로 이동합니다.

관심 있는 이벤트에는 DSM이 MobileOperatorNotification 이벤트에 대한 백그라운드 작업을 성공적으로 등록했음을 나타내는 이벤트 ID 220과 메타데이터 패키지에서 발견된 오류를 나타내는 이벤트 ID 7900이 포함됩니다.

프로비저닝 메타데이터가 성공적으로 적용되었는지 확인합니다.

프로비저닝 메타데이터를 적용할 때 ProvisionFromXmlDocumentResults.AllElementsProvisioned 가 true인지 확인합니다. 그렇지 않은 경우 오류에 대한 자세한 내용을 보려면 ProvisionResultsXml을 검사. 일반적인 모바일 광대역 오류는 다음과 같습니다.

  • PC의 SIM과 프로비저닝 파일 간의 불일치(ERROR_NOT_FOUND 프로필이 실패함)

  • 프로비저닝 파일의 CarrierId와 환경 메타데이터의 서비스 번호가 일치하지 않습니다.

System Event Broker에서 백그라운드 작업을 실행하고 있는지 확인합니다.

Windows에서 MobileOperatorNotification 이벤트를 생성하고 있고 이벤트 뷰어 확인하여 앱의 백그라운드 작업이 이벤트 브로커에 의해 실행되고 있는지 확인할 수 있습니다. 이러한 이벤트에 대한 로깅은 기본적으로 해제되어 있으며 다음 단계를 수행하여 사용하도록 설정할 수 있습니다.

  1. 이벤트 뷰어를 엽니다.

  2. 메뉴 탭에서 보기를 선택한 다음 분석 및 디버그 로그 표시를 클릭합니다.

  3. 애플리케이션 및 서비스 로그\Microsoft\Windows\BackgroundTaskInfrastructure로 이동합니다.

  4. 진단 로그를 마우스 오른쪽 단추로 클릭하고 로그 사용을 선택합니다.

로그를 사용하도록 설정하면 백그라운드 작업을 성공적으로 실행하면 이벤트 ID = 1의 이벤트가 발생합니다. "진입점<이 background_task_namespace_name 백그라운드 작업의 instance>.<> background_task_class_name 및 이름 MobileOperatorNotificationHandler는 세션 1에서 만들어졌으며 의 ID{11111111-1111-1111-1111-111111111111}가 지정되었습니다.

백그라운드 작업이 실행되지 않는 경우 먼저 서비스 메타데이터에 지정된 백그라운드 작업의 이름이 패키지의 AppXManifest.xml 파일의 이름과 일치하는지 확인합니다. 앱을 배포한 후 서비스 메타데이터 구문 분석이 트리거되고 모바일 광대역 디바이스가 삽입되는지 확인합니다.

Windows에서 SMS 및 USSD 알림을 받는지 확인

이벤트 뷰어 SmsRouter 이벤트를 확인하여 Windows에서 SMS 및 USSD 알림을 수신하고 있는지 확인할 수 있습니다.

이벤트 뷰어 애플리케이션 및 서비스 로그\Microsoft\Windows \Mobile-Broadband-Experience-SmsRouter\Microsoft-Windows-SMSRouter 아래에는 "SMSRouter가 SMS 운영자 알림 메시지를 받았습니다" 및 "SMSRouter가 문자 메시지를 받았습니다."와 같은 항목이 있습니다. 애플리케이션 및 서비스 로그\Microsoft\Windows \Mobile-Broadband-Experience-SmsApi\SMSApi 아래에는 "앱: Microsoft.SDKSamples.SmsSendReceive가 모바일 광대역 디바이스{11111111-1111-1111-1111-111111111111}에서 SMS 문자 메시지를 보냈습니다. "와 같은 항목이 있습니다.

수신된 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();
    }
})();

통신사 알림 및 시스템 이벤트 사용

인터넷 공유 환경 만들기 및 구성