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产品中,需要去掉短信发送功能,这就要从发送短信的流程中来分析了,从流程中了解是如何发送短信的,然后从短信的发送部分,根据系统属性来决定是否继续走完发送短 ...
最新文章
- Mysql5.7数据导出提示--secure-file-priv选项问题的解决方法
- linux7开启ntp服务,【NTP】CentOS7.2配置NTP服务
- arthas 查看哪个方法调用最耗时_阿里巴巴问题排查神器Arthas使用实践
- python-模拟property
- 那些在开发中用到的正则表达式
- Java FX swt_转: JAVA_SWT常用事件, 和方法
- endnotex8使用教程_EndnoteX8快速使用详细步骤
- Latex 箭头上面写字母
- oracle11g ora12170,11g告警日志中大量ORA-12170错误
- 《匆匆那年》的你,还记得吗?数学中的那些有(hui)趣(se)的定理(5)——鸡爪定理
- 高考作文题“幸存者偏差”难哭了?这有份标准答案
- windows安装golang多版本管理工具gvm/g
- 前端日历,vue日历,一周的日历
- 联想Y7000安装Ubuntu16.04/Win10双系统,wifi问题,显卡驱动和CUDA10安装
- Android Studio中 HAXM安装失败的问题(Intel HAXM installation failed. To install Intel HAXM follow the...)
- Android加载/处理超大图片神器!SubsamplingScaleImageView(subsampling-scale-image-view)【系列1】
- (转)GCC内联汇编入门
- 因式分解理论基础(3)最大公因式
- NP管理器和MT哪个强_MT管理器相信大家都很熟悉的[勉强],功能可以说非常强大,开发逆向的时候经常需要用到。...
- Go语言教程[一、Go语言概述]
热门文章
- 充分必要条件与C语言,充分条件与必要条件知识点总结,高中数学充分条件与必要条件知识点总结...
- 用Python编写斐波那契数列(Fibonacci Sequence)
- 【luogu 3868】中国剩余定理模板题
- 重磅消息!微信Windows电脑版本,终于支持刷朋友圈啦!
- reactos操作系统实现(119)
- 中文拼音的正则表达式
- CalendarPicker
- 机器学习-----聚类kmeans肘部图、轮廓图的绘制、以及聚类和聚类中心散点图的绘制
- java游戏房间匹配_一种游戏房间匹配方法与流程
- 从Mate X3看华为折叠屏手机的创新领启