Windows Phone - 取得相關設備的資訊

Windows Phone - 取得相關設備的資訊

最近在撰寫WP的專案時,常會遇到需要捉取設備的一些參數與硬體資訊,因此,該篇將介紹如何取得設備的相關資訊。

 

DeviceStatus

    在WP8開始如需要擷取設備的資訊,可以改用DeviceStatus類別來負責。過去WP7或WP7.1則使用DeviceExtendedProperties,

(但是WP8以後DeviceExtendProperties將不再支持,這是要特別注意的)二者的差別在那裡呢?DeviceStatus可在App執行過程中

取得設備的狀態,例如:設備總可用記憶體Size、設備版本、是否具有實體鍵盤…等相關資訊,更可以註冊一些事件當監控的屬性

變化時可以通知我們的App。

 

Property Name Description
ApplicationCurrentMemoryUsage 回傳應用程式目前記憶體的使用量,以bytes為單位。
ApplicationMemoryUsageLimit 回傳應用程式可以分配的大小記憶體量,以bytes為單位。
ApplicationPeakMemoryUsage 回傳當前應用程式的尖峰記憶體使用量,以bytes為單位。
DeviceFirmwareVersion 回傳設備上運行的固件版本。
DeviceHardwareVersion 回傳設備上運行的硬體版本。
DeviceManufacturer 回傳設備製造商的名稱。
DeviceName 回傳設備的名稱。
DeviceTotalMemory 回傳該設備實際RAM的大小,以bytes為單位。
IsKeyboardDeployed 指示使用者是否已部署設備的物理硬體鍵盤。
IsKeyboardPresent 指示該設備是否包涵一個物理硬體鍵盤。
PowerSource 指示該設備是目前正在使用電池電源運行還是插入到外部電源供電。

 

Event Name Description
KeyboardDeployedChanged 事件發生在鍵盤被開啟或關閉。
PowerSourceChanged 事件發生在設備電源狀態改變時。

 

常見的例子:

a. 取得設備資訊;

    這是最常見的使用例子,透過DeviceStatus來取得;例如:總記憶體、硬體資訊、手機製造商…等;

 

b. 在lock screen外運行App中擷取資訊;

    例如像Alarm或Travel類型的App在Lock Screen顯示時間、日期的情況可擷取如電力資訊(PowerSource)或改變的事件(PowerSourceChanged);

 

c. 檢查是否有鍵盤可使用;

    App能藉由實體鍵盤是否選擇支援landscape或portrait,使用IsKeyboardPresentIsKeyboardDeployed屬性與KeyboardDeployedChanged

事件來加以處理。   

 

d. 監控記憶體使用狀況;

    利用ApplicationCurrentMemoryUsageApplicationPeakMemoryUsage屬性監督記憶體使用率,而DeviceTotalMemory

ApplicationMemoryUsageLimit屬性來顯示設備與App記憶體可用限制。並不需要短時間去監控記憶體用量,而是在足夠的時間

監控記憶體的尖峰使用量。如果您發現自己的App記憶體用率符合「section 5.2 of Technical certification requirements for Windows Phone」,

您可能需要更詳細測試記憶體的使用狀況。例如:可追蹤Pages與User Controls為主要對象,如果過多將會造成大量使用記憶體問題,

所以要記得正常的released它們。

 

[注意]

*雖然DeviceStatus可擷取到設備原始的資料,但不應該直接顯示給使用者知道,應該是搭配Web Service或將資料整理成有用的資訊,

回報至Server加以分析與管理。

 

 

上方介紹了DevcieStatus的事件、屬性與常見劇情,下方將透過代碼的方式來簡單介紹操作:

 

[程式範例] (參考How to use the DeviceStatus class for Windows Phone 8)

1. 擷取DevieStatus提供的設備資訊;

