【#文档大全网# 导语】以下是®文档大全网的小编为您整理的《短信发送流程》,欢迎阅读!
详细解析短息发送流程:
1、上层开发调用的接口函数:SmsManager.getDefault().sendTextMessage() 函数实现:
public void sendTextMessage(
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"));// 在Binder注册服务,通过iccISms调用底层接口 if (iccISms != null) {
iccISms.sendText(destinationAddress, scAddress, text, sentIntent, deliveryIntent);// 调用底层函数 }
} catch (RemoteException ex) { // ignore it } }
2、Isms中处理sendText 到ISms.java中查找此函数发现有两个,尴尬,为什么会有两个? 有一个是:iccISms.sendText 另一个是:Proxy:sendText 明白了,一看就知道我们要的是第一个。但是当我们查看第一个函数的时候发现没有实现。。。为什么呢?这时候就要说到一个机制:Binder,这里就是它在捣鬼。这里给我们提供的接口就是Binder客户端的接口,具体实现是在Binder的服务。
3、寻找Binder服务中哪里实现的sendText
sendText是在SMSDispatcher.java文件中,但是他的实现是在GsmSMSDispatcher.java或者CdmaSMSDispatcher.java文件中。
protected void sendText(String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( scAddr, destAddr, text, (deliveryIntent != null));
sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent); }
4、sendRawPdu这个函数又返回到SMSDispatcher.java文件中,
protected void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent, PendingIntent deliveryIntent) {
if (pdu == null)
{
if (sentIntent != null)
{
try
{
sentIntent.send(RESULT_ERROR_NULL_PDU); } catch (CanceledException ex) {} } return;
}
HashMap map = new HashMap();
map.put("smsc", smsc); map.put("pdu", pdu);
SmsTracker tracker = new SmsTracker(map, sentIntent, deliveryIntent);
int ss = mPhone.getServiceState().getState();
if (ss != ServiceState.STATE_IN_SERVICE) { handleNotInService(ss, tracker); } else {
String appName = getAppNameByIntent(sentIntent); if (mCounter.check(appName, SINGLE_PART_SMS)) { sendSms(tracker); } else {
sendMessage(obtainMessage(EVENT_POST_ALERT, tracker)); } } }
5、sendSms看到这个函数感觉离真正干活的地方不远了。此函数又跑到GsmSMSDispatcher.java或者CdmaSMSDispatcher.java文件中了,说明两个网的实现方式还有有一定差异的。
protected void sendSms(SmsTracker tracker) { HashMap 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); }
有必要说一下mCm这个成员变量,比变量声明为:CommandsInterface,(怎么跑出来这么个东西?)这个是Ril层的接口层,里边提供了Ril实现的功能。
看到这里我们就可以跨过Ril机制了,直接找我们想要的功能实现。CommandsInterface.java只是提供接口,具体实现在Ril.java中。
6、sendSMS此函数在Ril.java中,看看怎么实现的。(这是什么东西,没看明白) 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); }
Ril.java中的实现方式基本都是一个样子,就是send(rr),这其实是Ril的机制,Ril.java其实是Rild的一个代理,他负责给Rild发消息,通知他去做具体的操作。
7、看看谁处理了RIL_REQUEST_SEND_SMS这个消息就知道谁在干活了。 onRequest
此函数就是处理消息的函数。对应case RIL_REQUEST_SEND_SMS会调用相应的函数requestSendSMS(data, datalen, t);
8、再往下看就是如何将请求编辑成AT命令发送给cp层了,这样就是Ril的真正意义。没必要再写了。
本文来源:https://www.wddqxz.cn/c3a6c71efc4ffe473368abca.html