高通android 7.0彩信傳送流程
阿新 • • 發佈:2019-02-15
ComposeMessageActivity.java
sendMessage WorkingMessage
send private void prepareForSave(boolean notify) { // Make sure our working set of recipients is resolved // to first-class Contact objects before we save. syncWorkingRecipients(); if (hasMmsContentToSave()) { ensureSlideshow(); syncTextToSlideshow(); } } 因為private SlideshowModel mSlideshow;這個是跟資料庫中part表資料對應的,所以現在要傳送彩信,如果有內容,則要將其都新增到mSlideshow中。 if (requiresMms() || addressContainsEmailToMms(conv, msgTxt)) {
注意,例如你現在添加了一張圖片,則這個時候其不會馬上存入資料庫中,但是會存入到mSlideshow中,當簡訊傳送或者儲存為草稿的時候才寫入到資料庫中的。 final PduPersister persister = PduPersister.getPduPersister(mActivity); 彩信是依靠PduPersister來將彩信資料寫入到資料庫的。 final SlideshowModel slideshow = mSlideshow;
final CharSequence subject = mSubject; final boolean textOnly = mAttachmentType == TEXT; 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();同樣開啟一個子執行緒來進行傳送彩信 private static SendReq makeSendReq(Conversation conv, CharSequence subject) { String[] dests = conv.getRecipients().getNumbers(true /* scrub for MMS address */); SendReq req = new SendReq(); EncodedStringValue[] encodedNumbers = EncodedStringValue.encodeStrings(dests); if (encodedNumbers != null) { req.setTo(encodedNumbers);//將收件人寫入 } if (!TextUtils.isEmpty(subject)) { req.setSubject(new EncodedStringValue(subject.toString()));//將主題寫入 } req.setDate(System.currentTimeMillis() / 1000L);//將當前時間寫入 return req; }
void sendMmsWorker(Conversation conv, Uri mmsUri, PduPersister persister,
SlideshowModel slideshow, SendReq sendReq, boolean textOnly)
DraftCache.getInstance().setSavingDraft(true);設定儲存草稿,好像是進行互斥,所以彩信是先要儲存草稿,然後才進行傳送
mStatusListener.onPreMessageSent();//彩信傳送前更新簡訊UI
if (newMessage) {//此時為true // 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); } if ((TelephonyManager.getDefault().getPhoneCount()) > 1) { values.put(Mms.SUBSCRIPTION_ID, mCurrentConvSubId); } else { values.put(Mms.SUBSCRIPTION_ID, SubscriptionManager.getDefaultDataSubscriptionId()); } mmsUri = SqliteWrapper.insert(mActivity, mContentResolver, Mms.Outbox.CONTENT_URI, values);//插入到發件箱中 }
同樣,彩信,pdu表中也有一個欄位是表示當前彩信的各種狀態的,就是msg_box欄位,這裡是發件箱,其型別type是PduHeaders.MESSAGE_TYPE_SEND_REQ,往資料庫pdu的發件箱寫入資料
mStatusListener.onMessageSent();//簡訊傳送後更新UI,此時顯示正在傳送中...
然後查詢所有處於發件箱的彩信,計算他們的附件總大小,看是否超出了限制(為什麼這裡有這個限制?)
if (newMessage) {
// Create a new MMS message if one hasn't been made yet.
mmsUri = createDraftMmsMessage(persister, sendReq, slideshow, mmsUri,
mActivity, null);//將mSlideshow的資料寫入到part表中
} else {
// Otherwise, sync the MMS message in progress to disk.
updateDraftMmsMessage(mmsUri, persister, slideshow, sendReq, null);//更新草稿
}
ContentValues values = new ContentValues(1);
if ((TelephonyManager.getDefault().getPhoneCount()) > 1) {
values.put(Mms.SUBSCRIPTION_ID, mCurrentConvSubId);
} else {
values.put(Mms.SUBSCRIPTION_ID, SubscriptionManager.getDefaultDataSubscriptionId());
}
SqliteWrapper.update(mActivity, mContentResolver, mmsUri, values, null, null);
更新subId
MessageSender sender = new MmsMessageSender(mActivity, mmsUri,
slideshow.getCurrentMessageSize(), mCurrentConvSubId);
呼叫MmsMessageSender的sendMessage來發送彩信
MmsMessageSender.java
sendMessage
首先是繼續更新資料庫的一些資料 PduPersister p = PduPersister.getPduPersister(mContext); GenericPdu pdu = p.load(mMessageUri);//從資料庫中載入URI為mMessageUri到記憶體中,所以對於彩信,與資料庫互動我們是直接用google提供的pdu,非常簡單,這個另外一個專題講。 SendReq sendReq = (SendReq) pdu; 傳送請求的資料型別
if (!mMessageUri.toString().startsWith(Mms.Draft.CONTENT_URI.toString())) { // If the message is already in the outbox (most likely because we created a "primed" // message in the outbox when the user hit send), then we have to manually put an // entry in the pending_msgs table which is where TransacationService looks for // messages to send. Normally, the entry in pending_msgs is created by the trigger: // insert_mms_pending_on_update, when a message is moved from drafts to the outbox. 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 { p.move(mMessageUri, Mms.Outbox.CONTENT_URI); } 我們已經是處於發件箱中,所以走第一個分支,即在表pending_msgs中插入一條資料,表示是待發送彩信 Intent intent = new Intent(mContext, TransactionService.class); intent.putExtra(Mms.SUBSCRIPTION_ID, mSubId); mContext.startService(intent); 啟動TransactionService服務來發送彩信。 TransactionService.java
onStartCommand
第一次是EVENT_NEW_INTENT訊息 private ServiceHandler mServiceHandler;
handleMessage
onNewIntent((Intent)msg.obj, msg.arg1);
mConnMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
傳送彩信需要先檢測ConnectivityManager服務,這個不是資料連線服務 我們假設傳送環境OK,可以傳送彩信。 Cursor cursor = PduPersister.getPduPersister(this).getPendingMessages( System.currentTimeMillis()); 載入所有的pending簡訊 int columnIndexOfRetryIndex = cursor.getColumnIndexOrThrow( PendingMessages.RETRY_INDEX); 這個是重試次數 transactionType是 Transaction.SEND_TRANSACTION;
TransactionBundle args = new TransactionBundle(transactionType, uri.toString(), subId); 此時uri是pdu的uri launchTransaction(serviceId, args, false);
Message msg = mServiceHandler.obtainMessage(EVENT_TRANSACTION_REQUEST);
case Transaction.SEND_TRANSACTION: transaction = new SendTransaction( TransactionService.this, serviceId, transactionSettings, args.getUri()); break; if (!processTransaction(transaction)) { transaction = null; return; } mPending和mProcessing此時是沒有的 beginMmsConnectivity(subId);開始mms的資料連線
if (!mIsAvailable[phoneId]) { mPending.add(transaction); LogTag.debugD("processTransaction: connResult=APN_REQUEST_STARTED, " + "defer transaction pending MMS connectivity"); return true; }如果當前sim卡不可用,就會將這條傳送記錄新增到mPending中 if (mProcessing.size() > 0) { LogTag.debugD("Adding transaction to 'mPending' list: " + transaction); mPending.add(transaction); return true; } else { LogTag.debugD("Adding transaction to 'mProcessing' list: " + transaction); mProcessing.add(transaction); }我們現在是走else,所以直接處理。所以這兩個的關係是,mPending是將要處理,而mProcessing是正在處理的。 transaction.attach(TransactionService.this); transaction.process(); process走的是SendTransaction的process public void process() { mThread = new Thread(this, "SendTransaction"); mThread.start(); } 所以啟動子執行緒傳送彩信,然後返回true,我們繼續看主執行緒。哦,直接return。 SendTransaction
run RateController rateCtlr = RateController.getInstance();
PduPersister persister = PduPersister.getPduPersister(mContext); SendReq sendReq = (SendReq) persister.load(mSendReqURI); 從資料庫載入要傳送的彩信 重新設定時間,這才是要傳送的時間,然後更新資料庫 byte[] response = sendPdu(SendingProgressTokenManager.get(tokenKey), new PduComposer(mContext, sendReq).make()); Transaction.java
/** * A common method to send a PDU to MMSC. * * @param token The token to identify the sending progress. * @param pdu A byte array which contains the data of the PDU. * @return A byte array which contains the response data. * If an HTTP error code is returned, an IOException will be thrown. * @throws IOException if any error occurred on network interface or * an HTTP error code(>=400) returned from the server. * @throws MmsException if pdu is null. */根據註釋,就是利用這個傳送彩信的,pdu是傳送的彩信內容,token是當前傳送的一個唯一標識,而返回值則是傳送結果 protected byte[] sendPdu(long token, byte[] pdu) throws IOException, MmsException { return sendPdu(token, pdu, mTransactionSettings.getMmscUrl()); } protected byte[] sendPdu(long token, byte[] pdu, String mmscUrl) throws IOException, MmsException { if (pdu == null) { throw new MmsException(); } return HttpUtils.httpConnection( mContext, token, mmscUrl, pdu, HttpUtils.HTTP_POST_METHOD, mTransactionSettings.isProxySet(), mTransactionSettings.getProxyAddress(), mTransactionSettings.getProxyPort()); } AndroidHttpClient往下看是利用AndroidHttpClient來發送。這個我們後面再看。
String respStr = new String(response);
我這裡是傳送失敗,看起來是亂碼 SendConf conf = (SendConf) new PduParser(response, PduParserUtil.shouldParseContentDisposition()).parse(); int respStatus = conf.getResponseStatus();//傳送失敗這裡是130,public static final int RESPONSE_STATUS_ERROR_SERVICE_DENIED = 0x82; values.put(Mms.RESPONSE_STATUS, respStatus); if (respStatus != PduHeaders.RESPONSE_STATUS_OK) {//不是傳送成功就更新狀態 SqliteWrapper.update(mContext, mContext.getContentResolver(), mSendReqURI, values, null, null); Log.e(TAG, "Server returned an error code: " + respStatus); return; } if (mTransactionState.getState() != TransactionState.SUCCESS) { mTransactionState.setState(TransactionState.FAILED); mTransactionState.setContentUri(mSendReqURI); Log.e(TAG, "Delivery failed."); } String messageId = PduPersister.toIsoString(conf.getMessageId()); values.put(Mms.MESSAGE_ID, messageId); SqliteWrapper.update(mContext, mContext.getContentResolver(), mSendReqURI, values, null, null); // Move M-Send.req from Outbox into Sent. Uri uri = persister.move(mSendReqURI, Sent.CONTENT_URI);//傳送成功應該會將pending裡面的條目刪除了,應該在資料庫中自動操作的。 傳送成功會將彩信狀態從待發送轉為已經發送 notifyObservers();//這裡會對監聽者進行回撥,TransactionService的update會被回撥。這裡應該是RetryScheduler的update被呼叫。都有。Transaction extends Observable提供了attach
mProcessing.remove(transaction);
else if (mProcessing.isEmpty()) { LogTag.debugD("update: endMmsConnectivity"); endMmsConnectivity(transaction.getSubId()); }關閉mms的資料連線 Intent intent = new Intent(TRANSACTION_COMPLETED_ACTION); TransactionState state = transaction.getState(); int result = state.getState(); intent.putExtra(STATE, result); case TransactionState.FAILED:
boolean failSetupDataCall = Transaction.FAIL_REASON_CAN_NOT_SETUP_DATA_CALL == transaction.getFailReason();這個是? isLastRetry scheme.getRetryLimit()這裡有5次
if (type == Transaction.SEND_TRANSACTION) { if (failSetupDataCall) { mToastHandler.sendEmptyMessage( TOAST_SETUP_DATA_CALL_FAILED_FOR_SEND); <string name="no_network_send_failed_retry">"無網路,傳送失敗,稍後自動重新發送。"</string> } else { mToastHandler.sendEmptyMessage(TOAST_SEND_FAILED_RETRY);<string name="send_failed_retry">"傳送失敗,稍後自動重新發送。"</string> } } sendBroadcast(intent);
finally { transaction.detach(this); stopSelfIfIdle(serviceId); } TRANSACTION_COMPLETED_ACTION 沒有發現哪個廣播會接收。
所以到這裡結束了。UI會根據資料庫的改變而重新整理介面。 彩信的重發機制 跟DefaultRetryScheme這個有關 <integer-array name="retry_scheme"> <item>0</item> <item>60000</item> <item>300000</item> <item>600000</item> <item>1800000</item> </integer-array> getWaitingInterval
RetryScheduler.java
如果想了解彩信傳送過程中與pdu的關係,可以看部落格 如果發現本部落格對您們有幫助,幫忙頂下。謝謝了!!
sendMessage WorkingMessage
send private void prepareForSave(boolean notify) { // Make sure our working set of recipients is resolved // to first-class Contact objects before we save. syncWorkingRecipients(); if (hasMmsContentToSave()) { ensureSlideshow(); syncTextToSlideshow(); } } 因為private SlideshowModel mSlideshow;這個是跟資料庫中part表資料對應的,所以現在要傳送彩信,如果有內容,則要將其都新增到mSlideshow中。 if (requiresMms() || addressContainsEmailToMms(conv, msgTxt)) {
注意,例如你現在添加了一張圖片,則這個時候其不會馬上存入資料庫中,但是會存入到mSlideshow中,當簡訊傳送或者儲存為草稿的時候才寫入到資料庫中的。 final PduPersister persister = PduPersister.getPduPersister(mActivity); 彩信是依靠PduPersister來將彩信資料寫入到資料庫的。 final SlideshowModel slideshow = mSlideshow;
final CharSequence subject = mSubject; final boolean textOnly = mAttachmentType == TEXT; 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();同樣開啟一個子執行緒來進行傳送彩信 private static SendReq makeSendReq(Conversation conv, CharSequence subject) { String[] dests = conv.getRecipients().getNumbers(true /* scrub for MMS address */); SendReq req = new SendReq(); EncodedStringValue[] encodedNumbers = EncodedStringValue.encodeStrings(dests); if (encodedNumbers != null) { req.setTo(encodedNumbers);//將收件人寫入 } if (!TextUtils.isEmpty(subject)) { req.setSubject(new EncodedStringValue(subject.toString()));//將主題寫入 } req.setDate(System.currentTimeMillis() / 1000L);//將當前時間寫入 return req; }
mStatusListener.onPreMessageSent();//彩信傳送前更新簡訊UI
if (newMessage) {//此時為true // 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); } if ((TelephonyManager.getDefault().getPhoneCount()) > 1) { values.put(Mms.SUBSCRIPTION_ID, mCurrentConvSubId); } else { values.put(Mms.SUBSCRIPTION_ID, SubscriptionManager.getDefaultDataSubscriptionId()); } mmsUri = SqliteWrapper.insert(mActivity, mContentResolver, Mms.Outbox.CONTENT_URI, values);//插入到發件箱中 }
MmsMessageSender.java
sendMessage
首先是繼續更新資料庫的一些資料 PduPersister p = PduPersister.getPduPersister(mContext); GenericPdu pdu = p.load(mMessageUri);//從資料庫中載入URI為mMessageUri到記憶體中,所以對於彩信,與資料庫互動我們是直接用google提供的pdu,非常簡單,這個另外一個專題講。 SendReq sendReq = (SendReq) pdu; 傳送請求的資料型別
if (!mMessageUri.toString().startsWith(Mms.Draft.CONTENT_URI.toString())) { // If the message is already in the outbox (most likely because we created a "primed" // message in the outbox when the user hit send), then we have to manually put an // entry in the pending_msgs table which is where TransacationService looks for // messages to send. Normally, the entry in pending_msgs is created by the trigger: // insert_mms_pending_on_update, when a message is moved from drafts to the outbox. 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 { p.move(mMessageUri, Mms.Outbox.CONTENT_URI); } 我們已經是處於發件箱中,所以走第一個分支,即在表pending_msgs中插入一條資料,表示是待發送彩信 Intent intent = new Intent(mContext, TransactionService.class); intent.putExtra(Mms.SUBSCRIPTION_ID, mSubId); mContext.startService(intent); 啟動TransactionService服務來發送彩信。 TransactionService.java
onStartCommand
第一次是EVENT_NEW_INTENT訊息 private ServiceHandler mServiceHandler;
handleMessage
onNewIntent((Intent)msg.obj, msg.arg1);
mConnMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
傳送彩信需要先檢測ConnectivityManager服務,這個不是資料連線服務 我們假設傳送環境OK,可以傳送彩信。 Cursor cursor = PduPersister.getPduPersister(this).getPendingMessages( System.currentTimeMillis()); 載入所有的pending簡訊 int columnIndexOfRetryIndex = cursor.getColumnIndexOrThrow( PendingMessages.RETRY_INDEX); 這個是重試次數 transactionType是 Transaction.SEND_TRANSACTION;
TransactionBundle args = new TransactionBundle(transactionType, uri.toString(), subId); 此時uri是pdu的uri launchTransaction(serviceId, args, false);
Message msg = mServiceHandler.obtainMessage(EVENT_TRANSACTION_REQUEST);
case Transaction.SEND_TRANSACTION: transaction = new SendTransaction( TransactionService.this, serviceId, transactionSettings, args.getUri()); break; if (!processTransaction(transaction)) { transaction = null; return; } mPending和mProcessing此時是沒有的 beginMmsConnectivity(subId);開始mms的資料連線
if (!mIsAvailable[phoneId]) { mPending.add(transaction); LogTag.debugD("processTransaction: connResult=APN_REQUEST_STARTED, " + "defer transaction pending MMS connectivity"); return true; }如果當前sim卡不可用,就會將這條傳送記錄新增到mPending中 if (mProcessing.size() > 0) { LogTag.debugD("Adding transaction to 'mPending' list: " + transaction); mPending.add(transaction); return true; } else { LogTag.debugD("Adding transaction to 'mProcessing' list: " + transaction); mProcessing.add(transaction); }我們現在是走else,所以直接處理。所以這兩個的關係是,mPending是將要處理,而mProcessing是正在處理的。 transaction.attach(TransactionService.this); transaction.process(); process走的是SendTransaction的process public void process() { mThread = new Thread(this, "SendTransaction"); mThread.start(); } 所以啟動子執行緒傳送彩信,然後返回true,我們繼續看主執行緒。哦,直接return。 SendTransaction
run RateController rateCtlr = RateController.getInstance();
PduPersister persister = PduPersister.getPduPersister(mContext); SendReq sendReq = (SendReq) persister.load(mSendReqURI); 從資料庫載入要傳送的彩信 重新設定時間,這才是要傳送的時間,然後更新資料庫 byte[] response = sendPdu(SendingProgressTokenManager.get(tokenKey), new PduComposer(mContext, sendReq).make()); Transaction.java
/** * A common method to send a PDU to MMSC. * * @param token The token to identify the sending progress. * @param pdu A byte array which contains the data of the PDU. * @return A byte array which contains the response data. * If an HTTP error code is returned, an IOException will be thrown. * @throws IOException if any error occurred on network interface or * an HTTP error code(>=400) returned from the server. * @throws MmsException if pdu is null. */根據註釋,就是利用這個傳送彩信的,pdu是傳送的彩信內容,token是當前傳送的一個唯一標識,而返回值則是傳送結果 protected byte[] sendPdu(long token, byte[] pdu) throws IOException, MmsException { return sendPdu(token, pdu, mTransactionSettings.getMmscUrl()); } protected byte[] sendPdu(long token, byte[] pdu, String mmscUrl) throws IOException, MmsException { if (pdu == null) { throw new MmsException(); } return HttpUtils.httpConnection( mContext, token, mmscUrl, pdu, HttpUtils.HTTP_POST_METHOD, mTransactionSettings.isProxySet(), mTransactionSettings.getProxyAddress(), mTransactionSettings.getProxyPort()); } AndroidHttpClient往下看是利用AndroidHttpClient來發送。這個我們後面再看。
String respStr = new String(response);
我這裡是傳送失敗,看起來是亂碼 SendConf conf = (SendConf) new PduParser(response, PduParserUtil.shouldParseContentDisposition()).parse(); int respStatus = conf.getResponseStatus();//傳送失敗這裡是130,public static final int RESPONSE_STATUS_ERROR_SERVICE_DENIED = 0x82; values.put(Mms.RESPONSE_STATUS, respStatus); if (respStatus != PduHeaders.RESPONSE_STATUS_OK) {//不是傳送成功就更新狀態 SqliteWrapper.update(mContext, mContext.getContentResolver(), mSendReqURI, values, null, null); Log.e(TAG, "Server returned an error code: " + respStatus); return; } if (mTransactionState.getState() != TransactionState.SUCCESS) { mTransactionState.setState(TransactionState.FAILED); mTransactionState.setContentUri(mSendReqURI); Log.e(TAG, "Delivery failed."); } String messageId = PduPersister.toIsoString(conf.getMessageId()); values.put(Mms.MESSAGE_ID, messageId); SqliteWrapper.update(mContext, mContext.getContentResolver(), mSendReqURI, values, null, null); // Move M-Send.req from Outbox into Sent. Uri uri = persister.move(mSendReqURI, Sent.CONTENT_URI);//傳送成功應該會將pending裡面的條目刪除了,應該在資料庫中自動操作的。 傳送成功會將彩信狀態從待發送轉為已經發送 notifyObservers();//這裡會對監聽者進行回撥,TransactionService的update會被回撥。這裡應該是RetryScheduler的update被呼叫。都有。Transaction extends Observable提供了attach
mProcessing.remove(transaction);
else if (mProcessing.isEmpty()) { LogTag.debugD("update: endMmsConnectivity"); endMmsConnectivity(transaction.getSubId()); }關閉mms的資料連線 Intent intent = new Intent(TRANSACTION_COMPLETED_ACTION); TransactionState state = transaction.getState(); int result = state.getState(); intent.putExtra(STATE, result); case TransactionState.FAILED:
boolean failSetupDataCall = Transaction.FAIL_REASON_CAN_NOT_SETUP_DATA_CALL == transaction.getFailReason();這個是? isLastRetry scheme.getRetryLimit()這裡有5次
if (type == Transaction.SEND_TRANSACTION) { if (failSetupDataCall) { mToastHandler.sendEmptyMessage( TOAST_SETUP_DATA_CALL_FAILED_FOR_SEND); <string name="no_network_send_failed_retry">"無網路,傳送失敗,稍後自動重新發送。"</string> } else { mToastHandler.sendEmptyMessage(TOAST_SEND_FAILED_RETRY);<string name="send_failed_retry">"傳送失敗,稍後自動重新發送。"</string> } } sendBroadcast(intent);
finally { transaction.detach(this); stopSelfIfIdle(serviceId); } TRANSACTION_COMPLETED_ACTION 沒有發現哪個廣播會接收。
所以到這裡結束了。UI會根據資料庫的改變而重新整理介面。 彩信的重發機制 跟DefaultRetryScheme這個有關 <integer-array name="retry_scheme"> <item>0</item> <item>60000</item> <item>300000</item> <item>600000</item> <item>1800000</item> </integer-array> getWaitingInterval
RetryScheduler.java
如果想了解彩信傳送過程中與pdu的關係,可以看部落格 如果發現本部落格對您們有幫助,幫忙頂下。謝謝了!!