알림 수신기: 모든 알림 액세스Notification listener: Access all notifications

알림 수신기는 사용자의 알림에 대 한 액세스를 제공 합니다.The notification listener provides access to a user's notifications. Smartwatches 및 기타 착용 식 장치용는 알림 수신기를 사용 하 여 휴대폰의 알림을 wearable 장치로 보낼 수 있습니다.Smartwatches and other wearables can use the notification listener to send the phone's notifications to the wearable device. Home automation 앱은 알림을 수신할 때 알림 수신기를 사용 하 여 특정 작업을 수행할 수 있습니다. 예를 들어 통화를 받을 때 표시등이 깜박일 수 있습니다.Home automation apps can use notification listener to perform specific actions when notifications are received, such as making the lights blink when you receive a call.

중요

기념일 업데이트 필요 : 알림 수신기를 사용 하려면 SDK 14393을 대상으로 하 고 빌드 14393 이상을 실행 해야 합니다.Requires Anniversary Update : You must target SDK 14393 and be running build 14393 or higher to use Notification Listener.

중요 한 api : usernotificationlistener 클래스, usernotificationchangedtrigger 클래스Important APIs : UserNotificationListener class, UserNotificationChangedTrigger class

사용자 알림 기능을 추가 하 여 수신기를 사용 하도록 설정Enable the listener by adding the User Notification capability

알림 수신기를 사용 하려면 앱 매니페스트에 사용자 알림 수신기 기능을 추가 해야 합니다.To use the notification listener, you must add the User Notification Listener capability to your app manifest.

  1. Visual Studio의 솔루션 탐색기에서 파일을 두 번 클릭 Package.appxmanifest 하 여 매니페스트 디자이너를 엽니다.In Visual Studio, in the Solution Explorer, double click your Package.appxmanifest file to open the manifest designer.
  2. 기능 탭을 엽니다.Open the Capabilities tab.
  3. 사용자 알림 수신기 기능을 확인 합니다.Check the User Notification Listener capability.

수신기가 지원 되는지 여부를 확인 합니다.Check whether the listener is supported

앱에서 이전 버전의 Windows 10을 지 원하는 경우 Apiinformation 클래스 를 사용 하 여 수신기가 지원 되는지 여부를 확인 해야 합니다.If your app supports older versions of Windows 10, you need to use the ApiInformation class to check whether the listener is supported. 수신기가 지원 되지 않는 경우 수신기 Api에 대 한 호출을 실행 하지 마십시오.If the listener isn't supported, avoid executing any calls to the listener APIs.

if (ApiInformation.IsTypePresent("Windows.UI.Notifications.Management.UserNotificationListener"))
{
    // Listener supported!
}
 
else
{
    // Older version of Windows, no Listener
}

수신기에 대 한 액세스 요청Requesting access to the listener

수신기는 사용자의 알림에 대 한 액세스를 허용 하므로 사용자는 자신의 알림에 액세스할 수 있는 권한을 앱에 부여 해야 합니다.Since the listener allows access to the user's notifications, users must give your app permission to access their notifications. 앱의 첫 실행 경험을 사용 하는 동안 알림 수신기를 사용 하기 위한 액세스를 요청 해야 합니다.During your app's first-run experience, you should request access to use the notification listener. 원하는 경우 사용자가 액세스를 허용 해야 하는 이유를 이해 하도록 Requestaccessasync를 호출 하기 전에 앱이 사용자의 알림에 액세스 해야 하는 이유를 설명 하는 몇 가지 예비 UI를 표시할 수 있습니다.If you want, you can show some preliminary UI that explains why your app needs access to the user's notifications before you call RequestAccessAsync, so that the user understands why they should allow access.

// Get the listener
UserNotificationListener listener = UserNotificationListener.Current;
 
// And request access to the user's notifications (must be called from UI thread)
UserNotificationListenerAccessStatus accessStatus = await listener.RequestAccessAsync();
 
switch (accessStatus)
{
    // This means the user has granted access.
    case UserNotificationListenerAccessStatus.Allowed:
 
        // Yay! Proceed as normal
        break;
 
    // This means the user has denied access.
    // Any further calls to RequestAccessAsync will instantly
    // return Denied. The user must go to the Windows settings
    // and manually allow access.
    case UserNotificationListenerAccessStatus.Denied:
 
        // Show UI explaining that listener features will not
        // work until user allows access.
        break;
 
    // This means the user closed the prompt without
    // selecting either allow or deny. Further calls to
    // RequestAccessAsync will show the dialog again.
    case UserNotificationListenerAccessStatus.Unspecified:
 
        // Show UI that allows the user to bring up the prompt again
        break;
}

