androidのMMS短信发送过程(一)
1. 在短信编辑界面 ComposeMessageActivity.java 中按下发送按钮,就开始信息的发送。从ComposeMessageActivity.java的onclick()开始,
首先看下流程图,然后对比看代码。
代码如下
public void onClick(View v) {/// M: Code analyze 028, Before sending message,check the recipients count/// and add sim card selection dialog if multi sim cards exist.@{// confirmSendMessageIfNeeded(); if (v == mSendButtonSms || v == mSendButtonMms || v == mSendButtonIpMessage) {if (mSendButtonCanResponse) {mSendButtonCanResponse = false;if (isPreparedForSending()) {/// M: add for ip message, unread dividermShowUnreadDivider = false;/// M: Since sending message here, why not disable button 'Send'??updateSendButtonState(false);checkRecipientsCount();mUiHandler.sendEmptyMessageDelayed(MSG_RESUME_SEND_BUTTON, RESUME_BUTTON_INTERVAL);} else {mSendButtonCanResponse = true;unpreparedForSendingAlert();}}
- if ((v == mSendButtonSms || v == mSendButtonMms) && isPreparedForSending()) {
- confirmSendMessageIfNeeded();
- }
private boolean isPreparedForSending() {if (isRecipientsEditorVisible()) {String recipientText = mRecipientsEditor.getText() == null ? "" : mRecipientsEditor.getText().toString();/// M: add for ip messagereturn mSimCount > 0 && !TextUtils.isEmpty(recipientText) && mIsSmsEnabled&& (mWorkingMessage.hasAttachment() || mWorkingMessage.hasText()|| mWorkingMessage.hasSubject() || mIpMessageDraft != null);} else {return mSimCount > 0 && mIsSmsEnabled && (mWorkingMessage.hasAttachment() || mWorkingMessage.hasText()|| mWorkingMessage.hasSubject() || mIpMessageDraft != null);}}
这里isRecipientsEditorVisible()用于判断 RecipientsEditor mRecipientsEditor; 这个添加联系人输入框是否可见,
isPreparedForSending()这个方法决定是否可发送,方法里需要判断 sim卡数目大于0,发送联系人输入框不为空,当前SIM卡可用,
以及判断当前编辑内容是否有附件,主题,内容,草稿
--继续回到onclick()方法中,看到 updateSendButtonState()这个方法,用来更新发送按钮状态的。代码如下:
private void updateSendButtonState(final boolean enabled) {
if (!mWorkingMessage.hasSlideshow()) {
View sendButton = showSmsOrMmsSendButton(mWorkingMessage.requiresMms());
/// M: for OP09
if (MmsConfig.isDualSendButtonEnable()) {
// mMmsComposePlugin.setCTSendButtonType();
if (mSimCount < 1) {
sendButton.setEnabled(enabled);
sendButton.setFocusable(enabled);
}
mMmsComposePlugin.updateDualSendButtonStatue(enabled, mWorkingMessage.requiresMms());
return;
}
sendButton.setEnabled(enabled);
sendButton.setFocusable(enabled);
} else {
mAttachmentEditor.setCanSend(enabled);
}
}
mWorkingMessage.hasSlideshow() 判断是否含有幻灯片, 这里用来设置发送按钮是否可以点击的状态。
---继续onclick()中,checkRecipientsCount();检查接受信息的号码数目。
mUiHandler.sendEmptyMessageDelayed(MSG_RESUME_SEND_BUTTON, RESUME_BUTTON_INTERVAL); 利用handler发送一个消息。
可以看到关于mUiHandler 的代码:
private Handler mUiHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
。。。。
case MSG_RESUME_SEND_BUTTON:
mSendButtonCanResponse = true;
break;
。。。。。
可以看到 handler中仅仅处理一个值:mSendButtonCanResponse = true;
然而关键发送流程,还要看checkRecipientsCount()方法中,代码如下:
private void checkRecipientsCount() {
。。。。。
if (mWorkingMessage.requiresMms() && (recipientCount() > mmsLimitCount || isRecipientsCcTooMany())) {
.............
} else {
.....
if (isRecipientsEditorVisible() &&
"".equals(mRecipientsEditor.getText().toString().replaceAll(";", "").replaceAll(",", "").trim())) {
。。。。
} else if (!isRecipientsEditorVisible() && "".equals(mConversation.getRecipients().serialize().replaceAll(";", "").replaceAll(",", ""))) {
。。。。
} else {
System.out.println("blueberry_EncapsulatedFeatureOption.MTK_GEMINI_SUPPORT="+EncapsulatedFeatureOption.MTK_GEMINI_SUPPORT);
System.out.println("blueberry_MmsConfig.getFolderModeEnabled()="+MmsConfig.getFolderModeEnabled());
/// M: cmcc feature, reply message with the card directly if only one card related in conversation
if (EncapsulatedFeatureOption.MTK_GEMINI_SUPPORT && MmsConfig.getFolderModeEnabled()) {
/// M: modify in op09; The Folder mode and dual send button can not coexist in this code block;
if (!MmsConfig.isDualSendButtonEnable() || MmsConfig.isSupportAutoSelectSimId()) {
send_sim_id = getAutoSelectSimId();
MmsLog.d(TAG, "send_sim_id="+send_sim_id); // -1
}
}
simSelection();// 这里是对sim 选择做的判断
}
}
}
选择好SIM卡后,还要看
simSelection()中
,
这里省略了方法内容
,继续看关键的方法confirmSendMessageIfNeeded(),代码如下:
private void confirmSendMessageIfNeeded() {
if (MmsConfig.isChangeLengthRequiredMmsToSmsEnable()) { <span style="font-family: Arial, Helvetica, sans-serif;">/// M: for length required MMS for op09@{</span>
if (mMmsComposePlugin.needConfirmMmsToSms()) {
confirmForChangeMmsToSms(); //<span style="color: rgb(85, 85, 85); line-height: 18px;">切换短彩信模式</span>
return;
} else {
mMmsComposePlugin.setConfirmMmsToSms(true);
}
}
if (!isRecipientsEditorVisible()) { //<span style="color: rgb(85, 85, 85); line-height: 18px;">// 接受方编辑框是否可见</span>
checkConditionsAndSendMessage(true); <span style="font-family: Arial, Helvetica, sans-serif;">/// M: Code analyze 030, Check condition before sending message.@{</span>
return;
}
boolean isMms = mWorkingMessage.requiresMms(); //判断当前是否发送是彩信
if (mRecipientsEditor.hasInvalidRecipient(isMms)) { <span style="color: rgb(85, 85, 85); line-height: 18px;"> //检查是否有不合法接受方</span>
/// M: Code analyze 054, Even if there are some invalid recipients , we also try to
/// send messag.Now, We do not disgingush there are some or all invalid recipients. @{
updateSendButtonState(); //更新发送按钮状态
String title = getResourcesString(R.string.has_invalid_recipient,
mRecipientsEditor.formatInvalidNumbers(isMms));
new AlertDialog.Builder(this)
.setCancelable(false)
.setIconAttribute(android.R.attr.alertDialogIcon)
.setTitle(title)
.setMessage(R.string.invalid_recipient_message)
.setPositiveButton(R.string.try_to_send,
new SendIgnoreInvalidRecipientListener())
.setNegativeButton(R.string.no, new CancelSendingListenerForInvalidRecipient())
.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
dialog.dismiss();
}
return false;
}
})
.show();
/** M: support mms cc feature. CT requested. here use simple logic.
* check to and cc only show one dialog, if users ignore To invalid address,
* don't show cc invalid too.
*/
} else if (isRecipientsCcEditorVisible() && mRecipientsCcEditor.hasInvalidRecipient(true)) {
//updateSendButtonState();
String title = getResourcesString(R.string.has_invalid_cc, mRecipientsCcEditor
.formatInvalidNumbers(true));
new AlertDialog.Builder(this)
.setCancelable(false)
.setIconAttribute(android.R.attr.alertDialogIcon)
.setTitle(title).setMessage(R.string.invalid_recipient_message)
.setPositiveButton(
R.string.try_to_send, new SendIgnoreInvalidRecipientListener())
.setNegativeButton(R.string.no, new OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
updateSendButtonState(true);
}
}).show();
} else {
/// M: Code analyze 030, Check condition before sending message.(All recipients are valid.)@{
checkConditionsAndSendMessage(true);
}
}
以下讲讲方法中所走的流程,省略方法内容。。。
然后 在checkConditionsAndSendMessage()方法中,进行发送前对环境监测,将simID转为卡槽id等。这里省略了方法checkConditionsAndSendMessage的内容
继续关注checkIpMessageBeforeSendMessage()这个方法中, sendMessage(bCheckEcmMode);这个方法开始进入发送关键地方。
private void sendMessage(boolean bCheckEcmMode) {
/// M:the method is extend to support gemini @{
mWorkingMessage.send(mDebugRecipients, mSelectedSimId);
MmsLog.d(TAG, "Compose.sendMessage(): after sendMessage. mConversation.ThreadId=" + mConversation.getThreadId()
+ ", MessageCount=" + mConversation.getMessageCount());
}
可以看到这里,调用了
mWorkingMessage.send(mDebugRecipients, mSelectedSimId);
下文详见androidのMMS短信发送过程(二)