发送代码流程图
发送彩信.pngOMA- MMS-CTR-v1_2-20030716-C.pdf
image.png
1.send
packages\apps\Mms\src\com\android\mms\data\WorkingMessage.java
public void send(final String recipientsInUI) {
new Thread(new Runnable() {
@Override
public void run() {
final SendReq sendReq = makeSendReq(conv, subject);
// Make sure the text in slide 0 is no longer holding onto a reference to
// the text in the message text box.
slideshow.prepareForSend();
sendMmsWorker(conv, mmsUri, persister, slideshow, sendReq, textOnly);
updateSendStats(conv);
}
}, "WorkingMessage.send MMS").start();
}
2.sendMmsWorker
packages\apps\Mms\src\com\android\mms\data\WorkingMessage.java
private void sendMmsWorker(Conversation conv, Uri mmsUri, PduPersister persister,
SlideshowModel slideshow, SendReq sendReq, boolean textOnly) {
//跟短信一样:重置主题输入框、内容输入框、附件、mWorkingMessage等
mStatusListener.onPreMessageSent();
threadId = conv.ensureThreadId(); //构建或者查询threadId
newMessage = mmsUri == null;
if (newMessage) {//如果之前没有往数据库插入这条记录
// Write something in the database so the new message will appear as sending
ContentValues values = new ContentValues();
values.put(Mms.MESSAGE_BOX, Mms.MESSAGE_BOX_OUTBOX);
values.put(Mms.THREAD_ID, threadId);
values.put(Mms.MESSAGE_TYPE, PduHeaders.MESSAGE_TYPE_SEND_REQ);
if (textOnly) {
values.put(Mms.TEXT_ONLY, 1);
}
//Mms表插入一条记录 public static final int MESSAGE_TYPE_OUTBOX = 4
mmsUri = SqliteWrapper.insert(mActivity, mContentResolver, Mms.Outbox.CONTENT_URI,values);
}
try {
if (newMessage) {
//更新Mms和part表
// Create a new MMS message if one hasn't been made yet.
mmsUri = createDraftMmsMessage(persister, sendReq, slideshow, mmsUri, mActivity, null);
} else {
// Otherwise, sync the MMS message in progress to disk.
updateDraftMmsMessage(mmsUri, persister, slideshow, sendReq, null);
}
// Be paranoid and clean any draft SMS up.
deleteDraftSmsMessage(threadId);
} finally {
DraftCache.getInstance().setSavingDraft(false);
}
int error = 0;
try {
slideshow.finalResize(mmsUri); //压缩附件,更新到part表
} catch (ExceedMessageSizeException e1) {
error = MESSAGE_SIZE_EXCEEDED;
} catch (MmsException e1) {
error = UNKNOWN_ERROR;
}
MessageSender sender = new MmsMessageSender(mActivity, mmsUri, slideshow.getCurrentMessageSize());
try {
if (!sender.sendMessage(threadId)) {
// The message was sent through SMS protocol, we should
// delete the copy which was previously saved in MMS drafts.
SqliteWrapper.delete(mActivity, mContentResolver, mmsUri, null, null);
}
// Make sure this thread isn't over the limits in message count
Recycler.getMmsRecycler().deleteOldMessagesByThreadId(mActivity, threadId);
} catch (Exception e) {
Log.e(TAG, "Failed to send message: " + mmsUri + ", threadId=" + threadId, e);
}
}
3.sendMessage
packages\apps\Mms\src\com\android\mms\transaction\MmsMessageSender.java
public boolean sendMessage(long token) throws MmsException {
if (!mMessageUri.toString().startsWith(Mms.Draft.CONTENT_URI.toString())) {
//之前的类型不是草稿,就在pending_msgs表插入一条记录
ContentValues values = new ContentValues(7);
values.put(PendingMessages.PROTO_TYPE, MmsSms.MMS_PROTO);
values.put(PendingMessages.MSG_ID, messageId);
values.put(PendingMessages.MSG_TYPE, pdu.getMessageType());
values.put(PendingMessages.ERROR_TYPE, 0);
values.put(PendingMessages.ERROR_CODE, 0);
values.put(PendingMessages.RETRY_INDEX, 0);
values.put(PendingMessages.DUE_TIME, 0);
SqliteWrapper.insert(mContext, mContext.getContentResolver(), PendingMessages.CONTENT_URI, values);
} else{
//如果之前是草稿,就更新为public static final int MESSAGE_TYPE_OUTBOX = 4
p.move(mMessageUri, Mms.Outbox.CONTENT_URI);
}
//启动TransactionService
mContext.startService(new Intent(mContext, TransactionService.class));
return true
}
4.TransactionService
packages\apps\Mms\src\com\android\mms\transaction\TransactionService.java
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
Message msg = mServiceHandler.obtainMessage(EVENT_NEW_INTENT);
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
return Service.START_NOT_STICKY;
}
5.handleMessage
packages\apps\Mms\src\com\android\mms\transaction\TransactionService.java
private final class ServiceHandler extends Handler {
public void handleMessage(Message msg) {
Transaction transaction = null;
switch (msg.what) {
case EVENT_NEW_INTENT:
onNewIntent((Intent)msg.obj, msg.arg1);
break;
}
}
}
6.onNewIntent
packages\apps\Mms\src\com\android\mms\transaction\TransactionService.java
public void onNewIntent(Intent intent, int serviceId) {
String action = intent.getAction();
if (ACTION_ONALARM.equals(action) || ACTION_ENABLE_AUTO_RETRIEVE.equals(action) ||
(intent.getExtras() == null)) {
//查询pending_msgs的所有在当前时间之前的所有彩信
Cursor cursor = PduPersister.getPduPersister(this).getPendingMessages(System.currentTimeMillis());
while (cursor.moveToNext()) {
int transactionType = getTransactionType(msgType); //如果是发送的彩信,SEND_TRANSACTION = 2
switch (transactionType) {
default:
Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI,cursor.getLong(columnIndexOfMsgId));
TransactionBundle args = new TransactionBundle(transactionType, uri.toString());
// FIXME: We use the same startId for all MMs.
launchTransaction(serviceId, args, false);
break;
}
}
}
}
7.launchTransaction
packages\apps\Mms\src\com\android\mms\transaction\TransactionService.java
private void launchTransaction(int serviceId, TransactionBundle txnBundle, boolean noNetwork) {
Message msg = mServiceHandler.obtainMessage(EVENT_TRANSACTION_REQUEST);
msg.arg1 = serviceId;
msg.obj = txnBundle;
mServiceHandler.sendMessage(msg);
}
8.handleMessage
packages\apps\Mms\src\com\android\mms\transaction\TransactionService.java
private final class ServiceHandler extends Handler {
public void handleMessage(Message msg) {
Transaction transaction = null;
switch (msg.what) {
case EVENT_TRANSACTION_REQUEST:
int transactionType = args.getTransactionType();
switch (transactionType) {
case Transaction.SEND_TRANSACTION:
transaction = new SendTransaction(TransactionService.this, serviceId,transactionSettings, args.getUri());
break;
}
if (!processTransaction(transaction)) {
transaction = null;
return;
}
}
}
}
9.processTransaction
packages\apps\Mms\src\com\android\mms\transaction\TransactionService.java
private boolean processTransaction(Transaction transaction) throws IOException {
synchronized (mProcessing) {
for (Transaction t : mPending) {
if (t.isEquivalent(transaction)) { //如果已经存在于mPending List,返回
return true;
}
}
for (Transaction t : mProcessing) { //如果已经存在于mProcessing List,返回
if (t.isEquivalent(transaction)) {
return true;
}
}
int connectivityResult = beginMmsConnectivity();
if (connectivityResult == PhoneConstants.APN_REQUEST_STARTED) {
mPending.add(transaction);
return true;
}
if (mProcessing.size() > 0) { //如果mProcessing List已经有 transaction
mPending.add(transaction);
return true;
} else{
mProcessing.add(transaction); //加入mProcessing List
}
}
sendMessageDelayed(obtainMessage(EVENT_CONTINUE_MMS_CONNECTIVITY), APN_EXTENSION_WAIT);
//将Transaction.this添加到自己的成员变量mObservers里
transaction.attach(TransactionService.this); //mObservers.add(observer);
transaction.process();
return true;
}
10.process
packages\apps\Mms\src\com\android\mms\transaction\SendTransaction.java
public void process() {
mThread = new Thread(this, "SendTransaction");
mThread.start();
}
11.run
packages\apps\Mms\src\com\android\mms\transaction\SendTransaction.java
public void run() {
try{
// Load M-Send.req from outbox
PduPersister persister = PduPersister.getPduPersister(mContext);
SendReq sendReq = (SendReq) persister.load(mSendReqURI);
//发送出去M-Send.req
byte[] response = sendPdu(SendingProgressTokenManager.get(tokenKey), new PduComposer(mContext, sendReq).make());
//收到M-Send.conf
SendConf conf = (SendConf) new PduParser(
response, PduParserUtil.shouldParseContentDisposition()).parse();
int respStatus = conf.getResponseStatus(); //发送结果
if (respStatus != PduHeaders.RESPONSE_STATUS_OK) { //0x80:128
SqliteWrapper.update(mContext, mContext.getContentResolver(), mSendReqURI, values, null, null);
return;
}
SqliteWrapper.update(mContext, mContext.getContentResolver(), mSendReqURI, values, null, null);
//更新彩信为public static final int MESSAGE_TYPE_SENT = 2
// Move M-Send.req from Outbox into Sent.
Uri uri = persister.move(mSendReqURI, Sent.CONTENT_URI);
} finally {
//调用TransactionService的update方法:处理mProcessing、mPending、网络连接等
notifyObservers();
}
}
12.sendPdu
packages\apps\Mms\src\com\android\mms\transaction\Transaction.java
protected byte[] sendPdu(long token, byte[] pdu) throws IOException, MmsException {
return sendPdu(token, pdu, mTransactionSettings.getMmscUrl());
}
13.sendPdu
packages\apps\Mms\src\com\android\mms\transaction\Transaction.java
protected byte[] sendPdu(long token, byte[] pdu, String mmscUrl) throws IOException, MmsException {
if (pdu == null) {
throw new MmsException();
}
ensureRouteToHost(mmscUrl, mTransactionSettings);
return HttpUtils.httpConnection(
mContext, token,
mmscUrl,
pdu, HttpUtils.HTTP_POST_METHOD,
mTransactionSettings.isProxySet(),
mTransactionSettings.getProxyAddress(),
mTransactionSettings.getProxyPort());
}
14.httpConnection
packages\apps\Mms\src\com\android\mms\transaction\HttpUtils.java
protected static byte[] httpConnection(Context context, long token,
String url, byte[] pdu, int method, boolean isProxySet,
String proxyHost, int proxyPort) throws IOException {
HttpResponse response = client.execute(target, req);
}
网友评论