您的位置:首页 > 移动开发 > Android开发

《Android发短信底层源码(android5.1)解析》---主要解析SMSDispatcher发短信部分源码

2017-03-20 18:13 507 查看
解析android底层发短信相关源码,包括短信的发送,以及RIL层返回结果的处理。如有错误请更正。本文从SMSDispatcher开始分析,不包括上层代码分析。

SMSDispatcher相关说明

SMSDispatcher的子类主要有GsmSMSDispatcher与CdmaSMSDispatcher。ImsSMSDispatcher相当于是对上面两个子类的一个包装,上层调用时主要调用ImsSMSDispatcher中的方法。ImsSMSDispatcher中再去选择调用的是Gsm还是Cdma中的方法。

GsmSMSDispatcher发短信解析(主要针对文本短信)

GsmSMSDispatcher.sendSms开始短信的发送。真正发送通过调用sendSmsByPstn

关键代码

if (tracker.mRetryCount == 0 && tracker.mExpectMore) {
// 发送失败时,原因同时有多条短信在发送则调用该方法
// EVENT_SEND_LIMIT_REACHED_CONFIRMATION
mCi.sendSMSExpectMore(IccUtils.bytesToHexString(smsc),
IccUtils.bytesToHexString(pdu), reply);
} else {
// 正常发送
mCi.sendSMS(IccUtils.bytesToHexString(smsc),
IccUtils.bytesToHexString(pdu), reply);
}


发送成功解析

主要发送成功,失败(多条短信等)

发送成功时会发送上面的reply消息。

关键代码在handleMessage中。成功后会调用对应的SentIntent中的send方法

关键代码

if (mSentIntent != null) {
try {
// Extra information to send with the sent intent
Intent fillIn = new Intent();
if (mMessageUri != null) {
// Pass this to SMS apps so that they know where it is stored
fillIn.putExtra("uri", mMessageUri.toString());
}
if (mUnsentPartCount != null && isSinglePartOrLastPart) {
// Is multipart and last part
fillIn.putExtra(SEND_NEXT_MSG_EXTRA, true);
}
// 发送成功报告
mSentIntent.send(context, Activity.RESULT_OK, fillIn);
} catch (CanceledException ex) {
Rlog.e(TAG, "Failed to send result");
}
}


关于送达报告的执行,要在SMSDispatcher创建的时候在CommandsInterface中进行注册。告诉底层RIL送到后发送的消息。

关键代码

public GsmSMSDispatcher(PhoneBase phone, SmsUsageMonitor usageMonitor,
ImsSMSDispatcher imsSMSDispatcher,
GsmInboundSmsHandler gsmInboundSmsHandler) {
super(phone, usageMonitor, imsSMSDispatcher);
// 注册送达报告消息
mCi.setOnSmsStatus(this, EVENT_NEW_SMS_STATUS_REPORT, null);
mGsmInboundSmsHandler = gsmInboundSmsHandler;
mUiccController = UiccController.getInstance();
mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
Rlog.d(TAG, "GsmSMSDispatcher created");
}
// 送达报告执行部分
PendingIntent intent = tracker.mDeliveryIntent;
Intent fillIn = new Intent();
fillIn.putExtra("pdu", IccUtils.hexStringToBytes(pduString));
fillIn.putExtra("format", getFormat());
try {
intent.send(mContext, Activity.RESULT_OK, fillIn);
} catch (CanceledException ex) {}


发送失败解析

如果发送失败主要还是进行重试,重试MAX_SEND_RETRIES次。重试的时候会有时间延时SEND_RETRY_DELAY

关键代码

if (!isIms() && ss != ServiceState.STATE_IN_SERVICE) {
tracker.onFailed(mContext, getNotInServiceError(ss), 0/*errorCode*/);
} else if ((((CommandException)(ar.exception)).getCommandError()
== CommandException.Error.SMS_FAIL_RETRY) &&
tracker.mRetryCount < MAX_SEND_RETRIES) {
tracker.mRetryCount++;
Message retryMsg = obtainMessage(EVENT_SEND_RETRY, tracker);
// 发送重试消息,进行重试
sendMessageDelayed(retryMsg, SEND_RETRY_DELAY);
}

// 这部分代码不知道是不是判断电话是不是在使用,有待验证
int ss = mPhone.getServiceState().getState();

if ( tracker.mImsRetry > 0 && ss != ServiceState.STATE_IN_SERVICE) {
// This is retry after failure over IMS but voice is not available.
// Set retry to max allowed, so no retry is sent and
//   cause RESULT_ERROR_GENERIC_FAILURE to be returned to app.
tracker.mRetryCount = MAX_SEND_RETRIES;

Rlog.d(TAG, "handleSendComplete: Skipping retry: "
+" isIms()="+isIms()
+" mRetryCount="+tracker.mRetryCount
+" mImsRetry="+tracker.mImsRetry
+" mMessageRef="+tracker.mMessageRef
+" SS= "+mPhone.getServiceState().getState());
}


要想知道失败原因还得细读失败时候的处理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息