高通android 7.0彩信重发机制

原创 2017年09月12日 09:02:04
彩信的重发机制
跟DefaultRetryScheme这个有关
<integer-array name="retry_scheme">
        <item>60000</item> 1分钟
        <item>300000</item> 5分钟
        <item>600000</item> 10分钟
        <item>1800000</item> 30分钟
    </integer-array>
单位是毫秒


getWaitingInterval

RetryScheduler.java是单例模式

scheduleRetry
update



public SendTransaction(Context context,
            int transId, TransactionSettings connectionSettings, String uri) {
        super(context, transId, connectionSettings);
        mSendReqURI = Uri.parse(uri);
        mId = uri;

        // Attach the transaction to the instance of RetryScheduler.
        attach(RetryScheduler.getInstance(context));
    } 
public void attach(Observer observer) {
        detach(observer);
        mObservers.add(observer);
    }
attach就是注册监听器
所以当调用notifyObservers就会出发调用update

SendTransaction在run的最后
finally {
            if (mTransactionState.getState() != TransactionState.SUCCESS) {
                mTransactionState.setState(TransactionState.FAILED);
                mTransactionState.setContentUri(mSendReqURI);
                Log.e(TAG, "Delivery failed.");
            }
            notifyObservers();
 }

 
现在我们来看下RetryScheduler的update方法
public void update(Observable observable) {
        Uri uri = null;
        Transaction t = (Transaction) observable;
        try {

            if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
                Log.v(TAG, "[RetryScheduler] update " + observable);
            }

            // We are only supposed to handle M-Notification.ind, M-Send.req
            // and M-ReadRec.ind.
            if ((t instanceof NotificationTransaction)
                    || (t instanceof RetrieveTransaction)
                    || (t instanceof ReadRecTransaction)
                    || (t instanceof SendTransaction)) {
                try {
                    TransactionState state = t.getState();
                    if (state.getState() == TransactionState.FAILED) {//如果是失败状态,获取Uri,然后启动重试
                        uri = state.getContentUri();
                        if (uri != null) {
                            scheduleRetry(mContext, uri);
                        }
                    }
                } finally {
                    t.detach(this);
                }
            }
        } finally {
            setRetryAlarm(mContext, uri);//这个设置alarm来进行重发
            Log.d(TAG, "set retry alarm");
        }
    }

scheduleRetry 这个方法是对pending_msgs表需要重发的字段进行更新,并且进行检测
我们还是以发送失败重发为例。
发送失败的话,其在pending_msgs仍然会有记录,
uriBuilder.appendQueryParameter("message", String.valueOf(msgId)); 查找到发送失败的msgId对应的pending_msgs中的记录
int retryIndex = cursor.getInt(cursor.getColumnIndexOrThrow(
                            PendingMessages.RETRY_INDEX)) + 1;
retry_index字段表示已经重试的次数
boolean isRetryDownloading =
                            (msgType == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND);下载失败也会进行重试的,这个我们略过,读者自己看代码

long retryAt = current + scheme.getWaitingInterval();
values.put(PendingMessages.DUE_TIME, retryAt); 所以due_time字段是下次重发的时间


注意,context是TransactionService的context
public static void setRetryAlarm(Context context, Uri mmsUrl) {
        Cursor mmsCursor = PduPersister.getPduPersister(context).getPendingMessages(
                Long.MAX_VALUE);
        if (mmsCursor != null) {
            try {
                Cursor cursor = getMmsCursor(mmsCursor, mmsUrl);
                if (cursor != null) {
                    // The result of getPendingMessages() is order by due time.
                    long retryAt = cursor.getLong(cursor.getColumnIndexOrThrow(
                            PendingMessages.DUE_TIME));

                    Intent service = new Intent(TransactionService.ACTION_ONALARM,
                            null, context, TransactionService.class);
                    PendingIntent operation = PendingIntent.getService(
                            context, 0, service, PendingIntent.FLAG_ONE_SHOT);
                    AlarmManager am = (AlarmManager) context.getSystemService(
                            Context.ALARM_SERVICE);
                    am.setExact(AlarmManager.RTC, retryAt, operation);

                    if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
                        Log.v(TAG, "Next retry is scheduled at"
                                + (retryAt - System.currentTimeMillis()) + "ms from now");
                    }
                }
            } finally {
                mmsCursor.close();
            }
        }
    }
