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

解析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());
}

要想知道失败原因还得细读失败时候的处理。

发布了170 篇原创文章 · 获赞 55 · 访问量 37万+

猜你喜欢

转载自blog.csdn.net/w695050167/article/details/64129872