公司設立流程詳細,Android 2.3發短信詳細流程

 2023-10-06 阅读 25 评论 0

摘要:在android中,APP通過SmsManager.java一系列方法實現發送短信的功能,而發送的內容有很很多種,比如sendTextMessage、sendMultipartTextMessage、sendDataMessage等等,在這篇文章里我們就以其中一個為例闡述發送短信的完整流程,如果有不對的

在android中,APP通過SmsManager.java一系列方法實現發送短信的功能,而發送的內容有很很多種,比如sendTextMessage、sendMultipartTextMessage、sendDataMessage等等,在這篇文章里我們就以其中一個為例闡述發送短信的完整流程,如果有不對的地方,請大家指正,一起學習。

1. 起點:SmsManager.java (frameworks/base/telephony/java/android/telephony/SmsManager.java)

sendTextMessage的核心代碼如下:


view plaincopy to clipboardprint?public void sendTextMessage(?
????????? ......?
?????? try {?
?????????? ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));?
?????????? if (iccISms != null) {?
?????????????? iccISms.sendText(destinationAddress, scAddress, text, sentIntent, deliveryIntent);?
?????????? }?
?????? } catch (RemoteException ex) {?
?????????? // ignore it??
?????? }?
?? }?
?public void sendTextMessage(
?????????? ......
??????? try {
??????????? ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
??????????? if (iccISms != null) {
??????????????? iccISms.sendText(destinationAddress, scAddress, text, sentIntent, deliveryIntent);
??????????? }
??????? } catch (RemoteException ex) {
??????????? // ignore it
??????? }
??? }其中,view plaincopy to clipboardprint?ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));?
ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));是通過AIDL的方式,獲得服務,再調用這個服務對象的sendText()方法,那這個服務對象在哪里呢?
2. 我們知道,在eclipse中創建一個xx.aidl文件后,IDE會利用相關工具自動生成一個名為xx.java的接口,它有一個名為Stub的內部類,那我們自己創建一個類并繼承這個內部類,則可以實現了進程間的通信,這個是aidl的知識,這兒不詳述。我們往下看:

公司設立流程詳細,根據aidl的實現流程,那該服務對象應該是繼承了ISms.Stub,經過查找我們發現這個服務類:IccSmsInterfaceManagerProxy.java,所以從SmsManager.sendTextMessage()方法調用了IccSmsInterfaceManagerProxy對象的sendText()方法。

3. 第二階段:IccSmsInterfaceManagerProxy.java(frameworks/base/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy)

我們看IccSmsInterfaceManagerProxy的sendText()方法核心代碼:

view plaincopy to clipboardprint?private IccSmsInterfaceManager mIccSmsInterfaceManager;?
......?
public void sendText(String destAddr, String scAddr,?
??????????? String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {?
??????? mIccSmsInterfaceManager.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent);?
??? }?
private IccSmsInterfaceManager mIccSmsInterfaceManager;
......
public void sendText(String destAddr, String scAddr,
??????????? String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
??????? mIccSmsInterfaceManager.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent);
??? }
繼續調用,此時調用的是IccSmsInterfaceManager對象的sendText()方法,那IccSmsInterfaceManager是什么玩意??

4. 第三階段:IccSmsInterfaceManager.java(frameworks/base/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java)

Android。從代碼看出IccSmsInterfaceManager是一個繼承了ISms.Stub的抽象類,相關核心代碼如下:

view plaincopy to clipboardprint?protected SMSDispatcher mDispatcher;?
public void sendText(String destAddr, String scAddr,?
??????????? String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {?
??????? mPhone.getContext().enforceCallingPermission(?
??????????????? "android.permission.SEND_SMS",?
??????????????? "Sending SMS message");?
??????? if (Log.isLoggable("SMS", Log.VERBOSE)) {?
??????????? log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr +?
??????????????? " text='"+ text + "' sentIntent=" +?
??????????????? sentIntent + " deliveryIntent=" + deliveryIntent);?
??????? }?
??????? mDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent);?
??? }?
protected SMSDispatcher mDispatcher;
public void sendText(String destAddr, String scAddr,
??????????? String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
??????? mPhone.getContext().enforceCallingPermission(
??????????????? "android.permission.SEND_SMS",
??????????????? "Sending SMS message");
??????? if (Log.isLoggable("SMS", Log.VERBOSE)) {
??????????? log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr +
??????????????? " text='"+ text + "' sentIntent=" +
??????????????? sentIntent + " deliveryIntent=" + deliveryIntent);
??????? }
??????? mDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent);
??? }
IccSmsInterfaceManager對象的sendText()方法調用了SMSDispatcher類的sendText()方法,繼續往下:
5. 第四階段:SMSDispatcher.java(frameworks/base/telephony/java/com/android/internal/telephony/SMSDispatcher.java)

該類是一個抽象類,它的sendText()并沒有實現,它的實現類是GsmSMSDispatcher.java或者CdmaSMSDispatcher.java,假設我們用的GSM網絡,則此時調用到GsmSMSDispatcher的sendText()方法。

