通常在网络协议制定的时候,经常需要客户端能够生成或者获取一些独特的不会重复的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 // {8D552BD1-E232-4107-B72D-38B6A4726439} const GUID bApplicationData1 = { 0x8d552bd1, 0xe232, 0x4107, { 0xb7, 0x2d, 0x38, 0xb6, 0xa4, 0x72, 0x64, 0x39 } }; const DWORD cbApplicationData1 = sizeof (bApplicationData1); g_cbDeviceID1 = GETDEVICEUNIQUEID_V1_OUTPUT; hr = GetDeviceUniqueID (reinterpret_cast<LPBYTE>(const_cast<LPGUID>(&bApplicationData1)), cbApplicationData1, GETDEVICEUNIQUEID_V1, g_bDeviceID1, &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, 有了这三个函数,一般的平台特性的问题都可以找到一些答案的!