Android 4.2短信小记
2014-06-11 20:11
411 查看
Android4.2短信小记
一、短信发送流程
1.
ComposeMessageActivity.java
这个类中主要处理用户输入并且响应用户的点击事件。
在onClick()中,函数调用顺序confirmSendMessageIfNeeded()-> sendMessage(true)
2.
sendMessage中会调用到WorkingMessage的send方法:
WorkingMessage的send方法会对此时消息做判断,如果包含Email或是MMS则启动彩信发送程序发送SendReq请求向MMSC. 彩信流程将会在以后介绍。
如果send方法判定为短信,则会new新线程。
3.
在新建线程中会调用preSendSmsWorker函式。
preSendSmsWorker其实只做以下几件事:
a. 调用MessageStatusListener的onPreMessageSent方法通知UI线程更新状态。
b. 调用sendSmsWorker函数去发送短信,参数包含了消息体接收人,所属线程id(此为消息所属会话线程ID,并非操作系统中的线程ID。
4.
sendSmsWorker函数中会创建SmsMessageSender实例并调用其sendMessage函式。
MessageSendersender = new SmsMessageSender(mActivity, dests, msgText, threadId);
sender.sendMessage(threadId);
5.
SmsMessageSender的sendMessage其实只是调用了自己的queueMessage。
queueMessage将消息入队,调用Framework中Telephony.java的内部类Sms,addMessageToUri将消息插入至SMS数据库(数据库的实现在smsprovider.java)
其中主要填写以下字段:
a. SUB_ID: 用于双卡标识
b. ADDRESS:发送地址
c. DATE:发送时间
d. READ:是否已读
e. SUBJECT:短信么有
f. BODY:消息体
g. STATUS:分为STATUS_COMPLETE,STATUS_PENDING,STATUS_FAILED,STATUS_NONE,此时会写为STATUS_PENDING。
h. THREAD_ID:会话线程ID.
值得注意的是STATUS与smsprovider在insert时会加入的TYPE, TYPE 中包含了MESSAGE_TYPE_INBOX,
MESSAGE_TYPE_SENT,
MESSAGE_TYPE_QUEUED,
MESSAGE_TYPE_OUTBOX等等。
此时我们是MESSAGE_TYPE_QUEUED类型。
6.
此时我们从Framework中回到app中。继续看queueMessage函式,在把数据加入队列后会发送广播消息ACTION_SEND_MESSAGE。此消息由SmsReceiver.java去接收。
7.
SmsReceiver.java接到消息就去startservice。这是编写android程序时常用的方法,在receiver中启动服务。在receiver中最好不处理长时间的数据,因为如果时间太长会阻塞UI线程并触发ANR。
8.
SmsReceiverService的handleMessage会接收到ACTION_SEND_MESSAGE,此时会调用handleSendMessage,它会判断是否在发送状态,如果不在发送中则会调用sendFirstQueuedMessage去发送队列中的消息。
此队列就是我们之前调用framework的addMessageToUri函式插入的消息的队列。
9.
通过查询队列,取到队列中的消息后我们会构造SmsSingleRecipientSender实例,SmsSingleRecipientSender用于单笔消息的发送。SmsSingleRecipientSender的sendMessage函式将被调用。
10.
sendMessage()主要做了以下几件事:
a. 如果目的地址为EMail地址,则会调用MmsConfig的getEmailGateway()取得预配置的SMS Email发送网关地址作为发送目的地址;
b. 调用SmsManager 的divideMessage;
c. 修改数据库中消息的TYPE,由MESSAGE_TYPE_QUEUED至MESSAGE_TYPE_OUTBOX;
d. 调用SmsManager的sendMultipartTextMessage去发送消息,单卡多卡会出现很多区别,使用的isms服务也存在区别。
11.
这里不管是长短信还是普通短信,注意:
ISms iccISms =ISms.Stub.asInterface(ServiceManager.getService("isms"));
搜索代码可以发现只有IccSmsInterfaceManagerProxy类在ServiceManager登记了isms服务:
当是普通短信时,调用SmsManager的sendTextMessage函数,这里同样:
继续看IccSmsInterfaceManagerProxy类的sendText,
mIccSmsInterfaceManager.sendText(destAddr, scAddr, text,sentIntent, deliveryIntent);
继续看IccSmsInterfaceManager类的sendText,
mDispatcher.sendText(destAddr, scAddr, text, sentIntent,deliveryIntent);
查看SMSDispatcher类的sendText,这是个abstract函数:
protected abstract void sendText(String destAddr, String scAddr,
Stringtext, PendingIntent sentIntent, PendingIntent deliveryIntent);
搜索实现的类,CdmaSMSDispatcher和GsmSMSDispatcher都继承了SMSDispatcher。这里调用了GsmSMSDispatcher的sendText。在PhoneProxy的handleMessage中收到EVENT_RADIO_ON后调用:
mCommandsInterface.getVoiceRadioTechnology(
this.obtainMessage(EVENT_REQUEST_VOICE_RADIO_TECH_DONE));
之后:
case EVENT_VOICE_RADIO_TECH_CHANGED:
caseEVENT_REQUEST_VOICE_RADIO_TECH_DONE:
updatePhoneObject(newVoiceTech);
在此调用deleteAndCreatePhone(newVoiceRadioTech),关键之处是:
根据手机类型,PhoneFactory创建相应的Phone:
Phone phone = new GSMPhone(sContext, sCommandsInterface,sPhoneNotifier);
在相应的构造函数中实例化SMSDispatcher mSMS:
mSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor,mSmsUsageMonitor);
因此短信发送直接调用的是GsmSMSDispatcher的sendText。
12.
无论是sendMultipartText或sendText都会调用到ImsSMSDispatcher的相应函式,并且都会判断其发送方式CDMA或GSM. 两者的实例类为CdmaSMSDispatcher和GsmSMSDispatcher。
在sendText函式中会调用sendRawPdu函式,后会调用CdmaSMSDispatcher或GsmSMSDispatcher的sendSms函式,这里将会调用到Ril的sendSMS.
13.
Ril中将组装RILRequest,并发送至ril层。
14.
当RIL发送成功后processSolicited将接收到RIL_REQUEST_SEND_SMS的response.此时会触发消息并由SMSDispatcher的handleMessage接收,消息名为EVENT_SEND_SMS_COMPLETE,此时会调用handleSendComplete函式并把结果传入(AsyncResult)。
以下几件事会被handleSendComplete执行:
a. 如果发现mDeliveryIntent不等于空则表明需要传送报告,所以会将SmsTracker加入deliveryPendingList以等待传送报告回执。
b. 如果返回的exception不存在,则说明发送时未出现异常,所以会发送intent至SmsReceiver。(可能这里会感觉Ril怎么能知道通知谁并用什么action呢?其实都是得益于发送时传入的deliveryIntents与sentIntents,这个可以查看SmsSingleRecipientSender的sendMessage,每当你发送时都会事先构造好回执的intent.)SmsReceiverService收到MESSAGE_SENT_ACTION后会触发下一个队列中消息的发送。
二、短信接收流程
短信接收是从Ril.cpp通过socket与Ril.java的socket交流,在Ril.java中由RILReceiver进行监听。
在这个for循环中读取数据并处理得到的数据。
这里有主动上报(比如网络、短信、来电)和被动响应两种处理方式,短信属于主动上报,使用processUnsolicites进行处理。
最终触发以上方法mGsmSmsRegistrant.notifyRegistrant()。这个方法在GsmSMSDispatcher的构造函数中给CommandsInterface设置handle的处理方法:
在SMSDispatcher的handleMessage函数中响应EVENT_NEW_SMS,最终在GsmSMSDispatcher的dispatchMessage函数中的dispatchNormalMessage处理,处理函数是dispatchPdus(pdus)。
最后,可以看出这个方法将短信通过顺序广播播放出去(action是SMS_RECEIVED_ACTION= "android.provider.Telephony.SMS_RECEIVED";),无论广播是否被中断最后都会调用mResultReceiver,这里会将已读或未读的状态告诉给对方。 如果短信广播中间没有受到終止,那么接下来的流程是:在最上层的 APP中Mms模块中transation中的PrivilegedSmsReceiver类接收到android.provider.Telephony.SMS_RECEIVED广播请求,并获取携带短信数据的intent,然后调用intent.setClass(context,SmsReceiverService.class);
启动SmsReceiverService服务类来处理短信并保存短信(短信内容号码在PrivilegedSmsReceiver中接收到的intent里面)。
最上层的App中的Mms里面:发送和接收短信的过程:
PrivilegedSmsReceiver把intent传递到 SmsReceiverService中SmsReceiverService中
接收短信时,调用 handleSmsReceived()保存短信,得到 messageUri,通知更新相关标识符:
保存短信的过程分为两种情况:替换和保存(更新和插入数据表(Inbox.CONTENT_URI))
一、短信发送流程
1.
ComposeMessageActivity.java
这个类中主要处理用户输入并且响应用户的点击事件。
在onClick()中,函数调用顺序confirmSendMessageIfNeeded()-> sendMessage(true)
2.
sendMessage中会调用到WorkingMessage的send方法:
mWorkingMessage.send(mDebugRecipients);
WorkingMessage的send方法会对此时消息做判断,如果包含Email或是MMS则启动彩信发送程序发送SendReq请求向MMSC. 彩信流程将会在以后介绍。
如果send方法判定为短信,则会new新线程。
new Thread(new Runnable() { @Override public void run() { preSendSmsWorker(conv,msgText, recipientsInUI); updateSendStats(conv); } }, "WorkingMessage.sendSMS").start();
3.
在新建线程中会调用preSendSmsWorker函式。
preSendSmsWorker其实只做以下几件事:
a. 调用MessageStatusListener的onPreMessageSent方法通知UI线程更新状态。
b. 调用sendSmsWorker函数去发送短信,参数包含了消息体接收人,所属线程id(此为消息所属会话线程ID,并非操作系统中的线程ID。
4.
sendSmsWorker函数中会创建SmsMessageSender实例并调用其sendMessage函式。
MessageSendersender = new SmsMessageSender(mActivity, dests, msgText, threadId);
sender.sendMessage(threadId);
5.
SmsMessageSender的sendMessage其实只是调用了自己的queueMessage。
queueMessage将消息入队,调用Framework中Telephony.java的内部类Sms,addMessageToUri将消息插入至SMS数据库(数据库的实现在smsprovider.java)
其中主要填写以下字段:
a. SUB_ID: 用于双卡标识
b. ADDRESS:发送地址
c. DATE:发送时间
d. READ:是否已读
e. SUBJECT:短信么有
f. BODY:消息体
g. STATUS:分为STATUS_COMPLETE,STATUS_PENDING,STATUS_FAILED,STATUS_NONE,此时会写为STATUS_PENDING。
h. THREAD_ID:会话线程ID.
值得注意的是STATUS与smsprovider在insert时会加入的TYPE, TYPE 中包含了MESSAGE_TYPE_INBOX,
MESSAGE_TYPE_SENT,
MESSAGE_TYPE_QUEUED,
MESSAGE_TYPE_OUTBOX等等。
此时我们是MESSAGE_TYPE_QUEUED类型。
6.
此时我们从Framework中回到app中。继续看queueMessage函式,在把数据加入队列后会发送广播消息ACTION_SEND_MESSAGE。此消息由SmsReceiver.java去接收。
mContext.sendBroadcast(newIntent(SmsReceiverService.ACTION_SEND_MESSAGE, null, mContext, SmsReceiver.class));
7.
SmsReceiver.java接到消息就去startservice。这是编写android程序时常用的方法,在receiver中启动服务。在receiver中最好不处理长时间的数据,因为如果时间太长会阻塞UI线程并触发ANR。
public void onReceive(Context context, Intent intent) { onReceiveWithPrivilege(context, intent, false); } protected voidonReceiveWithPrivilege(Context context, Intent intent, boolean privileged) { if (!privileged &&intent.getAction().equals(Intents.SMS_RECEIVED_ACTION)) { return; } intent.setClass(context,SmsReceiverService.class); intent.putExtra("result",getResultCode()); beginStartingService(context, intent); }
8.
SmsReceiverService的handleMessage会接收到ACTION_SEND_MESSAGE,此时会调用handleSendMessage,它会判断是否在发送状态,如果不在发送中则会调用sendFirstQueuedMessage去发送队列中的消息。
if(ACTION_SEND_MESSAGE.endsWith(action)) { handleSendMessage(); } private voidhandleSendMessage() { if (!mSending) { sendFirstQueuedMessage(); } }
此队列就是我们之前调用framework的addMessageToUri函式插入的消息的队列。
9.
final Uri uri =Uri.parse("content://sms/queued"); ContentResolverresolver = getContentResolver(); Cursor c =SqliteWrapper.query(this, resolver, uri, SEND_PROJECTION, null, null, "date ASC");
通过查询队列,取到队列中的消息后我们会构造SmsSingleRecipientSender实例,SmsSingleRecipientSender用于单笔消息的发送。SmsSingleRecipientSender的sendMessage函式将被调用。
SmsMessageSendersender = new SmsSingleRecipientSender(this, address, msgText, threadId, status == Sms.STATUS_PENDING,msgUri); try { sender.sendMessage(SendingProgressTokenManager.NO_TOKEN);; mSending = true; } catch (MmsExceptione) { mSending = false; messageFailedToSend(msgUri,SmsManager.RESULT_ERROR_GENERIC_FAILURE); success = false; }
10.
sendMessage()主要做了以下几件事:
a. 如果目的地址为EMail地址,则会调用MmsConfig的getEmailGateway()取得预配置的SMS Email发送网关地址作为发送目的地址;
b. 调用SmsManager 的divideMessage;
c. 修改数据库中消息的TYPE,由MESSAGE_TYPE_QUEUED至MESSAGE_TYPE_OUTBOX;
d. 调用SmsManager的sendMultipartTextMessage去发送消息,单卡多卡会出现很多区别,使用的isms服务也存在区别。
11.
if (parts.size() > 1) { try { ISms iccISms =ISms.Stub.asInterface(ServiceManager.getService("isms")); if(iccISms != null) { iccISms.sendMultipartText(destinationAddress, scAddress, parts, sentIntents, deliveryIntents); } } catch(RemoteException ex) { //ignore it } } else { PendingIntent sentIntent = null; PendingIntent deliveryIntent = null; if (sentIntents!= null && sentIntents.size() > 0) { sentIntent = sentIntents.get(0); } if(deliveryIntents != null && deliveryIntents.size() > 0) { deliveryIntent = deliveryIntents.get(0); } sendTextMessage(destinationAddress, scAddress, parts.get(0), sentIntent, deliveryIntent); }
这里不管是长短信还是普通短信,注意:
ISms iccISms =ISms.Stub.asInterface(ServiceManager.getService("isms"));
搜索代码可以发现只有IccSmsInterfaceManagerProxy类在ServiceManager登记了isms服务:
public IccSmsInterfaceManagerProxy(IccSmsInterfaceManager iccSmsInterfaceManager) { this.mIccSmsInterfaceManager = iccSmsInterfaceManager; if(ServiceManager.getService("isms") == null) { ServiceManager.addService("isms",this); } }
当是普通短信时,调用SmsManager的sendTextMessage函数,这里同样:
try { ISmsiccISms = ISms.Stub.asInterface(ServiceManager.getService("isms")); if(iccISms != null) { iccISms.sendText(destinationAddress,scAddress, text, sentIntent, deliveryIntent); } } catch(RemoteException ex) { //ignore it }
继续看IccSmsInterfaceManagerProxy类的sendText,
mIccSmsInterfaceManager.sendText(destAddr, scAddr, text,sentIntent, deliveryIntent);
继续看IccSmsInterfaceManager类的sendText,
mDispatcher.sendText(destAddr, scAddr, text, sentIntent,deliveryIntent);
查看SMSDispatcher类的sendText,这是个abstract函数:
protected abstract void sendText(String destAddr, String scAddr,
Stringtext, PendingIntent sentIntent, PendingIntent deliveryIntent);
搜索实现的类,CdmaSMSDispatcher和GsmSMSDispatcher都继承了SMSDispatcher。这里调用了GsmSMSDispatcher的sendText。在PhoneProxy的handleMessage中收到EVENT_RADIO_ON后调用:
mCommandsInterface.getVoiceRadioTechnology(
this.obtainMessage(EVENT_REQUEST_VOICE_RADIO_TECH_DONE));
之后:
case EVENT_VOICE_RADIO_TECH_CHANGED:
caseEVENT_REQUEST_VOICE_RADIO_TECH_DONE:
updatePhoneObject(newVoiceTech);
在此调用deleteAndCreatePhone(newVoiceRadioTech),关键之处是:
if (ServiceState.isCdma(newVoiceRadioTech)) { mActivePhone = PhoneFactory.getCdmaPhone(); } else if(ServiceState.isGsm(newVoiceRadioTech)) { mActivePhone = PhoneFactory.getGsmPhone(); }
根据手机类型,PhoneFactory创建相应的Phone:
Phone phone = new GSMPhone(sContext, sCommandsInterface,sPhoneNotifier);
在相应的构造函数中实例化SMSDispatcher mSMS:
mSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor,mSmsUsageMonitor);
因此短信发送直接调用的是GsmSMSDispatcher的sendText。
12.
无论是sendMultipartText或sendText都会调用到ImsSMSDispatcher的相应函式,并且都会判断其发送方式CDMA或GSM. 两者的实例类为CdmaSMSDispatcher和GsmSMSDispatcher。
在sendText函式中会调用sendRawPdu函式,后会调用CdmaSMSDispatcher或GsmSMSDispatcher的sendSms函式,这里将会调用到Ril的sendSMS.
13.
Ril中将组装RILRequest,并发送至ril层。
14.
当RIL发送成功后processSolicited将接收到RIL_REQUEST_SEND_SMS的response.此时会触发消息并由SMSDispatcher的handleMessage接收,消息名为EVENT_SEND_SMS_COMPLETE,此时会调用handleSendComplete函式并把结果传入(AsyncResult)。
以下几件事会被handleSendComplete执行:
a. 如果发现mDeliveryIntent不等于空则表明需要传送报告,所以会将SmsTracker加入deliveryPendingList以等待传送报告回执。
b. 如果返回的exception不存在,则说明发送时未出现异常,所以会发送intent至SmsReceiver。(可能这里会感觉Ril怎么能知道通知谁并用什么action呢?其实都是得益于发送时传入的deliveryIntents与sentIntents,这个可以查看SmsSingleRecipientSender的sendMessage,每当你发送时都会事先构造好回执的intent.)SmsReceiverService收到MESSAGE_SENT_ACTION后会触发下一个队列中消息的发送。
二、短信接收流程
短信接收是从Ril.cpp通过socket与Ril.java的socket交流,在Ril.java中由RILReceiver进行监听。
for (;;) { Parcel p; length = readRilMessage(is, buffer); ……………… processResponse(p); }
在这个for循环中读取数据并处理得到的数据。
private void processResponse (Parcel p) { int type; type = p.readInt(); if (type == RESPONSE_UNSOLICITED) { processUnsolicited (p); } else if (type == RESPONSE_SOLICITED){ processSolicited (p); } releaseWakeLockIfDone(); }
这里有主动上报(比如网络、短信、来电)和被动响应两种处理方式,短信属于主动上报,使用processUnsolicites进行处理。
case RIL_UNSOL_RESPONSE_NEW_SMS: { …… SmsMessage sms; sms = SmsMessage.newFromCMT(a); if (mGsmSmsRegistrant != null) { mGsmSmsRegistrant .notifyRegistrant(newAsyncResult(null, sms, null)); } break;
最终触发以上方法mGsmSmsRegistrant.notifyRegistrant()。这个方法在GsmSMSDispatcher的构造函数中给CommandsInterface设置handle的处理方法:
mCm.setOnNewGsmSms(this, EVENT_NEW_SMS, null); mCm.setOnSmsStatus(this,EVENT_NEW_SMS_STATUS_REPORT, null); mCm.setOnNewGsmBroadcastSms(this,EVENT_NEW_BROADCAST_SMS, null);
在SMSDispatcher的handleMessage函数中响应EVENT_NEW_SMS,最终在GsmSMSDispatcher的dispatchMessage函数中的dispatchNormalMessage处理,处理函数是dispatchPdus(pdus)。
protected void dispatchPdus(byte[][] pdus) { Intent intent = newIntent(Intents.SMS_RECEIVED_ACTION); intent.putExtra("pdus", pdus); intent.putExtra("format",getFormat()); dispatch(intent, RECEIVE_SMS_PERMISSION); } public void dispatch(Intent intent, Stringpermission) { mWakeLock.acquire(WAKE_LOCK_TIMEOUT); mContext.sendOrderedBroadcast(intent,permission, mResultReceiver, this, Activity.RESULT_OK, null, null); } private final BroadcastReceiver mResultReceiver = newBroadcastReceiver() { @Override publicvoid onReceive(Context context, Intent intent) { if(intent.getAction().equals(Intents.SMS_CB_RECEIVED_ACTION) || intent.getAction().equals(Intents.SMS_EMERGENCY_CB_RECEIVED_ACTION)) { // Ignore this intent. Apps will process it. }else { // Assume the intent is one of the SMS receive intents that // was sent as an ordered broadcast. Check result and ACK. int rc = getResultCode(); boolean success = (rc == Activity.RESULT_OK) || (rc ==Intents.RESULT_SMS_HANDLED); // For a multi-part message, this only ACKs the last part. // Previous parts were ACK'd as they were received. acknowledgeLastIncomingSms(success, rc, null); //子类调用接口mCm.acknowledgeLastIncomingGsmSms(success,resultToCause(result), response); } } };
最后,可以看出这个方法将短信通过顺序广播播放出去(action是SMS_RECEIVED_ACTION= "android.provider.Telephony.SMS_RECEIVED";),无论广播是否被中断最后都会调用mResultReceiver,这里会将已读或未读的状态告诉给对方。 如果短信广播中间没有受到終止,那么接下来的流程是:在最上层的 APP中Mms模块中transation中的PrivilegedSmsReceiver类接收到android.provider.Telephony.SMS_RECEIVED广播请求,并获取携带短信数据的intent,然后调用intent.setClass(context,SmsReceiverService.class);
启动SmsReceiverService服务类来处理短信并保存短信(短信内容号码在PrivilegedSmsReceiver中接收到的intent里面)。
protected void onReceiveWithPrivilege(Contextcontext, Intent intent, boolean privileged) { if(!privileged && intent.getAction().equals(Intents.SMS_RECEIVED_ACTION)){ return; } intent.setClass(context, SmsReceiverService.class); intent.putExtra("result", getResultCode()); beginStartingService(context, intent); }
最上层的App中的Mms里面:发送和接收短信的过程:
PrivilegedSmsReceiver把intent传递到 SmsReceiverService中SmsReceiverService中
@Override public voidonCreate() { //Temporarily removed for this duplicate message track down. // if(Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { // Log.v(TAG, "onCreate"); // } //Start up the thread running the service. Note that we create a //separate thread because the service normally runs in the process's // mainthread, which we don't want to block. HandlerThread thread = new HandlerThread(TAG,Process.THREAD_PRIORITY_BACKGROUND); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); } @Override public intonStartCommand(Intent intent, int flags, int startId) { //Temporarily removed for this duplicate message track down. // if(Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { // Log.v(TAG, "onStart: #" + startId +": " + intent.getExtras()); // } mResultCode = intent != null ? intent.getIntExtra("result", 0): 0; Messagemsg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj= intent; mServiceHandler.sendMessage(msg); returnService.START_NOT_STICKY; } 启动service,调用 onStartCommand()把 intent转到Message里面,发送到ServiceHandler中处理 private final class ServiceHandler extends Handler { publicServiceHandler(Looper looper) { super(looper); } /** *Handle incoming transaction requests. * Theincoming requests are initiated by the MMSC Server or by the MMS Client itself. */ @Override public voidhandleMessage(Message msg) { intserviceId = msg.arg1; Intent intent = (Intent)msg.obj; if(intent != null) { String action = intent.getAction(); int error = intent.getIntExtra("errorCode", 0); if (MESSAGE_SENT_ACTION.equals(intent.getAction())) { handleSmsSent(intent, error); } else if (SMS_RECEIVED_ACTION.equals(action)) { handleSmsReceived(intent, error); } else if(SMS_CB_RECEIVED_ACTION.equals(action)) { handleCbSmsReceived(intent, error); } else if (ACTION_BOOT_COMPLETED.equals(action)) { handleBootCompleted(); } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)){ handleServiceStateChanged(intent); } else if (ACTION_SEND_MESSAGE.endsWith(action)) { handleSendMessage(); } else if (Sms.Intents.WAP_PUSH_RECEIVED_ACTION.equals(action)) { handleWapPushReceived(intent); } } //NOTE: We MUST not call stopSelf() directly, since we need to //make sure the wake lock acquired by AlertReceiver is released. SmsReceiver.finishStartingService(SmsReceiverService.this, serviceId); } }
接收短信时,调用 handleSmsReceived()保存短信,得到 messageUri,通知更新相关标识符:
保存短信的过程分为两种情况:替换和保存(更新和插入数据表(Inbox.CONTENT_URI))
相关文章推荐
- Android 4.2短信发送流程小记
- Android下实现短信SMS的收发
- android短信服务
- 在Android中发送短信和彩信,监听短信并显示
- Android 开发之旅:短信的收发及在android模拟器之间实践(一)
- Android下调用收发短信邮件等(转载)
- Android 开发之旅:短信的收发及在android模拟器之间实践(一)
- android收发短信
- Android上监听收到的短信(SMS)
- Android中短信相关信息的数据库
- android短信服务
- Android开发(一)发送短信程序
- Android下实现短信的收发
- Android上监听收到的短信(SMS)
- Android中发送和接收短信
- Android(OPhone) 学习笔记 - 短信发送
- android 的短信发送
- Android中短信相关信息的数据库
- Android 如何删除短信