2013-05-20 98 views
3

我看了很多帖子和多短信,例如:如何检查成功的多部手机短信发送上发送短信

Sending SMS in AndroidSending and Receiving SMS and MMS in Android (pre Kit Kat Android 4.4)Android PendingIntent extras, not received by BroadcastReceiver

...等,但他们似乎没有进入检查该消息的所有部分已成功发送。

从我所了解的情况来看,通过多部分消息,您可以为每个消息部分添加一个PendingIntent,但我所看到的例子似乎没有检查是否所有部分均已成功发送...如果是(I猜第一个),他们似乎认为它是成功的......

所以我想我会送一个多部分消息和跟踪部分。我不会说这个消息被成功发送,直到所有部分都成功发送。

我试图做到这一点在下面的代码... 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会让您首先提供它们的列表)。

我为长的问题道歉,但真的不知道如何在更短的方式向更清楚:-)

问候 科林

回答

4

这里是我已经结束了使用的代码,这是我原来的混合和博尔顿(博尔顿感谢:-))。

新的代码可以检测部分的失败要好,有点难以测试,上面的代码将anyError为false每个消息的一部分,因此,如果第1部分失败和第2部分成功它可能会认为整个事情的成功......下面电话(我的)messageInfo.fail的代码不会得到恢复,如果后续消息部分成功......我想这是所有漂亮不必要的,你会想,如果一个部分作品,其余无论如何,下面是我最终使用的代码。

编辑>更新的代码去除附加在意向重负载下,多个意图(我认为)得到了合并成一个(使用不同的PendingIntent标志没有帮助)。最后,我对每条消息使用了不同的intent动作(例如,新的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); 
} 
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(); 
+0

感谢你的解决方案比我的简单一些。我的应用程序可能会同时发送几条消息,并且我认为intent可能会混入广播接收器,因此我将该消息标识保存在意图中。但是,调整代码getExtras返回null,除非在添加它们时设置PendingIntent标志。我还注意到,我的'临时演员'不像我预期的那样工作,因为我似乎收到了两个意图,但额外的不是我设置的意思......我想尝试在发送消息和删除复杂性。 – user2400538

+0

如果这可以帮助(2年后),我有同样的问题,但你只需要一个PendingIntent与不同的RequestCode(在getBroadcast)。这防止覆盖已经使用但尚未接收到PendingIntent。 – AxelH