SMS 短信发送过程(仅供病毒分析时参考)

消息基本单位是条目Entry.
--------------------------关键类-----------------------------------
1. CMsvSession
该类代表客户端(客户端MTM、用户接口MTM或者客户端消息应用程序)与消息服务器端的通讯通道。每一个客户端线
程对应一个该类的实例,CMsvSession提供客户端能及时获取消息服务端消息的有效方式。一个消息客户端应用必须
在正常使用任何MTM或CMsvEntry对象前,使用OpenSyncL()或者OpenASyncL()来新建一个session对象。

2. CClientMtmRegistry
Registry掌握了客户端所有目前可用的MTM有关的细节,消息客户端可以使用该类获得从CBaseMtm继承de对象。

3. CBaseMtm: 处理消息数据结构内部表示和用户界面接口,如新建、修改sms等
   CBaseMtmUi: 提供用户界面功能,如阅览,编辑消息等.
   CBaseMtmUiData: 用户界面数据.

4. CMsvEntry
相当于一个特定消息服务器的入口,当前entry与其的具体内容相关联。CMsvEntry包含两个部分的功能:一是可以
允许访问与这个entry关联的,不同类型的数据;而是运行访问它的子entry。该类只在客户端使用,服务器端使用
CMsvServerEntry。
用于代表消息服务器的一个入口,主要用于sms的新建, 删除, 操作, 移动和访问等Entry.

5. CMsvSrverEntry: 用于服务器端.

-------------------------关键API-------------------------------------
消息API函数:
(1) 客户/服务器会话
    CMsvEntry* NewL(CMsvSession& aMsvSession, TMsvId aMsvId, constTMsvSelectionOrdering& aSortType);\
    创建函数,在实例化任何MTM或CMsvEntry对象之前创建一个会话对象.
     CMsvSession* OpenSyncL(MMsvSessionObserver& aObserver);//同步打开会话,一旦启动会话保持有效,该函数就返回.
     CMsvSession* OpenAsyncL(MMsvSessionObserver& aObserver);//异步打开
     建立了会话,就可以对注册内条目访问
(2) CMsvEntry 条目操作
     CMsvEntry::GetEntryL(TMsvId aId): 获取条目并返回指向改消息树内部所需要的对象指针.
     CMsvEntry::GetEntryL(TMsvId aId, TMsvId& aService, TMsvEntry& aEntry);
     CMsvEntry::RemoveEntry(TMsvId aId);//从消息树中删除一个条目.
     CMsvEntry::DeleteL(TMsvId aId, TRequestStatus& aStatus);//删除条目函数
     CMsvEntry::CopyL(TMsId aMsvid, TMsvid aTargetId, TRequestStatus& aStatus);//复制ID
     CMsvEntry::ChangeL(const TMsEntry& aEntry); //对条目进行修改
     CMsvEntry::ChangeEntry(const TMsEntry& aEntry); //对条目进行修改,提交
(3)  消息服务器操作
     AddObserverL(MMsvEntryObserver& aObserver); //加入观察者程序,用于提示接口
     OpensyncL(MMsvEntryObserver& aObserver); //同步创建一个消息线程
     OpenAsynscL(MMsvEntryObserver& aObserver);//异步创建一个消息线程
     HandleSessionEventL(); //通知会话事件
     如果异步方式开启会话,就会以一个EMsvServerReady事件来通知观察者程序.
(4)  客户端MTM 操作
     CBaseMtm::CreateMessageL(TMsvId aServiceId); // 新创建的消息
     AddAddresseeL(); //添加代表收件人的描述符(字符串)
     SaveMessageL(); //保存消息
     SetSubjectL(); // 添加主题描述符
     ValidateMessage(TMsvPartList aPartList); //消息确认函数,函数返回确认结果
     ReplyL(TmsvId aDestination, TmsvPartlist aPartList, TRequestStatus& aCompletionStatus);//对当前消息产生一个回复
     ForWardL(TmsvId aDestination, TmsvPartlist aPartList, TRequestStatus& aCompletionStatus);//对当前的消息进行转发
     InvokeAsyncFunctionL();//启动附加扩展.

