admin 管理员组

文章数量: 887006

上一篇文章(链接)对Win10中Toast通知的模板进行了简要解析。

本篇文章将讲解Toast通知与应用程序的交互问题,也就是说,用户可以在操作Toast通知中某些元素,进而实现与程序交互。

在Toast的模板中,actions节点就是程序与用户交互的关键所在。

我们知道,actions节点下有input和action两类节点(不知道?那就看我的上一篇博客吧)

算了,我还是当一回好人,再啰嗦一次吧

1、行为节点 actions

在UWP应用中,开发者可以添加自定义交互行为到toast通知里。有两中类型的子节点,input和action,注意的是input元素必须放在action元素的前面。

2、input 节点

input节点的id属性必须设置,而且必须唯一,激活应用程序时会传递给应用

当type属性取text时,就是一个普通的输入框,用户能够在input节点中键入信息,应用程序可以对用户的输入进行响应,如短信的快捷回复。placeHolderContent属性设置占位文本
当type属性取selection时,是一个下拉选择框。defaultInput表示默认选择的项

3、action 节点

可以简单理解为就是一个button,通过此节点开发者能在toast通知内部指定3个自定义或系统行为。

content属性表示显示的文本,imageUrl表示按钮上的图标,如果不需要就可以不做设置,arguments属性表示的是当激活应用时传入的参数,activationType表示激活应用的类型是前台还是后台,如果值为foreground,表明toast通知将在前台激活应用,这时候用户可以看见应用程序;如果值为background,表明toast通知通过后台方式激活应用,此时用户看不到应用程序,后台激活必须指定一个后台任务,当激活时就会执行后台任务。如果值为protocol,表示将通过协议来激活应用程序。

本篇文章着重讲解action 节点的activationType属性

应用程序前台激活:activationType=foreground

Toast通知模板:

 string xml = "<toast>" +
                            "<visual>" +
                                "<binding template=\"ToastGeneric\">" +
                                    "<text>Title</text>" +
                                "</binding>" +
                            "</visual>" +
                            "<actions>" +
                                    "<input id=\"name\" type=\"text\" placeHolderContent=\"请输入姓名\" />" +
                                    "<action content = \"确定\" arguments = \"ok\" activationType=\"foreground\"/>" +
                                    "<action content = \"取消\" arguments = \"cancel\" activationType=\"foreground\/>" +
                            "</actions >" +
                         "</toast>";

当activationType=foreground时,需要在应用的App类中重载OnActivated方法。

protected override void OnActivated(IActivatedEventArgs args)
        {
            // 判断激活类型 确认是否由Toast通知激活应用
            if (args.Kind == ActivationKind.ToastNotification)
            {
                // 转换参数类型
                var toastargs = (ToastNotificationActivatedEventArgs)args;
                // 获取页面引用
                Frame root = Window.Current.Content as Frame;
                if (root == null)
                {
                    root = new Frame();
                    Window.Current.Content = root;
                }
                if (root.Content == null)
                    root.Navigate(typeof(MainPage));

                MainPage page = (MainPage)root.Content;
                // 判断用户点击哪个按钮
                if (toastargs.Argument== "ok") //确定按钮
                {
                    // 获取用户输入的内容
                    string name = toastargs.UserInput["name"] as string;
                    page.ShowToastArgs(name);
                }
                else //取消按钮
                {
                    //TODO
                }
            }
            Window.Current.Activate();
        }
现在对这个方法进行解析

首先用args.Kind == ActivationKind.ToastNotification判断程序是否是被Toast通知激活的,然后将参数args转化为ToastNotificationActivatedEventArgs,根据其Argument属性获取用户的操作项,如这里的ok就是我们在xml中定义的action节点的arguments值。再根据其UserInput属性获取用户在input中输入的值UserInput是个字典类型,key对应的是xml模板中的input所对应的id值。

代码中的ShowToastArgs方法是在MainPage中定义的,其作用就是在XAML页面中显示传入的参数

public void ShowToastArgs(string arg)
        {
            txtArg.Text = arg;
        } 

