高通android 7.0短信发送流程

原创 2017年09月11日 14:03:00
ComposeMessageActivity.java
sendMessage
mWorkingMessage.setWorkingMessageSub(mSelectedSubId);设置subId
mWorkingMessage.send(mDebugRecipients);
我们注意,在输入收件人获取的收件人和当前的mConversation.getRecipients()是不一样的,我们并不会每次编辑一次收件人就将其设置mConversation中,而我们发送短信时,当是新建短信人,其收件人是从收件编辑框获取,而不是新建,则是从mConversation中获取。

WorkingMessage.java代表着是一个当前正在编辑的短信
Conversation.java代表着当前的会话(一个会话对应着和一个联系人的联系,包含着多条短信彩信)

mText里面放着是发送的文本

new Thread(new Runnable() {
    @Override
    public void run() {
        preSendSmsWorker(conv, msgText, recipientsInUI);
        updateSendStats(conv);
    }
}, "WorkingMessage.send SMS").start();
启动后台线程来发送短信

preSendSmsWorker
mStatusListener.onPreMessageSent(); ComposeMessageActivity实现了这个借口,这样是根据短信当前状态来更新UI
发送之前对UI进行更新
ComposeMessageActivity
resetMessage() 有可能之前是新建短信,所以发送后要隐藏收件人编辑框等,还有处理焦点等

sendSmsWorker(msgText, semiSepRecipients, threadId);
调用SmsMessageSender的sendMessage来发送短信

deleteDraftSmsMessage(threadId);因为发送了,所以将属于这个thread对话的所有草稿都删除。

SmsMessageSender.java 其实这个类并不是执行真正发送短信的类,主要工作是新建sms记录,然后启动广播
sender = new SmsMessageSender(mActivity, dests, msgText, threadId,
                    mCurrentConvSubId);
先将发送短信需要的参数都传递进去

mStatusListener.onMessageSent();更新短信UI

SmsMessageSender.java
sendMessage
queueMessage
requestDeliveryReport是否需要发送报告,对应短信设置中的送达情况报告

int slotId = SubscriptionManager.getSlotId(mSubId);
这里对subId和slotId进行大致讲解:
subId,对应物理卡槽的位置,所以对于双卡,subId就分别为1和2,默认-1
slotId,是不断往上递增,也就是手机记录了手机插入的所有卡的信息,然后将他们存入到数据库中,可以看telephony表

Sms.addMessageToUri调用Telephony的方法在短信数据库的sms表中创建一条记录,thread表在之前获取threadId的时候就已经创建记录了。
Uri.parse("content://sms/queued")这是表示待发送的短信,一般uri后边附上queued这些类型的,都是设置字段type,表示当前短信的各种状态。
这里注意一点
if (deliveryReport) {
    values.put(STATUS, STATUS_PENDING);
}即如果需要发送情况报告的话,要将表中的status设置为pending

Intent intent = new Intent(SmsReceiverService.ACTION_SEND_MESSAGE, null, mContext,
                SmsReceiver.class);
intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, mSubId);
// Notify the SmsReceiverService to send the message out
mContext.sendBroadcast(intent);
接着启动广播

启动广播SmsReceiver.java
其action是SmsReceiverService中的
public static final String ACTION_SEND_MESSAGE =
            "com.android.mms.transaction.SEND_MESSAGE";

onReceive
onReceiveWithPrivilege
intent.setClass(context, SmsReceiverService.class);
intent.putExtra("result", getResultCode());
beginStartingService(context, intent);

启动服务SmsReceiverService,因为intent是之前传递过来的,所以之前设置的一些内容,例如action都还在的
onStartCommand
ServiceHandler mServiceHandler
handleSendMessage(intent);
sendFirstQueuedMessage(subId)为什么是first?这是考虑到长短信的场景,一条长短信要被分割成多条短信进行发送,但是数据库中只有一条,显示也只显示一条

final Uri uri = Uri.parse("content://sms/queued");
ContentResolver resolver = getContentResolver();
String where = "sub_id=?";
String[] whereArgs = new String[] {Integer.toString(subscription)};
Cursor c = SqliteWrapper.query(this, resolver, uri, SEND_PROJECTION, where, whereArgs, "date ASC"); 
将数据库中,queue状态的,subId等于要发送的subId,都从数据库查找出来,这样群发的就会将所有要群发的都查找出来。

 if (c.moveToNext()) {
   isExpectMore = true; 所以这个表示了是否还有短信要发送,跟群发有关
 }
SmsSingleRecipientSender这个类才是真正负责发送短信的类
调用sendMessage来发送短信
messageFailedToSend(msgUri, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
如果遇到异常,会将其type修改为failed

SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(mSubId);
ArrayList<String> messages 长短信会被切割
messages = smsManager.divideMessage(mMessageText); 分割短信

boolean moved = Sms.moveMessageToFolder(mContext, mUri, Sms.MESSAGE_TYPE_OUTBOX, 0);
改变其字段type,将其移动到发件箱

ArrayList<PendingIntent> deliveryIntents =  new ArrayList<PendingIntent>(messageCount);送达情况报告,这个是要送达到对方手机
ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>(messageCount);发送出去,只要发送成功就可以
deliveryIntents.add(PendingIntent.getBroadcast(
                        mContext, 0,
                        new Intent(
                                MessageStatusReceiver.MESSAGE_STATUS_RECEIVED_ACTION,
                                mUri,
                                mContext,
                                MessageStatusReceiver.class),
                                0));
Intent intent  = new Intent(SmsReceiverService.MESSAGE_SENT_ACTION,
                    mUri,
                    mContext,
                    SmsReceiver.class);
            intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, mSubId);
