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.java frameworks/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; }
其中有一部分是我另加的代码.为了记录接收的短信.