2
I have an app that sends text messages on android, and a Broadcast to capture errors if I can’t send to the recipient. If you cannot send a message, I capture the object and write to the database with the type of error that occurred, for later sending.
The method works perfectly if I send one at a time, but I performed a battery of tests where I have more than 50 messages to send at a time, and the method always returns me the last object in the list of those who gave error.
Example, if I send the following sms, and disable airplane mode to simulate an error, in that order:
1 - Consignee A
2 - Consignee B
3 - Consignee C
4 - Consignee D
Broadcast records 4 times in the database element 4.
I pass the object through Extras of Intent, when I create Broadcast, and recover in the code below.
@Override
public void onReceive(Context ctx, Intent intent) {
if (naoEnviadoDao == null) {
naoEnviadoDao = ORMLiteHelper.getInstance(ctx).getNaoEnviadosDao();
}
//Recupero o objeto passado como parâmetro no envio
//Se eu mandar um sms por vez, funciona, mas se for mais 3-4 por exemplo, sempre grava o último n vezes.
NaoEnviado naoEnviado = (NaoEnviado) intent.getSerializableExtra("naoEnviado");
if (!naoEnviados.contains(naoEnviado)) {
naoEnviados.add(naoEnviado);
}
switch (getResultCode()) {
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
naoEnviado.setTipoFalha("Falha genérica.");
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
naoEnviado.setTipoFalha("Sem serviço.");
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
naoEnviado.setTipoFalha("Falha no Provedor PDU.");
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
naoEnviado.setTipoFalha("Modo avião ativo.");
break;
}
if (naoEnviado.getTipoFalha() != null &&
!naoEnviado.getTipoFalha().equals("")) {
try {
naoEnviadoDao.create(naoEnviado);
} catch (Exception e) {
e.printStackTrace();
}
naoEnviado = new NaoEnviado();
}
}
Another detail that I noticed in tests, is that if I put a Thread.Sleep of 6 seconds for example, it records right, but I have situations that I need to send more than 200 sms at a time, which ends up leaving the screen stuck, someone has an idea of what it might be?
//Code I register the Broadcast
public void sendSMS(final String mensagem, final String nomeParceiro, String telefone) {
//Remove caracteres do cel e formata a msg antes de enviar...
Telefone tel = new Telefone(ctx);
final String celular = tel.formataTelefone(telefone);
final String msg = mensagem.replace("%nome%", nomeParceiro.substring(0,
nomeParceiro.indexOf(" ") > 0 ? nomeParceiro.indexOf(" ") : nomeParceiro.length()));
SmsManager smsManager = SmsManager.getDefault();
SmsManager sms = SmsManager.getDefault();
ArrayList<String> parts = sms.divideMessage(msg);
int messageCount = parts.size();
ArrayList<PendingIntent> deliveryIntents = new ArrayList<PendingIntent>();
ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>();
NaoEnviado naoEnviado = new NaoEnviado();
naoEnviado.setMensagem(msg);
naoEnviado.setNome(nomeParceiro);
naoEnviado.setTelefone(celular);
Intent itSent = new Intent(SENT);
itSent.putExtra("naoEnviado", naoEnviado);
Intent itDelivery = new Intent(DELIVERED);
itDelivery.putExtra("naoEnviado", naoEnviado);
PendingIntent sentPI = PendingIntent.getBroadcast(ctx, 0, itSent,
PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent deliveredPI = PendingIntent.getBroadcast(ctx, 0, itDelivery,
PendingIntent.FLAG_UPDATE_CURRENT);
for (int j = 0; j < messageCount; j++) {
sentIntents.add(sentPI);
deliveryIntents.add(deliveredPI);
}
//Registra os receiver de envio e recebimento
((Activity) ctx).registerReceiver(SentReceiver.getInstance(),
new IntentFilter(SENT));
((Activity) ctx).registerReceiver(DeliveredReceiver.getInstance(),
new IntentFilter(DELIVERED));
sms.sendMultipartTextMessage(tel.removeCaracteres(celular),
null, parts, sentIntents, deliveryIntents);
}
I found two possible solutions:
1) If you want to pass an Object as parameter, after the sendMultipartTextMessage method, I added a 6 seconds pause, and the method started working, it is not an elegant solution, but solved.
//Envia o SMS
sms.sendMultipartTextMessage(telefone, null, parts, sentIntents, deliveryIntents);
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
}
2) Instead of passing an object as a parameter, I passed a String, and retrieved it in Onreceive() as getStringExtra(), so it worked without further problems.
//OnReceive
String aux = Intent.getStringExtra("obj");
Exactly that, it took a little bit of work to find the solution, but it was solved, thank you very much for the help @ramaral
– Geferson
You noticed that the solution passes by using a different value in the second parameter of
PendingIntent.getBroadcast()
?– ramaral
Yes, but for me I just need to pass the phone number through Intent by parameter, in the case of a String, instead of passing the id as requestcode, the simple fact of using primitive types also solved the problem.
– Geferson
That’s why in my tests the use of setData() worked and with you it didn’t. In my test I used a string as extra!
– ramaral
Yes, exactly, I noticed the problem, when I redid the code and used a is, i as an extra, the same example that you tested, and it worked. then I just adapted my code with this.
– Geferson