应用程序后台激活:activationType=background
Toast通知模板:
 string xml = "<toast>" +
                            "<visual>" +
                                "<binding template=\"ToastGeneric\">" +
                                    "<text>Title</text>" +
                                "</binding>" +
                            "</visual>" +
                            "<actions>" +
                                    "<input id=\"name\" type=\"text\" placeHolderContent=\"请输入姓名\" />" +
                                    "<action content = \"确定\" arguments = \"ok\" activationType=\"background\"/>" +
                                    "<action content = \"取消\" arguments = \"cancel\" activationType=\"background\"/>" +
                            "</actions >" +
                         "</toast>";
相比于前台通知,后台通知所要做的工作量就多了许多

1、首先我们需要在解决方案的名称右键选择“Windows运行时组建”来新建一个后台任务


2、ToastBackgroundTask类实现IBackgroundTask的接口

当Toast激活后台任务时,从taskInstance.TriggerDetails属性获取激活的对象实例。跟前台激活一样的,根据其Argument属性获取用户的操作项,如这里的ok就是我们在xml中定义的action节点的arguments值。再根据其UserInput属性获取用户在input中输入的值UserInput是个字典类型,key对应的是xml模板中的input所对应的id值。

最后我们把获取得参数保存到应用程序设置中,这样就可以在主应用中获取当前的输入参数。这里只是做简单是示例,你也可以对获得的参数做更多更复杂的操作

ToastBackgroundTask类的实现

public sealed class ToastBackgroundTask : IBackgroundTask
    {
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            var deferral = taskInstance.GetDeferral();
            var details = taskInstance.TriggerDetails as ToastNotificationActionTriggerDetail;
            if (details != null)
            {
                string arg = details.Argument;
                if (arg == "ok")//判断用户是否点击ok
                {
                    // 保存数据
                    var settings = ApplicationData.Current.LocalSettings;
                    settings.Values["name"] = details.UserInput["name"];// 获取选择的项
                }
            }
            deferral.Complete();
        }
    }

3、在主项目中添加对这个后台任务项目的引用


4、打开Package.appxmanifest文件,添加后台任务的声明。入口点填写后台任务组件的“命名空间.类名”,这里填写BackgroundTasks.ToastBackgroundTask


当然也可以以文本形式打开,找到Package/Applications/Application节点,并添加后台任务的声明

<Extensions>
      <Extension Category="windows.backgroundTasks" EntryPoint="BackgroundTasks.ToastBackgroundTask">
        <BackgroundTasks>
          <Task Type="general"/>
        </BackgroundTasks>
      </Extension>
</Extensions>

5、在主程序中获取用户的输入参数

 protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            var settings = ApplicationData.Current.LocalSettings;
            var val = settings.Values["name"];
            if (null!=val)
            {
                string name = val.ToString();
                //TODO
            }
            base.OnNavigatedTo(e);
        }

6、注册后台任务

在App类中添加如下方法实现对后台任务的注册

private async void RegToastBackgroundTask()
        {
            // 判断一下是否允许访问后台任务
            var status = await BackgroundExecutionManager.RequestAccessAsync();
            if (status == BackgroundAccessStatus.Denied || status == BackgroundAccessStatus.Unspecified)
                return;

            Type type = typeof(BackgroundTasks.ToastBackgroundTask);
            var task = BackgroundTaskRegistration.AllTasks.Values.FirstOrDefault(t => t.Name == type.Name);
            if (task == null)
            {
                // 注册后台任务
                var tBuilder = new BackgroundTaskBuilder();
                tBuilder.Name = type.Name;
                tBuilder.TaskEntryPoint = type.FullName;
                // 声明触发器
                var trigger = new ToastNotificationActionTrigger();
                tBuilder.SetTrigger(trigger);
                task = tBuilder.Register();
            }
        }
然后在OnLaunched方法的最后调用此方法就实现了后台任务的注册

7、运行应用程序,点击“后台通知”,此时弹出Toast通知,关闭应用程序,在Toast通知中输入参数然后确定。等下次运行该应用时就可以看到Toast通知传入的参数了


源码下载:https://github/hebecherish/ToastDemo



本文标签: 知之 Toast