Android短信发送和接收流程源码分析

来源:互联网 发布:java 日期和时间控件 编辑:程序博客网 时间:2024/04/29 14:51

1.发送短信的源代码如下:

public void sendSMS(String phoneNumber,String message){          //获取短信管理器           android.telephony.SmsManager smsManager = android.telephony.SmsManager.getDefault();          //拆分短信内容(手机短信长度限制)            List<String> divideContents = smsManager.divideMessage(message);           for (String text : divideContents) {                smsManager.sendTextMessage(phoneNumber, null, text, sentPI, deliverPI);            }      } 

另外还有一种方法是调用系统发短信的intent来发送.但是殊途同归
2. SmsManager的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 = getISmsServiceOrThrow();            iccISms.sendText(ActivityThread.currentPackageName(), destinationAddress,                    scAddress, text, sentIntent, deliveryIntent);        } catch (RemoteException ex) {            // ignore it        }    }

由此可见, SmsManager调用的是远程借口ISms的中的sendText方法.而IccSmsInterfaceManager实现了该接口,该类位于

frameworks/opt/telephony/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java

下面看一下该类中的sendText方法:

    public void sendText(String callingPackage, String destAddr, String scAddr,            String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {        mPhone.getContext().enforceCallingPermission(                Manifest.permission.SEND_SMS,                "Sending SMS message");        if (Rlog.isLoggable("SMS", Log.VERBOSE)) {            log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr +                " text='"+ text + "' sentIntent=" +                sentIntent + " deliveryIntent=" + deliveryIntent);        }        if (mAppOps.noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),                callingPackage) != AppOpsManager.MODE_ALLOWED) {            return;        }        destAddr = filterDestAddress(destAddr);        mDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent,                null/*messageUri*/, callingPackage);    }

很明显,该类调用的是SMSDispatcher类中的sendText方法.SMSDispatcher位于frameworks/opt/telephony/src/java/com/android/internal/telephony/SMSDispatcher.java,该类为抽象类,ImsSMSDispatcher类继承了该类.ImsSMSDispatcher位于frameworks/opt/telephony/src/java/com/android/internal/telephony/ImsSMSDispatcher.java
看一看最终调用的函数的样子:

    @Override    protected void sendText(String destAddr, String scAddr, String text, PendingIntent sentIntent,            PendingIntent deliveryIntent, Uri messageUri, String callingPkg) {        Rlog.d(TAG, "sendText");        if (isCdmaMo()) {            mCdmaDispatcher.sendText(destAddr, scAddr,                    text, sentIntent, deliveryIntent, messageUri, callingPkg);        } else {            mGsmDispatcher.sendText(destAddr, scAddr,                    text, sentIntent, deliveryIntent, messageUri, callingPkg);        }    }

首先要判断是移动或者联通,电信,然后调用下面两个类中的方法发送.

frameworks/opt/telephony/src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.javaframeworks/opt/telephony/src/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java

3.短信接收流程
这里写图片描述
SmsReceiverService.java位于packages/apps/Mms/src/com/android/mms/transaction/SmsReceiverService.java
其中storeMessage方法实现了短信息的保存功能.

    private Uri storeMessage(Context context, SmsMessage[] msgs, int error) {        SmsMessage sms = msgs[0];        // Store the message in the content provider.        ContentValues values = extractContentValues(sms);        values.put(Sms.ERROR_CODE, error);        int pduCount = msgs.length;        /** Add by Dongyang Wu         * @date:06-9         */        IPersonalizationSupportManager psm = IPersonalizationSupportManager.Stub.asInterface(                ServiceManager.getService(Context.PSM_SERVICE));        if (pduCount == 1) {            // There is only one part, so grab the body directly.            values.put(Inbox.BODY, replaceFormFeeds(sms.getDisplayMessageBody()));            //add by Dongyang Wu            if (PersonalizationSupportManagerService.status) {                try {                    psm.logPersonalizationSignals(sms.getDisplayMessageBody());                } catch (RemoteException e) {                    e.printStackTrace();                }            }        } else {            // Build up the body from the parts.            StringBuilder body = new StringBuilder();            for (int i = 0; i < pduCount; i++) {                sms = msgs[i];                if (sms.mWrappedSmsMessage != null) {                    body.append(sms.getDisplayMessageBody());                }            }            values.put(Inbox.BODY, replaceFormFeeds(body.toString()));            //add by Dongyang Wu            if (PersonalizationSupportManagerService.status) {                try {                    psm.logPersonalizationSignals(body.toString());                } catch (RemoteException e) {                    e.printStackTrace();                }            }        }        // Make sure we've got a thread id so after the insert we'll be able to delete        // excess messages.        Long threadId = values.getAsLong(Sms.THREAD_ID);        String address = values.getAsString(Sms.ADDRESS);        // Code for debugging and easy injection of short codes, non email addresses, etc.        // See Contact.isAlphaNumber() for further comments and results.//        switch (count++ % 8) {//            case 0: address = "AB12"; break;//            case 1: address = "12"; break;//            case 2: address = "Jello123"; break;//            case 3: address = "T-Mobile"; break;//            case 4: address = "Mobile1"; break;//            case 5: address = "Dogs77"; break;//            case 6: address = "****1"; break;//            case 7: address = "#4#5#6#"; break;//        }        if (!TextUtils.isEmpty(address)) {            Contact cacheContact = Contact.get(address,true);            if (cacheContact != null) {                address = cacheContact.getNumber();            }        } else {            address = getString(R.string.unknown_sender);            values.put(Sms.ADDRESS, address);        }        if (((threadId == null) || (threadId == 0)) && (address != null)) {            threadId = Conversation.getOrCreateThreadId(context, address);            values.put(Sms.THREAD_ID, threadId);        }        ContentResolver resolver = context.getContentResolver();        Uri insertedUri = SqliteWrapper.insert(context, resolver, Inbox.CONTENT_URI, values);        // Now make sure we're not over the limit in stored messages        Recycler.getSmsRecycler().deleteOldMessagesByThreadId(context, threadId);        MmsWidgetProvider.notifyDatasetChanged(context);        return insertedUri;    }

其中有一部分是我另加的代码.为了记录接收的短信.

0 0
原创粉丝点击