--------------------------消息开发-----------------------------------
1. 发送消息
步骤: (1)选择MTM
         SetMtmL(TUid aMtmUid);//设置MTM
         CDesCArry& AvailableMtms() const;//获取MTM值
      (2)选择一个服务
         CDesCArray& AvalilableService() const;//返回字符串,描述服务是否存在
         void SetService(Tint aServiceIndex); //选择相应的服务
      (3)创建消息
         void CreateMessageL();
         void CreatemessageL(TmsvId aId);//消息从输入的参数中复制过来
         信息接收者可以由以下函数一个添加或修改
         CDesCArray& RecipientList() const;//获取地址字符串
         void AddRecipientL(const TDesc &aRealAddress);//添加收件人的地址
         void RemoveRecipent(Tint aIndex);//删除接收者
         void SetSubjectL(const TDesC& aSubject); //信息标题
         void SetBodyL(const CRichText& aMessageBody);//信息主题
         void CreateAttachmentL(...);//创建附件
         void DeleteAttachmentL(...);//删除附件
         void SetAttachmentL(..)//设置信息到附件
       (4) 存储和发送信息
         void SaveMessageL(TBOOL aMakeVisible = ETURE);//是否内容在服务器中可见
       void SaveMessageL(TRequestStatus& aCompletionStatus, TBOOL aMakeVisible = ETURE);//异步存储

2.  接收消息
应用程序的消息接收主要是指消息到来的通知过程,消息服务器负责完成消息的监听和传送,应用程序只需注册,当有消息被通知.
    iSession = CMsvSession::OpeSyncL(*this);
    然后使用HandleSessionEventL处理
   
------------------------------- 短信 SMS------------------------------------
SMS 实例:  基于SMS MTM
信息的发送的部分:
TInt CSMSAppUi :: CreateAndSendNewSMSL()
{
 //在消息服务器目录中的entry
 TMsvEntry newEntry;
 //消息的类型
 newEntry.iMtm = KUidMsgTypeSMS;
 //给出entry 的类型
 newEntry.iType = KuiMsvMessageEntry;
 //将ServiceId 设置为本地服务,取得时间,设置信息状态
 newEntry.iServiceId = KMsvlocaServiceIndexEntryId;
 newEntry.iData.HomeTime();
 newEntry.SetInPreparation(ETrue);
 CMsvEntry* entry = CMsvEntry::newL(..);
 CleanupStack::PushL(entry);
 //创建新的entry,并且设置内容
 entry ->CreateL(newEntry);
 entry ->SetEntry(newEntry.Id());
 //注册消息MTM客户端
 CClientMtmRegistry* mtmReg;
 mtmReg = CClientMtmRegistry::NewL(*session);
 CleanupStack::PushL(mtmReg);
 //创建一个客户端的SMS MTM对象
 CBaseMtm* mtm = mtmReg -> NewMtmL(entry ->Entry().iMtm);
 CleaupStack::PushL(mtm);
 mtm ->SetCurrentEntry(entry);
 CleanupStack::PopAndDestroy(3);
 
 //填入消息内容
 CRichText& mtmBody = mtm ->Body();
 mtmBody.Reset();
 _LIT(KTestSmsMsg, "Hello world");
 //插入文本
 mtmBody.InsertL(0, KTestSmsMsg);
 newEntry.SetInPreparation(EFalse);
 newEntry.SetSendingState(KMsvSendStateWaiting);
 //设置本地时间
 newEntry.iDate.HomeTime();
 entry->ChangeL(newEntry);
 //处理一些SMS MTM使用规范
 CSmsClientMtm* smsMtm = static_cast<CSmsClientMtm*>(mtm);
 CleaupStack::PushL(smsMtm);
 //将头部信息和选项更改放入Cache
 smsMtm ->RestoreServiceAndSettingL();
 
 //CSmsHeader 获得SMS头部信息
 CSmsHeader& header = smsMtm -> SmsHeader();
 CSmsSetting* sendOptions = CSmsSettings::NewL();
 CleaupStack::PushL(sendOptions);
 //恢复当前的服务设置
 sendOptions ->CopyL(smsMtm -> ServiceSettings());
 //设置发送的选项
 sendOptions -> SetDelivery(ESmsDeliveryImmediately());
 header.SetSmsSettingsL(*sendOptions);
 CleanupStack::PopAndDestroy(2);
 
 //设置目的地址,并且将改变从缓存提交
 _LIT(KDestinationAdd, "+12345678910");
 smmMtm -> AddresseL(KDestinationAdd);
 //提交缓存中的改变值
 smsMtm -> SaveMessageL();
 //现在消息已经准备好了可以发送了,首先把他放入发件箱,从发件箱再被发到目的地
 //将entry移到发件箱中, 然后处理父节点
 CMsvEntry* parentEntry = CMsventry::NewL(...);
 CleanipStack::PushL(parentEntry);
 //将原始的消息移从根目录移到发件箱
 CMuiuOperationWait* wait = CMuiuOperationWait::NewL();
 CMsvOpertion * op = parentEntry -> MoveL(NewEntry.Id(), KMsvGlobalOutBoxIndexEntryId, wait -> iStatue);
 CleanipStack::PushL(op);
 wait -> Start(); //等待操作完成
 CleanupStack::PopAndDestroy(2);
}
//发送消息
void CSMSAppUi :: SetScheduledSendingStateL(CMsvEntrySession& aMsvSession)
{
 CBaseMtm* smsMtm = iMtm;
 //将Entry 加入到任务队列中
 TBuf8<1> dummyPrams;
 CMuiuOperationWait *wait = CMuiuOperationWait::NewL();
 CMsvOperation* op = smsMtm -> InvokeAsyncFunctionL(..);
 CleanipStack::PushL(op);
 Wait -> Start();
 CleanupStack::PopAndDestroy(2);
}

