建立牢固的多功能Smartphone应用程序 03
- UID
- 872238
|
建立牢固的多功能Smartphone应用程序 03
对于多数商业应用程序,你需要把数据保存在文件系统中。尽管能够将数据写入RAM文件系统,但是并不推荐这样使用,因为当设备关闭或掉电时所有数据都会丢失。对于持续的存储器,Smartphone设备提供作为IPSM内存控件的闪存文件系统。在多数 Smartphone上空间受到限制,但是许多设备包含一个存储卡槽,允许使用可移走的存储卡。
编程决定Smartphone上在哪儿存储数据很简单,这得感谢你在Windows CE 平台上进行开发所熟悉的一些API。这些调用可以在Windows Shell API文档中找到。现在我将聚焦于SHGetSpecialFolderPath函数。该函数允许你访问主要的Smartphone文件系统并在运行时检索完整的路径。在检索路径后,你能使用该路径存储与应用程序相关的数据。该函数需要一个CSIDL_常数作为输入参数。这些常数反映了 Smartphone操作系统中的共有文件夹(应用程序数据、收藏夹、程序、开始等等)。因为这些公共区域也许在不同设备上,CSIDL常量提供了一个唯一的系统标识来识别这些目录。推荐客户应用程序在CSIDL_APPDATA常量返回目录的子目录中保存数据。例如:
#ifdef CSIDL_APPDATAif(!SHGetSpecialFolderPath(NULL, szFolderPath, CSIDL_APPDATA, TRUE)) { ASSERT(FALSE); hr = HRESULT_FROM_WIN32(GetLastError()); }#else // Pocket PC没有这种定义来在根中读取目录。//也许未来会作些改变,但代码仍然可以工作 _tcscpy(szFolderPath, TEXT("\\"));#endif |
我先前讲到,有些设备需要附加存储卡。与你的桌面计算机的硬盘驱动器不同,Smartphone没有为存储卡分配驱动器符号。作为代替,操作系统在根目录中建立目录来表现每块存储卡上的不同部分。为了访问一个设备中的不同卡,使用FindFirstFlashCard和FindNextFlashCard函数。如果找到了存储卡,FindFirstFlashCard返回一个指向第一块存储卡的句柄和指针。如果句柄是正确的,你可以把它传递给 FindNextFlashCard,该函数将返回下一块存储卡的指针和一个BOOL值来表明搜索是否成功。
一旦你找到了希望使用的存储卡,下一步就是查找一个位置来存储数据。在访问设备上的文档时通常使用SHGetDocumentsFolder函数。它可用于新的或者原来的存储卡。下面是使用SHGetDocumentsFolder的一个例子:
TCHAR szDocPath[250];if (!SHGetDocumentsFolder(L"\\",szDocPath)) MessageBox(NULL,L"Retrieveing Path Failure",L"Call Failure",MB_OK); else MessageBox(NULL,szDocPath,L"Documents Folder Path",MB_OK); |
模拟器笔记:Smartphone模拟器不支持存储卡。它也不支持附加在运行模拟器的PC上的真正的存储卡。
数据库操作
对于几乎所有商业应用程序来说,把数据保存到本地数据库是必要的,对于许多Smartphone应用程序也是这样。与Windows CE和Pocket PC相比, Smartphone上数据库的选择只有少许的不同。对于第一个Smartphone版本Smartphone 2002,只支持本地Windows CE数据库,目前它不支持SQL Server CE或者Pocket Access。此外访问Windows CE数据库的唯一选择是使用包含在Windows CE 3.0中的数据库API。不过访问Windows CE数据库的代码与为Windows CE设备所写的代码几乎相同。
同步数据
在使用完连接并处理数据后,下一步就是与远程数据存储同步。因为我已经介绍过使用XMLDOM通过互联网检索数据,我将继续使用该模型并将改变通过XMLHTTP对象发送回远程服务器。
在介绍使用XMLHTTP的细节前,我们看看Smartphone怎样使用Web服务。目前,在Smartphone平台上没有内建库或组件提供SOAP客户端功能。但是Smartphone 的SOAP客户端并不在可能的范围之外,因为Smartphone 2002 SDK支持所有可能需要的组件。如果Smartphone上需要SOAP客户端,我建议查看第三方库,它也许能移植到Smartphone而没有太多问题。此外你应该记得一旦Smartphone上的.NET简洁框架组件可以使用,就能使用Smartphone客户端的功能了。
从Smartphone向远程数据存储同步数据的第一步是从主存储器中检索所有改变了的数据并转换为XML格式。完成后,实例化XMLHTTP对象并把数据传递到处理同步的特定URL。
先前讲到,因为XMLHTTP对象拥有使用XML格式发送信息到远程服务器的能力,在这儿它将被使用到。XMLHTTP对象是前面的项目中包含的MSXML 库中可用的另一个对象。图4是该对象的使用。它很容易使用,从IXMLHttpRequest接口中建立了一个对象。此外,建立一个VARIANT来保持 IXMLDOMDocument对象。为了传递这个复杂的类型,VARIANT必须通过VT_DISPATCH类型设置。剩下的步骤是调用XMLHTTP 对象的open和send方法。
MSXML::IXMLDOMDocument *iXMLDoc = NULL;MSXML::IXMLHttpRequest *iXMLHttp = NULL;HRESULT hr;BSTR bStr = NULL;VARIANT vUserID;VARIANT vPassword;VARIANT vPassValue;VARIANT vAsync;short tEmpty;hr = CoInitializeEx(NULL,COINIT_MULTITHREADED);if(!SUCCEEDED(hr)) return 0;hr = CoCreateInstance (MSXML::CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, MSXML::IID_IXMLDOMDocument, (LPVOID *)&iXMLDoc);if(iXMLDoc){ iXMLDoc->put_async(VARIANT_FALSE); // Smartphone 2002工作区: //删除文档安全选项 IObjectSafety *pSafety; DWORD dwSupported, dwEnabled; if ( SUCCEEDED(iXMLDoc->QueryInterface(IID_IObjectSafety, (void**)&pSafety))) { pSafety->GetInterfaceSafetyOptions( MSXML::IID_IXMLDOMDocument, &dwSupported, &dwEnabled ); pSafety->SetInterfaceSafetyOptions( MSXML::IID_IXMLDOMDocument, dwSupported, 0 ); } iXMLDoc->put_async(VARIANT_FALSE); iXMLDoc->loadXML(L"JoeSmith", &tEmpty);}VariantInit(&vAsync);vAsync.vt = VT_BOOL;vAsync.boolVal = false;VariantInit(&vUserID);vUserID.vt = VT_BSTR;vUserID.bstrVal = L"";VariantInit(&vPassword);vPassword.vt = VT_BSTR;vPassword.bstrVal = L"";VariantInit(&vPassValue);vPassValue.vt = VT_DISPATCH;vPassValue.pdispVal = iXMLDoc;hr = CoInitializeEx(NULL,COINIT_MULTITHREADED); if(!SUCCEEDED(hr)) return 0;hr = CoCreateInstance (MSXML::CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, MSXML::IID_IXMLHttpRequest, (LPVOID *)&iXMLHttp);iXMLHttp->open(L"GET", L"http://localhost/smartphonesavetest.asp", vAsync,vUserID,vPassword);hr=iXMLHttp->send(vPassValue);iXMLHttp->get_responseText(&bStr); |
|
|
|
|
|
|