建立牢固的多功能Smartphone应用程序Word文档下载推荐.docx
《建立牢固的多功能Smartphone应用程序Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《建立牢固的多功能Smartphone应用程序Word文档下载推荐.docx(10页珍藏版)》请在冰豆网上搜索。
这种类型的应用程序是已存在的内容提供商的最好选择,他们希望将出售物扩展到Smartphone所有者。
Smartphone上的基于浏览器的应用程序与其它平台上的好处相同:
简单的软件分发和维护,因为所有的代码在Web服务器上。
当然,缺点是并不能保证始终连接到互联网。
另一个问题是袖珍互联网浏览器应用程序不能与设备的内建特性交互。
尽管如此,这类应用程序可以使用已经存在的(例如ASP.NET移动控件)Web开发和优化工具开发。
与Web应用程序不同,你能使用类似嵌入式(eMbedded)VisualC++的工具来开发一个定制的应用程序。
幸运的是Smartphone与PocketPC平台相似。
因为大多数API相同,使用嵌入式VisualC++为PocketPC平台开发的应用程序能简单地移植到Smartphone上,其结果是在很大程度上节省了为两个设备开发的成本。
我移植了两个应用程序,一个只需要简单地重新编译,另一个只花了结果几个小时来解决平台之间的微弱不同。
开发独立的应用程序时你有更大的灵活性,这类应用程序往往更加牢固,并能用于连接和不连接的模式。
对多数商业应用,独立的应用程序也许是最好的选择。
它们在离线环境下使用,也提供了根据需要在远程系统间传递数据的机制。
此外,独立应用程序也可以使用特定设备的特性,包括技术特性和访问本地数据存储,例如PocketOutlook和WindowsCE数据库(CEDB)引擎。
当离线时,为了将来同步,数据可以被存储起来。
但是,独立应用程序面临着更多的分发和维护问题。
此外建立独立应用程序还需要C++经验,通常它的成本更高并难以找到开发者。
但是这种情况不会发生了,预计微软.NETCompactFramework和SmartDeviceExtensions最后将支持Smartphone。
如果这实现了,开发者可以使用C#和VisualBasic.NET等语言建立Smartphone应用程序。
数据检索
因为任何商业应用程序最基本的特性是检索数据,设计的部分问题围绕可用连接的类型。
你能依赖持续的连接或者连接可能中断吗?
你的系统只有一定的次数和访问点才需要连接吗?
Smartphone为从远程数据源检索数据提供了几种选择。
一种是ActiveSync,你可以使用它手动地在桌面计算机和Smartphone之间推/拉(push/pull)文档。
另一个选择是编程从PC上访问该设备并使用远程API(RAPI)复制文件。
虽然这些方法完成了任务,但是不是最好的选择。
Smartphone的内建互联网连接更好。
在Smartphone设备上通过互联网检索远程数据非常简单。
实际上,如果你已经开发了一个通过互联网检索数据的PocketPC应用程序,就已经知道所有需要的了。
在Smartphone上与远程服务器通讯的最简单的方法是WinInet功能(HTTP或者FTP)、在远程载入数据的XMLDOMAPI和微软互联网浏览器
XMLDOM给Web开发人员提供了几种数据检索的方法。
使用DOM你能通过两个主要的方法检索数据:
文档对象和XMLHTTP对象的Load方法。
两个对象都允许从远程Web服务器上的XML格式中检索数据。
两者之间最大的区别是XMLHTTP对象允许你传递一个XML对象作为调用的一部分,尽管Load命令没有允许。
在为了检索数据而需要传递数据的情况下,你应该使用XMLHTTP对象。
不管你在XMLDOM中使用那种方法,只需要在代码中作一点点更改。
首先你必须包括正确的头文件:
#include
namespaceMSXML
{
}
objsafe.h和ocidl.h都是必须的,因为它们包含GUID描述,而GUID是与COM一起工作的指针必须的。
为了使COM调用进入MSXML分析程序,你必须建立MSXML名字空间并包含msxml.h。
此外,为了项目编译正确,你应该把ole32.lib和oleaut32.lib库添加到连接程序设置中。
一旦代码使用XMLDOM,你能简单地使用DOMDocument的load方法从远程服务器检索数据。
该方法只需要一个能找到并检索数据的URL。
它在文档中重复构建窗体上的一个微调控件(spinnercontrol)。
完成后它显示一个包含整个XML文档的消息框。
MSXML:
:
IXMLDOMDocument*iXMLDoc=NULL;
IXMLDOMParseError*pParsingErr=NULL;
IXMLDOMElement*iXMLElm=NULL;
IXMLDOMNodeList*iXMLChild=NULL;
IXMLDOMNode*iXMLItem=NULL;
shorttEmpty;
BSTRbStr;
VARIANTvXMLSrc;
HRESULThr;
HWNDhListBox;
longlLength;
hr=CoInitializeEx(NULL,COINIT_MULTITHREADED);
if(!
SUCCEEDED(hr))return0;
hr=CoCreateInstance(MSXML:
CLSID_DOMDocument,
NULL,CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER,
MSXML:
IID_IXMLDOMDocument,(LPVOID*)&
iXMLDoc);
if(iXMLDoc)
iXMLDoc->
put_async(VARIANT_FALSE);
//Smartphone2002工作区:
//删除文档安全选项
IObjectSafety*pSafety;
DWORDdwSupported,dwEnabled;
if(SUCCEEDED(iXMLDoc->
QueryInterface(
IID_IObjectSafety,(void**)&
pSafety)))
{
pSafety->
GetInterfaceSafetyOptions(
IID_IXMLDOMDocument,&
dwSupported,&
dwEnabled);
SetInterfaceSafetyOptions(
IID_IXMLDOMDocument,dwSupported,0);
}
VariantInit(&
vXMLSrc);
vXMLSrc.vt=VT_BSTR;
vXMLSrc.bstrVal=SysAllocString(L"
http:
/localhost/
smartphonearticledata.xml"
);
hr=iXMLDoc->
load(vXMLSrc,&
tEmpty);
SysFreeString(vXMLSrc.bstrVal);
get_documentElement(&
iXMLElm);
iXMLElm->
selectNodes(L"
//DATA/STATUS/S"
&
iXMLChild);
//iXMLElm->
get_childNodes(&
iXMLChild->
get_length(&
lLength);
hListBox=GetDlgItem(hWnd,IDC_LISTISSUES);
for(intx=0;
xget_item(x,&
iXMLItem);
iXMLItem->
get_text(&
bStr);
SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)bStr);
//iXMLChild->
get_item(1,&
get_xml(&
MessageBox(NULL,bStr,TEXT("
ArticleDemo"
),MB_OK);
本地存储数据
在检索数据到Smartphone后,下一步是研究在设备上本地存储数据的方法。
一种选择是根本不保存。
你可以检索数据,执行一些操作,接着从内存中释放数据。
不幸的是在大多数情况下没有这么简单,因此你不得不决定适合应用程序的格式。
你也许会保存数据到文件存储(例如闪存卡),或者保存在本地的数据存储(例如CEDB)中。
对于多数商业应用程序,你需要把数据保存在文件系统中。
尽管能够将数据写入RAM文件系统,但是并不推荐这样使用,因为当设备关闭或掉电时所有数据都会丢失。
对于持续的存储器,Smartphone设备提供作为IPSM内存控件的闪存文件系统。
在多数Smartphone上空间受到限制,但是许多设备包含一个存储卡槽,允许使用可移走的存储卡。
编程决定Smartphone上在哪儿存储数据很简单,这得感谢你在WindowsCE平台上进行开发所熟悉的一些API。
这些调用可以在WindowsShellAPI文档中找到。
现在我将聚焦于SHGetSpecialFolderPath函数。
该函数允许你访问主要的Smartphone文件系统并在运行时检索完整的路径。
在检索路径后,你能使用该路径存储与应用程序相关的数据。
该函数需要一个CSIDL_常数作为输入参数。
这些常数反映了Smartphone操作系统中的共有文件夹(应用程序数据、收藏夹、程序、开始等等)。
因为这些公共区域也许在不同设备上,CSIDL常量提供了一个唯一的系统标识来识别这些目录。
推荐客户应用程序在CSIDL_APPDATA常量返回目录的子目录中保存数据。
例如:
#ifdefCSIDL_APPDATA
SHGetSpecialFolderPath(NULL,szFolderPath,CSIDL_APPDATA,TRUE))
ASSERT(FALSE);
hr=HRESULT_FROM_WIN32(GetLastError());
#else
//PocketPC没有这种定义来在根中读取目录。
//也许未来会作些改变,但代码仍然可以工作
_tcscpy(szFolderPath,TEXT("
\\"
));
#endif
我先前讲到,有些设备需要附加存储卡。
与你的桌面计算机的硬盘驱动器不同,Smartphone没有为存储卡分配驱动器符号。
作为代替,操作系统在根目录中建立目录来表现每块存储卡上的不同部分。
为了访问一个设备中的不同卡,使用FindFirstFlashCard和FindNextFlashCard函数。
如果找到了存储卡,FindFirstFlashCard返回一个指向第一块存储卡的句柄和指针。
如果句柄是正确的,你可以把它传递给FindNextFlashCard,该函数将返回下一块存储卡的指针和一个BOOL值来表明搜索是否成功。
一旦你找到了希望使用的存储卡,下一步就是查找一个位置来存储数据。
在访问设备上的文档时通常使用SHGetDocumentsFolder函数。
它可用于新的或者原来的存储卡。
下面是使用SHGetDocumentsFolder的一个例子:
TCHARszDocPath[250];
if(!
SHGetDocumentsFolder(L"
szDocPath))
MessageBox(NULL,L"
RetrieveingPathFailure"
L"
CallFailure"
MB_OK);
else
MessageBox(NULL,szDocPath,L"
DocumentsFolderPath"
模拟器笔记:
Smartphone模拟器不支持存储卡。
它也不支持附加在运行模拟器的PC上的真正的存储卡。
数据库操作
对于几乎所有商业应用程序来说,把数据保存到本地数据库是必要的,对于许多Smartphone应用程序也是这样。
与WindowsCE和PocketPC相比,Smartphone上数据库的选择只有少许的不同。
对于第一个Smartphone版本Smartphone2002,只支持本地WindowsCE数据库,目前它不支持SQLServerCE或者PocketAccess。
此外访问WindowsCE数据库的唯一选择是使用包含在WindowsCE3.0中的数据库API。
不过访问WindowsCE数据库的代码与为WindowsCE设备所写的代码几乎相同。
同步数据
在使用完连接并处理数据后,下一步就是与远程数据存储同步。
因为我已经介绍过使用XMLDOM通过互联网检索数据,我将继续使用该模型并将改变通过XMLHTTP对象发送回远程服务器。
在介绍使用XMLHTTP的细节前,我们看看Smartphone怎样使用Web服务。
目前,在Smartphone平台上没有内建库或组件提供SOAP客户端功能。
但是Smartphone的SOAP客户端并不在可能的范围之外,因为Smartphone2002SDK支持所有可能需要的组件。
如果Smartphone上需要SOAP客户端,我建议查看第三方库,它也许能移植到Smartphone而没有太多问题。
此外你应该记得一旦Smartphone上的.NET简洁框架组件可以使用,就能使用Smartphone客户端的功能了。
从Smartphone向远程数据存储同步数据的第一步是从主存储器中检索所有改变了的数据并转换为XML格式。
完成后,实例化XMLHTTP对象并把数据传递到处理同步的特定URL。
先前讲到,因为XMLHTTP对象拥有使用XML格式发送信息到远程服务器的能力,在这儿它将被使用到。
XMLHTTP对象是前面的项目中包含的MSXML库中可用的另一个对象。
图4是该对象的使用。
它很容易使用,从IXMLHttpRequest接口中建立了一个对象。
此外,建立一个VARIANT来保持IXMLDOMDocument对象。
为了传递这个复杂的类型,VARIANT必须通过VT_DISPATCH类型设置。
剩下的步骤是调用XMLHTTP对象的open和send方法。
IXMLHttpRequest*iXMLHttp=NULL;
BSTRbStr=NULL;
VARIANTvUserID;
VARIANTvPassword;
VARIANTvPassValue;
VARIANTvAsync;
CLSID_DOMDocument,NULL,
CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER,
//Smartphone2002工作区:
QueryInterface(IID_IObjectSafety,
(void**)&
loadXML(L"
Joe
Smith"
&
VariantInit(&
vAsync);
vAsync.vt=VT_BOOL;
vAsync.boolVal=false;
vUserID);
vUserID.vt=VT_BSTR;
vUserID.bstrVal=L"
"
;
vPassword);
vPassword.vt=VT_BSTR;
vPassword.bstrVal=L"
vPassValue);
vPassValue.vt=VT_DISPATCH;
vPassValue.pdispVal=iXMLDoc;
if(!
CLSID_XMLHTTPRequest,NULL,
IID_IXMLHttpRequest,(LPVOID*)&
iXMLHttp);
iXMLHttp->
open(L"
GET"
L"
//localhost/smartphonesavetest.asp"
vAsync,vUserID,vPassword);
hr=iXMLHttp->
send(vPassValue);
get_responseText(&
访问电话特性
通过WindowsCEAPI,开发人员能简单地给应用程序添加电话功能。
类似自动拨号、与调用日志交互、访问SIM卡的能力、发送和接收SMS消息等等特性可以简单地添加到应用程序。
为了工作正常,大多数技术API需要真实的设备或者GSM无线设备连接到模拟器,因此如果你计划开发这些类型的特性,准备好测试真实的设备。
电话特性的一个最简单的例子是在应用程序中建立语音通话。
因为我们有随着Smartphone一起发布的辅助TAPI,只需要一行代码。
所有需要作的是在代码中包含astdtapi.h文件,在连接程序设置中添加cellcore.lib,并调用tapiRequestMakeCall函数:
TCHARszDefaultNum[]=TEXT("
+1(555)555-5555"
LONGlResult;
lResult=tapiRequestMakeCall((LPTSTR)szDefaultNum,NULL,NULL,NULL);
returnTRUE;
发送SMS消息也很简单。
有了辅助TAPI,你只需要在代码中添加一个文件引用(sms.h),在连接程序设置中添加一个库(sms.lib)。
发送或者接收消息的第一步是调用SmsOpen函数,下一步初始化源和目的地址,完成后调用SmsSendMessage函数。
最后一步是调用SmsClose函数清除建立的SMS_HANDLE。
代码见图5。
SMS_HANDLEsmshHandle;
SMS_ADDRESSsmsaSource;
SMS_ADDRESSsmsaDestination;
TEXT_PROVIDER_SPECIFIC_DATAtpsd;
SMS_MESSAGE_IDsmsmidMessageID;
//尝试打开一个SMS句柄
if(FAILED(SmsOpen(SMS_MSGTYPE_TEXT,SMS_MODE_SEND,&
smshHandle,NULL)))
CalltoSmsOpenfailed."
Error"
MB_OK|
MB_ICONERROR);
return;
//建立源地址
bUseDefaultSMSC)
smsaSource.smsatAddressType=SMSAT_INTERNATIONAL;
_tcsncpy(smsaSource.ptsAddress,lpszSMSC,SMS_MAX_ADDRESS_LENGTH);
//建立目标地址