短信发送状态报告流程分析
短信发送状态报告流程分析
//应用层分析://SmsSingleRecipientSender.javapublic boolean sendMessage(long token) throws MmsException {if (mMessageText == null) {// Don't try to send an empty message, and destination should be just// one.throw new MmsException("Null message body or have multiple destinations.");}SmsManager smsManager = SmsManager.getDefault();ArrayList<String> messages = null;if ((MmsConfig.getEmailGateway() != null) &&(Mms.isEmailAddress(mDest) || MessageUtils.isAlias(mDest))) {String msgText;msgText = mDest + " " + mMessageText;mDest = MmsConfig.getEmailGateway();messages = smsManager.divideMessage(msgText);} else {messages = smsManager.divideMessage(mMessageText);// remove spaces from destination number (e.g. "801 555 1212" -> "8015551212")mDest = mDest.replaceAll(" ", "");}int messageCount = messages.size();if (messageCount == 0) {// Don't try to send an empty message.throw new MmsException("SmsMessageSender.sendMessage: divideMessage returned " +"empty messages. Original message is \"" + mMessageText + "\"");}boolean moved = Sms.moveMessageToFolder(mContext, mUri, Sms.MESSAGE_TYPE_OUTBOX, 0);if (!moved) {throw new MmsException("SmsMessageSender.sendMessage: couldn't move message " +"to outbox: " + mUri);}ArrayList<PendingIntent> deliveryIntents = new ArrayList<PendingIntent>(messageCount);ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>(messageCount);for (int i = 0; i < messageCount; i++) {if (mRequestDeliveryReport) {// TODO: Fix: It should not be necessary to// specify the class in this intent. Doing that// unnecessarily limits customizability.deliveryIntents.add(PendingIntent.getBroadcast( //设置回执状态报告intentmContext, 0,new Intent(MessageStatusReceiver.MESSAGE_STATUS_RECEIVED_ACTION, //底层发出的状态报告消息mUri,mContext,MessageStatusReceiver.class), //接收消息:MessageStatusReceiver. MESSAGE_STATUS_RECEIVED_ACTION,0));}Intent intent = new Intent(SmsReceiverService.MESSAGE_SENT_ACTION,mUri,mContext,SmsReceiver.class);int requestCode = 0;if (i == messageCount -1) {// Changing the requestCode so that a different pending intent// is created for the last fragment with// EXTRA_MESSAGE_SENT_SEND_NEXT set to true.requestCode = 1;intent.putExtra(SmsReceiverService.EXTRA_MESSAGE_SENT_SEND_NEXT, true);}sentIntents.add(PendingIntent.getBroadcast(mContext, requestCode, intent, 0));}try {smsManager.sendMultipartTextMessage(mDest, mServiceCenter, messages, sentIntents, deliveryIntents/*在下发短信时设置deliveryIntents*/); //注意此处} catch (Exception ex) {throw new MmsException("SmsMessageSender.sendMessage: caught " + ex +" from SmsManager.sendTextMessage()");}if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {log("sendMessage: address=" + mDest + ", threadId=" + mThreadId +", uri=" + mUri + ", msgs.count=" + messageCount);}return false;}//应用层接收短信状态信息,并更新数据库//MessageStatusReceiver.javapublic void onReceive(Context context, Intent intent) { mContext = context; if (MESSAGE_STATUS_RECEIVED_ACTION.equals(intent.getAction())) { Uri messageUri = intent.getData(); byte[] pdu = (byte[]) intent.getExtra("pdu"); SmsMessage message = updateMessageStatus(context, messageUri, pdu);//更新短信状态:数据库SMS表status字段,状态报告取值:/*STATUS_NONE = -1;STATUS_COMPLETE = 0;STATUS_PENDING = 32;STATUS_FAILED = 64; */ // Called on the UI thread so don't block. if (message.getStatus() < Sms.STATUS_PENDING) MessagingNotification.nonBlockingUpdateNewMessageIndicator(context, true, message.isStatusReportMessage()); }}//框架层分析://SMSDispatcher.java@Override public void handleMessage(Message msg) { AsyncResult ar; switch (msg.what) { case EVENT_NEW_SMS_STATUS_REPORT: handleStatusReport((AsyncResult)msg.obj); //转到派生类GsmSMSDispatcher.java中处理 break;} }//GsmSMSDispatcher.java@Override protected void handleStatusReport(AsyncResult ar) { String pduString = (String) ar.result; SmsMessage sms = SmsMessage.newFromCDS(pduString); int tpStatus = sms.getStatus(); if (sms != null) { int messageRef = sms.messageRef; for (int i = 0, count = deliveryPendingList.size(); i < count; i++) {//deliveryPendingList定义在父类SMSDispatcher.java中,并在handleSendComplete函数里对每个短信发送完成后获取状态信息: /*if (tracker.mDeliveryIntent != null) { // Expecting a status report. Add it to the list. int messageRef = ((SmsResponse)ar.result).messageRef; tracker.mMessageRef = messageRef; deliveryPendingList.add(tracker); }*/// SmsTracker tracker = deliveryPendingList.get(i); if (tracker.mMessageRef == messageRef) { // Found it. Remove from list and broadcast. if(tpStatus >= Sms.STATUS_FAILED || tpStatus < Sms.STATUS_PENDING ) { deliveryPendingList.remove(i); } PendingIntent intent = tracker.mDeliveryIntent; Intent fillIn = new Intent(); fillIn.putExtra("pdu", IccUtils.hexStringToBytes(pduString)); fillIn.putExtra("encoding", getEncoding()); try { intent.send(mContext, Activity.RESULT_OK, fillIn); } catch (CanceledException ex) {} // Only expect to see one tracker matching this messageref break; } } } acknowledgeLastIncomingSms(true, Intents.RESULT_SMS_HANDLED, null); }?