사용자는 언제 든 지 Windows 설정을 통해 액세스 권한을 해지할 수 있습니다.The user can revoke access at any time via Windows Settings. 따라서 앱은 알림 수신기를 사용 하는 코드를 실행 하기 전에 항상 Getaccessstatus 메서드를 통해 액세스 상태를 확인 해야 합니다.Therefore, your app should always check the access status via the GetAccessStatus method before executing code that uses the notification listener. 사용자가 액세스를 취소 하면 api가 예외를 throw 하는 대신 자동으로 실패 합니다. 예를 들어 모든 알림을 가져오는 API는 단순히 빈 목록을 반환 합니다.If the user revokes access, the APIs will silently fail rather than throwing an exception (for example, the API to get all notifications will simply return an empty list).

사용자의 알림 액세스Access the user's notifications

알림 수신기를 사용 하 여 사용자의 현재 알림 목록을 가져올 수 있습니다.With the notification listener, you can get a list of the user's current notifications. GetNotificationsAsync 메서드를 호출 하 고 가져오려는 알림 유형을 지정 합니다. 현재 지원 되는 알림 유형은 알림 메시지 뿐입니다.Simply call the GetNotificationsAsync method, and specify the type of notifications you want to get (currently, the only type of notifications supported are toast notifications).

// Get the toast notifications
IReadOnlyList<UserNotification> notifs = await listener.GetNotificationsAsync(NotificationKinds.Toast);

알림 표시Displaying the notifications

각 알림은 알림이 있는 앱에 대 한 정보, 알림이 생성 된 시간, 알림 ID 및 알림 자체에 대 한 정보를 제공 하는 Usernotification로 표시 됩니다.Each notification is represented as a UserNotification, which provides information about the app that the notification is from, the time the notification was created, the notification's ID, and the notification itself.

public sealed class UserNotification
{
    public AppInfo AppInfo { get; }
    public DateTimeOffset CreationTime { get; }
    public uint Id { get; }
    public Notification Notification { get; }
}

AppInfo 속성은 알림을 표시 하는 데 필요한 정보를 제공 합니다.The AppInfo property provides the info you need to display the notification.

참고

단일 알림을 캡처할 때 예기치 않은 예외가 발생 하는 경우 try/catch에서 단일 알림을 처리 하는 모든 코드를 둘러싸는 것이 좋습니다.We recommend surrounding all your code for processing a single notification in a try/catch, in case an unexpected exception occurs when you are capturing a single notification. 하나의 특정 알림과 관련 된 문제로 인해 다른 알림은 완전히 표시 하지 못할 수 있습니다.You shouldn't completely fail to display other notifications just because of an issue with one specific notification.

// Select the first notification
UserNotification notif = notifs[0];
 
// Get the app's display name
string appDisplayName = notif.AppInfo.DisplayInfo.DisplayName;
 
// Get the app's logo
BitmapImage appLogo = new BitmapImage();
RandomAccessStreamReference appLogoStream = notif.AppInfo.DisplayInfo.GetLogo(new Size(16, 16));
await appLogo.SetSourceAsync(await appLogoStream.OpenReadAsync());

알림 텍스트와 같은 알림 자체의 내용은 알림 속성에 포함 되어 있습니다.The content of the notification itself, such as the notification text, is contained in the Notification property. 이 속성에는 알림의 시각적 부분이 포함 되어 있습니다.This property contains the visual portion of the notification. Windows에서 알림을 보내는 방법에 대해 잘 알고 있는 경우 알림 개체의 시각적 개체 및 시각적 개체 바인딩 속성 은 알림을 볼 때 개발자가 전송 하는 내용에 해당 합니다.(If you are familiar with sending notifications on Windows, you will notice that the Visual and Visual.Bindings properties in the Notification object correspond to what developers send when popping a notification.)

