高通Android 4.4 彩信发送流程

本文详细解析了在高通Android 4.4系统中,彩信发送的具体步骤,从ComposeMessageActivity的onClick开始,经过WorkingMessage.java的send()函数,到MmsMessageSender和TransactionService的服务交互,再到SendTransaction的执行,包括HTTP连接的建立和彩信数据的发送。在过程中涉及线程、数据库操作、消息监听和服务交互等关键环节。同时指出在附件加载和HttpUtils中遇到的异常现象。
MMS send flow in QCOM


MMS发送流程图

Mms send flow.jpg
Key Point
1:在点击短信界面的发送button(高通插入双卡后有两个botton)后,会进入ComposeMessageActivity.java的onClick()函数。

 这个函数将进行会在调用checkRecipientsCount()函数中继续向下调用其他函数,最终调用到sendMessage()函数。

2:Compose的sendMessage()跳转到WorkingMessage.java的send()函数,在这个函数中会区分短信和彩信的发送,如果是彩信类型或者包含有email地址的收信人,则新建一个线程,进入发送。 该线程: (1)makeSendReq(),将会话的联系人的号码、主题、时间整理为一个请求,然后进入sendMmsWorker()。 
(2)sendMmsWorker()中,首先对threadId进行确认,调用到Threads.getOrCreateThreadId(context, recipients),在thread(对应表中的_id)表中查询,查询不到,则递加生产新ID。
(3)Conversation.verifySingleRecipient,如果只有一个联系人,则对联系人的号码查询,如果查询出的号码与传入的号码不一样,则将新号码插入进sendReq中。
(4)

               ContentValues values = new ContentValues();
               values.put(Mms.MESSAGE_BOX, Mms.MESSAGE_BOX_OUTBOX);
               values.put(Mms.THREAD_ID, threadId);
               values.put(Mms.MESSAGE_TYPE, PduHeaders.MESSAGE_TYPE_SEND_REQ);
               if (textOnly) {
                   values.put(Mms.TEXT_ONLY, 1);
               }
               mmsUri = SqliteWrapper.insert(mActivity, mContentResolver, Mms.Outbox.CONTENT_URI,
                       values);

向outbox中预先插入一些值,已更新UI界面为sending状态。
(5)

          cursor = SqliteWrapper.query(mActivity, mContentResolver,
                   Mms.Outbox.CONTENT_URI, MMS_OUTBOX_PROJECTION, null, null, null);
           if (cursor != null) {
               long maxMessageSize = MmsConfig.getMaxSizeScaleForPendingMmsAllowed() *
               MmsConfig.getMaxMessageSize();
               long totalPendingSize = 0;
               while (cursor.moveToNext()) {
                   totalPendingSize += cursor.getLong(MMS_MESSAGE_SIZE_INDEX);
               }
               if (totalPendingSize >= maxMessageSize) {
                   unDiscard();    // it wasn't successfully sent. Allow it to be saved as a draft.
                   mStatusListener.onMaxPendingMessagesReached();
                   markMmsMessageWithError(mmsUri);
                   return;
               }
           }

查询pending中的彩信总的size,如果大于默认值,则返回错误。
(6)

           if (newMessage) {
               // Create a new MMS message if one hasn't been made yet.
               mmsUri = createDraftMmsMessage(persister, sendReq, slideshow, mmsUri,
                       mActivity, null);
               // Remove the sd card mmsUri will be null
               if (mmsUri == null) {
                   Toast.makeText(mActivity, R.string.cannot_send_attach_reason,
                           Toast.LENGTH_SHORT).show();
                   return;
               }
           } else {
               // Otherwise, sync the MMS message in progress to disk.
               updateDraftMmsMessage(mmsUri, persister, slideshow, sendReq, null);
           }

这里确保data/data/com.android.providers.telephony/app_parts下的PART_XXX附件文件被创建,否则进行重新创建的过程。
updateDraftMmsMessage(mmsUri, persister, slideshow, sendReq, null),这里对part表进行更新,为最新的发送时间,threadid 和number。然后进入MmsMessageSender的sendMessage函数。
3:MmsMessageSender的sendMessage函数,先对date进行更新,然后Move the message into MMS Outbox,最新启动TransactionService服务。
4:TransactionService服务这里用到的obverser模式,对SendTransaction等进行监听:。
5:通过handleMessage进行消息的处理EVENT_NEW_INTENT到onNewIntent(),再到launchTransaction(),最后到

                  transaction = new SendTransaction(
                                       TransactionService.this, serviceId,
                                       transactionSettings, args.getUri());到processTransaction中。

6:processTransaction()中对Transaction在mPending和mProcessing表中进行判断,然后建立APN链接(这里有个循环的过程) transaction.attach(TransactionService.this),对SendTransaction等被观察者增加观察者,transaction.process()然后进行发送。
7:SendTransaction中启动一个新线程
(1)persister.load(mSendReqURI),其子函数会调用sql.query()操作去查询pdu表中的数据。并封装成pdu格式返回。
(2)values.put(Mms.DATE, date);SqliteWrapper.update(mContext, mContext.getContentResolver(),mSendReqURI, values, null, null);这一步主要的作用是更新当前的时间到pdu表中。
(3)sendPdu()函数这一步是主要的进行彩信发送的函数,最终调用到HttpUtils.httpConnection()。进行http链接。
(4)再次更新数据库,更新发送结果及message_i。
(5)将该信息从outbox移到sent box。信息就会变成sent。
(6)notifyObservers(),这个函数是继承自Observe类。会调用之前注册的update()函数。
8:notifyObservers()会调用到TransactionService中的update,更具返回值,去做重发,或者下一条彩信等动作。

PS下:
(1)这里跟踪高通的附件加载过程,发现temp.jpg等文件没有在sdcard/Android/data/com.android.mms/cache下建立,不知道啥原因

 代码在composemessageactivity下的onActivityResult中case REQUEST_CODE_TAKE_PICTURE
               File file = new File(TempFileProvider.getScrapPath(this));
               Uri uri = Uri.fromFile(file);
               // Remove the old captured picture's thumbnail from the cache
               MmsApp.getApplication().getThumbnailManager().removeThumbnail(uri);

(2)高通HttpUtils关系http链接的工具类,httpConnection()会有异常关掉socket的,还往socket里写数据的情况,不知道啥原因

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值