`

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

 
阅读更多

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

//应用层分析:
//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);
    }

 

分享到:
评论

相关推荐

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

    java短信验证,从前后js的控制,到后台的完整代码。适用于小白。

    飞信数据库短信发送接口

    二、客户程序发送流程: 1)客户程序将命令记录(如"发送短信")插入表(注意reok字段要等于0,retxt字段要为空) SQL语句例:INSERT FetionTb(Com,myMNo,myMPass,toMNo,Msg,reok,retxt,addTime,mtype) VALUES('发送...

    PHP短信接口demo

    发送短信接入流程: ...3.申请签名(以公司简称或缩写命名)备注:平台申请签名,API接口加上申请签名 ...状态报告接入流程: 1.配置一个外网可以访问的URL来接受创蓝服务器的异步推送 2.参考receive.php

    基于STM32单片机老人防跌倒报警系统GSM短信上报(毕业设计)

    本设计由STM32单片机核心板电路+ADXL345加速度传感器电路+GSM电路+指示灯电路+按键电率+蜂鸣器报警电路+电源... 程序源码 电路图 任务书 答辩技巧 开题报告 参考论文 系统框图 程序流程图 使用到的芯片资料 器件清单

    python如何使用腾讯云发送短信

    腾讯云方面的申请和流程都比较简单,基本都是可视化操作的,这里就不在赘述了。这篇文章着重讲解怎么用python实现调用...发送短信我们需要用到的模块有下面2个 from qcloudsms_py import SmsMultiSender, SmsSingleSen

    华阳佳讯优势通短信中间件

     3、在系统和工作流程中增加短信收发功能,例如:短信提醒,业务确认、短信报警、短信报表。  4、私密或不便于记录的信息,以短信形式告知客户,例如:账户信息,密码信息、查询结果。  5、短信自助服务:账户查询、...

    基于51单片机GPS定位系统经纬度GSM短信上报设计

    3、短信发送及初始化有状态指示灯指示。 4、GSM模块是SIM800A,该模块和SIM900A电路程序完全兼容外观外形一模一样 资料包含: 程序源码 电路图 任务书 答辩技巧 开题报告 参考论文 系统框图 程序流程图 使用到的芯片...

    招聘系统,源码和项目描述,C#项目

    招聘流程管理:包括安排面试、发送面试通知、跟踪面试状态等功能。 通知与沟通:系统可以通过邮件或短信通知候选人面试安排或其他相关信息。 统计分析:提供招聘数据的统计和分析,帮助企业了解招聘效果,优化招聘...

    基于STM32单片机远程浇花花盆GSM短信浇水补光设计

    本设计由STM32F103C8T6单片机核心电路+温湿度传感器DHT11电路+LCD1602液晶显示电路+继电器控制电路+...资料内容:程序源码 电路图 任务书 答辩技巧 开题报告 参考论文 系统框图 程序流程图 使用到的芯片资料 器件清单

    C#+Asp.Net开发的大型OA办公系统

    个人办公: 通知公告 即时消息 传阅信息 发起的传阅 收到的传阅 考勤登记考勤统计 出差登记 邮件管理 发送邮件 收件箱 发件箱 邮箱设置 修改资料 修改密码 日程任务:添加日程 个人日程 部门日程 公文管理:公文分类...

    ISAG,WAP接入最新文档

    3.6 WAP Push 状态报告接口开发 58 4. 彩信 61 4.1彩信的构成 61 4.2 彩信在电信网络里面的网络结构 62 4.3 彩信开发接口开发环境搭建 63 彩信发送接口开发 69 4.5 彩信上行 81 5.1 TcpMon使用 94 5.2 Web Services ...

    供应彩信二次开发接口,彩信开发平台,研发各种软件功能

    6.应用系统可通过读取MSG_Sentbox和MSG_Failedbox表中的信息来判断彩信/短信发送是否成功 接收彩信过程 1.手机用户向GPRS彩信设备发送了一条彩信 2.彩信系统将收到的“彩信通知“保存到MSG_Inbox中,并控制GPRS...

    asp实现新评论自动发短信提示的代码

    程序的流程是这样的,当有人发表评论的时候就会把那条评论发到我手机上,是通过过一个网站的api接口实现信息发送的,其实就是飞信的api。飞信不是可以自己发信息给自己吗?原理其实很简单。 提醒:你手机必须开通...

    绿叶OA协同办公软件

    2)流程审批:按照流水号、流程标题、状态、当前流转、审批人数、发送人等主要信息读取所有接收流程审批信息,对未读流程加粗显示,使审批用户对流程概况有最基本了解。进入流程审批,提交审批结果与内容,流程将进入...

    基于51单片机的家庭防火防盗系统

    本次设计需要实现的主要功能是,使用矩阵键盘输入4G通信模块所要发送信息的电话号码并将其存入AT24C02中以达到掉电不丢失的效果,通过红外遥控器控制整个系统在“布防”与“撤防”状态之间进行切换,当工作在“布防...

    中国移动客户服务系统功能需求规范(1.0版)

    表14. 不同状态工单量统计分析指标 141 表15. 知识库统计分析指标 141 表16. 公告统计分析指标 142 表17. 便笺统计分析指标 142 表18. 招聘信息统计分析指标 143 表19. 考勤统计分析指标 143 表20. 人员流失率统计...

    淘特OA办公自动化系统 v2.0.rar

    个人办公: 通知公告 即时消息 传阅信息 发起的传阅 收到的传阅 考勤登记考勤统计 出差登记 邮件管理 发送邮件 收件箱 发件箱 邮箱设置 修改资料 修改密码 日程任务:添加日程 个人日程 部门日程 公文管理:公文...

    SpringBoot项目疫苗接种管理系统.zip

    5. 数据分析报告:后台生成各种分析报告,包括疫苗使用效率、接种人群分布等,为决策者提供支持。 6. 安全监测:系统记录任何报告的不良反应,确保疫苗的安全性和有效性。 7. 通知系统:通过短信、邮件或APP推送向...

    思科影楼管理软件

    3、以家庭为基本单位的短信发送模式,如妻子过生日,丈夫和妻子会同时收到短信,且短信内容自动匹配; 4、自定义短信模板,用户可设定个性化短信内容,影楼活动通知、节日祝福等可随心发送; 5、自定义发送模式,可...

Global site tag (gtag.js) - Google Analytics