《Comms和消息传送.ppt》由会员分享,可在线阅读,更多相关《Comms和消息传送.ppt(78页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第十二章 Comms和消息传送 1完成本章内容之后我们将能够:掌握Symbian OS 的通讯架构了解多媒体短信业务(MMS)本本 章章 目目 标标2 本章概述了Symbian OS提供的comms工具,并详细研究了用于消息传送,特别是用于发送和接收多媒体消息(MMS)的API。3概述 Symbian OS上的comms开发可从3个主要方面考虑:l开发与通信硬件(比如串口或电话硬件)对话的驱动程序。这一类型的开发在手机生产时由手机开发商承担。Symbian提供与某些特定的基准硬件(如Intel Lubbock板)一起工作的驱动程序,它可用于开发其中的真正手机硬件和驱动程序。l开发协议实现,如用
2、于访问Web的HTTP实现,或用于红外线协议的红外线。手机开发者和第三方可以开发协议实现,并扩充到Symbian OS已经提供的部分中。4概述l开发使用有效协议的应用程序:手机开发者提供具有基本通信应用程序的手机,如电话和消息传送等应用程序。不过,很多领域中的应用程序可以受益于与通信的集成,其中包括游戏它可以通过多玩家通过本地通信协议(如蓝牙)或通过2.5G电话网络上的包数据进行比赛,从而实现交互。企业应用与专用应用程序服务器通信。5概述通信组通信组目前可用的通信组件包括:l串行通信框架。l套接字框架。l电话框架。lTCP/IP栈。l蓝牙栈。l红外线栈。lSMS和EMS栈。6概述lWAP栈。l
3、HTTP传输框架。lTelnet和FTP引擎。l消息协议支持,包括MMS、SMTP、POP3和IMAP4。这些组件提供了应用程序可访问的API。7概述CommsComms及平台及平台 如同其他领域的Symbian OS开发,在进行comms相关的工作时,需要了解什么是Symbian OS提供的,什么是UI平台增加的,比如Series 60和UIQ。基本原则是:Symbian OS提供实现特定通信协议的引擎组件,并向这些引擎公布API;UI平台提供使用这些引擎的应用程序。例如,Symbian OS提供了实现因特网电子邮件协议的组件,而UIQ和Series 60提供允许用户发送和接收电子邮件的消息
4、传送应用程序。8OS Comms架构要理解Symbian OS的comms,需要理解所提供通用框架和插入这些框架的特定协议的实现。本节首先从框架着手。每种关键框架都使用了Symbian OS的客户端服务器架构。在这种架构中,后台运行的程序(服务器)为其他多个程序(客户)提供服务。当手机上的多个客户程序需要访问一些公共资源时,会选择这种方案。服务器的任务是控制对资源的访问。对于底层的comms服务器,所讨论的资源可能是一个硬件资源,比如串口。资源也可以是共享的数据,比如消息的存储。9 尽管框架通常具有服务器本身之外的其他要素,如实用工具类的库,但提到整个框架时,通常还是简称为服务器。某些情况下,
5、API使得客户端服务器架构的运用变得显而易见。例如,使用电话功能时,基本的任务就是创建一个RTelServer对象,它提供与电话服务器的初始连接(Symbian OS约定就是和RTelServer类似的API类,它用于访问以R开头的服务器)。如消息等其他API,提供广泛的客户端类,从客户程序中隐藏了客户端服务器接口的直接使用。OS Comms架构10 核心服务器如下:l套接字:利用TCP/IP等协议,提供可寻址端点之间的通信。自Symbian OS的第一版起,即成为它的一部分,7.0增加了一个新的API,用于创建和管理连接。l串行comms:提供简单串行连接之上的通信,如用于处理RS232。l
6、消息传送:利用因特网电于邮件和SMS这类协议,提供消息的发送、检索和存储。l电话:提供电话呼叫及服务的控制,以及对电话功能配置的控制。OS Comms架构11套接字套接字 套接字的概念首次出现于加州大学伯克利分校的Unix伯克利软件发行中心(BSD),它是以C语言写的一个API。自此之后,套接字常见于很多操作系统和语言中。套接字代表一个通信“信道”的逻辑端点。它是物理机器的网络地址和逻辑端口号的组合,另一个套接字可以给它传输数据。因为套接字由机器地址和端口号确定,所以在一个特定的计算机网络中,每个套接字是惟一标识的。这就允许应用程序惟一地识别网络中与其通信的另一位置。OS Comms架构12
7、套接字通常用于在运行因特网协议(IP)的网络上进行通信。这时机器地址就是一个IP地址,端口将指定一些因特网应用程序,如Web或FTP。与其他操作系统的套接字相比,Symbian OS实现的套接字有两个主要不同:l套接字可用于访问多种协议,而不仅访问TCP/IP。其中包括蓝牙协议L2CAP和 RFCOMM,以及红外线协议IrDA、IrTinyTP和IrMUX。lAPI用C+编写,与传统的BSD C API不同。如果考虑必须使用C API,例如向其他操作系统移植代码时,可以考虑Symbian OS的C标准库(STDLIB)实现中可使用的C API。OS Comms架构13 用于套接字的Symbia
8、n OS C+API是套接字客户API,发布在头文件es_sock.h和库文件esock.dll中。与套接字服务器的客户接口由RSocketServ提供,套接字本身由RSocket封装。套接字的客户API异步调用套接字服务器,它协调客户端访问套接字服务,并管理与协议模块的通信,这些协议模块提供了对特定网络协议的支持。协议模块是插件DLL,服务器根据需要进行加载和卸载。OS Comms架构14 除与套接字连接,并读写数据外,API还提供了对其他工具的访问:l主机名解析(RHostResolver):一些网络类型能够在适合于给最终用户显示的符号主机地址与协议内部使用的数字地址之间转换。在TCP/I
9、P中,主机名解析服务就是域名服务(DNS)。对于蓝牙和红外线,解析接口可用于发现其他哪些设备在范围内,并可使用这些协议进行通信。通过RHostResolver对象产生的查询打包在TNameEntry描述符中,它保存了包含主机名和地址的TNameRecord对象。OS Comms架构15l协议信息(TProtocolDesc):可以查询手机上支持哪些套接字协议,并可以得到每个协议的信息,比如协议名称和用于表明其性能的标志。l套接字API还提供了下述功能,它们可能用得比较少:l网络数据库访问(RNetDatabase):用于访问关于设备的数据库。对于红外线,存在IrDA信息访问服务(IAS)这种服
10、务。它与TCP/IP或蓝牙没有关联。l服务解析(RServiceResolver):用于查询远程设备的性能,也就是说,该设备在相应的协议上可以提供什么服务。它不是为了TCP/IP、蓝牙或红外线而实现的。蓝牙标准中有种服务,即蓝牙业务搜寻协议(SDP),但是Symbian OS蓝牙设备没有为此使用套接字API,因为它有自己专门的SDP API。OS Comms架构16 在Symbian OS V7.0s以前的版本中,如何构建网络连接以实现套接字请求,套接字客户API的调用者不必关心。连接是隐式建立的,举例如下。例如,应用程序请求与某个远程地址的TCP套接字。与管理网络接口(NIFMAN)相关的S
11、ymbian OS组件检查没有已存在的网络连接。它就读取通信设置项数据库(CommDb),了解怎样建立连接。例如,设置项可以指定拨号连接到某个服务提供商(ISP)。调用能够完成拨号的其他组件,并利用适当的协议(如PPP)连接到ISP。建立连接的所需设置,如ISP的电话号码和登录信息,也保存在通信数据库中。OS Comms架构17 诸如W-CDMA和最新版本的GPRS等技术都可以在一个连接中建立多个子连接。这在v7.0s中是由连接管理接口RConnection来支持的。它向客户提供创建、配置和监视连接与子连接的功能。OS Comms架构18串行通信串行通信 串行通信比套接字要简单一些。数据从手机
12、的一个端口简单地写入和读取,而不需要连接许多可能的设备及其服务。习惯上,当Symbian OS设备通过一根电缆或红外线连接到PC进行同步,或连接到外部调制解调器,此时使用这种方式。与套接字类似,Symbian OS串行comms的实现使用了一个服务器,它可以加载插件模块来处理特定的通信协议。这些插件模块称做CSY模块,它们被串行通信服务器加载,客户应用程序不能直接访问。OS Comms架构19 Symbian OS手机可能包括许多CSY模块作为标准配置,比如用于处理RS232和红外线串口通信的模块。串口协议模块API允许开发新的CSY模块。通过服务器会话类RCommServ,可以找到手机上可用
13、的串口以及它们的协议。一旦选定了要用的端口,就可以通过串口接口RComm访问它。该类用于读、写、配置、设置中断条件和得到端口状态信息。OS Comms架构20 通常,使用端口前,要先设置其配置。这包括设置数据速率、奇偶类型和握手控制等。这些设置保存在一个TCommConfigV01类型的串口配置块中。在配置串口前,可以先检查它的性能,以保证所需配置是可行的。该串口的性能由一个TCommCapsV01类型的对象进行封装。OS Comms架构21消息传送消息传送 Symbian OS的消息传送组件为多协议消息传送提供了一个框架,并且支持特定的消息传送协议。消息传送为建立高性能消息客户应用程序以及创
14、建用于支持个别消息传送协议的插件模块提供了可能。建立这种插件模块的组件集合叫做消息类型模块(MTM)。与底层通信协议(如TCP/IP)的所有交互均由MTM完成。OS Comms架构22 消息传送架构提供了一些基类,这些基类定义了用于MTM实现的组件接口。利用基类按口,允许客户应用程序发现并动态使用可用的消息传送协议。协议提供者为他们的MTM实现开发新库。这些实现在协议需要时访问底层通信库。OS Comms架构23消息服务器消息服务器 消息服务器控制对消息数据的访问,并将协议相关的请求委托给服务器端MTM。由服务器保存的每条消息部有一个TMsvId类型的整型标识符。一条消息的状态(例如是否可读或
15、不可读)和一些常规属性对大多数消息是公用的,如日期和主题保存在头部数据对象中,需要通过TMsvEntry类访问。消息还可以具有:l一个文件存储:保存消息正文文本、协议相关的数据:它由CMsvStore类封装。l一个目录:可存放相关文件(如消息附件)OS Comms架构24 总体上,消息从ID、头部、存储和文件目录,都可以访问和操作,并由CMsvEntry封装。除消息本身之外,服务器还保存代表服务和文件夹的记录。一个服务就是一个收集设置信息的有用抽象。例如SMTP,服务将为邮件帐户指定设置。文件夹保存记录组(消息和其他文件夹)。其中某些文件夹,如收件箱和草稿箱,总是存在并且在消息服务器首次启动时
16、创建。用户也可以创建自己的文件夹。消息以树形结构保存,与文件系统的目录树形式类似。树中的每条记录代表一个服务、消息文件夹或消息部分。图8-1给出了一个实例。OS Comms架构25OS Comms架构图8-1 消息存储26树可以分解为三级:l根记录:只是用来表示将树结构捆绑在一起。l服务记录:有一个本地服务,在它下面保存文件夹和消息,还有零或多个远程服务。远程服务代表消息账号。l消息和文件夹记录:本地服务下的消息和文件夹代表存储在设备上的消息。远程服务下的消息和文件夹代表远程服务器上存在的消息在本地的副本。例如,在POP3电子邮件服务下面,会有POP3电子邮件服务器上存在的所有消息的副本;而在
17、SMS服务下面,可以找到SIM上保存的SMS消息。OS Comms架构27MTMMTM基类基类 MTM基类是提供消息传送协议支持的子类,可以认为有四个类。用户接口MTM(CBaseMtmUi)提供用户接口操作,其中包括:l创建:运行消息编辑器并打开一条新消息。l编辑:如果记录是一条消息,则装入编辑器;如果记录是一个服务,则编辑设置。l浏览:为消息运行浏览器。l显示操作的进度。OS Comms架构28 客户端MTM(CBaseMtm)提供一个通用接口来操作消息数据。该类定义的函数可以用于:l创建消息。l回复消息。l转发消息。l增加删除地址。l增加删除正文文本。l增加删除主题。l增加删除附件。OS
18、 Comms架构29 UI数据MTM(CBaseMtmUiData)提供对特定UI MTM相关资源的访问。它包括:l用于消息服务器记录的MTM相关图标。l用于MTM相关操作的用户界面文字,例如菜单。l信息函数,用于检查MTM函数是否适用于某条记录。OS Comms架构30 最后,服务器端MTM(CBaseServerMtm)提供了通过相关通信协议对远程服务的消息传输,它的功能包括:l移动或拷贝当前处于远程服务下的记录。l从本地服务移动或拷贝到远程服务下的一个目的地。l创建、删除或修改远程记录(如果协议允许操作远程服务器上的消息)。l实现MTM相关命令。例如,同步化记录与远程服务器上消息的命令。
19、OS Comms架构31注册注册 MTM必须用消息服务器注册。这就允许客户查询当前是什么类型的MTM,服务器可以知道哪些DLL要加载,以创建一个给定的MTM组件。通过为每个MTM提供一个资源文件来完成注册。注册类允许标识和实例化MTM组件。关键的类是CClientMtmRegistry和CmtmUiDataRegistry。OS Comms架构32SendAsSendAs 该接口的使用很简单,它允许应用程序创建发出的消息。注意,并不是像接口的名字的含义那样,SendAs提供的API只能创建而不能发送消息。使用SendAs时,它首先向调用者提供一个所有支持发送消息的已注册MTM列表。然后,应用程
20、序可以对MTM列表增加更多的限制:例如,可以要求MTM支持附件或确定的消息大小。SendAs按这些附加的条件查询每一个MTM,并从列表中移除那些与条件不匹配的MTM。应用程序完成条件的增加之后,选择留在列表中的一个MTM,并用它构建消息、添加地址、标题、正文文本和附件。OS Comms架构33 基本接口由CSendAs和MSendAsObserver提供。但是,还存在“引擎”API,它们不为创建和发送消息提供可以简单添加到应用程序中的用户接口。不过,用户接口平台确实提供了包装器类来达到这一目的,它们是:lUIQ API:CqikSendAsDialog。lSeries 60 API:Csend
21、AppUi。OS Comms架构34规划发送规划发送 规划发送功能为客户提供了能够将消息发送安排在稍后某一时刻,而不是立即发送。它允许为规划消息、删除规划、重新规划和核对规划。它还提供针对性的状态信息,如消息目前是否已规划、正在发送或失败等。MTM可以选择是否为规划提供支持。要支持规划,服务器MTM必须派生于CscheduleBase ServerMtm。服务器MTM使用另一个叫做任务规划器的Symbian OS组件,它可以负责在指定时刻启动指定的动作。与任务规划器的接口由CMsvScheduleSend封装。OS Comms架构35电话电话 移动电话是一个包含很多用于手机服务、网络和硬件标准
22、的复杂领域。Symbian OS提供的电话API及其框架希望通过提供与手机功能的公共接口来减少这种复杂性,而不必关心下层硬件或网络。电话API使用Symbian OS客户端朋艮务器框架,并提供向电话服务器发送请求的R类。服务器反过来将请求传递给管理物理设备的适当电话驱动器插件。OS Comms架构36 手机制造商利用电话API提供手机上的电话应用程序,使用户能够拨打电话及设置服务选项。除了这个用途,电话API可认为是低层次的,主要用于其他更高级的comms组件。例如,套接字一节讲述了要求连接套接字的应用程序请求如何最终拨号连接到ISP。如果确实需要从应用程序中直接使用电话,你会发现一个难题:授
23、权商通常选择在他们的SDK中不暴露过多的高级电话API。所以,除非你是授权商或Symbian的合作伙伴,否则应用程序有可能不能访问所有的手机电话功能。OS Comms架构37 然而,SDK确实暴露了两个应用程序编程者通常感兴趣的API:ETel Core和Third PartyTelephony。ETel Core定义了一组几乎所有电话设备和服务都支持的核心函数。应用程序可以直接使用它来访问通用电话设备。该API可细分为四个主要的类,它们分别封装了与电话服务器、手机、线路和呼叫的会话。l会话类RTelServer:提供了对系统电话信息的访问,特别是可用的手机和TSY。l手机类RPhone:对特
24、定的电话设备进行抽象化。它允许客户访问设备的状态和功能,并在它们改变时得到通知。OS Comms架构38l线路类RLine:代表属于手机的一条线路。客户可以访问线路的状态和功能,并在它们改变时得到通知。l最后,线路可以有零或多个激活的呼叫,呼叫由RCall类进行封装。呼叫具有拨号、等待呼入以及挂机等功能。前面一样,客户可以取得状态和功能的信息,并在它们改变时得到通知。OS Comms架构39 可见,ETel Core具有相当直接和合理的结构,而它的功能封装却比较简单。Third Party Telephony API也是如此,它为电话数据呼叫提供了一个高级接口。它允许此API用户发出电话呼叫、
25、等待呼入或检查线路状态。此API有单独一个类CTelephony。调用者将一个RComm(串口)对象传递给CTelephony对象,当呼叫建立后,它利用该对象读写连接上的数据。OS Comms架构40高级高级APIAPI 现代移动电话标准提供的功能远不止接打电话。Symbian OS对基本ETel Core API提供了扩展,以支持对这些高级性能的使用。不过,如前所述,这些扩展在SDK中可能不提供。主要的高级API是ETel Multimode,它扩展了ETel Core API,以提供对用于多种空中接口蜂窝标准(或模式)的公共移动电话服务的访问。在v7.0s版本中,模式有GSM、GPRS、E
26、DGE、CDMA(IS-95)、3GPP2 cdma2000 1x(版本A)和3GPP W-CDMA。该API还为用于特定标准的专用服务(如GSM)提供访问。OS Comms架构41其他高级电话API有:lETel Multimode Packet Data:提供用于电话包数据标准的公用API,如GPRS、CDMAOne和CDMA2000中的包数据。lSIM应用程序工具箱:提供一个API,用于访问由手机SIM卡提供的功能。l完成电话API的综述前,还要提到几个不太重要的API:l拨号:提供拨号相关的实用工具,如处理电话号码。l电话簿同步器:同步化Symbian OS手机上的两种地址信息存储,即
27、手机ICC(在GSM手机上称为SIM卡)上的电话簿和联系人数据库。OS Comms架构42最后,对传真的支持也和电话API紧密相关:lETel传真客户用于运用Symbian OS传真存储文件收发传真。Faxio API为传真编码和压缩提供库。Fax存储API用于l访问存储的传真。随着电话框架的介绍,结束了对Symbian OS comms架构中最重要组件的综述。现在可以进一步介绍该架构所开发的很多具体comms协议。OS Comms架构43 多媒体消息传送业务是开放移动联盟(最初由WAP论坛)定义的个标准,用于发送和接收具有丰富内容的消息,通过移动电话网络,从用户发送到服务器,再发送到用户。M
28、MS操作通过拨号(CSD)或GPRS连接,并使用WAP或HTTP进行消息的传输和通知。MMS消息本身与MIME电子邮件消息类似,它们包含定义消息属性的头部,还包含理论上可以是任何媒体类型的MIME正文。实际上,希望的MMS消息格式是MIME内容类型:多部分关联。MMS44 例如,消息包含一些多媒体对象,如图片、声音和文字。第一个对象应该是一个同步多媒体语言(SMIL)文件,个向客户提供关于如何呈现消息中其他媒体对象的XML文档。如前所见,Symbian OS设备之间存在兼容性问题的不仅仅是comms,MMS的实现在一般性Symbian OS、UIQ中的使用和Series60之间也不同。这里所描
29、述的API都是Symbian版本。对于Nokia版本,参见Series 60 SDK文档的“Desigming MMS Client Applications for the Series 60Plateform(为Series 60平台设计MMS客户应用程序)”。MMS45MTMMTM及及APIAPIMMS:实现是通过消息传送框架的插件来提供的,其中有些支持实用工具库:lMMS客户MTM为MMS消早的创建、检索、发送、转发和回复等操作提供接口。lMMS服务器MTM调用低层comms组件来发送和接收MMS消息。它不具有客户接口。lMMS。实用工具库提供了封装MMS消息及消息头部和媒体对象等部分
30、的类。MMS46 这些库不提供任何可供显示和编辑MMS消息的功能,也不提供其他任何用户接口操作。不过,有一个库可以用来解析SMIL文档。实际上,如果将问题复杂化,可以说有两个这样的库。一个原始库,称做SMIL解析器和设计器,(smiltranslator.lib),它是为v7.0s制作的。v7.0s实际上对此方法进行了改进,使其更加灵活,具有处理各种特定DTD的XML,文档的能力。此API称为消息传送XML支持API。v7.0API仍然可用,但如果编码新代码,则最好使用新API。MMS47 现在将完成一些涉及使用消息传送框架和MMS API来发送和接收MMS消息的任务。这些任务是:l连接消息服
31、务器。l获取客户MTM。l创建消息。l设置消息内容和属性。l发送消息。l接收消息。MMS48服务器会话服务器会话 消息传送框架围绕一个服务器程序为基础,在执行消息传送之前,必须建立与它的连接(会话)。会话类叫做CMsvSession,消息客户应用程序在启动时通常创建该类的一个实例。客户端MTM实例、用户接口MTM和高层客户库类维护对消息客户应用程序的会话对象的引用,以便在需要时,它们可以向服务器发出请求。MMS49/创建消息服务器会话iMsvSession=CMsvSession:OpenSyncL(*this);OpenSyncL()方法接受一个MMsvSessionObserver类型的参
32、数,所以,为使该代码工作,包含的类必须实现这个观察器接口。它使服务器能够呼叫客户,向它通知重要事件,如注册个新MTM。MMS50客户MTM 应用程序不能直接为它希望使用的MTM创建对象,它必须请求消息服务器为它创建该对象。所有安装在机器上的MTM组件的记录保存在一个由消息服务器管理的专用注册文件中。注册类利用此注册数据标识和实例化MTM组件。例如,CClientMtmRegistry类有一个成员函数可用于创建客户端MTM对象:l消息客户应用程序调用该函数,传递它需要的MTM组件的UID。lCClientMtmRegistry搜索所需MTM组件的记录注册,并从中获得库名和可刨建MTM对象的库导出
33、工厂函数的序数。lCClientMtmRegistry加载DLL,并调用工厂函数,将新对象传回调用者。MMS51 类似的处理用于用户接口和UI数据MTM。这样的MTM对象由创建它们的客户拥有。客户还负责删除这些对象。在当前示例中,需要MMS客户MTM,因此要利用CClientMtmRegistry:/创建客户注册对象iClientMtmRegistry=CClientMtmRegistry:NewL(*iMsvSession);MMS52/请求MMS客户MTM对象iMmsClientMtm=(CMmsClientMtm*)iClientMtmRegistry-NewMtmL(KUidMsgTy
34、peMMS);注册NewMtmL()函数返回一个指向客户MTM基类CBaseMtm的指针,将它转换成MMS客户类CMmsClientMtm。MMS53消息创建和删除消息创建和删除 在创建新消息前,需要决定在哪里存储它。通常创建新记录的地方是草稿文件夹。客户端MTM具有当前项或上下文的概念,在此进行操作,因此需要将当前项设置为草稿文件夹。也许你还记得前面讨论的消息结构,每个项均有一个标识符用以查阅。草稿文件夹的标识符是KMsvDraftEntryld,在API中公开。下面的调用将当前项设置为该文件夹:MMS54/设置草稿文件夹的上下文iMmsClientMtm-SwitchCurrentEntr
35、yL(KMsvDraftEntryId);在创建消息前,还需要设置它属于什么服务。可以通过编程方式发现哪些服务是可用的。下面的代码使用了消息项ChildrenWithMtmL()函数来请求消息根项下MMS类型项的列表。由于服务都存储在根下,这样将得到一个MMS服务的列表。MMS55/获取消息服务器根项CMsvEntry*root=CMsvEntry:NewL(*iMsvSession,KMsvRoot IndexEntryId,TMsvSelectionOrdering(KMsvNoGrouping,EMsvSortByOescriPtlon);CleanupStack:PushL(root)
36、;/获取根的所有MMS类型的子项IDcmsvEntrySelection*Services=root-ChildrenWithMtmL(KUidMsgTypeNMS);CleanupStack:PushL(Services);MMS56/如果无MMs服务则退出if(services-Count()=0)User:Leave(KErrNotFound);该代码得到MMS服务的ID列表,如果没有可用的MMS,服务将退出。消息传送还具有默认服务的概念,除非用户指定了其他服务,否则将使用默认服务。默认服务设置可通过类CMsvDefaultServices找到。它们存储在与根项关联的消息存储器中。下面的
37、代码从这个存储器中读取默认服务设置,并获得serviceld中默认MMS服务的ID。MMS57CMsvDefaultServices*services=new(ELeave)CMsvDefaultServices;CleanupStack:PushL(services);TMsvId serviceId;if(root-HasStoreL()/如果根具有存储器,则恢复默认的服务CMsvStore*store=root-ReadStoreL();CleanupStack:PushL(store);services-RestoreL(*store);CteanupStack:PopAndDestr
38、oy();/存储器 MMS58TInt error=services-DefaultService(KUidMsgTypeMMS,serviceId);CleanupStack:PopAndDestroy();/服务 经过这些准备之后,就可以直接创建消息了:/创建新消息项iMmsClientMtm-CreateMessageL(serviceId);还可以分别用CMmsClientMtm:ForwardL()和CMmsClientMtm:ReplyL()通过转发或回复已存在的MMS消息来创建新消息。在这些情形下,新消息创建时,从原始消息中拷入适当的内容和头。MMS59设置消息内容设置消息内容
39、下一项任务是设置消息的内容和头。客户MTM基类CBaseMtm定义了一些函数,大部分MTM均可以使用它们来完成这项任务:lSetSubjectL():设置消息主题。lBody():读取和设置正文文本。lAddAddresseeL():设置收件人。lCreateAttachmentL():添加附件。MMS60 然而,MMS消息的属性和内容比使用上述通用函数所定义的要复杂得多。因此,API在它的类CMmsClientMessage和基类CMmsMessage中提供了MMS消息的完整封装。该消息类拥有个对象,该对象封装了消息头CMmsHeaders和一个CMmsMediaObject对象列表,每个对
40、象均描述了一种多媒体对象,如SMIL或图像文件。MMS61 为了获取刚创建消息的CMmsClientMessge对象,使用如下调用:/将新项设置为一条MMS消息iMmsClientMessage=CMmsClientMessage:NewL(*iMsvSession,iMmsClientMtm-Entry()EntryId();这里,NewL()的第二个参数是MMS消息的ID。序列iMmsClientMtm-Entry()Entryld()要求客户MTM返回当前项的ID:因为CreateMessageL()函数设置当前项为新消息,返回新消息的1D。MMS62 CMmsClientMessage
41、对象承担舶第一项任务是设置消息头。,MMS规范定义了很多可以在MMS消息头中设置的字段。其中一些是强制性的,如消息类型、事务ID、MMS版本号、发件人地址、内容类型和至少一个收件人地址字段(To,Cc或Bcc)。除客户必须自行指定收件人外,MMS服务器MTM为所有强制字段给出了适当的值。这一过程相当直接,下例是为消息设置了一个To收件人(anewRecipient是一个指定地址的描述符)。MMS63iMmsClientMessage-Headers().AddRecipientL(CMmsHeaders:ETo,aNewRecipient);还可以设置可选字段。设置消息的主题:iMmsClie
42、ntMessage-Headers().SetSubjectL(aSubject);MMS64媒体对象媒体对象 消息的媒体内容通过添加一个或多个媒体对象来定义。媒体对象可以通过CMmsMessage:CreateMediaObjectL()添加。CreateMediaObjectL()返回另一个MMS实用工具类CMmsMediaObject对象。该对象指定了拷贝媒体数据(如图像或SMIL文件)的目标文件名。当添加媒体对象后,调用者就可以指定该对象为消息的“根”对象:通常是包含了其他对象表达的SMIL文件。下述代码添加一个根SMIL文件,其文件名在smilFile中指定。MMS65/要求创建MO
43、,传递根选项MIME类型和文件扩展名/文件的MIME类型_LIT(KSMILMIME,application/smil);/文件的扩展名_LIT(KSMILExt,.smil);CMmsMediaObject&newMO=iMmsClientMessage-CreateMediaObjectL (ETrue,KSMILMIME,KSMILExt);/将数据复制到媒体对象指定的目标文件err=BaflUtils:CopyFile(ifs,smilFile,newMO.Filename();MMS66 每个对象也有一个ID,即一个TMmsMediaObjectld,它可以作为一个句柄。调用者可以用
44、Id()方法恢复并存储它,以便以后引用。TMsvId smilId=newMO.Id();加入了所有的媒体对象后,基本上准备好发送消息了。在这之前,最后的任务是告知客户MTM已完成消息的修改。这样做保证了客户MTM本地所做的任何修改都已存入服务器的消息存储器。/将修改过的消息或新消息保存到(服务器端)的消息存储器iMmsClientMtm-SaveMessageL();MMS67发送消息 也许令人惊讶,客户MTM基类CBaseMtm并不提供发送消息的方法。然而,它为MTM提供了一种标准手段使MTM特有的功能可用。为此,MTM实现了两个虚方法InvokeAsyncFunctionL()(用于异步
45、操作)和InvokeSyncFunctionL()(,用于同步操作),或只实现其中一个方法。许多MTM利用这些函数提供了发送消息的命令,MMS通过InvokeAsyncFunctionL()来完成。MMS68函数的参数包括:l指定执行命令的参数。枚举TMmsMtmCmds定义了MMS MTM特有操作的ID:lKMmsMtmSendMessage是发送命令的ID。l要执行命令的消息ID。l可拥有可选参数的缓冲(这里不用)。l异步操作的常用请求状态参数。MMS69 下述代码开始发送数组ildToSend中列出的消息,数组的类型是CMsvEntrySelection。TBuf8param;/未使用/
46、异步发送消息CMsvOperation*msvOperation=iMmsClientMtm-InvokeAsyncFunctionL(KMmsMtmSendMessage,*iIdToSend,param,aCompletionStatus);MMS70 消息API的一个特性是,像这样完成异步操作的函数,返回一个CMsvOperation对象。这就允许调用者得到操作的进度信息(例如,发送了四条消息中的两条),并可取消该操作。发送消息的另一种方式是利用CMsvEntry:CopyL(),将消息从本地文件夹拷贝到远程服务项中。结束关于MMS的讨论前,再看看应用程序怎样处理到达的消息。MMS71到
47、达的消息到达的消息 消息传送架构声明了一对抽象接口,定义了会话观察器和数据项观察器。会话观察器必须实现接口MMsvSesionObserver,它得到新消息到达、新MTM注册等事件通知。数据项观察器实现了接口MMsvEntryObserver,当更改或访问各个数据项时,它得到事件通知。为了处理到达的消息,需要一个会话观察器类。接口只需实现一个函数:void HandleSessionEventL(TMsvSessionEvent aEvent,TAny*aArgl,TAny*aArg2,TAny*aArg3)=0;MMS72 TMsvSessionEvent参数说明发生了什么类型的事件:其他参
48、数根据事件类型,可以提供与该事件有关的数据。对于到达的MMS消息,两种事件类型需要处理:lEMsvEntriesCreated当通知新MMS消息到达手机时发生。aArgl是包含新数据顶的CMsvEntrySelection,而aArg2是父数据项的TMsvld。lEMsvEntriesChanged当取得消息正文并可运行或可显示时发生。该事件的参数同EMsvEntriesCreated。MMS73 由于MMS消息不一定需要完全从服务器上取得,所以有两个事件。而远程MMS服务器首先向手机发送一条通知,告知现有一条新消息。此时,SymbianOS MMS实现在消息存储器中创建一个新数据项,并设置那
49、些通知可用的头字段(其他字段保持空值)。随后,手机可以选择是否要获得消息正文(它的媒体对象)。MMS74 取得数据可以自动或按请求进行。MMS服务可以用方法CMmsSettings:SetAutomatiFetch()设置为自动取得完整的消息。未设置自动取得数据的地方,应用程序可以通过CMmsClientMtm:InvokeAsyncFunctionL(),利用KMmsMtmFetchMessage或KMmsMtmBackgroundFetchMessage命令明确地请求取得数据。可以通过检查TMsvEntry:Complete()标志是否为真,来检查消息是否己完全取得。MMS75 另一个需小
50、心的复杂之处是,观察器将接收所有类型消息的通知,而不仅仅是MMS。所以,处理MMS的代码需保证首先检查与MMS消息相关的事件。下列代码可以实现这一点,它假设entries是包含新数据项ID的CMsvEntrySelection。MMS76TInt count=entries-Count();while(count-!=0)const TMsvId id=(*entries)count;CMsvEntry*msvEntry=iMsvSession-GetEntryL(id);CleanupStack:PushL(msvEntry);if(msvEntry-Entry().iMtm=KUidMsg