我有一个android应用程序,它可以在短时间内发送大量消息,并且该应用程序需要处理交付报告。这一切都很好,应用程序稳定运行,没有任何崩溃,消息被发送,交付报告工作正常。。。好一段时间。
假设我在消息之后发送消息(前一条消息之后的每条消息都被成功发送-我正在查看smsSent PendingIntent-只有当hasOnProgressSend==false时,我才能发送新消息(。交付报告可以在大约1-2小时内正常工作。然后交付报告的行为就很奇怪。不断丢弃几个交付报告。
因此,在发送完成后,大约7小时后,大约8000条短信的发送报告停止了,但收到了很多消息,但应用程序没有收到发送报告。
但现在出现了奇怪的部分:(。第二天,我又试了一次测试,又发了8000条信息。邮件立即开始发送给收件人,但我收到的送达报告是前一天的,而不是最后一天的BroadcastReceiver。我试着换了SIM卡,还收到了前一天发送的信息。
在我重新启动应用程序后,一切都一样,最后一天的交付报告。但在我重新启动设备后,它仍然像前一天一样工作(大约1-2个小时工作正常,然后交付报告慢了很多(。
综上所述:我收到的交付报告很好,直到某个设备队列似乎已满。之后的交付报告非常缓慢。另一天,当我再次开始发送(使用新SIM卡(时,我的快递BroadcastReceiver收到了昨天发送的邮件的快递报告,而昨天的快递报告没有收到。我重新启动后,应用程序是一样的。在我重新启动设备后,它开始像第一天一样工作。因此,如果我的BrodactReceivers在我的活动的onCreate方法中注册,而应用程序重新启动没有帮助,这一定是我需要在应用程序中以某种方式处理的安卓队列问题(可能是为了放慢发送速度,在成功发送消息后再延迟一段时间,或者如果几个未送达的消息大于某个值,则停止发送?(
谢谢你,对这个巨大的问题感到抱歉:(
我在onCreate:中注册了两个BroadcastReceiver
@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, Integer.parseInt(msgId), 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, null, parts, sentPis, delPis);
}
hasOnProgressSend = true;
编辑1:刚刚找到-通过向2个号码发送消息进行测试。A号在联机设备中,B在关机设备中。直到大约250条未送达的消息发送到B,应用程序正在接收A的送达报告。在250条未交付的消息之后,A的送达通知将停止发送到应用程序。在给B供电后,所有发送到A和B的消息都会收到所有通知。因此,大约有250个等待传递报告的队列。有没有办法将分娩周期限制在10分钟左右?
好的,发现问题。设备上有大约250个待定交付意图的限制。所以我需要以某种方式限制或取消旧的交付等待意向。