2020年的UWP(1)——通过Radio类控制Cellular

最近在做UWP的项目,在2020年相信这已经是相对小众的技术了,但是在学习的过程中,发现某软这么几年仍然添加了不少的API,开放了相当多的权限。所以打算总结一下最近的一些经验和收获,介绍一下2020年的UWP。
之前在《UWP开发入门(25)——通过Radio控制Bluetooth, WiFi》篇中我们回顾了在UWP中如何操作Bluetooth和WiFi。在相当长的一段时间里,我都认为Radio类就止步于此了。然鹅最近的实践表明,Cellular也可以通过Radio类来控制了。

在介绍使用Windows.Devices.Radios.Radio控制Bluetooth和WiFi对象时,我们提到了GetRadiosAsync方法。

var radios = await Radio.GetRadiosAsync();
Bluetooth = radios.FirstOrDefault(r => r.Kind == RadioKind.Bluetooth);
WiFi = radios.FirstOrDefault(r => r.Kind == RadioKind.WiFi);

我们会根据RadioKind枚举来判断拿到Radio对象的具体类型。

只有认真读文档的同学,才会发现MobileBroadband在1703之后获得了支持。1703大概是2017年4月发布的。
这是不是意味着MobileBroadband在1703之后,就可以像Bluetooth和WiFi一样通过

public static IAsyncOperation<IReadOnlyList<Radio>> GetRadiosAsync();

来获取实例对象了,还真不是。通过GetRadiosAsync根本拿不到MobileBroadband类型的Radio对象,也就是本文提到的Cellular。
我们只能通过更原始的方式,通过

public static IAsyncOperation<Radio> FromIdAsync(string deviceId);

方法来查找Cellular类型的Radio对象。

        public async Task InitializeAsync()
        {
            //var radios = await Radio.GetRadiosAsync();
            //RadioModel = radios.FirstOrDefault(r => r.Kind == RadioKind);
            var selectorString = Radio.GetDeviceSelector();
            var deviceInfos = await DeviceInformation.FindAllAsync(selectorString);
            foreach (var deviceInfo in deviceInfos)
            {
                var radio = await Radio.FromIdAsync(deviceInfo.Id);
                if (radio.Kind == RadioKind)
                {
                    RadioModel = radio;
                }
            }
            this.OnPropertyChanged("IsOn");
        }

首先我们通过Radio.GetDeviceSelector方法拿到了用于查找Radio设备的字符串,然后通过DeviceInfomation.FindAllAsync方法取得当前设备上所有符合selectorString的Radio对象。再通过RadioKind.MobileBroadband筛选取得Cellular类型的Radio对象。

至此,我们通过Radio控制Cellular的目的在理论上算是达成了。实际呢,千万不要忘记打开Package.appxmanifest文件添加Capabilities。首先对所有的Radio操作而言

<DeviceCapability Name="radios"></DeviceCapability>

权限是必须的。而想要控制Cellular,那还需要申请受限的

<rescap:Capability Name="cellularDevcieControl"></rescap:Capability>

Namespace rescap的声明如下:

<Package
  xmlns="//schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:mp="//schemas.microsoft.com/appx/2014/phone/manifest"
  xmlns:uap="//schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="//schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
  IgnorableNamespaces="uap mp rescap">

需要留意的是,<rescap:Capability>必须写在<DeviceCapability>的前面才能生效。

  <Capabilities>
    <rescap:Capability Name="cellularDeviceControl"/>
    <DeviceCapability Name="radios"/>
  </Capabilities>

 

本篇算是一个序章,后续打算分享下UWP在2020年可以做到的一些有意思的feature,感觉已经无限接近传统的desktop application了。
有趣的是,曾在知乎上看到对UWP一些讨论,似乎对desktop extension的方式很不认同,认为是在背后偷偷摸摸干坏事。我想说的是,仍然还在做UWP的,很多都是用爱发电了。哪有那份心去干坏事啊……
本篇Sample Code:

//github.com/manupstairs/UWPSamples/tree/master/UWPSamples/RadioDevice

Tags: