应用开发中,开发者时常需要获取一些系统、用户信息用于数据统计遥测、问题反馈、用户识别等功能。本文旨在介绍在 Windows UWP 应用中获取一些常用系统、用户信息的方法。示例项目代码可参见 Github:
由于涉及内容较多,故本文会分为多篇展开。本篇为系列第二篇,介绍如何获取商店授权信息、零售演示模式信息、广告ID、EAS 设备信息、硬件识别信息、硬件设备信息以及移动网络信息。
原博客阅读地址:http://validvoid.net/uwp-system-info-collect-2/
商店授权信息
Windows.ApplicationModel.Store
命名空间提供了与 Windows Store 商店交互的类型和成员。我们使用其中的 CurrentApp 类获取当前应用的授权信息。
需要注意的是,如果你还没有 Windows Store 开发者账号,或者正在进行本地调试,需要使用 CurrentAppSimulator
而不是 CurrentApp
类。顾名思义,CurrentAppSimulator
正是 CurrentApp
的模拟类,代替了过去 WP8 上的 Mock IAP Lib 用于模拟正式的商店交互。CurrentAppSimulator
的成员和用法与 CurrentApp
完全一致。推荐做法是使用编译条件,Debug 时使用 CurrentAppSimulator
,而 Release 时使用 CurrentApp
。
有关
CurrentAppSimulator
的详情,可以参考 MSDN 文档。
授权信息
CurrentApp
类包含三个属性:
- AppId 获取 Windows Store 商店为通过认证的应用生成的 GUID。
- LicenseInformation 获取当前应用的授权元数据。
- LinkUri 获取当前应用商店页面的 URI。
其中的 LicenseInformation
属性是判断当前应用整体授权情况(不包含应用内购产品的授权信息)的关键。该属性的工作不要求网络连接,因此在设备离线状态下,应用依然可以通过此 API 正确检测授权情况。LicenseInformation
属性 的类型为LicenseInformation。LicenseInformation
类型包含四项只读属性:
- ExpirationDate 获取相对于系统时钟的授权过期时间。
- IsActive 指示当前授权状态是否有效。
- IsTrial 指示当前授权是否为试用授权。
- ProductLicenses 获取与当前应用关联的应用内商品授权列表。
我们可以通过前三项属性控制应用的试用、购买授权。对于试用版应用,试用期间 IsTrial
属性会返回 true, IsActive
属性也会返回 true。超过试用期,IsActive
会返回 false。从试用版升级为完整版,则IsTrial
属性会返回 false,IsActive
属性会返回 true。
市场活动 ID
除以上成员外,CurrentApp
类还提供了一个方法GetAppPurchaseCampaignIdAsync。该方法用于返回市场活动 ID。这是 Windows 10 新增的一项特性。市场活动 ID(campaign ID) 本质上是一个可自定义的参数,允许你据此获得应用安装的来源渠道,从而进一步开展应用推广、用户活动、分渠道数据分析等工作。假设你要开展影响活动,从微博安装应用的用户可获赠某项应用内产品,那么在微博发布应用的商店下载链接时,就需要附加上市场活动 ID。当用户通过此携带市场活动 ID 的链接安装你的应用并满足转化条件时,用户启动应用后,应用可以通过 GetAppPurchaseCampaignIdAsync
获取到你在推广链接中预置的市场活动 ID,进而为该用户发放赠品。从用户点击携带市场活动 ID 的链接到完成应用安装,就实现了一次转化。
创建市场活动 ID
如果你希望发布应用的商店页面链接,使用户通过浏览器导航跳转进入应用的商店网页进行安装,那么需要使用 HTTP 格式的商店链接,并附加市场活动 ID 参数。例如:
图中前半部分为 Skype 的商店页面链接,在此链接后附加了 ?cid=facebook_campaign
表示这是来自 Facebook 页面的推广链接。
而如果你希望在其它应用中通过附加市场活动 ID 的链接直接跳转到 Windows Store 商店应用推广你的应用,则需要使用协议格式的 URL。同样以 Skype 举例,在另一个应用中,使用代码方式跳转到链接:
ms-windows-store://pdp/?PRODUCTID=9wzdncrfj364&cid=facebook_campaign
市场活动 ID 的转化条件
你可以在 Windows 开发人员中心面板中的“通道和转换报告”栏目查看市场活动 ID 的转化数据。需要注意的是,对于该栏目的数据统计,以及调用 GetAppPurchaseCampaignIdAsync
以编程方式获得市场活动 ID 的满足条件是不一样的。
要被“通道和转换报告”统计认定为有效转化,需要满足以下条件:
- 具有已识别的微软帐户的用户点击了自定义市场活动 ID 的应用 URL,然后重定向到该应用的 Windows 应用商店页面。
- 该用户在完成上一步动作后 24 小时内安装该应用。即使用户点击了自定义市场活动 ID 的 Windows 应用商店 URL,但在另一台登录相同微软账户计算机或设备上安装该应用,这仍然认定为有效转化。
要被编程方式获取市场活动 ID 认定为有效转化,需要满足以下条件:
- 具有已识别的 Microsoft 帐户的用户点击了自定义市场活动 ID 的应用 URL,然后重定向到该应用的 Windows 应用商店页面。
- 用户在点击 URL 后跳转到的 Windows 应用商店页面立即安装该应用。如果用户离开页面,然后在 24 小时内返回到该页面(无论在同一台计算机或设备上还是不同的计算机或设备上)并安装应用,将认定为“通道和转换报告”的有效转化,但如果你以编程方式获取市场活动 ID,则这不会认定为有效转化。
有关市场活动 ID 的更多详情,可以参考 MSDN 文档 Create a custom app promotion campaign,或中文版《创建自定义应用促销活动》。不过个人觉得中文版的翻译不是很顺畅,推荐阅读英文版。之后我也会另写一篇博客补上市场活动 ID 的更多相关内容。
零售演示模式信息
Windows 10 包含一个隐藏的“零售演示模式”。启用该模式时 Windows 会删除系统当前登录的账户信息,自动开启一个演示用账户。如果你的应用被选为零售 Windows 设备上的预装应用,那么可能需要获取与系统零售演示模式相关的信息。 Windows.System.Profile
命名空间下的 RetailInfo 正是提供次功能的一个工具类。
RetailInfo
类只包含一个方法 IsDemoModeEnabled
和一个属性 Properties
。
'IsDemoModeEnabled' 用于检测当前应用是否运行于零售演示模式。如果是,返回 true,否则将返回 false。假设你的应用是 Windows 设备的预装应用,你希望顾客在商店体验 Windows 系统和你的应用时展示一些不同的内容,就可以通过此方法判断当前是否运行于演示模式,如果是则展示用于演示的内容,比如产品介绍视频。
只读属性 Properties
返回一系列用于演示模式应用的属性设置。当应用不处于演示模式时,该属性不返回任何内容。类似于上一篇文章中提到的 KnownUserProperties
,RetailInfo.Properties
的键名由 KnownRetailInfoProperties 类定义,该类包含以下只读属性:
属性 | 访问类型 | 说明 |
---|---|---|
BatteryLifeDescription | 只读 | 获取电池续航信息属性值的键名。 |
DisplayDescription | 只读 | 获取显示设备说明信息属性值的键名。 |
DisplayModelName | 只读 | 获取显示设备型号信息属性值的键名。 |
FormFactor | 只读 | 获取设备规格信息属性值的键名。 |
FrontCameraDescription | 只读 | 获取前置摄像头信息属性值的键名。 |
GraphicsDescription | 只读 | 获取图形处理器信息属性值的键名。 |
HasNfc | 只读 | 获取是否搭载 NFC 设备信息属性值的键名。 |
HasOpticalDrive | 只读 | 获取是否搭载光驱信息属性值的键名。 |
HasSdSlot | 只读 | 获取是否搭载 SD 卡插槽信息属性值的键名。 |
IsFeatured | 只读 | 获取是否为推荐产品信息属性值的键名。 |
IsOfficeInstalled | 只读 | 获取是否安装 Office 信息属性值的键名。 |
ManufacturerName | 只读 | 获取制造商名称属性值的键名。 |
Memory | 只读 | 获取内存信息属性值的键名。 |
ModelName | 只读 | 获取设备型号名属性值的键名。 |
Price | 只读 | 获取设备价格信息属性值的键名。 |
ProcessorDescription | 只读 | 获取处理器信息属性值的键名。 |
RearCameraDescription | 只读 | 获取背部摄像头信息属性值的键名。 |
RetailAccessCode | 只读 | 获取零售访问代码信息属性值的键名。 |
ScreenSize | 只读 | 获取屏幕尺寸信息属性值的键名。 |
StorageDescription | 只读 | 获取储存设备说明信息属性值的键名。 |
Weight | 只读 | 获取设备重量信息属性值的键名。 |
WindowsEdition | 只读 | 获取搭载 Windows 版本信息属性值的键名。 |
广告 ID
Windows.System.UserProfile.AdvertisingManager
类提供了一个属性 AdvertisingId
,该属性返回一个字符串类型的值,即广告 ID。广告 ID 也是开发者实现应用数据统计的重要参考项之一。不过使用 AdvertisingId
中有几点问题需要注意:
- 广告 ID 是每用户、每设备唯一的
- 广告 ID 可以被用户通过系统设置关闭
- 广告 ID 不具有持久性,在不同情况下会发生改变
- 广告 ID 在儿童账户中是关闭的
有关广告 ID 的更多介绍,以及更多获取设备唯一 ID 实现数据统计的方案介绍,请参阅之前的文章 《Windows Store 应用获得设备 ID 的几种方案》。
EAS 设备信息
Windows.Security.ExchangeActiveSyncProvisioning
命名空间下的EasClientDeviceInformation 类提供了获取 EAS 设备信息的能力。所谓的 EAS 即 Exchange ActiveSync。EAS 是一套使移动设备与 Exchange 服务同步数据的协议。EasClientDeviceInformation
往往也是开发者获取系统信息的一个重要渠道,例如,使用 Github 上的示例代码在一台搭载 Windows 10 Mobile 的名为 "Steve's Phone" 的 Lumia 1520 上会得到如下 EAS 信息输出:
EAS Client Device Information
Id: 3d776048-51ef-da40-d1ad-3ce62a9b8ca4
FriendlyName: Steve's Phone
OperatingSystem: WindowsPhone
SystemFirmwareVersion: 02540.00019.15236.45005
SystemHardwareVersion: 5.3.0.
SystemManufacturer: NOKIA
SystemProductName: RM-939_apac_prc_200
SystemSku: NOKIA RM-939_apac_prc_200
而在一台搭载了技嘉 B85 主板的 Windows 10 台式机上运行则会得到以下 EAS 输出:
Id: 3f69ad8d-1362-3f96-507c-453ff2efbe7c
FriendlyName: Creeper's PC
OperatingSystem: WINDOWS
SystemFirmwareVersion:
SystemHardwareVersion:
SystemManufacturer: Gigabyte Technology Co., Ltd.
SystemProductName: B85M-D3V
SystemSku: To be filled by O.E.M.
EasClientDeviceInformation
的使用方法也很简单:
var eascdi = new Windows.Security.ExchangeActiveSyncProvisioning.EasClientDeviceInformation();
EasClientDeviceInformation
包含了以下只读属性提供 EAS 相关的系统、设备信息:
- FriendlyName 返回设备名称。
- Id 返回设备 ID。
- OperatingSystem 返回设备操作系统。
- SystemFirmwareVersion 返回系统固件版本号。
- SystemHardwareVersion 返回硬件版本号。
- SystemManufacturer 返回制造商名称。
- SystemProductName 返回设备型号名。
- SystemSku 返回 SKU。此项仅限 Windows Store 应用使用。其内容从注册表获取,如果注册表不可访问,则该项返回空字符串。当为空时,建议以设备型号作为 SKU 值,否则应当适用制造商名称和设备型号名构造 SKU 值。
如果你打算使用 EAS ID 做唯一设备是别,需要注意 EAS ID 是每用户、每设备、每应用唯一的,这意味着不同用户、不同设备、不同应用获取到的 EAS ID 都是不一样的。有关设备 ID 的更多内容,可参阅我之前编写的文章《Windows Store 应用获得设备 ID 的几种方案》。
硬件识别信息
如果你打算在你的应用中实现每设备逻辑,那么就会用到 Windows.System.Profile
命名空间下定义的 HardwareIdentification 类。该类只包含一个方法:GetPackageSpecificToken。该方法用于返回当前应用在当前设备的硬件识别 ID(简称为 ASHWID)。方法的返回值类型为 HardwareToken。
HardwareToken
类型包含三个只读属性:
- Certificate 获取用于校验硬件识别 ID 的证书。
- Id 获取硬件识别 ID。
- Signature 获取用于校验硬件识别 ID 的数字签名。
要获得 ASHWID 的值,我们可以使用如下方法:
string strDeviceUniqueId = ""; string strSignature = ""; string strCertificate = ""; var token = HardwareIdentification.GetPackageSpecificToken(null); IBuffer hardwareId = token.Id; IBuffer signature = token.Signature; IBuffer certificate = token.Certificate; var byteArray = new byte[hardwareId.Length]; var dataReader = DataReader.FromBuffer(hardwareId); dataReader.ReadBytes(byteArray); foreach (byte b in byteArray) { string strTemp = b.ToString(); if (1 == strTemp.Length) { strTemp = "00" + strTemp; } else if (2 == strTemp.Length) { strTemp = "0" + strTemp; } strDeviceUniqueId += strTemp; }
需要注意的是,ASHWID 是用户间一致,每设备、每应用唯一的。也就是说同一用户在不同设备上使用同一应用获得的 ASHWID 取值不同;同一用户在相同设备上使用不同应用获得的 ASHWID 取值也不同。
有关 ASHWID 以及实现每设备应用逻辑的更多详情可以参阅我之前编写的文章《Windows Store 应用获得设备 ID 的几种方案》。
移动网络信息
在 Windows.Networking.NetworkOperators
命名空间中定义了很多移动网络相关 API。例如 MobileBroadbandAccount
类表示了移动宽带账户,'MobileBroadbandNetwork' 类表示移动宽带网络等。该命名空间下提供的所有功能特性属于微软合作伙伴 API。这意味着开发者需要从微软获得特定的私有权限才能在应用中调用这些 API 并正常工作。由于我不是手机制造商,也不是移动网络工作人员,无法拿到这些私有权限的授权,并且大部分开发者也拿不到,故在此不再赘述此命名空间相关 API,仅在此给出参考资料,有兴趣的朋友可以参阅:
- Mobile Broadband Overview
- Mobile broadband WinRT API overview
- List of mobile broadband Windows Runtime APIs
- Best practices for using Mobile Broadband Windows Runtime API
UWP 应用获取各类系统、用户信息第二篇到此结束。后续随着对 UWP 各种 API 了解的深入,我会继续更新本系列文章和示例代码演示如何获取常用信息。