public MainPage()
{
    InitializeComponent();
 
    // 註冊鍵盤與電力的event handlers
    DeviceStatus.PowerSourceChanged += new EventHandler(DeviceStatus_PowerSourceChanged);
    DeviceStatus.KeyboardDeployedChanged += new EventHandler(DeviceStatus_KeyboardDeployedChanged);
 
    // 取得DevieStatus提供的設備資訊
    // 取得製造商的名稱
    deviceManufacturerTextBlock.Text = DeviceStatus.DeviceManufacturer;
 
    // 取得設備的名稱
    deviceNameTextBlock.Text = DeviceStatus.DeviceName;
 
    // 取得設備的固件版本
    deviceFirmwareVersionTextBlock.Text = DeviceStatus.DeviceFirmwareVersion;
 
    // 取得設備的硬體版本
    deviceHardwareVersionTextBlock.Text = DeviceStatus.DeviceHardwareVersion;
 
    // 取得設備總記憶體(bytes)
    deviceTotalMemoryTextBlock.Text = string.Format("{0} MB", ConvertBytesToMegabytes(DeviceStatus.DeviceTotalMemory).ToString());
        //DeviceStatus.DeviceTotalMemory.ToString();
 
    // 取得目前App使用的記憶體量(bytes)
    appCurrentMemoryUsageTextBlock.Text = string.Format("{0} MB", ConvertBytesToMegabytes(DeviceStatus.ApplicationCurrentMemoryUsage).ToString());
        //DeviceStatus.ApplicationCurrentMemoryUsage.ToString();
 
    // 取得App可用最大記憶體量(bytes)
    appMemoryUsageLimitTextBlock.Text = string.Format("{0} MB", ConvertBytesToMegabytes(DeviceStatus.ApplicationMemoryUsageLimit).ToString());
        //DeviceStatus.ApplicationMemoryUsageLimit.ToString();
 
    // 取得應用程式的尖峰記憶體使用量(bytes)
    appPeakMemoryUsageTextBlock.Text = string.Format("{0} MB", ConvertBytesToMegabytes(DeviceStatus.ApplicationPeakMemoryUsage).ToString());
        //DeviceStatus.ApplicationPeakMemoryUsage.ToString();
 
    // 取得設備是否包涵一個物理硬體鍵盤
    isKeyboardPresentTextBlock.Text = DeviceStatus.IsKeyboardPresent.ToString();
 
    // 取得是否已部署設備的物理硬體鍵盤
    isKeyboardDeployedTextBlock.Text = DeviceStatus.IsKeyboardDeployed.ToString();
 
    // 取得目前正在使用電池電源運行還是插入到外部電源供電
    powerSourceTextBlock.Text = DeviceStatus.PowerSource.ToString();
}

 

2. 針對鍵盤與電力事件的處理;

void DeviceStatus_PowerSourceChanged(object sender, EventArgs e)
{
    // The PowerSourceChanged event is not raised on the UI thread, 
    // so the Dispatcher must be invoked to update the Text property.
    this.Dispatcher.BeginInvoke(() =>
    {
        powerSourceTextBlock.Text = DeviceStatus.PowerSource.ToString();
    }
    );
}
 
void DeviceStatus_KeyboardDeployedChanged(object sender, EventArgs e)
{
    // The KeyboardDeployedChanged event is not raised on the UI thread, 
    // so the Dispatcher must be invoked to update the Text property.
    this.Dispatcher.BeginInvoke(() =>
    {
        isKeyboardDeployedTextBlock.Text = DeviceStatus.IsKeyboardDeployed.ToString();
    }
    );
}
 
/// <summary>
/// 轉換bytes為megabytes
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
private double ConvertBytesToMegabytes(long bytes)
{
    return (bytes / 1024f) / 1024f;
}

透過上述的介紹最常用到的還是在於記憶體、電力事件的監控,因為記憶體的管理對於應用上非常要注意的,電力的管理對於LocationService的應用App

尤其需要監控的一點。

那麼可能會想要知道DeviceStatus沒有像DeviceExtendedProperties可以取得DeviceUniqueId,該怎麼處理呢?

我們需要改用HostInformation.PublisherHostId的方式來取得,範例如下:

txtDeviceID.Text = Windows.Phone.System.Analytics.HostInformation.PublisherHostId;

 

至於WP8.1之後呢?請參考<Guidance on using the App Specific Hardware ID (ASHWID) to implement per-device app logic>。

 

最後再補充DeviceExtendedProperties的說明以支援WP7、WP7.1所開發的應用程式。

 

Microsoft.Phone.Info.DeviceExtendedProperties

   提供應用程式在執行過程中取得設備的相關資訊。要記得宣告操作「ID_CAP_IDENTITY_DEVICE」的Capabilities。

藉由二個方法:GetValue(propertyName)與TryGetValue(propertyName, out propertyValue)來嘗試取得指定propertyName的Value。

以下介紹可以透過該類別來取得的相關資訊:

Property name

Value type

Description

ApplicationCurrentMemoryUsage

A long integer.

當前應用程式記憶體的使用率以位元組為單位。
建議改用DeviceStatus.ApplicationCurrentMemoryUsage

ApplicationPeakMemoryUsage

A long integer.