所以重发机制是设置了alarm。

TransactionService的ACTION_ONALARM
onNewIntent
接着就是继续之前描述的彩信流程了。




短信重发机制

短信发送失败时,是怎样重发的? [SOLUTION] 目前短信重发分别做在Modem和 App ,对应不同的情况。 Modem:      Modem的重发做在SMS-TL/ SM...
  • lipengshiwo
  • lipengshiwo
  • 2016年08月25日 23:12
  • 1066

高通android 7.0彩信发送流程

ComposeMessageActivity.java sendMessage WorkingMessage send private void prepareForSave(...
  • tangyisen18
  • tangyisen18
  • 2017年09月12日 08:59
  • 1826

从错误处理角度记录一下Android发送彩信

简单记录,为了下次忘记的时候可以很快回忆起。 发送或接受彩信时经过处理走到TransactionService.java,在这个类里面,这个类里面有著名的 beginMmsConnctivity(...
  • hugobada
  • hugobada
  • 2012年11月12日 19:21
  • 1355

高通android 7.0彩信发送过程中使用到的google pdu

对于彩信与数据库的交互操作,google并没有将这部分代码放在Mms中,而是放在framework中的pdu部分。 具体代码路径是在:opt\telephony\src\java\com\googl...
  • tangyisen18
  • tangyisen18
  • 2017年09月14日 10:42
  • 327

Android或者Java发送Http自动重发请求的解决方案

Android或者Java发送Http自动重发请求的解决方案
  • ljz2009y
  • ljz2009y
  • 2014年04月24日 09:24
  • 8114

MTK方案上基于Android N拦截黑名单中的短/彩信的方法

--- 作者 zuhui.zhang 安卓7.0原生系统增加了在framework层拦截黑名单来电和短信,但不会将数据保存到数据库,因此无法查看到被拦截的来电和短信。在安卓7.0之前,黑...
  • maetelibom
  • maetelibom
  • 2017年11月22日 15:49
  • 532

android 实现发送彩信功能

最近有个需求,不去调用系统界面发送彩信功能。做过发送短信功能的同学可能第一反应是这样:  不使用 StartActivity,像发短信那样,调用一个类似于发短信的方法  SmsManager sm...
  • nosxcy
  • nosxcy
  • 2013年03月27日 18:04
  • 1091

高通android 7.0短信会话界面加载流程

在短信会话列表界面,点击其中一条记录,会进入相对应的短信会话详情界面。 短信加载内容分为草稿和历史聊天记录。UI分面分为新建短信和打开已经保存在数据库的历史短信会话。 新建短信在前面我们已经...
  • tangyisen18
  • tangyisen18
  • 2017年09月13日 15:20
  • 287

彩信发送和接收关键流程

MMS 的设计基于WAP协议; DataConnection 手机上网数据连接,其中5种常用类型的APN配置信息中就有MMS类型,即收发彩信时需要建立手机上网数据连接; MMS发送和接收,...
  • hongkang218
  • hongkang218
  • 2016年09月20日 16:48
  • 1428

项目难题之编程实现数据不对重发的机制

ARM接收PC机通过串口发来的数据,数据打包成帧的形式,有针头针尾,我要实现的功能是:ARM通过检验帧头针尾是否正确,决定是否请求PC机重新发送上一帧的数据。 我们知道汇编中有调到特定位置的程序的功能...
  • hannibaychty
  • hannibaychty
  • 2015年04月11日 20:24
  • 928
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:高通android 7.0彩信重发机制
举报原因:
原因补充:

(最多只允许输入30个字)