问题描述
我有一个 android 应用,它在短时间内发送了大量消息,该应用需要处理交付报告。这一切都很好,应用很稳定,运行没有任何崩溃,发送消息,交付报告工作正常......一段时间没问题。
假设我在发送一条消息后发送一条消息(成功发送前一条消息之后的每条消息 - 我正在查看 smsSent PendingIntent - 我只能在 hasOnProgressSend == false 时发送新消息)。交付报告可以正常工作约 1-2 小时。然后交付报告表现得很奇怪。不断丢弃一些交付报告。
所以发送完成后,大约 7 小时后,大约 8000 条短信发送报告停止出现,但有很多消息已收到,但应用程序没有收到发送报告。
但现在奇怪的部分来了:)。第二天我尝试了另一个测试并发送了另外 8000 条消息。消息立即开始发送给收件人,但我收到的交付报告来自前一天,而不是最后一天到达 broadcastReceiver。我尝试更换了我的 SIM 卡,并且还收到了前一天发送的消息。
重新启动应用程序后,一切都一样,最后一天的交付报告。但是在我重新启动设备后,它仍然表现得像昨天一样(大约 1-2 小时工作正常,然后交付报告速度变慢了很多)。
总结一下: 我收到交付报告就好了,直到看起来某些设备队列已满。此后交付报告非常缓慢。另一天,当我再次开始发送(使用新 SIM 卡)时,我的交付 broadcastReceiver 从昨天发送的消息中获取交付报告,而昨天发送的报告没有出现。我重新启动应用程序后是一样的。在我重新启动设备后,它开始表现得像第一天一样。因此,如果我的 brodactReceivers 是在我的 Activity 的 onCreate 方法中注册的,并且应用程序重新启动无济于事,这一定是我需要在我的应用程序中以某种方式处理的一些 android 队列问题(可能会减慢发送速度,在成功发送后进行更多延迟)如果几条未传递的消息大于某个值,则停止发送消息或停止发送?)
谢谢,很抱歉问这么大的问题:)
我在 onCreate 中注册了两个 broadcarsReceiver:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
... check all persmissions
receiverSentGlobal = new broadcastReceiver() {
@Override
public void onReceive(Context context,Intent intent) {
hasOnProgressSend = false;
JSONObject currentMsgSentStatus = new JSONObject();
try {
currentMsgSentStatus.put("msg_id",intent.getStringExtra("msg_id"));
currentMsgSentStatus.put("sim_id",intent.getStringExtra("sim_id"));
} catch (JSONException e) {
e.printstacktrace();
}
switch (getResultCode()) {
case Activity.RESULT_OK:
try {
currentMsgSentStatus.put("status","OK");
} catch (JSONException e) {
e.printstacktrace();
}
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
try {
currentMsgSentStatus.put("status","GENERIC_FAILURE");
} catch (JSONException e) {
e.printstacktrace();
}
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
try {
currentMsgSentStatus.put("status","NO_SERVICE");
} catch (JSONException e) {
e.printstacktrace();
}
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
try {
currentMsgSentStatus.put("status","NULL_PDU");
} catch (JSONException e) {
e.printstacktrace();
}
break;
case SmsManager.RESULT_ERROR_RAdio_OFF:
try {
currentMsgSentStatus.put("status","RAdio_OFF");
} catch (JSONException e) {
e.printstacktrace();
}
break;
}
sendStatus.put(currentMsgSentStatus);
}
};
registerReceiver(receiverSentGlobal,new IntentFilter(ACTION_SMS_SENT));
receiverDeliveryGlobal = new broadcastReceiver() {
@RequiresApi(api = Build.VERSION_CODES.Q)
@Override
public void onReceive(Context context,Intent intent) {
JSONObject currentMsgDeliveryStatus = new JSONObject();
try {
currentMsgDeliveryStatus.put("msg_id",intent.getStringExtra("msg_id"));
currentMsgDeliveryStatus.put("sim_id",intent.getStringExtra("sim_id"));
} catch (JSONException e) {
e.printstacktrace();
}
switch (getResultCode()) {
case Activity.RESULT_OK:
try {
currentMsgDeliveryStatus.put("status","DELIVERED");
} catch (JSONException e) {
e.printstacktrace();
}
break;
case Activity.RESULT_CANCELED:
try {
currentMsgDeliveryStatus.put("status","CANCELED");
} catch (JSONException e) {
e.printstacktrace();
}
break;
}
deliveryStatus.put(currentMsgDeliveryStatus);
}
};
registerReceiver(receiverDeliveryGlobal,new IntentFilter(ACTION_SMS_DELIVERED));
...
}
我的sendSMS方法:
SmsManager sm;
... there is also some code to handle subscription,but let's make it more simple
sm = SmsManager.getDefault();
ArrayList<String> parts = sm.divideMessage(msg);
Intent iSent = new Intent(ACTION_SMS_SENT);
iSent.putExtra("msg_id",msgid);
iSent.putExtra("sim_id",String.valueOf(lastSendSimId));
PendingIntent piSent = PendingIntent.getbroadcast(this,Integer.parseInt(msgid),iSent,PendingIntent.FLAG_ONE_SHOT);
//Intent iDel = new Intent(ACTION_SMS_DELIVERED+msgid);
Intent iDel = new Intent(ACTION_SMS_DELIVERED);
iDel.putExtra("msg_id",msgid);
iDel.putExtra("sim_id",String.valueOf(lastSendSimId));
PendingIntent piDel = PendingIntent.getbroadcast(this,iDel,PendingIntent.FLAG_ONE_SHOT);
if (parts.size() == 1)
{
msg = parts.get(0);
sm.sendTextMessage(number,null,msg,piSent,piDel);
}
else
{
ArrayList<PendingIntent> sentPis = new ArrayList<PendingIntent>();
ArrayList<PendingIntent> delPis = new ArrayList<PendingIntent>();
int ct = parts.size();
for (int i = 0; i < ct; i++)
{
sentPis.add(i,piSent);
delPis.add(i,piDel);
}
sm.sendMultipartTextMessage(number,parts,sentPis,delPis);
}
hasOnProgressSend = true;
编辑 1: 刚刚找到 - 通过向 2 个号码发送消息进行测试。 A号码在在线设备中,B在关机设备中。直到大约 250 条未发送到 B 的消息,应用程序正在接收 A 的发送报告。在 A 的 250 条未发送消息发送通知停止后,应用程序将停止发送。在为 B 供电后,所有发送给 A 和 B 的消息的所有通知都出现了。因此,有一些队列大约有 250 个等待传递报告。有什么办法可以将传递过程的生命周期限制在 10 分钟左右?
解决方法
好的,发现问题。设备上有大约 250 个待处理的交付意图的限制。所以我需要以某种方式限制或取消旧的交付待定意图。