You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用UWP应用检测Windows 10中其他应用触发的Toast通知

UWP Toast通知监听功能修复方案

1. 补充应用清单权限配置

仅在系统层面开启通知权限无法满足监听要求,必须在项目的Package.appxmanifest文件中显式声明通知监听能力:

  • 在根节点<Package>中补充uap7命名空间声明:
<Package
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
  xmlns:uap7="http://schemas.microsoft.com/appx/manifest/uap/windows10/7"
  IgnorableNamespaces="uap uap7">
  • 在<Capabilities>节点下添加监听权限:
<Capabilities>
  <uap7:Capability Name="userNotificationListener" />
</Capabilities>

2. 修复现有代码逻辑缺陷

你当前的代码存在三处核心问题导致无法拿到通知列表更新:

  • 授权请求RequestAccessAsync不需要放在循环内重复调用,仅需在功能首次触发时调用一次即可,重复调用会导致接口返回异常缓存
  • 当检测到通知数为0时直接执行break退出了循环,后续不会再执行检测逻辑,自然无法捕获新弹出的通知
  • 无间隔的高频循环会占用大量UI线程资源,同时会触发系统接口限流,导致返回的通知列表长期不变

3. 推荐实现方案:使用系统事件替代轮询

UserNotificationListener自带NotificationChanged事件,会在系统通知状态变更时主动触发,无需主动轮询,效率更高且不会遗漏通知,参考实现代码如下:

// 将listener声明为类全局变量,避免被GC回收导致事件失效
private Windows.UI.Notifications.Management.UserNotificationListener _notificationListener;
private Windows.Media.Playback.MediaPlayer _mediaPlayer = new Windows.Media.Playback.MediaPlayer();
private bool _isListening = false;

private async void Button_Click(object sender, RoutedEventArgs e)
{
    if (_isListening) return;

    switchStatus = "ON";
    this.Status.Text = switchStatus;

    _notificationListener = Windows.UI.Notifications.Management.UserNotificationListener.Current;
    var accessStatus = await _notificationListener.RequestAccessAsync();

    switch (accessStatus)
    {
        case Windows.UI.Notifications.Management.UserNotificationListenerAccessStatus.Allowed:
            // 绑定通知变更事件
            _notificationListener.NotificationChanged += OnNotificationChanged;
            _isListening = true;
            break;
        case Windows.UI.Notifications.Management.UserNotificationListenerAccessStatus.Denied:
            // 自定义逻辑提示用户前往系统设置开启通知访问权限
            break;
        case Windows.UI.Notifications.Management.UserNotificationListenerAccessStatus.Unspecified:
            // 自定义逻辑引导用户重新授权
            break;
    }
}

private async void OnNotificationChanged(Windows.UI.Notifications.Management.UserNotificationListener sender, Windows.UI.Notifications.Management.UserNotificationChangedEventArgs args)
{
    // 仅处理新添加的Toast通知事件
    if (args.ChangeKind != Windows.UI.Notifications.Management.UserNotificationChangedKind.Added) return;

    var toastNotifications = await sender.GetNotificationsAsync(Windows.UI.Notifications.NotificationKinds.Toast);
    if (toastNotifications.Count <= 0) return;

    // 如需操作UI元素,需调度到UI线程执行
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        try
        {
            _mediaPlayer.Source = Windows.Media.Core.MediaSource.CreateFromUri(new Uri("ms-appx:///Assets/audio.mp3"));
            _mediaPlayer.Play();
            playing = true;
        }
        catch (Exception)
        {
            // 自定义异常处理逻辑
        }
    });
}

4. 额外检查项

  • 确认项目Assets目录下的audio.mp3文件属性:「生成操作」设置为「内容」,「复制到输出目录」设置为「如果较新则复制」
  • 如需过滤掉已经存入通知中心的历史通知,仅捕获正在弹出的Toast,可以过滤UserNotification的DismissalTime属性,仅保留DismissalTime == null的活跃通知

内容的提问来源于stack exchange,提问作者Dennis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 10:54:04