sentIntents.add(PendingIntent.getBroadcast(mContext, requestCode, intent, 0));

smsManager.sendMultipartTextMessage(mDest, mServiceCenter, messages,
                    sentIntents, deliveryIntents, mPriority, isExpectMore, validityPeriod);
这个才是真正发送短信的,当前,这个是在应用层的最终地方,到了framework层还有其他流程。

前面sentIntents,当短信发送,无论成功还是失败,会调用这个Intent,所以SmsReceiver->SmsReceiverService还是这个流程。
if (MESSAGE_SENT_ACTION.equals(intent.getAction())) {
     handleSmsSent(intent, error);
}

if (resultCode == Activity.RESULT_OK) 如果之前的发送成功,则
boolean sendNextMsg = intent.getBooleanExtra(EXTRA_MESSAGE_SENT_SEND_NEXT, false);
是否还有待发送的短信,记得之前isExpectMore ,应该就是和这个对应,有的话
if (sendNextMsg) {
    Log.v(TAG, "handleSmsSent: move message to sent folder uri: " + uri);
    if (!Sms.moveMessageToFolder(this, uri, Sms.MESSAGE_TYPE_SENT, error)) {
       Log.e(TAG, "handleSmsSent: failed to move message " + uri + " to sent folder");
    }
    sendFirstQueuedMessage(subId);
}

else if ((resultCode == SmsManager.RESULT_ERROR_RADIO_OFF) ||
                (resultCode == SmsManager.RESULT_ERROR_NO_SERVICE))
如果是因为这两种情况,一种是射频关闭,例如飞行模式(其中,如果处于飞行模式的时候,发送按钮是不可用的),一种是没有信号,则重新将他们放入到queue中
Sms.moveMessageToFolder(this, uri, Sms.MESSAGE_TYPE_QUEUED, error);
然后弹出目前无法发送信息,系统会在服务恢复后发送。提醒
这个系统服务恢复是否在下一次用同一个subId发送短信的时候才检测?看代码应该是。

else if (resultCode == SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE)
标志为错误,然后提醒,您只能向固定拨号号码发送信息。接着发送下一条短信如果有的话

最后剩下的,则归类于发送失败,然后接着发送下一条
messageFailedToSend(uri, error); 
if (sendNextMsg) {
     sendFirstQueuedMessage(subId);
}

相关文章推荐

MTK启动短信优化闪屏(闪白屏或者黑屏)

Activity启动的时候需要一段时间去初始化,这个时候就会有一定的延迟,为了提高用户体验,Android引入了StartingWindow来对这个过程进行过度,在真正的Activity进行初始化的时...

android之layout_weight属性

我们知道在xml布局的时候,LinearLayout下面的子控件可以使用layout_weight属性,那么我们根据源码,来分析下这个属性的一些知识点。 首先,在系统代码attrs.xml,我们可...

高通Android4.4短信发送流程

高通Android4.4短信发送流程
  • vvvvcp
  • vvvvcp
  • 2015年04月13日 11:11
  • 886

高通Android 4.4 彩信发送流程

MMS send flow in QCOM MMS发送流程图 Key Point 1:在点击短信界面的发送button(高通插入双卡后有两个botton)后,会进入ComposeMessag...
  • vvvvcp
  • vvvvcp
  • 2015年04月13日 11:16
  • 870

android4.4的短信发送流程

android4.4 原生代码信息分析之短信发送流程

Android短信发送流程之多收件人发送(原)

前面的《Android短信发送流程之长短信发送》中介绍了长短信对于普通短信的区别,而对于多收件人的情况,在SmsMessageSender的queueMessage()方法中我们了解到,发送之前,将多...

Android 短信发送流程

短信发送Framework流程,源代码的版本是4.4 1、通过Mms源代码可以知道短信发送最后调用的关键api如下: SmsSingleRecipientSender.java ...

Android短彩信源码解析-短信发送流程(三)

android短信pdu的压缩与解析代码逻辑。短信发送是发送短信打包成的byte数组信息,这个byte数组信息内包含了短信属性标识信息、短信正文信息、短信时间戳信息等。...

简述Android短信发送流程

详细解析短息发送流程:1、上层开发调用的接口函数:SmsManager.getDefault().sendTextMessage()函数实现: public void sendTextMessage(...

Android Mms短信的发送流程,短信发送源码解析

发送前的校验 从短信的点击按钮开始着手: // packages/apps/Mms/src/com/android/mms/ui/ComposeMessageActivity.java @O...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:高通android 7.0短信发送流程
举报原因:
原因补充:

(最多只允许输入30个字)