我已经阅读了很多关于发送短信和多部分短信的帖子,例如:
Sending SMS in Android, Sending and Receiving SMS and MMS in Android (pre Kit Kat Android 4.4), Android PendingIntent extras, not received by BroadcastReceiver
......和其他人,但他们似乎没有检查邮件的所有部分是否已成功发送。
根据我的理解,使用多部分消息,您为每个消息部分添加PendingIntent,但我看到的示例似乎没有检查所有部分是否已成功发送...如果是(我猜)第一个)他们似乎认为它是成功的......
所以我想我会发送一个多部分消息并跟踪部分。在成功发送所有部件之前,我不会说消息已成功发送。
我试图在以下代码中执行此操作... SmsMessageInfo只是一个简单的类,其中包含电话号码,消息和已处理零件的布尔列表以及成功发送的零件列表,它还具有唯一性消息ID。
我尝试了以下内容:
private void sendLongSmsMessage(Context context, final SmsMessageInfo messageInfo) {
// Receive when each part of the SMS has been sent (or does it????)
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String messageIdAsString = intent.getExtras().getString(INTENT_EXTRA_MESSAGE_ID_KEY);
Log.i("SMSMessageSender", "Broadcast Intent Recieved, IntentMessageID: " + messageIdAsString + " messageInfoId: " + messageInfo.messageId);
if (messageIdAsString != null) {
if (Long.parseLong(messageIdAsString) == messageInfo.messageId) {
String messagePartNrAsString = (String) intent.getExtras().get(INTENT_EXTRA_PART_NR_KEY);
int messagePartNr = Integer.parseInt(messagePartNrAsString);
Log.i("SMSMessageSender", "Broadcast Intent Recieved Multi Part Message Part No: " + messagePartNrAsString);
// We need to make all the parts succeed before we say we have succeeded.
switch (getResultCode()) {
case Activity.RESULT_OK:
messageInfo.partsSent.add(messagePartNr, true);
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
messageInfo.failMessage = "Error - Generic failure";
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
messageInfo.failMessage = "Error - No Service";
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
messageInfo.failMessage = "Error - Null PDU";
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
messageInfo.failMessage = "Error - Radio off";
break;
}
messageInfo.partsProcessed.add(messagePartNr, true);
boolean allSent = true;
for (Boolean partSent : messageInfo.partsSent) {
allSent = allSent && partSent;
}
messageInfo.sent = allSent;
boolean allProcessed = true;
for (Boolean partProcessed : messageInfo.partsProcessed) {
allProcessed = allProcessed && partProcessed;
}
if (allProcessed) {
// We have our response for all of our message parts, so we can unregister our receiver.
Log.i("SMSMessageSender", "All message part resoponses received, unregistering message Id: " + messageIdAsString);
context.unregisterReceiver(this);
}
} else {
Log.w("SMSMessageSender", "Received a broadcast message with Id for a different message");
}
} else {
Log.w("SMSMessageSender", "Received a broadcast message but not for message Id");
}
}
}, new IntentFilter(SENT));
ArrayList<String> messageList = SmsManager.getDefault().divideMessage(messageInfo.message);
ArrayList<PendingIntent> pendingIntents = new ArrayList<PendingIntent>(messageList.size());
messageInfo.partsSent.clear();
for (int i = 0; i < messageList.size(); i++) {
messageInfo.partsSent.add(i, false);
messageInfo.partsProcessed.add(i, false);
Intent sentIntent = new Intent(SENT);
sentIntent.putExtra(INTENT_EXTRA_MESSAGE_ID_KEY, Long.toString(messageInfo.messageId));
sentIntent.putExtra(INTENT_EXTRA_PART_NR_KEY, Integer.toString(i));
Log.i("SMSMessageSender", "Adding part " + i + " tp multi-part message Id: " + messageInfo.messageId);
pendingIntents.add(PendingIntent.getBroadcast(context, 0, sentIntent, PendingIntent.FLAG_ONE_SHOT));
}
Log.i("SMSMessageSender", "About to send multi-part message Id: " + messageInfo.messageId);
SmsManager.getDefault().sendMultipartTextMessage(messageInfo.phoneNumber, null, messageList, pendingIntents, null);
}
这个问题是永远不会收到第二个消息部分。
创建多个PendingIntents只是为了不去检查它们是否全部工作,这似乎很奇怪。
在我显示消息部件号的日志消息中,它始终为0,我从未得到第二部分,因此此代码从未认为它已完成。
我只是把它弄得太复杂了,我是否应该把任何旧的PendingIntent带回来并假设同样适用于其余部分(在这种情况下,为什么Google会让你首先提供它们的列表)。< / p>
我为这个冗长的问题道歉,但不知道如何以更短的方式更清楚地问: - )
此致 科林
答案 0 :(得分:5)
这是我最终使用的代码,它是我的原始和Bolton的混合(感谢Bolton: - ))。
新代码可能检测到部件故障更好,有点难以测试,上面的代码为每个消息部分设置anyError为false,所以如果第1部分失败而第2部分成功了可能会认为整个事情都成功了...下面的代码调用(my)messageInfo.fail,如果后续的消息部分成功,它将不会被重置...我想这都是非常不需要的,因为你会认为如果一个部分工作,其余的也将...无论如何,下面是我最终使用的代码。
编辑&gt;更新了代码以在重载下移除intent中的Extras,多个意图(我认为)合并为一个(使用不同的PendingIntent标志没有帮助)。最后,我对每条消息使用了不同的意图动作(例如新的Intent(SENT + messageInfo.getMessageId())),这样接收器肯定只能获得自己消息的广播。似乎在重载下工作得更好。
感谢。
private void sendLongSmsMessage4(Context context, final SmsMessageInfo messageInfo) {
// Receive when each part of the SMS has been sent
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// We need to make all the parts succeed before we say we have succeeded.
switch (getResultCode()) {
case Activity.RESULT_OK:
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
messageInfo.fail("Error - Generic failure");
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
messageInfo.fail("Error - No Service");
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
messageInfo.fail("Error - Null PDU");
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
messageInfo.fail("Error - Radio off");
break;
}
nMsgParts--;
if (nMsgParts <= 0) {
// Stop us from getting any other broadcasts (may be for other messages)
Log.i(LOG_TAG, "All message part resoponses received, unregistering message Id: " + messageInfo.getMessageId());
context.unregisterReceiver(this);
if (messageInfo.isFailed()) {
Log.d(LOG_TAG, "SMS Failure for message id: " + messageInfo.getMessageId());
} else {
Log.d(LOG_TAG, "SMS Success for message id: " + messageInfo.getMessageId());
messageInfo.setSent(true);
}
}
}
};
context.registerReceiver(broadcastReceiver, new IntentFilter(SENT + messageInfo.getMessageId()));
SmsManager smsManager = SmsManager.getDefault();
ArrayList<String> messageParts = smsManager.divideMessage(messageInfo.getMessage());
ArrayList<PendingIntent> pendingIntents = new ArrayList<PendingIntent>(messageParts.size());
nMsgParts = messageParts.size();
for (int i = 0; i < messageParts.size(); i++) {
Intent sentIntent = new Intent(SENT + messageInfo.getMessageId());
pendingIntents.add(PendingIntent.getBroadcast(context, 0, sentIntent, 0));
}
Log.i(LOG_TAG, "About to send multi-part message Id: " + messageInfo.getMessageId());
smsManager.sendMultipartTextMessage(messageInfo.getPhoneNumber(), null, messageParts, pendingIntents, null);
}
答案 1 :(得分:0)
我正在使用以下代码向多个联系人发送多部分邮件,并且工作正常:
// Send the SMS message
SmsManager sms = SmsManager.getDefault();
ArrayList<String> parts = sms.divideMessage(content);
final int numParts = parts.size();
ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>();
sentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "SMS onReceive intent received.");
boolean anyError = false;
switch (getResultCode()) {
case Activity.RESULT_OK:
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
case SmsManager.RESULT_ERROR_NO_SERVICE:
case SmsManager.RESULT_ERROR_NULL_PDU:
case SmsManager.RESULT_ERROR_RADIO_OFF:
anyError = true;
break;
}
msgParts--;
if (msgParts == 0) {
hideProgressBar();
if (anyError) {
Toast.makeText(context,
getString(R.string.sms_send_fail),
Toast.LENGTH_SHORT).show();
} else {
//success
}
unregisterReceiver(sentReceiver);
}
}
};
registerReceiver(sentReceiver, new IntentFilter(SENT_ACTION));
// SMS delivered receiver
// registerReceiver(new BroadcastReceiver() {
// @Override
// public void onReceive(Context context, Intent intent) {
// Log.d(TAG, "SMS delivered intent received.");
// }
// }, new IntentFilter(DELIVERED_ACTION));
for (int i = 0; i < numParts; i++) {
sentIntents.add(PendingIntent.getBroadcast(this, 0, new Intent(
SENT_ACTION), 0));
}
for (PhoneInfo phone : recipientsList) {
sms.sendMultipartTextMessage(phone.num, null, parts, sentIntents,
null);
}
msgParts = numParts * recipientsList.size();
showProgressBar();