android的短信发送全过程源代码分析
首先调用 mWorkingMessage.send(); 发送短信
mWorkingMessage.send(); 不用猜测他是什么你就当作是Button的OnClick把
mWorkingMessage.send(){
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
LogTag.debug("send");
}
// Get ready to write to disk.
prepareForSave(true /* notify */);
// We need the recipient list for both SMS and MMS.
final Conversation conv = mConversation;
String msgTxt = mText.toString();
if (requiresMms() || addressContainsEmailToMms(conv, msgTxt)) {
// Make local copies of the bits we need for sending a message,
// because we will be doing it off of the main thread, which will
// immediately continue on to resetting some of this state.
//使我们的比特的信息需要发送一个本地副本,
//因为我们将做它关闭了主线程,这将
//立即继续以这种状态重置一些
final Uri mmsUri = mMessageUri;
final PduPersister persister = PduPersister.getPduPersister(mContext);
final SlideshowModel slideshow = mSlideshow;
final SendReq sendReq = makeSendReq(conv, mSubject);
// Make sure the text in slide 0 is no longer holding onto a reference to the text
// in the message text box.
slideshow.prepareForSend();
// Do the dirty work of sending the message off of the main UI thread.
new Thread(new Runnable() {
public void run() {
sendMmsWorker(conv, mmsUri, persister, slideshow, sendReq);
}
}).start();
} else {
// Same rules apply as above.
final String msgText = mText.toString();
new Thread(new Runnable() {
public void run() {
sendSmsWorker(conv, msgText); //抓住这点继续追查
}
}).start();
}
// update the Recipient cache with the new to address, if it's different更新了新的收件人地址缓存,如果它的不同
RecipientIdCache.updateNumbers(conv.getThreadId(), conv.getRecipients());
// Mark the message as discarded because it is "off the market" after being sent.
mDiscarded = true;
}
//-------------------------------------------------------------------------------------------------------------------
sendSmsWorker(conv, msgText){
mStatusListener.onPreMessageSent();
// Make sure we are still using the correct thread ID for our
// recipient set.
long threadId = conv.ensureThreadId();
String[] dests = conv.getRecipients().getNumbers(); //获取收件人的号码
try {
MessageSender sender = new SmsMessageSender(mContext, dests, msgText, threadId);//构造一个MessageSender
sender.sendMessage(threadId); //继续追查数据是怎么发送的
// Make sure this thread isn't over the limits in message count
Recycler.getSmsRecycler().deleteOldMessagesByThreadId(mContext, threadId);
} catch (Exception e) {
Log.e(TAG, "Failed to send SMS message, threadId=" + threadId, e);
}
mStatusListener.onMessageSent();
}
//一个默认的构造函数 没有什么特别的地方
public SmsMessageSender(Context context, String[] dests, String msgText, long threadId) {
mContext = context;
mMessageText = msgText;
mNumberOfDests = dests.length;
mDests = new String[mNumberOfDests];
System.arraycopy(dests, 0, mDests, 0, mNumberOfDests);
mTimestamp = System.currentTimeMillis();
mThreadId = threadId;
mServiceCenter = getOutgoingServiceCenter(mThreadId);
}
//-----------------------------------------------------------------------------
sender.sendMessage(threadId){
if ((mMessageText == null) || (mNumberOfDests == 0)) {
// Don't try to send an empty message.
throw new MmsException("Null message body or dest.");
}
SmsManager smsManager = SmsManager.getDefault();
//群体发送短信
for (int i = 0; i < mNumberOfDests; i++) {
ArrayList<String> messages = null; //将要发送的短信
if ((MmsConfig.getEmailGateway() != null) &&
(Mms.isEmailAddress(mDests[i]) || MessageUtils.isAlias(mDests[i]))) {
String msgText;
msgText = mDests[i] + " " + mMessageText; //对消息组装 我:你好
mDests[i] = MmsConfig.getEmailGateway();
messages = smsManager.divideMessage(msgText);
} else {
messages = smsManager.divideMessage(mMessageText);
}
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 + "\"");
}
ArrayList<PendingIntent> deliveryIntents =
new ArrayList<PendingIntent>(messageCount);
ArrayList<PendingIntent> sentIntents =
new ArrayList<PendingIntent>(messageCount);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
boolean requestDeliveryReport = prefs.getBoolean(
MessagingPreferenceActivity.SMS_DELIVERY_REPORT_MODE,
DEFAULT_DELIVERY_REPORT_MODE);
Uri uri = null;
try {
uri = Sms.Outbox.addMessage(mContext.getContentResolver(), mDests[i],
mMessageText, null, mTimestamp, requestDeliveryReport, mThreadId); //将要发送的短信添加到数据库中
} catch (SQLiteException e) {
SqliteWrapper.checkSQLiteException(mContext, e);
}
for (int j = 0; j < messageCount; j++) {
if (requestDeliveryReport) {
// TODO: Fix: It should not be necessary to
// specify the class in this intent. Doing that
// unnecessarily limits customizability.
deliveryIntents.add(PendingIntent.getBroadcast(
mContext, 0,
new Intent(
MessageStatusReceiver.MESSAGE_STATUS_RECEIVED_ACTION,
uri,
mContext,
MessageStatusReceiver.class),
0));
}
sentIntents.add(PendingIntent.getBroadcast(
mContext, 0,
new Intent(SmsReceiverService.MESSAGE_SENT_ACTION,
uri,
mContext,
SmsReceiver.class),
0));
}
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
log("sendMessage: address[" + i + "]=" + mDests[i] + ", threadId=" + mThreadId +
", uri=" + uri + ", msgs.count=" + messageCount);
}
try {
smsManager.sendMultipartTextMessage( //该是核心发送模块了吧 结果失望了
mDests[i], mServiceCenter, messages, sentIntents,
deliveryIntents);
} catch (Exception ex) {
throw new MmsException("SmsMessageSender.sendMessage: caught " + ex +
" from SmsManager.sendMultipartTextMessage()");
}
}
return false;
}
//-----------------------------------------------------------------
smsManager.sendMultipartTextMessage(
mDests[i], mServiceCenter, messages, sentIntents,
deliveryIntents){
String destinationAddress, //对方地址
String scAddress, //消息中心
ArrayList<String> parts, //消息 不过是大块的分成小块的啦
ArrayList<PendingIntent> sentIntents,
ArrayList<PendingIntent> deliveryIntents) {
if (TextUtils.isEmpty(destinationAddress)) {
throw new IllegalArgumentException("Invalid destinationAddress");
}
if (parts == null || parts.size() < 1) {
throw new IllegalArgumentException("Invalid message body");
}
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); //继续追查ing
}
}
//------------------------------------------------------------------
sendTextMessage(destinationAddress, scAddress, parts.get(0),
sentIntent, deliveryIntent){
String destinationAddress, String scAddress, String text,
PendingIntent sentIntent, PendingIntent deliveryIntent) {
if (TextUtils.isEmpty(destinationAddress)) {
throw new IllegalArgumentException("Invalid destinationAddress");
}
if (TextUtils.isEmpty(text)) {
throw new IllegalArgumentException("Invalid message body");
}
try {
ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms")); //获得分布式通知服务
if (iccISms != null) {
iccISms.sendText(destinationAddress, scAddress, text, sentIntent, deliveryIntent); //终于到了核心发送模块
}
} catch (RemoteException ex) {
// ignore it
}
}
//--------------------------------------------------------------------------------------------
结论google的短信发送过程结构比较合理但是过于复杂
对于短信的发送 核心部分就是
ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms")); //获得分布式通知服务
if (iccISms != null) {
iccISms.sendText(destinationAddress, scAddress, text, sentIntent, deliveryIntent); //终于到了核心发送模块
其中ServiceManager.getService("isms")这个我们不必继续查了知道他就是通知底层(C++)我要获得一个ISMS服务的接口规范
然后调用.sendText(destinationAddress, scAddress, text, sentIntent, deliveryIntent); 将信息发布出去
destinationAddress 接收者的地址 手机号码
scAddress 暂时没深入关注 猜测可能是中心号
text 不说了
sentIntent ,deliveryIntent 暂时没怎么看
android的短信发送全过程源代码分析相关推荐
- Android Sms短信发送
界面布局: 具体代码: private void sendSms() {// 获取电话号码和短信内容String number = number1.getText().toString();Strin ...
- Android短信发送流程之长短信发送(原)
从前面< Android短信发送流程之普通短信发送 >流程看到,长短信与普通短信的流程从SmsManager的sendMultipartTextMessage()方法开始区分,现在我们来看 ...
- Android短信发送流程之普通短信发送(原)
我们先来看最简单的流程入手分析,即收件人只有一个,而且不是长短信的情况. 一.地址有效性检测 当点击发送按钮时,触发onClick事件: [java] view plaincopy @ComposeM ...
- Android6.0的SMS(短信)源码分析--短信发送
1 SMS发送流程 1.1 SmsManager Android发送短信的接口可以认为是SmsManager,当然并不是所有的App都可以发送短信的,必须配置相关的权限.App中可以通过S ...
- Android Mms短信的发送流程,短信发送源码解析
发送前的校验 从短信的点击按钮开始着手: // packages/apps/Mms/src/com/android/mms/ui/ComposeMessageActivity.java@Overrid ...
- Android项目实践——短信发送接口的封装与设计
版权声明:本文为博主原创文章,未经博主允许不得转载. 系列教程:Android开发之从零开始系列 大家要是看到有错误的地方或者有啥好的建议,欢迎留言评论 前言:前一段时间公司服务端开发人手不足,而项目 ...
- 一枚Android 短信小偷 病毒的分析
一.样本简介 样本来自于吾爱破解论坛链接地址为http://www.52pojie.cn/thread-410238-1-1.html,样本不是很复杂有空就分析了一下.Android病毒样本还是很有意 ...
- android 11.0屏蔽短信功能(短信发送开关)
1.概述 11.0定制化开发中,需要去掉短信发送功能,这就要从发送短信的流程中来分析了,从流程中了解是如何发送短信的,然后从短信的发送部分,根据系统属性来决定是否继续走完发送短信的流程 2.屏蔽短信功 ...
- Android 12.0 屏蔽短信功能(短信发送开关)
1.概述 在12.0定制化开发中,在一些wifi产品中,需要去掉短信发送功能,这就要从发送短信的流程中来分析了,从流程中了解是如何发送短信的,然后从短信的发送部分,根据系统属性来决定是否继续走完发送短 ...
最新文章
- IPsec ××× 配置實例
- es6箭头函数this问题
- qt creator:一款能够在windows/linux/mac系统上开发c程序的IDE
- ssm三大框架工作原理_蒸发器最常见的三大工作原理
- php memcache可存,php使用memcache共享存储session(二)
- mysql_sed_使用sed提取mysql备份的一行部分
- Java命令行界面(第27部分):cli-parser
- Missing iOS Distribution signing identity问题解决
- Linux 进程状态 说明
- Google工程师多图详解Android系统架构
- idea 常用配置和快捷键
- 结构力学求解器_结构力学学好这些内容对施工很关键,你都学懂了吗?
- 解剖SQLSERVER 第九篇 OrcaMDF现在能通过系统DMVs显示元数据(译)
- 第四章 类中数据的共享和保护
- 计算机专业毕业设计题目大全(各种类型系统设计想法汇总)
- 『NLP学习笔记』AllenNLP的注册机制
- 论文中MathType公式居中,编号右对齐
- 华为无线ensp跨ac三层漫游
- 【开发模板】Vue和SpringBoot的前后端分离开发模板
- Python学习——语法错误与异常
热门文章
- 隐私计算秘密学-秘密分享
- 申请开通自媒体账号的署名文章
- Tensorflow 2.* 网络训练(二) fit(x, y, batch_size, epochs, verbose, validation_split, initial_epoch... )
- 【杂七杂八的笔记】2019CVPR论文快读
- 教你分析快递揽收后,第二条物流是否超过12小时
- Linux驱动学习--V4L2框架
- java.lang.NoClassDefFoundError: com/huaban/analysis/jieba/JiebaSegmenter
- exadata的infiniband交换机的ilom
- DVWA windows提权
- 多域名同一空间的处理实例附(ASP代码)