通常在網路通訊協定制定的時候,經常需要用戶端能夠產生或者擷取一些獨特的不會重複的ID,輔之以一些平台,版本資訊來作為協議的一部分,背景伺服器可以根據這些資訊來做統計處理. 這裡就對這些常用的資訊的擷取辦法做一個匯總.
1. 開發平台. 這裡需要知道的是PPC還是Smartphon. 其實這個和協議的關係不大, 但是和用戶端開發比較密切. smartphone和ppc對clientRect的定義略有不同,所以還是需要可以動態區分一下,這裡就需要用到經典的控制台函數SystemParametersInfo. 對應大代碼形如:
TCHAR szPlatform[30];
SystemParametersInfo(SPI_GETPLATFORMTYPE, sizeof(szPlatform), szPlatform, 0);
if (_tcscmp(szPlatform, _T("SmartPhone")) == 0)
// On Pocket PC, szPlatform would be "PocketPC"
{}
2. 手機型號. 這個也是開發過程中為手機定製的常用的資訊.比如說有的像i900這樣的手機螢幕尺寸非常詭異如240*400.我們如何拿到它是i900的資訊呢?類似的也是SystemParametersInfo這個函數,不過是不同的參數:
TCHAR szDeviceName[30];
SystemParametersInfo(SPI_GETOEMINFO, sizeof(szDeviceName), szDeviceName, 0);
當然,這裡的函數執行成功了以後, 你最好還是看一下這個szDeviceName的內容到底是什麼, 因為一些對手機的簡稱並不一定可以通過這個這個函數反應出來,並不完全和你想象的名字一致,比如i900得到的值是"sgh-i900", 比如HTC Touch Pro, 試了之後的傳回值是"vogu100".
3. Device ID. 這個ID是一個很詭異的手機特有的ID. 說他詭異是在於Windows MObile team blog上面說This ID is not the same as an IMEI or a phone number found on a phone
based device, both of which can be changed, but instead this code lives
and dies with the device.這個ID既不是IMEI也不是電話號碼, 用這裡的話來說,這個id不會改變這是一個不滅的號碼!我們來看這段代碼把他看看這個ID到底是什麼東東:
// Application specific data<br /> // {8D552BD1-E232-4107-B72D-38B6A4726439}<br /> const GUID bApplicationData1 = { 0x8d552bd1, 0xe232, 0x4107, { 0xb7, 0x2d, 0x38, 0xb6, 0xa4, 0x72, 0x64, 0x39 } };<br /> const DWORD cbApplicationData1 = sizeof (bApplicationData1);<br /> g_cbDeviceID1 = GETDEVICEUNIQUEID_V1_OUTPUT;<br /> hr = GetDeviceUniqueID (reinterpret_cast<LPBYTE>(const_cast<LPGUID>(&bApplicationData1)),<br /> cbApplicationData1,<br /> GETDEVICEUNIQUEID_V1,<br /> g_bDeviceID1,<br /> &g_cbDeviceID1);
這段代碼在SDK的sample裡面可以找到(Windows Mobile 5.0 Pocket PC SDK/Samples/CPP/Win32/Getdeviceid)這個ID的結構類似與GUID,但是他又不是GUID, 它是你應用程式的GUID和硬體的一些特性HASH出來的一個值! 所以你用不同的GUID作為參數傳入,將得到不同的device ID! 儘管有人說在不同的多普達的手機上得到過相同的DeviceID,但是我這裡測試了D600, S1, HTC Touch, 得到的值都是不同的, 所以說這個ID用來識別手機是比較恰當的!
4. IMEI和IMSI.
這個是比較傳統的問題了, 在SDK的sample裡面也有他們的影子!
位置就在Windows Mobile 5.0 Pocket PC SDK/Samples/CPP/Win32/Cellcore/Extapi這個工程裡面就有辦法, 大體上圍繞著lineGetGeneralInfo來調用, (代碼不貼出來了)但是這算是個特權函數, 在windows mobile 6.0裡面和smarphone裡面都需要簽名以後再可以使用, 簽名的辦法麼請點擊在 Visual C++ 項目中對項目輸出進行簽名. 這裡面有非常詳細的說明!需要說明的事情是IMSI不是不可以用, 這個id儲存在SIM卡裡面,但是他表示的是在GSM網路的認證! 所以如果你的手機在CDMA網路裡面用呢, 這個ID就不知道怎麼弄了.... 這裡的lineGetGeneralInfo可以同時讀出這個IMEI和IMSI的資訊, 還有工廠的資訊(這個資訊是chipset的生產廠商, 比如Qualcomm:))! 在這個號碼的擷取上, RIL也可以拿出IMEI的資訊(RIL_Initializ一個函數就可以了), 但是看到一些官方的說法都是不推薦的, 所以在這裡就不展開了.
5. 手機號碼
這個一直是很多人都想得到的一個東西,在之前的版本裡面都沒有看到蹤跡,但是到6.0開始, 這個東西貌似可以拿到了。在微軟的網頁上看到了這麼一個東西: http://msdn.microsoft.com/en-us/library/bb158759.aspx 這裡面說道在SDK下面有一個例子, 這個例子就是SDK下面的sample, C:/Program Files/Windows Mobile 6 SDK/Samples/Common/CPP/Win32/GetPhoneNumber. 一樣的 代碼就不貼了, 為了重點突出這個說明, 我們還是看看:
For this sample, it is assumed that the mobile device uses a SIM with the device's phone number programmed into it. Some devices do not store their phone number on a SIM. For
these devices, there is no way to programmatically determine the
device's phone number and this sample will not successfully return the
number.
This
application does not need to run Privileged (i.e., it does not need to
be signed with a certificate from the privileged store).
首先, 一樣有SIM卡,沒有SIM卡不談, 再者,要手機號碼放在SIM卡裡面,不然也沒有辦法談。
好的,所以到目前為止, 一定要記住的是三個有用的函數:
SystemParametersInfo, GetDeviceUniqueID和lineGetGeneralInfo, 有了這三個函數,一般的平台特性的問題都可以找到一些答案的!