当你在编辑界面ComposeMessageActivity.java按下发送按钮的那一刻,就开始信息的发送之路。当然发短信和发彩信并不完全一样,会用两篇文章别说明,不过最后的图是画在一起的。
从ComposeMessageActivity.java的onclick()开始,在这里对联系人的个数是有个判断的,这个函数 isPreparedForSending(),这个判断之后会通过confirmSendMessageIfNeeded()检查联系人是否有效,如包含无效联系人会有对话框提示的,还是比较友好的。这里要注意的是源码判断少于3个数字的联系人是非法的,并且数字号码是否合法的判断方法也不是很严密,4.0的代码貌似把多选联系人的功能加上去,这个方法 launchMultiplePhonePicker(),对应代码如下。
public void onClick(View v) { if ((v == mSendButtonSms || v == mSendButtonMms) && isPreparedForSending()) { confirmSendMessageIfNeeded(); } else if ((v == mRecipientsPicker)) { launchMultiplePhonePicker(); } }
private void sendSmsWorker(String msgText, String semiSepRecipients, long threadId) {//文本内容,收件人,会话ID String[] dests = TextUtils.split(semiSepRecipients, ";"); MessageSender sender = new SmsMessageSender(mActivity, dests, msgText, threadId);//运行时绑定,这算是多态的一个应用吧。 try { sender.sendMessage(threadId); // Make sure this thread isn't over the limits in message count Recycler.getSmsRecycler().deleteOldMessagesByThreadId(mActivity, threadId); } catch (Exception e) { Log.e(TAG, "Failed to send SMS message, threadId=" + threadId, e); } mStatusListener.onMessageSent(); }
到了短信的关键服务SmsReceiverService.java,关键的原因是因为发送接收都在这里,这是必经之路,发送是要走sendFirstQueuedMessage(),发送成功或失败的消息handleSmsSent()这个函数处理,实际发送是在SmsSingleRecipientSender.java这个类里,在这处理会把长短信分段,这个代码:
messages = smsManager.divideMessage(mMessageText)处理完长短信,发送信息执行下面代码,这个代码后我们就要离开packages层了。
smsManager.sendMultipartTextMessage(mDest, mServiceCenter, messages, sentIntents, deliveryIntents);
Framework层 SmsManager.java的sendMultipartTextMessage()方法、sendTextMessage()和sendDataMessage()方法负责发送,前两个发普通短信,最后一个发端口短信比如以短信形式发vcard。再向下跟GsmSMSDispatcher.java的sendText()方法,在个方法里开始编码了,看贴出的代码:
protected void sendText(String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent) { SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( scAddr, destAddr, text, (deliveryIntent != null)); if (pdu != null) { sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent); } else { Log.e(TAG, "GsmSMSDispatcher.sendText(): getSubmitPdu() returned null"); } }还在这个类里sendSms()方法,这里调用的Ril.java的方法,终于到ril了。
protected void sendSms(SmsTracker tracker) { HashMap<String, Object> map = tracker.mData; byte smsc[] = (byte[]) map.get("smsc"); byte pdu[] = (byte[]) map.get("pdu"); Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker); mCm.sendSMS(IccUtils.bytesToHexString(smsc), IccUtils.bytesToHexString(pdu), reply); }Ril.java的方法,看好那个TAG,RIL_REQUEST_SEND_SMS这个我们会在Referece-ril.c的代码中找到它,当然这是源码,不同的vendor厂商可能会根据自己的需要修改的
public void sendSMS (String smscPDU, String pdu, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_SEND_SMS, result); rr.mp.writeInt(2); rr.mp.writeString(smscPDU); rr.mp.writeString(pdu); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); }到这里,发短信的流程基本上结束了,当然这里还很多细节没有展开,比如短信的编码,别急,后面我会写的