當前應用程式的尖峰記憶體使用量以位元組為單位。
建議改用DeviceStatus.ApplicationPeakMemoryUsage

ApplicationWorkingSetLimit

A long integer.

The working set limit in bytes.(工作集限制以位元組為單位。)
This property applies to Windows Phone OS 7.1 and higher.

DeviceFirmwareVersion

A string.

設備上運行的固件版本,非OS版本。可利用System.Environment來擷取。
取得值是一個System.Version的格式,採用遞增的方式顯示。這不是必需的。此值可能為空。
建議改用DeviceStatus.DeviceFirmwareVersion

DeviceHardwareVersion

A string.

硬體版本運行的設備。這不是的 OS 版本,可利用System.Environment來擷取。取得值是一個System.Version的格式,採用遞增的方式顯示。這不是必需的。此值可能為空。
建議改用DeviceStatus.DeviceHardwareVersionDeviceHardwareVersion。

DeviceManufacturer

A string. 256 characters maximum.

The name of the manufacturer of the device. There is no standard format for this string. We recommend that the same value be used by every device from a manufacturer, but this is not enforced. This value may be empty.

This property is deprecated. Use the DeviceManufacturer property instead.

DeviceName

A string. 256 characters maximum.

The name of the device. There is no standard format for this string. This value may be empty.

This property is deprecated. Use the DeviceName property instead.

DeviceTotalMemory

A long integer.

The physical RAM size of the device in bytes. This value will be less than the actual amount of device memory, but can be used for determining memory consumption requirements.

This property is deprecated. Use the DeviceTotalMemory property instead.

DeviceUniqueId

A byte array. 20 bytes in length.

A unique hash for the device.

  • For Windows Phone 8 apps running on Windows Phone 8 devices and later, the DeviceUniqueId value is unique per device and per app publisher. For Windows Phone 8 apps, DeviceUniqueId is functionally identical to the HostInformation.PublisherHostId property in the Windows Runtime.

  • For Windows Phone OS 7.1 apps running on Windows Phone 8 devices, the DeviceUniqueId value is unique per device.

This value is constant and does not change if the phone is updated with a new version of the operating system.

Don’t use DeviceUniqueId in your apps to identify users. The device ID remains unchanged even if ownership of the device is transferred.

IsApplicationPreInstalled

A Boolean value.

Indicates whether the app was pre-installed with the device image. Apps that are downloaded from the Windows Phone Store always return a value of false.

OriginalMobileOperatorName

A string.

A string that represents the mobile operator's name.

PhysicalScreenResolution

Size

A Size value containing the height and width of the device’s screen.

RawDpiX

Double

A Double containing the raw number of pixels along the horizontal axis of the screen; when this value is not available, it returns 0.0

RawDpiY

Double

A Double containing the raw number of pixels along the vertical axis of the screen; when this value is not available, it returns 0.0

 

如果上述指定的propertyName取不到值或是對應的權限(Capabilities)未開啟的話,將會得到以下的Exceptions:

Exception Condition
ArgumentNullException 指定的propertyName是null。
ArgumentOutOfRangeException 指定的propertyName不存在。
UnauthorizedAccessException 未開啟指定的Capability無法擷取資料。
NotSupportedException 指定的propertyName不支援無法被擷取。

 

======

從以上的介紹可以得知以後如果要操作設備的相關資訊,建議採用DeviceStatus類別來操作會得到比較完整的功能。

DeviceStatus也有支援WP8.1中使用,所以可以安心使用。另外注意的是DeviceUniqueId的值在不同系統運作時值會不同,

所以不建議直接用來當識別User的方式,假設真的需要可以參考「how to get unique device id for Windows 8 and Windows Phone app」,

但我不保證一定符合需求。希望對大家有所幫助,謝謝。

 

References:

How to use the DeviceStatus class for Windows Phone 8 (重要) & SampleCode

Device status for Windows Phone 8 (重要)

App capabilities and hardware requirements for Windows Phone 8 (重要)

DeviceExtendedProperties Class

Windows Phone 7 取得設備資訊

Finding the Device Model on Windows Phone 7

how to get unique device id for Windows 8 and Windows Phone app

Get Unique Device ID (UDID) under Windows Phone 8

Device status for Windows Phone 8

EvenTiles and 256-MB Windows Phone Devices

Technical certification requirements for Windows Phone (重要)

Guidance on using the App Specific Hardware ID (ASHWID) to implement per-device app logic (重要)

HardwareIdentification.GetPackageSpecificToken | getPackageSpecificToken method

 

Dotblogs Tags: