短信发送流程
说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。
详细解析短息发送流程: 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.wddqw.com/doc/c3a6c71efc4ffe473368abca.html