SMS发送接收流程

1.短信发送的起点是在短信编辑界面,点击发送按钮开始的

public class ComposeMessageActivity extends Activity  ...{
....public void sendMessage(boolean bCheckEcmMode) { ....//这里面准备发送的数据处理,比如生成PDU数据,存储到数据mWorkingMessage.send(mDebugRecipients, mSelectedSubId);  }

这里写图片描述

mWorkingMessage中具体发送短信的工作在preSendSmsWorker方法里面
private void preSendSmsWorker(Conversation conv, String msgText, String recipientsInUI,
int subId, boolean hasBeenSplit) {
// just do a regular send. We’re already on a non­ui thread so no need to fire
// off another thread to do this work.
/// M: Code analyze 047, For new feature ALPS00316567, add a parameter for msim . @{
sendSmsWorker是最主要的类,做了实际的发送工作,但他里面不是立即发送短信,而是发送短信的请求封装成SmsMessageSender,
sendSmsWorker(msgText, semiSepRecipients, threadId, subId);
/// @}

} .
SmsReceiverService
SmsMessageSender*******************************************
将待发送的短信存储到数据库表格中,content://sms/queued
然后再启动服务SmsReceiverService,让服务去单个发送每一条短信,SmsReceiverService重待发送短信表格中取出一条短信,然后交由
SmsSingleRecipientSender去发送。

这里写图片描述

MessageSender sender = new SmsMessageSender(mActivity, dests, msgText, threadId, subId);短信发送处理public boolean sendMessage(long token) throws MmsException {
号码处理,将其中的空格去除。得到有效的发送号码。
生成2个广播1.发送报告广播,2.发送短信广播
最终调用系统接口SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(mSubId);
SmsManager***************************************************************************************************public void sendMultipartTextMessage(String destinationAddress, String scAddress, ArrayList<String> parts,ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {if (parts.size() > 1) {try {ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));if (iccISms != null) {iccISms.sendMultipartText(destinationAddress, scAddress, parts,sentIntents, deliveryIntents);}} catch (RemoteException ex) {// ignore it}} else {PendingIntent sentIntent = null;PendingIntent deliveryIntent = null;if (sentIntents != null && sentIntents.size() > 0) {sentIntent = sentIntents.get(0);}if (deliveryIntents != null && deliveryIntents.size() > 0) {deliveryIntent = deliveryIntents.get(0);}sendTextMessage(destinationAddress, scAddress, parts.get(0),sentIntent, deliveryIntent);}
****************************************************************************
ISms.Stub.asInterface(ServiceManager.getService("isms"));,这个的服务类型有多种,
发送彩信********************************************************************************************
sendMmsWorker(spliter.getMMSConversation(),mmsUri, persister, slideshow, sendReq, subId);
/// M: Code analyze 047, For new feature ALPS00316567, add a parameter for msim . @{private void sendSmsWorker(String msgText, String semiSepRecipients, long threadId, int subId) {/// @}String[] dests = TextUtils.split(semiSepRecipients, ";"if (LogTag.VERBOSE || Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {Log.d(LogTag.TRANSACTION, "sendSmsWorker sending message: recipients=" +semiSepRecipients + ", threadId=" + threadId);}MessageSender sender = new SmsMessageSender(mActivity, dests, msgText, threadId, subId);try {sender.sendMessage(threadId);// Make sure this thread isn't over the limits in message countRecycler.getSmsRecycler().deleteOldMessagesByThreadId(mActivity, threadId);} catch (Exception e) {Log.e(TAG, "Failed to send SMS message, threadId=" + threadId, e);}mStatusListener.onMessageSent();MmsWidgetProvider.notifyDatasetChanged(mActivity);}  public boolean sendMessage(long token) throws MmsException {// In order to send the message one by one, instead of sending now, the message will split,// and be put into the queue along with each destinationsreturn queueMessage(token);}private boolean queueMessage(long token) throws MmsException {/// M:MmsLog.v(MmsApp.TXN_TAG, "queueMessage()"if ((mMessageText == null) || mMessageText.isEmpty() || (mNumberOfDests == 0)) {// Don't try to send an empty message.throw new MmsException("Null message body or dest.");}SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);boolean requestDeliveryReport = prefs.getBoolean(mSubId + "_" + SmsPreferenceActivity.SMS_DELIVERY_REPORT_MODE,DEFAULT_DELIVERY_REPORT_MODE);MmsLog.d(MmsApp.TXN_TAG, "SMS DR request=" + requestDeliveryReport);/// @}Uri smsUri = null;//star os add by liuweibolong timeStamp = System.currentTimeMillis();for (int i = 0; i < mNumberOfDests; i++) {try {if (LogTag.DEBUG_SEND) {Log.v(TAG, "queueMessage mDests[i]: " + mDests[i] + " mThreadId: " + mThreadId);}smsUri = mOpSmsMessageSender.queueMessage(mNumberOfDests,//star os modify by liuweibomContext.getContentResolver(), mDests[i], mMessageText, mTimestamp,requestDeliveryReport, mThreadId, mSubId, ­timeStamp);if (smsUri == null) {smsUri=Sms.addMessageToUri(mSubId,//star os modify by liuweibomContext.getContentResolver(),Uri.parse("content://sms/queued"), mDests[i],mMessageText, null, mTimestamp,true /* read */,requestDeliveryReport,mThreadId);}//star os add start by liuweiboIntent sentIt = new Intent("delay_send_sms", null, mContext,SmsReceiver.class);long msgId = Integer.valueOf(smsUri.toString().substring(14));sentIt.putExtra("message_id", msgId);mContext.sendBroadcast(sentIt);//star os add end by liuweibo} catch (SQLiteException e) {if (LogTag.DEBUG_SEND) {Log.e(TAG, "queueMessage SQLiteException", e);}SqliteWrapper.checkSQLiteException(mContext, e);}}// Notify the SmsReceiverService to send the message out//star os del start by liuweibo/*mContext.sendBroadcast(new Intent(SmsReceiverService.ACTION_SEND_MESSAGE,null,mContext,SmsReceiver.class));*///star os del end by liuweiboreturn false;} 

这里写图片描述

/frameworks/opt/telephony/src/java/android/telephony/SmsManager.java
sendStoredMultimediaMessage
/*** Send a system stored MMS message** This is used for sending a previously sent, but failed-to-send, message or* for sending a text message that has been stored as a draft.** @param messageUri the URI of the stored message* @param configOverrides the carrier-specific messaging configuration values to override for*  sending the message.* @param sentIntent if not NULL this <code>PendingIntent</code> is*  broadcast when the message is successfully sent, or failed* @throws IllegalArgumentException if messageUri is empty* {@hide}*/
public void sendStoredMultimediaMessage(Uri messageUri, Bundle configOverrides,
PendingIntent sentIntent) {
if (messageUri == null) {
throw new IllegalArgumentException("Empty message URI");
}
try {
IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms"));
if (iMms != null) {
iMms.sendStoredMessage(
getSubscriptionId(), ActivityThread.currentPackageName(), messageUri,
configOverrides, sentIntent);
}
} catch (RemoteException ex) {
// ignore it
}
}
短信接收***********************************************************************************
首先系统发出android.provider.Telephony.Sms.Intents.SMS_DELIVER_ACTION广播,然后SmsReceiver接收,接收后启动
service SmsReceiverService处理

这里写图片描述

系统是什么地方发送广播:


/frameworks/opt/telephony/src/java/com/android/internal/telephony/InboundSmsHandler.java

 /*** In the delivering state, the inbound SMS is processed and stored in the raw table.* The message is acknowledged before we exit this state. If there is a message to broadcast,* transition to {@link WaitingState} state to send the ordered broadcast and wait for the* results. When all messages have been processed, the halting state will release the wakelock.*/private class DeliveringState extends State {****@Overridepublic boolean processMessage(Message msg) {log("DeliveringState.processMessage:" + msg.what);log("DeliveringState.processMessage:" + msg.what);switch (msg.what) {case EVENT_BROADCAST_SMS:// if any broadcasts were sent, transition to waiting stateInboundSmsTracker inboundSmsTracker = (InboundSmsTracker) msg.obj;if (processMessagePart(inboundSmsTracker)) {transitionTo(mWaitingState);} else {// if event is sent from SmsBroadcastUndelivered.broadcastSms(), and// processMessagePart() returns false, the state machine will be stuck in// DeliveringState until next message is received. Send message to// transition to idle to avoid that so that wakelock can be releasedlog("No broadcast sent on processing EVENT_BROADCAST_SMS in Delivering " +"state. Return to Idle state");sendMessage(EVENT_RETURN_TO_IDLE);}return HANDLED;****private boolean processMessagePart(InboundSmsTracker tracker) {****dispatchSmsDeliveryIntent(pdus, tracker.getFormat(), destPort, resultReceiver,IConcatenatedSmsFwkExt.UPLOAD_FLAG_NONE);/private void dispatchSmsDeliveryIntent(byte[][] pdus, String format, int destPort,BroadcastReceiver resultReceiver, int longSmsUploadFlag) {// MTK­ENDIntent intent = new Intent();intent.putExtra("pdus", pdus);intent.putExtra("format", format);if (destPort == ­1) {intent.setAction(Intents.SMS_DELIVER_ACTION);***dispatchIntent(intent, android.Manifest.permission.RECEIVE_SMS,AppOpsManager.OP_RECEIVE_SMS, options, resultReceiver, UserHandle.SYSTEM);
­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­public void dispatchIntent(Intent intent, String permission, int appOp,Bundle opts, BroadcastReceiver resultReceiver, UserHandle user) {intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);******mContext.sendOrderedBroadcastAsUser(intent, user, permission, appOp, opts,resultReceiver, getHandler(), Activity.RESULT_OK, null, null);
到这里,消息广播就发送出去了。

这里写图片描述

将PDU数据插入到raw表中/*** Insert a message PDU into the raw table so we can acknowledge it immediately.* If the device crashes before the broadcast to listeners completes, it will be delivered* from the raw table on the next device boot. For single­part messages, the deleteWhere* and deleteWhereArgs fields of the tracker will be set to delete the correct row after* the ordered broadcast completes.** @param tracker the tracker to add to the raw table* @return true on success; false on failure to write to database*/private int addTrackerToRawTable(InboundSmsTracker tracker, boolean deDup) {

短信接收时序图:
这里写图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/17098.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android短信接收处理和发送

关于短信接收处理方面&#xff0c;当前已经有一些app做的比较好了&#xff0c;比如发给手机发验证码验证的问题&#xff0c;很多app在手机接收到验证码后&#xff0c;不需要输入&#xff0c;就直接可以跳过验证界面&#xff0c;这就是用到了对接收到的短信的处理。至于短信的发…

被 ChatGPT “霍霍”的文学界:由 AI 编写的投稿激增,17 岁老牌杂志宣布暂停征稿...

整理 | 郑丽媛 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 上线近三个月&#xff0c;这把名为 “ChatGPT” 的火&#xff0c;燃到了科技圈、烧到了教育界&#xff0c;如今终于也向文学界蔓延了——越来越多人开始用 ChatGPT 写文章甚至书籍。 在众多“尝鲜者”…

再不玩Midjourney Ai 绘画你就落伍了 超详细入门指南

本文来源&#xff1a;chatgoo 认识的设计朋友&#xff0c;他已经用Midjourney&#xff0c;从每天工作6小时&#xff0c;变成每天工作2小时了。 尤其是当甲方自己都不明确需求时&#xff0c;可以快速给出多种风格图片&#xff0c;确定后进行精修。标准版也就30美刀而已。 设计、…

2023 IJCAI YES 报名通道正式开启!快来上海与学术大咖、青年学者们来一场双向奔赴吧...

内容一览&#xff1a;2023 IJCAI YES 报名通道正式开启。本次盛会中&#xff0c;HyperAI超神经将作为协办单位参与其中。 关键词&#xff1a;2023 IJCAI YES WAIC IJCAI ChatGPT 的出现引领了一场人工智能界的狂欢&#xff0c;在科技巨头们前赴后继打响「诸神之战」的同…

万字干货:10 位科学、人文大咖论道,Max Tegmark 贡献思想火花,共同直面 AI 奇点时刻...

点击蓝字 &#xff5c;关注我们 2023 年 7 月 7 日&#xff0c;由世界人工智能大会 (WAIC) 组委会指导&#xff0c;国际人工智能联合会 (IJCAI) 中国办公室、华东师范大学联合主办&#xff0c;华东师范大学政治与国际关系学院承办&#xff0c;华东师范大学奇点政治研究院、安远…

马斯克称英伟达不会永远垄断AI芯片市场;苹果大幅削减MR头显销售目标;谷歌DeepMind发布新AI系统丨每日大事件...

‍ ‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 企业动态 星环科技&#xff1a;拟定增募资不超过15.2亿元 用于数据分析大模型建设等项目 6月7日&#xff0c;星环科技公告称&#xff0c;拟定增募资不超过15.2亿元&#xff0c;用于数据分析大模型建设项目、智能量化投研…

重磅!2023 智源大会完整日程公布,百场精彩报告研讨邀你参加

2023北京智源大会将于6月9日召开&#xff0c;我们邀请AI领域的探索者、实践者、以及关心智能科学的每个人&#xff0c;分享研究成果、交换实践经验、建立联系合作。本次大会核心议题包括&#xff1a;图灵奖得主Yann LeCun等领衔探讨大模型发展现状与未来趋势&#xff1b;未来生…

生成式 AI 或致全球三亿人失业

大家好&#xff0c;我是校长。 前几天看到一条新闻&#xff1a;几个月来&#xff0c;越来越多的知名人士预计&#xff0c;年内大热的 ChatGPT 有望掀起一场新的工业革命。而纵观历史&#xff0c;历次工业革命往往会深远改变当时的社会结构 —— 从机械织布机到内燃机再到第一台…

被陆奇文章刷屏了,细思极恐

大家好&#xff0c;我是校长。 最近陆奇的文章在网络上刷屏了。 2023 年 4 月 22 日&#xff0c;陆奇在上海举行小规模演讲&#xff0c;讲了他目前对大语言模型的一看自己的思考和看法。我看了腾讯新闻发布的长篇文章了&#xff0c;演讲的内容质量确实很高。 陆奇是谁呢&#x…

科大讯飞上半年营收78亿元;福特与英特尔协同开发自动驾驶;蚂蚁拟回购约7.6%股份丨每日大事件...

‍ ‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 企业动态 千方科技&#xff1a;公司目前已经完成自动驾驶产业链布局&#xff0c;并不断完善中 7月10日&#xff0c;千方科技在互动平台表示&#xff0c;公司从2015年开始布局无人驾驶相关业务&#xff0c;主要涉及如下几…

Python实现彩票双色球、大乐透随机预测出号

彩票要是能通过预测都能拿奖&#xff0c;那也是需要攒多少人品才行呀 老老实实做好事&#xff0c;多积德行善&#xff0c;做公益 近期出差的时候&#xff0c;闲来没事&#xff0c;下班路过彩站每天都顺便买一张彩票。 同时&#xff0c;就引发了对所学专业的应激反应&#xff…

放大招啦,用Python来预测双色球

一、需求简介 之前偶然见到一位网友提出了关于双色球数据的分析需求&#xff0c;感觉颇有趣味&#xff0c;便着手操作了一番。如下为某双色球发布站的页面&#xff0c;可以看到每期会产生红/蓝两种颜色的数字&#xff0c;其中红球为 33 选 6&#xff0c;蓝球为 16 选 1&#x…

java实现双色球彩票中奖游戏

目录 前言 一、游戏规则 二、代码实现 编程思想 代码展示 三、结果展示 前言 根据游戏规则&#xff0c;设计一个双色球号码竞猜游戏&#xff0c;根据规则&#xff0c;获得不同的奖项和奖金。 一、游戏规则 二、代码实现 编程思想 设置两个数组&#xff0c;分别记录输入的双色…

Python项目分析:预测双色球福利彩票中奖号码(随便玩玩,不要当真)

前言 双色球是中国福利彩票的一种玩法。 红球一共6组&#xff0c;每组从1-33中抽取一个&#xff0c;六个互相不重复。然后蓝球是从1-16中抽取一个数字&#xff0c;这整个组成的双色球 python从零基础入门到实战&#xff0c;想要源码数据集的&#xff0c;戳我 今天&#xff…

用Python预测双色球福利彩票中奖号码(请不要当真)

前言 双色球是中国福利彩票的一种玩法。 红球一共6组&#xff0c;每组从1-33中抽取一个&#xff0c;六个互相不重复。然后蓝球是从1-16中抽取一个数字&#xff0c;这整个组成的双色球 python从零基础入门到实战 今天&#xff0c;我们就用Python来统计一下各号码的中奖概率&…

Python预测双色球福利彩票中奖号码(随便玩玩,不要当真)

前言 铁子们应该都是听说过双色球的吧 双色球是中国福利彩票的一种玩法 红球一共6组&#xff0c;每组从1-33中抽取一个&#xff0c;六个互相不重复。然后蓝球是从1-16中抽取一个数字&#xff0c;这整个组成的双色球 今天&#xff0c;我们就用Python来统计一下各号码的中奖概…

双色球的程序代码

双色球其实是有个很有趣的小游戏,仅供大家参考和学习,别无他意. 代码: package test;import java.util.Arrays; import java.util.Random; import java.util.Scanner;public class ShuangSeQiu {public static void main(String[] args) throws InterruptedException {//彩票双…

Python项目分析:预测双色球福利彩票中奖号码

前言 大家早好、午好、晚好吖 ❤ ~ 双色球是中国福利彩票的一种玩法。 红球一共6组&#xff0c;每组从1-33中抽取一个&#xff0c;六个互相不重复。 然后蓝球是从1-16中抽取一个数字&#xff0c;这整个组成的双色球 python从零基础入门到实战&#xff0c;想要源码数据集的&…

基于python的数据分析系统,python数据分析经典案例

大家好&#xff0c;本文将围绕利用python进行数据分析案例展开说明&#xff0c;基于python的数据分析系统是一个很多人都想弄明白的事情&#xff0c;想搞清楚基于python的数据分析题目需要先了解以下几个事情。 1、如何利用python进行数据分析 利用python进行数据分析 链接: …

自己的智能AI聊天机器人,可自定义头像,免费html源码分享,粘贴即用!

1.展示效果 效果预览图&#xff1a; 新增小功能&#xff1a; ① 在原有的基础上加入了本地实时存档的功能&#xff0c;按照下面的步骤便可以随时在本地查看以往和智能AI所有的聊天记录哦&#xff01;再也不用担心关闭网页后先前的聊天内容全部消失啦&#xff01; PS&#xff1a…