6. 第五階段:GsmSMSDispatcher.java(frameworks/base/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java)

核心代碼如下:

活動流程?view plaincopy to clipboardprint?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);?
??? }?
......?
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);
??? }
......

到這兒,"sendText()"這個字眼就沒了,換成了另外一個方法名:sendRawPdu(),追蹤這個方法可以發現它是SMSDispatcher.java的一個方法,這個類看著很眼熟吧?不錯,在第四階段我們已經和它打過交道了!我們來看看它的sendRawPdu到底是干嘛的:view plaincopy to clipboardprint?protected void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,?
??????????? PendingIntent deliveryIntent) {?
?????????? ......?
?????????? sendSms(tracker);?
?????????? .....?
?}?
protected void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
??????????? PendingIntent deliveryIntent) {
?????????? ......
?????????? sendSms(tracker);
?????????? .....
?}又來了一個新方法名:sendSms(),從sendRawPdu()傳來的信息經過封裝傳遞給sendSms()方法進行處理,而在SMSDispatcher.java中,這個方法只是聲明了一下,它的具體實現由子類:GsmSMSDispatcher.java完成。下面我們來看GsmSMSDispatcher.java
7. 第六階段:GsmSMSDispatcher.java(frameworks/base/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java)

GsmSMSDispatcher.java的sendSms()方法核心代碼如下:

view plaincopy to clipboardprint?protected CommandsInterface mCm;?
?
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);?
??? }?
protected CommandsInterface mCm;

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);
??? }離成功已經不遠了....
我們知道,CommandsInterface是一個特殊的接口,它的RIL.java息息相關,而在上面的代碼中sendSms()調用來CommandsInterface對象的sendSMS()方法來做事情,而CommandsIterface是一個接口,所以事情只好由它的兒子(其實是孫子,RIL的爸爸BaseCommands是CommandsInterface的兒子)來完成,好,進入RIL.java.

8. 第七階段:RIL.java(/frameworks/base/telephony/java/com/android/internal/telephony/RIL.java)

只要研究過ril層的,對這玩意都一定很熟悉,所以直接看它的sendSMS()方法:

view plaincopy to clipboardprint?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);?
??? }?
?
//send(RILRequest rr)??
<pre name="code" class="java">private void?
??? send(RILRequest rr) {?
??????? Message msg;?
?
??????? msg = mSender.obtainMessage(EVENT_SEND, rr);?
?
??????? acquireWakeLock();?
?
??????? msg.sendToTarget();?
??? }?
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);
??? }

//send(RILRequest rr)
<pre name="code" class="java">private void
??? send(RILRequest rr) {
??????? Message msg;

??????? msg = mSender.obtainMessage(EVENT_SEND, rr);

安卓手機怎么發送短信???????? acquireWakeLock();

??????? msg.sendToTarget();
??? }

OK!在sendSMS()方法中,我們把上面所傳下來的東東寫入到Parcel中,協同一個特殊的RILRequest被發送出去,發送到哪里了?接著看:view plaincopy to clipboardprint?public void?
??????? handleMessage(Message msg) {?
??????????? RILRequest rr = (RILRequest)(msg.obj);?
??????????? RILRequest req = null;?
?
??????????? switch (msg.what) {?
??????????????? case EVENT_SEND:?
??????????????????? boolean alreadySubtracted = false;?
??????????????????? try {?
????????????????????? LocalSocket s;?
????????????????????? ......?
????????????????????? s.getOutputStream().write(dataLength);?
????????????????????? s.getOutputStream().write(data);?
??????????????????? } catch (IOException ex) {?
????????????????????? ......??????
??????????????????? }?
??????????????????? break;?
??????????? }?
??????? }?
public void
??????? handleMessage(Message msg) {
??????????? RILRequest rr = (RILRequest)(msg.obj);
??????????? RILRequest req = null;

??????????? switch (msg.what) {
??????????????? case EVENT_SEND:
??????????????????? boolean alreadySubtracted = false;
??????????????????? try {
????????????????????? LocalSocket s;
????????????????????? ......
????????????????????? s.getOutputStream().write(dataLength);
????????????????????? s.getOutputStream().write(data);
??????????????????? } catch (IOException ex) {
????????????????????? ......????
??????????????????? }
??????????????????? break;
??????????? }
??????? }重點:LocalSocket、s.getOutputStream().write(data)
我們把短信相關的數據及特殊RILRequst對象寫入到Socket的的輸出流中,進而將數據傳遞到RIL層,即底層,然后RIL層通過接收Socket中傳過來的數據解析得到請求內容并進行處理,到此,發短信的Java部分講完了。

RIL層以后再分析,如果文中有不對的地方,請大家告訴我,謝謝!

安卓手機怎么發短信給別人、轉載于:https://www.cnblogs.com/kevincode/p/3868380.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/2/120135.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息