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