`

短信发送状态报告流程分析

 
阅读更多

短信发送状态报告流程分析

//应用层分析:
//SmsSingleRecipientSender.java
public 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( //设置回执状态报告intent
mContext, 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.java
public 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);
    }

 

分享到:
评论

相关推荐

    短信发送状态报告错误码(含移动、联通、电信及福建联通自定义错误码)

    然而,在短信发送过程中,由于网络环境、系统状态或用户设备等多种因素的影响,可能会遇到各种错误情况,从而导致短信发送失败或者状态报告异常。本文将详细介绍短信发送状态报告中的错误码,包括中国移动、中国联通...

    AT短信猫,发短信接收短信流程

    在本文中,我们将详细探讨AT短信猫的初始化过程以及短信的发送和接收流程。 首先,初始化短信猫是使用AT指令的起点。发送"AT"指令可以确保设备处于标准状态,等待进一步的命令。接着,关闭回显功能,使用"ATE0"指令...

    短信业务流程分析.pptx

    总结来说,短信业务流程分析涉及到短信的发送模式、PDU格式、AT指令的使用以及PDU编码的细节。理解这些知识点对于开发、维护和优化短信服务系统至关重要,特别是在管理信息化的背景下,能够有效提高通信效率和用户...

    Java版本CMPP移动收发短信,网关报告,状态报告全套.zip

    4. CMPP_REPORT:这是状态报告的命令,当短信发送完成后,SMSC会回传一个状态报告,告知短信是否成功送达,或者遇到了什么问题。 5. CMPP_GATEWAY_REPORT:网关报告则是关于短信在网络中传输状态的详细信息,如路由...

    em310短信例子发送短信流程

    EM310短信发送流程是通过串行通信与EM310模块进行交互,实现短信的发送。在这一过程中,主要涉及到了多个AT命令,包括设置短信编码、短信模式、新消息指示、发送短信以及短信管理等关键步骤。以下是详细的步骤解析:...

    电信CDMA中的SMS流程分析

    【电信CDMA中的SMS流程分析】 短信服务(SMS)在电信网络中扮演着重要的角色,尤其是在CDMA(码分多址)系统中。CDMA是一种无线通信技术,它利用独特的编码方式分配频率资源,实现多个用户在同一频段上同时通信。在...

    短信发送sdk包

    对于开发者来说,通过集成这样的SDK,可以大大简化短信发送的流程,无需关心底层通信协议和短信网关的细节,只需按照SDK提供的API进行调用即可。 【标签】“短信发送”进一步明确了这个SDK的核心功能,即它的主要...

    java短信验证(前后台全部)

    4. 返回响应:后端发送短信成功后,返回一个状态码或消息给前端,告知发送结果。 三、验证码验证: 1. 前端提交:用户输入验证码后,前端将手机号码和验证码一起提交到后端进行验证。 2. 后端验证:后端接收到请求...

    短信息发送实例

    通过理解短信猫的工作原理、掌握API接口和通信协议,我们可以构建高效、可靠的短信发送系统。"JDM2M_INTRO.exe"这个文件可能提供了一个起点,帮助开发者快速入门短信息发送的世界。在实际项目中,根据需求选择合适的...

    实用的asp短信发送代码.rar

    3. 短信发送流程: - 用户请求:在ASP页面中,用户触发发送短信的操作,如注册、忘记密码等。 - 脚本处理:ASP代码接收到请求后,调用短信接口的函数,传入必要的参数,如接收手机号码、短信内容等。 - 接口调用...

    阿里云/腾讯云短信发送(C#版)

    - 处理响应:解析返回的`SendSmsResponse`对象,检查短信发送状态。 2. 腾讯云短信发送: - 初始化配置:设置SecretId、SecretKey、Region等参数。 - 创建客户端:使用`SmsClient`类初始化腾讯云短信服务的...

    java 短信发送程序

    本篇文章将详细探讨Java实现短信发送功能的核心技术和流程。 1. **SMS API和库** Java 短信发送通常依赖于SMS Gateway提供商提供的API。这些API允许开发者通过HTTP请求或Socket通信与短信服务商进行交互。例如,...

    简单的安卓短信发送程序

    【Android短信发送程序详解】 在Android开发中,创建一个简单的短信发送程序是常见的实践,尤其对于初学者来说,这是理解Android系统服务和权限管理的重要环节。这个程序的实现基于老师的指导,通过实际操作并测试...

    短信发送协议(CMPP,SMPP,SGIP,SMGP).zip

    短信发送协议是通信行业中用于移动网络短信服务的重要标准,这些协议包括CMPP(China Mobile Packet Protocol)、SMPP(Short Message Peer-to-Peer)、SGIP(Short Message Gateway Internet Protocol)以及SMGP...

    vb短信接口开发_vb发送短信验证码通知_Visual Basic短信demo示例.docx

    在实际开发中,您需要处理这个响应,检查状态码和返回信息,以确定短信发送的状态。如果发送失败,可能需要进行重试或者显示错误信息给用户。 此外,为了确保代码的健壮性,应添加错误处理机制,如使用`On Error ...

    CMPP3.0 短信发送

    这个协议是基于TCP/IP的,旨在提供高效、稳定、安全的短信发送服务。CMPP3.0相对于之前的版本,如CMPP2.0,在功能、性能和安全性上都有所增强,更加适应大规模、高并发的短信业务需求。 CMPP3.0协议主要包括以下几...

    SIM900短信AT命令操作流程

    根据提供的部分内容,我们可以看到一个完整的短信发送和接收流程: 1. **初始化模块**:通过一系列AT命令确保模块处于可用状态。 2. **发送短信**:“AT+CMGS”命令后跟手机号码和短信内容,通过Ctrl+Z键结束输入。...

    短信一体机测试报告

    根据给定的“短信一体机测试报告”,我们可以深入解析并提炼出以下关键IT知识点: ### 短信一体机测试报告解析 #### 测试报告结构与要素 测试报告是IT项目中不可或缺的一部分,用于记录测试过程、结果和发现的问题...

    android源码短信发送流程.pdf

    总的来说,Android短信发送流程涉及用户交互、日志记录、数据准备、消息类型判断、非主线程操作以及状态更新等多个环节,确保了短信发送的可靠性和用户体验。在实际的Android开发中,理解这些细节有助于优化和调试...

Global site tag (gtag.js) - Google Analytics