SMS发送接收流程
来源:互联网 发布:网络工程规划与设计 编辑:程序博客网 时间:2024/06/10 10:47
1.短信发送的起点是在短信编辑界面,点击发送按钮开始的
public class ComposeMessageActivity extends Activity ...{.... public void sendMessage(boolean bCheckEcmMode) { .... //这里面准备发送的数据处理,比如生成PDU数据,存储到数据 mWorkingMessage.send(mDebugRecipients, mSelectedSubId); }
mWorkingMessage中具体发送短信的工作在preSendSmsWorker方法里面
private void preSendSmsWorker(Conversation conv, String msgText, String recipientsInUI,
int subId, boolean hasBeenSplit) {
// just do a regular send. We’re already on a nonui thread so no need to fire
// off another thread to do this work.
/// M: Code analyze 047, For new feature ALPS00316567, add a parameter for msim . @{
sendSmsWorker是最主要的类,做了实际的发送工作,但他里面不是立即发送短信,而是发送短信的请求封装成SmsMessageSender,
sendSmsWorker(msgText, semiSepRecipients, threadId, subId);
/// @}
…
} .
SmsReceiverService
SmsMessageSender*******************************************
将待发送的短信存储到数据库表格中,content://sms/queued
然后再启动服务SmsReceiverService,让服务去单个发送每一条短信,SmsReceiverService重待发送短信表格中取出一条短信,然后交由
SmsSingleRecipientSender去发送。
MessageSender sender = new SmsMessageSender(mActivity, dests, msgText, threadId, subId); 短信发送处理 public boolean sendMessage(long token) throws MmsException {号码处理,将其中的空格去除。得到有效的发送号码。生成2个广播1.发送报告广播,2.发送短信广播最终调用系统接口SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(mSubId);SmsManager*************************************************************************************************** public void sendMultipartTextMessage( String destinationAddress, String scAddress, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) { 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.Stub.asInterface(ServiceManager.getService("isms"));,这个的服务类型有多种,发送彩信********************************************************************************************sendMmsWorker(spliter.getMMSConversation(), mmsUri, persister, slideshow, sendReq, subId);/// M: Code analyze 047, For new feature ALPS00316567, add a parameter for msim . @{ private void sendSmsWorker(String msgText, String semiSepRecipients, long threadId, int subId) { /// @} String[] dests = TextUtils.split(semiSepRecipients, ";"); if (LogTag.VERBOSE || Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { Log.d(LogTag.TRANSACTION, "sendSmsWorker sending message: recipients=" + semiSepRecipients + ", threadId=" + threadId); } MessageSender sender = new SmsMessageSender(mActivity, dests, msgText, threadId, subId); try { sender.sendMessage(threadId); // Make sure this thread isn't over the limits in message count Recycler.getSmsRecycler().deleteOldMessagesByThreadId(mActivity, threadId); } catch (Exception e) { Log.e(TAG, "Failed to send SMS message, threadId=" + threadId, e); } mStatusListener.onMessageSent(); MmsWidgetProvider.notifyDatasetChanged(mActivity); } public boolean sendMessage(long token) throws MmsException { // In order to send the message one by one, instead of sending now, the message will split, // and be put into the queue along with each destinations return queueMessage(token); } private boolean queueMessage(long token) throws MmsException { /// M: MmsLog.v(MmsApp.TXN_TAG, "queueMessage()"); if ((mMessageText == null) || mMessageText.isEmpty() || (mNumberOfDests == 0)) { // Don't try to send an empty message. throw new MmsException("Null message body or dest."); } SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext); boolean requestDeliveryReport = prefs.getBoolean(mSubId + "_" + SmsPreferenceActivity.SMS_DELIVERY_REPORT_MODE, DEFAULT_DELIVERY_REPORT_MODE); MmsLog.d(MmsApp.TXN_TAG, "SMS DR request=" + requestDeliveryReport); /// @} Uri smsUri = null;//star os add by liuweibo long timeStamp = System.currentTimeMillis(); for (int i = 0; i < mNumberOfDests; i++) { try { if (LogTag.DEBUG_SEND) { Log.v(TAG, "queueMessage mDests[i]: " + mDests[i] + " mThreadId: " + mThreadId); } smsUri = mOpSmsMessageSender.queueMessage(mNumberOfDests,//star os modify by liuweibo mContext.getContentResolver(), mDests[i], mMessageText, mTimestamp, requestDeliveryReport, mThreadId, mSubId, timeStamp); if (smsUri == null) { smsUri=Sms.addMessageToUri(mSubId,//star os modify by liuweibo mContext.getContentResolver(), Uri.parse("content://sms/queued"), mDests[i], mMessageText, null, mTimestamp, true /* read */, requestDeliveryReport, mThreadId); } //star os add start by liuweibo Intent sentIt = new Intent("delay_send_sms", null, mContext, SmsReceiver.class); long msgId = Integer.valueOf(smsUri.toString().substring(14)); sentIt.putExtra("message_id", msgId); mContext.sendBroadcast(sentIt); //star os add end by liuweibo } catch (SQLiteException e) { if (LogTag.DEBUG_SEND) { Log.e(TAG, "queueMessage SQLiteException", e); } SqliteWrapper.checkSQLiteException(mContext, e); } } // Notify the SmsReceiverService to send the message out //star os del start by liuweibo /* mContext.sendBroadcast(new Intent(SmsReceiverService.ACTION_SEND_MESSAGE, null, mContext, SmsReceiver.class)); */ //star os del end by liuweibo return false; }
/frameworks/opt/telephony/src/java/android/telephony/SmsManager.java
sendStoredMultimediaMessage/** * Send a system stored MMS message * * This is used for sending a previously sent, but failed-to-send, message or * for sending a text message that has been stored as a draft. * * @param messageUri the URI of the stored message * @param configOverrides the carrier-specific messaging configuration values to override for * sending the message. * @param sentIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is successfully sent, or failed * @throws IllegalArgumentException if messageUri is empty * {@hide} */public void sendStoredMultimediaMessage(Uri messageUri, Bundle configOverrides,PendingIntent sentIntent) {if (messageUri == null) {throw new IllegalArgumentException("Empty message URI");}try {IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms"));if (iMms != null) {iMms.sendStoredMessage(getSubscriptionId(), ActivityThread.currentPackageName(), messageUri,configOverrides, sentIntent);}} catch (RemoteException ex) {// ignore it}}短信接收***********************************************************************************首先系统发出android.provider.Telephony.Sms.Intents.SMS_DELIVER_ACTION广播,然后SmsReceiver接收,接收后启动service SmsReceiverService处理
系统是什么地方发送广播:
/frameworks/opt/telephony/src/java/com/android/internal/telephony/InboundSmsHandler.java
/** * In the delivering state, the inbound SMS is processed and stored in the raw table. * The message is acknowledged before we exit this state. If there is a message to broadcast, * transition to {@link WaitingState} state to send the ordered broadcast and wait for the * results. When all messages have been processed, the halting state will release the wakelock. */ private class DeliveringState extends State { **** @Override public boolean processMessage(Message msg) { log("DeliveringState.processMessage:" + msg.what); log("DeliveringState.processMessage:" + msg.what); switch (msg.what) { case EVENT_BROADCAST_SMS: // if any broadcasts were sent, transition to waiting state InboundSmsTracker inboundSmsTracker = (InboundSmsTracker) msg.obj; if (processMessagePart(inboundSmsTracker)) { transitionTo(mWaitingState); } else { // if event is sent from SmsBroadcastUndelivered.broadcastSms(), and // processMessagePart() returns false, the state machine will be stuck in // DeliveringState until next message is received. Send message to // transition to idle to avoid that so that wakelock can be released log("No broadcast sent on processing EVENT_BROADCAST_SMS in Delivering " + "state. Return to Idle state"); sendMessage(EVENT_RETURN_TO_IDLE); } return HANDLED; **** private boolean processMessagePart(InboundSmsTracker tracker) { **** dispatchSmsDeliveryIntent(pdus, tracker.getFormat(), destPort, resultReceiver, IConcatenatedSmsFwkExt.UPLOAD_FLAG_NONE); ///// private void dispatchSmsDeliveryIntent(byte[][] pdus, String format, int destPort, BroadcastReceiver resultReceiver, int longSmsUploadFlag) { // MTKEND Intent intent = new Intent(); intent.putExtra("pdus", pdus); intent.putExtra("format", format); if (destPort == 1) { intent.setAction(Intents.SMS_DELIVER_ACTION); *** dispatchIntent(intent, android.Manifest.permission.RECEIVE_SMS, AppOpsManager.OP_RECEIVE_SMS, options, resultReceiver, UserHandle.SYSTEM); public void dispatchIntent(Intent intent, String permission, int appOp, Bundle opts, BroadcastReceiver resultReceiver, UserHandle user) { intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); ****** mContext.sendOrderedBroadcastAsUser(intent, user, permission, appOp, opts, resultReceiver, getHandler(), Activity.RESULT_OK, null, null);到这里,消息广播就发送出去了。
将PDU数据插入到raw表中 /** * Insert a message PDU into the raw table so we can acknowledge it immediately. * If the device crashes before the broadcast to listeners completes, it will be delivered * from the raw table on the next device boot. For singlepart messages, the deleteWhere * and deleteWhereArgs fields of the tracker will be set to delete the correct row after * the ordered broadcast completes. * * @param tracker the tracker to add to the raw table * @return true on success; false on failure to write to database */ private int addTrackerToRawTable(InboundSmsTracker tracker, boolean deDup) {
短信接收时序图:
- SMS发送接收流程
- android MMS/SMS 收发流程分析(接收发送)
- android sms接收流程
- SMS 发送流程
- SMS短信发送/接收模块
- SMS发送流程 Android2.2
- Android sms 发送、接收及格式
- android sms发送、接收及格式
- android sms 发送、接收及格式
- Android SMS发送和接收(示例)
- rabbitmq发送接收流程
- 短信发送流程:系统短信(SMS)发送流程
- 短信监听 接收短信 发送短信 SMS监听
- 通过广播简单实现sms短信的发送和接收
- Telephone--短信发送/接收流程
- 关于android 4.4短信(sms)接收流程-状态机篇
- 驱动的发送接收流程分析
- OSAL串口接收发送数据流程简介
- CCS环境中对DSP编程时使用pow函数导致死机
- 绑定Service专题
- java架构师视频
- ajax常用的几种写法
- 线性分类器之 logistic regression与neural networks的关系
- SMS发送接收流程
- 零基础开始自学python
- Java 并发开发:Lock 框架详解
- 华为CodeCraft2017算法结果检查工具(包含测试用例展示)
- 删除链表中倒数第n个节点-LintCode
- iOS UITextField输入限制(中英文混合
- EasyUI使用心得——中文化
- Android NDK(八):JNI多线程
- asp网站在iis7上配制后打不开!在官网看到的结果