알림 바인딩을 검색 하려고 합니다 (오류 증명 코드의 경우 바인딩이 null이 아님을 확인 해야 함).We want to look for the toast binding (for error-proof code, you should check that the binding isn't null). 바인딩에서 텍스트 요소를 가져올 수 있습니다.From the binding, you can obtain the text elements. 원하는 수 만큼 텍스트 요소를 표시 하도록 선택할 수 있습니다.You can choose to display as many text elements as you would like. (이상적으로는 모두 표시 해야 합니다.) 텍스트 요소를 다르게 처리 하도록 선택할 수 있습니다. 예를 들어 첫 번째 항목을 제목 텍스트로, 후속 요소를 본문 텍스트로 처리 합니다.(Ideally, you should display them all.) You can choose to treat the text elements differently; for example, treat the first one as title text, and subsequent elements as body text.

// Get the toast binding, if present
NotificationBinding toastBinding = notif.Notification.Visual.GetBinding(KnownNotificationBindings.ToastGeneric);
 
if (toastBinding != null)
{
    // And then get the text elements from the toast binding
    IReadOnlyList<AdaptiveNotificationText> textElements = toastBinding.GetTextElements();
 
    // Treat the first text element as the title text
    string titleText = textElements.FirstOrDefault()?.Text;
 
    // We'll treat all subsequent text elements as body text,
    // joining them together via newlines.
    string bodyText = string.Join("\n", textElements.Skip(1).Select(t => t.Text));
}

특정 알림 제거Remove a specific notification

Wearable 또는 서비스에서 사용자가 알림을 해제할 수 있는 경우 실제 알림을 제거 하 여 사용자가 나중에 휴대폰 이나 PC에서이를 볼 수 없도록 할 수 있습니다.If your wearable or service allows the user to dismiss notifications, you can remove the actual notification so the user doesn't see it later on their phone or PC. 제거 하려는 알림의 알림 ID ( usernotification 개체에서 가져옴)를 제공 하면 됩니다.Simply provide the notification ID (obtained from the UserNotification object) of the notification you'd like to remove:

// Remove the notification
listener.RemoveNotification(notifId);

모든 알림 지우기Clear all notifications

Usernotificationlistener. ClearNotifications 메서드는 모든 사용자의 알림을 지웁니다.The UserNotificationListener.ClearNotifications method clears all the user's notifications. 이 메서드는 주의 해 서 사용 합니다.Use this method with caution. Wearable 또는 서비스가 모든 알림을 표시 하는 경우에만 모든 알림을 지워야 합니다.You should only clear all notifications if your wearable or service displays ALL notifications. Wearable 또는 서비스에 특정 알림만 표시 되는 경우 사용자가 "알림 지우기" 단추를 클릭 하면 사용자에 게 특정 알림만 제거 될 것으로 예상 됩니다. 그러나 clearnotifications 메서드를 호출 하면 wearable 또는 서비스가 표시 하지 않는 알림을 비롯 한 모든 알림이 제거 될 수 있습니다.If your wearable or service only displays certain notifications, when the user clicks your "Clear notifications" button, the user is only expecting those specific notifications to be removed; however, calling the ClearNotifications method would actually cause all the notifications, including ones that your wearable or service wasn't displaying, to be removed.

// Clear all notifications. Use with caution.
listener.ClearNotifications();

추가/해제 된 알림에 대 한 백그라운드 작업Background task for notification added/dismissed

앱이 알림을 수신할 수 있도록 하는 일반적인 방법은 앱이 현재 실행 중인지 여부에 관계 없이 알림이 추가 되거나 해제 된 시기를 알 수 있도록 백그라운드 작업을 설정 하는 것입니다.A common way to enable an app to listen to notifications is to set up a background task, so that you can know when a notification was added or dismissed regardless of whether your app is currently running.

기념일 업데이트에 추가 된 단일 프로세스 모델 덕분에 백그라운드 작업을 추가 하는 작업은 매우 간단 합니다.Thanks to the single process model added in the Anniversary Update, adding background tasks is fairly simple. 주 앱의 코드에서 알림 수신기에 대 한 사용자 액세스 권한을 획득 하 고 백그라운드 작업을 실행 하기 위한 액세스 권한을 얻은 후에는 새 백그라운드 작업을 등록 하 고 알림 메시지 종류를 사용 하 여 Usernotificationchangedtrigger 를 설정 하면 됩니다.In your main app's code, after you have obtained the user's access to Notification Listener and obtained access to run background tasks, simply register a new background task, and set the UserNotificationChangedTrigger using the Toast notification kind.

// TODO: Request/check Listener access via UserNotificationListener.Current.RequestAccessAsync
 
// TODO: Request/check background task access via BackgroundExecutionManager.RequestAccessAsync
 
// If background task isn't registered yet
if (!BackgroundTaskRegistration.AllTasks.Any(i => i.Value.Name.Equals("UserNotificationChanged")))
{
    // Specify the background task
    var builder = new BackgroundTaskBuilder()
    {
        Name = "UserNotificationChanged"
    };
 
    // Set the trigger for Listener, listening to Toast Notifications
    builder.SetTrigger(new UserNotificationChangedTrigger(NotificationKinds.Toast));
 
    // Register the task
    builder.Register();
}

그런 다음 App.xaml.cs에서 OnBackgroundActivated 메서드를 재정의 하 고, 아직 작업 이름에 대해 switch 문을 사용 하 여 여러 백그라운드 작업 트리거를 호출 했는지 확인 합니다.Then, in your App.xaml.cs, override the OnBackgroundActivated method if you haven't yet, and use a switch statement on the task name to determine which of your many background task triggers was invoked.

protected override async void OnBackgroundActivated(BackgroundActivatedEventArgs args)
{
    var deferral = args.TaskInstance.GetDeferral();
 
    switch (args.TaskInstance.Task.Name)
    {
        case "UserNotificationChanged":
            // Call your own method to process the new/removed notifications
            // The next section of documentation discusses this code
            await MyWearableHelpers.SyncNotifications();
            break;
    }
 
    deferral.Complete();
}

백그라운드 작업은 단순히 "어깨 탭" 이며, 추가 되거나 제거 된 특정 알림에 대 한 정보를 제공 하지 않습니다.The background task is simply a "shoulder tap": it doesn't provide any information about which specific notification was added or removed. 백그라운드 작업이 트리거되면 플랫폼의 알림을 반영 하도록 wearable의 알림을 동기화 해야 합니다.When your background task is triggered, you should sync the notifications on your wearable so that they reflect the notifications in the platform. 이렇게 하면 백그라운드 작업이 실패 하는 경우 다음에 백그라운드 작업이 실행 될 때 wearable에 대 한 알림을 계속 복구할 수 있습니다.This ensures that if your background task fails, notifications on your wearable can still be recovered the next time your background task executes.

SyncNotifications 는 구현 하는 방법입니다. 다음 섹션에서는 방법을 보여 줍니다.SyncNotifications is a method you implement; the next section shows how.

추가 및 제거 된 알림 확인Determining which notifications were added and removed

SyncNotifications메서드에서 추가 또는 제거 된 알림 (wearable와의 동기화 동기화)을 확인 하려면 현재 알림 컬렉션과 플랫폼의 알림 사이의 델타를 계산 해야 합니다.In your SyncNotifications method, to determine which notifications have been added or removed (syncing notifications with your wearable), you have to calculate the delta between your current notification collection, and the notifications in the platform.

// Get all the current notifications from the platform
IReadOnlyList<UserNotification> userNotifications = await listener.GetNotificationsAsync(NotificationKinds.Toast);
 
// Obtain the notifications that our wearable currently has displayed
IList<uint> wearableNotificationIds = GetNotificationsOnWearable();
 
// Copy the currently displayed into a list of notification ID's to be removed
var toBeRemoved = new List<uint>(wearableNotificationIds);
 
// For each notification in the platform
foreach (UserNotification userNotification in userNotifications)
{
    // If we've already displayed this notification
    if (wearableNotificationIds.Contains(userNotification.Id))
    {
        // We want to KEEP it displayed, so take it out of the list
        // of notifications to remove.
        toBeRemoved.Remove(userNotification.Id);
    }
 
    // Otherwise it's a new notification
    else
    {
        // Display it on the Wearable
        SendNotificationToWearable(userNotification);
    }
}
 
// Now our toBeRemoved list only contains notification ID's that no longer exist in the platform.
// So we will remove all those notifications from the wearable.
foreach (uint id in toBeRemoved)
{
    RemoveNotificationFromWearable(id);
}

추가/해제 된 알림에 대 한 포그라운드 이벤트Foreground event for notification added/dismissed

중요

알려진 문제: 빌드 17763/10 월 2018 업데이트/버전 1809 이전 빌드에서 포그라운드 이벤트는 CPU 루프가 발생 하거나 작동 하지 않습니다.Known issue: In builds before Build 17763 / October 2018 Update / Version 1809, The foreground event will cause a CPU loop and/or didn't work. 이전 빌드에 대 한 지원이 필요한 경우 백그라운드 작업을 대신 사용 합니다.If you need support on those earlier builds, use the background task instead.

메모리 내 이벤트 처리기에서 알림을 수신할 수도 있습니다.You can also listen to notifications from an in-memory event handler...

// Subscribe to foreground event
listener.NotificationChanged += Listener_NotificationChanged;
 
private void Listener_NotificationChanged(UserNotificationListener sender, UserNotificationChangedEventArgs args)
{
    // Your code for handling the notification
}

백그라운드 작업 지연 문제를 해결 하는 방법How to fix delays in the background task

앱을 테스트할 때 백그라운드 작업이 지연 되는 경우도 있고 몇 분 동안 트리거되지 않을 수도 있습니다.When testing your app, you might notice that the background task is sometimes delayed and doesn't trigger for several minutes. 지연을 해결 하려면 사용자에 게 시스템 설정으로 이동 하 라는 메시지를 표시 합니다. > 시스템-앱에의 한 배터리 사용 > 배터리 > 목록에서 앱을 찾아 선택 하 고 "항상 허용 됩니다."로 설정 합니다.To fix the delay, prompt the user to go to the system settings -> System -> Battery -> Battery usage by app, find your app in the list, select it, and set it to be "Always allowed in background." 그런 다음, 백그라운드 작업은 수신 되는 알림 중 두 번째를 기준으로 항상 트리거됩니다.After this, the background task should always be triggered within around a second of the notification being received.