例子2:
#include "SMSHandler.h"
 private: //data       
 ... 
 CSmsHandler* iSmsHandler; //创建对象
 
//初始化 SmsHandler object.
CYrApplicationContainer::ConstructL()
{...   
 SetRect(aRect);   
 ActivateL();    
 iSmsHandler = CSmsHandler::NewL(); // 创建一个SmsHandler对象
}

//发送消息
void CYrApplicationContainer ::SendMsg()
{      
   TBuf<128> SMSText,PhoneNumber;   
   SMSText.Copy(_L("Test Message"));   
   PhoneNumber.Copy(_L("999999999")); //Replace Number as per your needs    
   iSmsHandler->SendL( PhoneNumber, SMSText) ;
}

//从收件箱,发信箱...读取
void CSmsHandler::ReadInbox()
{
 HBufC* SMSContent = HBufC::NewLC(400);
 HBufC8* SMSContent8 = HBufC8::NewLC(400);
 TMsvSelectionOrdering sort;
 sort.SetShowInvisibleEntries(ETrue); //设置句柄可见.
 CMsvEntry* inboxContext=CMsvEntry::NewL(*iSession,KMsvGlobalInBoxIndexEntryId,sort); // 从收件箱中读取消息
 CleanupStack::PushL( entries );
 TInt msgCount= entries->Count();
 for (TInt i=0; i<entries->Count(); i++)
 {
 
  TMsvId entryID = entries->At(i);
  iSmsMtm->SwitchCurrentEntryL(entryID);
  CMsvEntry* entry= iSession->GetEntryL((*entries)[i]);
  CleanupStack::PushL(entry);
   CMsvStore* inboxStore;
  TRAPD(r, inboxStore = entry->ReadStoreL());
  if(KErrNone != r)
  {
    CleanupStack::PopAndDestroy(entry);
    continue;
  }
  CleanupStack::PushL(inboxStore);
  if (inboxStore->HasBodyTextL())
  {
                TMsvEntry entry1 =  entry->Entry();
                /* Gives you phone Number or Contact Name if Contact is present*/
    TBufC<50>text(entry1.iDetails);                
                TBuf16<30> msg;
    msg.Copy(_L("Name: "));
    msg.Append(text);
 
                 /*If you want to get the Recipient Number, when iDetails gives you Contact's Name. */
                 iSmsMtm->LoadMessageL();
                 CSmsHeader& header = iSmsMtm->SmsHeader();
                 TPtrC from = header.FromAddress(); 
                 TBuf8<60> number;
     number.Copy(_L("Number: "));
        number.Append(from);
 
               /* To read phone number from Sent Item folder, see the Note below */
    CRichText& richText= iSmsMtm->Body();
    inboxStore->RestoreBodyTextL(richText);
          const TInt length = richText.DocumentLength();
 
                /* Gives you actual content(Body) of SMS */
    SMSContent->Des().Copy(richText.Read(0,length));
    richText.Reset();
    SMSContent8->Des().Copy(SMSContent->Des());
                         /* Write SMS Body in the SMSBody.txt file*/
    //WriteToFile(SMSContent8->Des());
                        /* Write SMS Body, number and contact name in file*/
                WriteToFile(msg, number,SMSContent8->Des());
  }
  else
  {
    // no text in SMS
  }
    CleanupStack::PopAndDestroy(2,entry);
  }
    CleanupStack::PopAndDestroy(4,SMSContent);
}

//读取电话号码,发送文件夹中消息
CSmsHeader& smsHeader = iSmsMtm->SmsHeader();
const CArrayPtrFlat<CSmsNumber>&  array= smsHeader.Recipients();
CSmsNumber* smsNumber = array.At(0);
TPtrC recipentNumber = smsNumber->Address(); // recipentNumber will contain the recipient Number
。。。。

posted @ 2012-12-22 17:38  小金马  阅读(737)  评论(0编辑  收藏  举报