zoukankan      html  css  js  c++  java
  • Windows Hello 浅尝(3)

    继续加油

    前面讲到在Task中无法使用DeviceWatcher来枚举蓝牙设备,那么解决方法同样在官方Demo中有

    地址: https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/DeviceEnumerationAndPairing

    就是需要再注册一个接收枚举事件的Task,那么步骤其实和注册一个接收Windows Hello事件的Task的方法是一样的

    string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected" };
    DeviceWatcherEventKind[] triggerEventKinds = { DeviceWatcherEventKind.Add, DeviceWatcherEventKind.Remove, DeviceWatcherEventKind.Update };
    DeviceWatcher deviceWatcher = null;
    deviceWatcher = DeviceInformation.CreateWatcher("(System.Devices.Aep.ProtocolId:="{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}")",
                                                    requestedProperties,
                                                    DeviceInformationKind.AssociationEndpoint);
    
    DeviceWatcherTrigger deviceWatcherTrigger = deviceWatcher.GetBackgroundTrigger(triggerEventKinds);
    
    BackgroundTaskBuilder taskBuilder;
    taskBuilder = new BackgroundTaskBuilder();
    taskBuilder.Name = strTaskPerName + g_strTaskPostName;
    taskBuilder.TaskEntryPoint = strEntryPoint;
    taskBuilder.SetTrigger(deviceWatcherTrigger);
    BackgroundTaskRegistration backgroundTaskRegistration = taskBuilder.Register();

     对应的Task的Run函数里面是这样的

    public void Run(IBackgroundTaskInstance taskInstance)
    {
    Debug.WriteLine("BackgroundDeviceWatcher.Run called");
    
    uint eventCount = 0;
    ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
    DeviceWatcherTriggerDetails triggerDetails = (DeviceWatcherTriggerDetails)taskInstance.TriggerDetails;
    
    Debug.WriteLine(String.Format("Trigger contains {0} events", triggerDetails.DeviceWatcherEvents.Count));
    
    foreach (DeviceWatcherEvent e in triggerDetails.DeviceWatcherEvents)
    {
        switch (e.Kind)
        {
        case DeviceWatcherEventKind.Add:
            Debug.WriteLine("Add: " + e.DeviceInformation.Id);
            break;
    
        case DeviceWatcherEventKind.Update:
            Debug.WriteLine("Update: " + e.DeviceInformationUpdate.Id);
            break;
    
        case DeviceWatcherEventKind.Remove:
            Debug.WriteLine("Remove: " + e.DeviceInformationUpdate.Id);
            break;
        }
    };
                
    if (null != settings.Values["eventCount"] &&
        settings.Values["eventCount"].GetType() == typeof(uint))
    {
        eventCount = (uint)settings.Values["eventCount"];
    }
    
    // Add the number of events for this trigger to the number of events received in the past
    eventCount += (uint)triggerDetails.DeviceWatcherEvents.Count;
    
    Debug.WriteLine(eventCount + " events processed for lifetime of trigger");
    
    settings.Values["eventCount"] = eventCount;
    }

     还是很简单的是吧! 

    我一开始做了个测试,就是这两个Task任务我写在同一个工程里,代码如下 

    public sealed class MyHelloWinTask : IBackgroundTask
    {
        static int i = 0;
    
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            i++;
        }
    }

     我发现这两个Task是同一个进程,并且当变量 i 是static变量的时候是可以累加的,所以我天真的以为注册的两个Task是同一个进程的不同的 MyHelloWinTask 实例对象,所以只要是静态对象那么数据就可以在两个Task之间共享。

    所以我的做法就是

    public sealed class MyHelloWinTask : IBackgroundTask
    {
        static private List DeviceList = new List();
        public void Run(IBackgroundTaskInstance taskInstance)
        {
        
            // 标记任务延迟完成
            var deferral = taskInstance.GetDeferral();
    
            // 可以根据注册Task的时候的名字判断是什么事件
            if (String.Equals(taskInstance.Task.Name, "MyHelloWinTask_Unlock"))
            {
               // 解锁设备就去解锁
               从List中获取所有设备和解锁设备进行比较
    
            }
            else
            {
                收到的数据加入List DeviceList
            }
    
            // 标记任务完成了
            deferral.Complete();
        }
    }

     这样子就可能承接 上一篇中的逻辑继续下去,并且在我写好对应代码之后,事情也是按照这个预期进行的。

    当我以为这个项目完成的时候,我突然发现他失灵了。

    我再次探究之后发现,如果你的界面进程开着,或者使用VS在调试的时候,这两个Task的确是同一个进程,但是一旦你把桌面进程关闭了,或者是在你开机的时候他们必然是两个独立的进程。所以就无法简单的通过static变量来通讯了。

    于是就想解决方法啦,无非就是进程间的通讯。于是我就去找UWP怎么进行进程间的通讯啊什么什么的,找了好久才漠然回首到其实可以使用 DeviceConfigurationData  通讯的,反正现在DeviceConfigurationData存的是json数据也不差多加个变量,DeviceConfigurationData 的长度最多可以是4K

    于是就多加了个CanUnlok变量。

    思路就又变了 

    在DeviceEumTask启动的时候将所有解锁设备的UnLock设为False,然后当枚举到一个蓝牙设备的时候检查有没有对应的解锁设备,有对应的解锁设备那么这个解锁设备的CanUnlock就设置为True,如果接到设备更新或者删除事件那么更新对应的CanUnlock

    在LoginTask中当接收到解锁事件的时候枚举所有解锁设备看他们的属性中Unlock是否为True,为Ture就直接使用它解锁Windows。

    但是这个逻辑也有问题,那就是配对的蓝牙设备即使设备不在旁边也总是能枚举到,没配对的设备Task又枚举不到。

    我研究了设备的IsConnected属性,发现这个属性不是很准。。这个问题暂时还没解决。。

    现在工程的代码就是按照这个逻辑写的

    项目地址: http://git.oschina.net/alwaysking/MyHelloWin

  • 相关阅读:
    Simpo
    Numpy技巧
    流程图
    注册免费试用12个月的亚马逊AWS云计算服务
    java-Collection
    CoreGraphic
    吴裕雄--天生自然python学习笔记:python 用pygame模块开发俄罗斯方块游戏
    吴裕雄--天生自然python学习笔记:python 用pygame模块检测键盘事件和鼠标事件
    吴裕雄--天生自然python学习笔记:python 用pygame模块角色类(Sprite)移动与碰撞
    吴裕雄--天生自然python学习笔记:python 用pygame模块动画一让图片动起来
  • 原文地址:https://www.cnblogs.com/alwaysking/p/7258930.html
Copyright © 2011-2022 走看看