如何为android中的每个联系人/人发送短信确认? [英] How to get sms sent confirmation for each contact/person in android?

查看:27
本文介绍了如何为android中的每个联系人/人发送短信确认?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想向多人发送短信并验证短信是否已发送.我检查了多个链接(这里提到)并想到使用 PendingIntentbroadCast Receiver 进行确认.

I want to send sms to multiple people and verify whether sms sent or not. I checked multiple links (mentioned here) and got the idea of using PendingIntent and broadCast Receiver for confirmation.

了解短信是否已被发送的实用方法发送
在android中以编程方式发送短信
http://mobiforge.com/design-development/sms-messaging-android

但关键问题是,我在 arrayList 中有不同的 50 个联系人号码,而在另一个 arrayList 中有不同的消息.

But the key problem is that, I have different 50 contacts number in an arrayList and their different msgs in another arrayList.

我使用此代码:

for (Condition) {   
    sms = SmsManager.getDefault();   
    try {   
        . . . sms.sendTextMessage(phoneNumbers[i], null, messages[i], sentPI, deliveredPI);  
    }   
    catch(IllegalArgumentException e) {     }  
}

现在,我无法确定有多少人收到了他们的 msg,又有多少人没有收到.因为如帖子所示(上面提到的链接),每次我们只收到一条消息,短信已发送".

Now, I can't identify how many people do get their msg and how many don't. Because as shown in post(mentioned link above), every time we just get one msg, "SMS delivered".

所以请让我知道,当我发送 msg 并从 broadcast Receiver 获取额外内容以获取特定内容的详细信息时,如何在 Intent 中添加额外内容"联系人/个人.

So please let me know, how can I put "extras" in Intent, when I send msg and get the extras from broadcast Receiver to get the detail of specific contact/person.

One More thing :PendingIntent 中有四种不同的标志值选项(FLAG_ONE_SHOTFLAG_NO_CREATEFLAG_CANCEL_CURRENTFLAG_UPDATE_CURRENT).当我在 for 循环中发送消息以获得正确结果时,我应该使用哪一个?

One More thing : There are four different option for flag value in PendingIntent (FLAG_ONE_SHOT, FLAG_NO_CREATE, FLAG_CANCEL_CURRENT,FLAG_UPDATE_CURRENT). Which one should I use when I send messages in for loop for correct result?

推荐答案

这是一个非常简单的示例,用于演示所有 SmsManager 可用的发送和交付 PendingIntent 的使用#send*() 方法,并将数据附加到这些方法中,以便在 Receiver 中轻松区分结果.

This is a very simple example to demonstrate the use of the send and delivery PendingIntents available for all of the SmsManager#send*() methods, and attaching data to those to easily differentiate the results in the Receiver.

附加数据就像在支持 PendingIntentIntent 上添加额外内容一样简单,我们传递给 send*() 方法.问题在于 PendingIntents 可能不会像人们预期的那样表现.为了节约资源,系统只会在必要时创建新资源.get*() 方法只会返回一个不同的 PendingIntent 如果 Intent 每个 Intent#filterEquals() 方法,请求代码当前未用于相同的 Intent,或者传递了适当的标志.

Attaching that data is as simple as putting extras on the Intents backing the PendingIntents we pass to the send*() methods. The catch is that PendingIntents might not behave as one expects. To conserve resources, the system will only create new ones when it must. The get*() methods will only return a distinct PendingIntent if the Intent is different per the Intent#filterEquals() method, the request code is not currently in use for an equal Intent, or an appropriate flag is passed.

在具有相同请求代码的其他相同Intent 上的不同附加不会导致创建新的PendingIntent.根据在这种情况下传递的标志,这些额外的可能会被忽略,或者覆盖当前活动的 PendingIntent 中的那些,这可能会导致错误的结果.

Different extras on an otherwise-same Intent with the same request code will not cause a new PendingIntent to be created. Depending on the flag passed in that case, those extras might be ignored, or overwrite those in a currently active PendingIntent, which can lead to incorrect results.

在我们的示例中,我们基本上对每次发送使用相同的 Intent,因此我们将通过传递唯一的请求代码来确保每个发送都有不同的 PendingIntent.这个简单的示例使用这些代码的收缩列表的大小,这在单次运行的上下文中将是唯一的.请求代码最终可以是任意的 int,只要您知道它在请求时未被使用.

In our example, we're basically using the same Intent for each send, so we'll ensure a distinct PendingIntent for each by passing unique request codes. This simple example uses the size of a shrinking list for those codes, which will be unique in the context of a single run. The request code can ultimately be any arbitrary int, as long as you know it's unused at the time of request.

系统会想要缓存这些PendingIntent,如果我们在不久的将来再次需要它们,所以我们也会通过FLAG_ONE_SHOT来清除它们"使用后,并确保我们在后续运行中获得正确的当前附加项.

The system will want to cache these PendingIntents, should we need them again in the near future, so we'll also pass FLAG_ONE_SHOT to "clear them out" after use, and make sure we get the correct, current extras in subsequent runs.

public class SmsActivity extends Activity implements View.OnClickListener {
    private static final String SMS_SENT_ACTION = "com.mycompany.myapp.SMS_SENT";
    private static final String SMS_DELIVERED_ACTION = "com.mycompany.myapp.SMS_DELIVERED";
    private static final String EXTRA_NUMBER = "number";
    private static final String EXTRA_MESSAGE = "message";

    // Initialize our sample numbers list.
    private final List<String> numberList = new ArrayList<String>() {{{
                add("111-111-1111");
                add("222-222-2222");
                add("333-333-3333");
    }}};

    // Initialize our sample message list.
    private final List<String> messageList = new ArrayList<String>() {{{
                add("Hello.");
                add("Howdy.");
                add("Hi.");
    }}};

    private SmsManager smsManager;
    private IntentFilter intentFilter;
    private BroadcastReceiver resultsReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sms);

        findViewById(R.id.button_send).setOnClickListener(this);

        smsManager = SmsManager.getDefault();
        resultsReceiver = new SmsResultReceiver();

        intentFilter = new IntentFilter(SMS_SENT_ACTION);
        intentFilter.addAction(SMS_DELIVERED_ACTION);
    }

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(resultsReceiver, intentFilter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(resultsReceiver);
    }

    public void onClick(View v) {
        v.setEnabled(false);
        sendNextMessage();
    }

    private void sendNextMessage() {
        // We're going to remove numbers and messages from
        // the lists as we send, so if the lists are empty, we're done.
        if (numberList.size() == 0) {
            return;
        }

        // The list size is a sufficiently unique request code,
        // for the PendingIntent since it decrements for each send.
        int requestCode = numberList.size();

        String number = numberList.get(0);
        String message = messageList.get(0);

        // The Intents must be implicit for this example,
        // as we're registering our Receiver dynamically.
        Intent sentIntent = new Intent(SMS_SENT_ACTION);
        Intent deliveredIntent = new Intent(SMS_DELIVERED_ACTION);

        // We attach the recipient's number and message to
        // the Intents for easy retrieval in the Receiver.
        sentIntent.putExtra(EXTRA_NUMBER, number);
        sentIntent.putExtra(EXTRA_MESSAGE, message);
        deliveredIntent.putExtra(EXTRA_NUMBER, number);
        deliveredIntent.putExtra(EXTRA_MESSAGE, message);

        // Construct the PendingIntents for the results.
        // FLAG_ONE_SHOT cancels the PendingIntent after use so we
        // can safely reuse the request codes in subsequent runs.
        PendingIntent sentPI = PendingIntent.getBroadcast(this,
                                                          requestCode,
                                                          sentIntent,
                                                          PendingIntent.FLAG_ONE_SHOT);

        PendingIntent deliveredPI = PendingIntent.getBroadcast(this,
                                                               requestCode,
                                                               deliveredIntent,
                                                               PendingIntent.FLAG_ONE_SHOT);

        // Send our message.
        smsManager.sendTextMessage(number, null, message, sentPI, deliveredPI);

        // Remove the number and message we just sent to from the lists.
        numberList.remove(0);
        messageList.remove(0);
    }

    private class SmsResultReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            // A simple result Toast text.
            String result = null;

            // Get the result action.
            String action = intent.getAction();

            // Retrieve the recipient's number and message.
            String number = intent.getStringExtra(EXTRA_NUMBER);
            String message = intent.getStringExtra(EXTRA_MESSAGE);

            // This is the result for a send.
            if (SMS_SENT_ACTION.equals(action)) {
                int resultCode = getResultCode();
                result = "Send result : " + translateSentResult(resultCode);

                // The current send is complete. Send the next one.
                sendNextMessage();
            }
            // This is the result for a delivery.
            else if (SMS_DELIVERED_ACTION.equals(action)) {
                SmsMessage sms = null;

                // A delivery result comes from the service
                // center as a simple SMS in a single PDU.
                byte[] pdu = intent.getByteArrayExtra("pdu");
                String format = intent.getStringExtra("format");

                // Construct the SmsMessage from the PDU.
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && format != null) {
                    sms = SmsMessage.createFromPdu(pdu, format);
                }
                else {
                    sms = SmsMessage.createFromPdu(pdu);
                }

                // getResultCode() is not reliable for delivery results.
                // We need to get the status from the SmsMessage.
                result = "Delivery result : " + translateDeliveryStatus(sms.getStatus());
            }

            result = number + ", " + message + "
" + result;
            Toast.makeText(context, result, Toast.LENGTH_SHORT).show();
        }

        String translateSentResult(int resultCode) {
            switch (resultCode) {
                case Activity.RESULT_OK:
                    return "Activity.RESULT_OK";
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    return "SmsManager.RESULT_ERROR_GENERIC_FAILURE";
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    return "SmsManager.RESULT_ERROR_RADIO_OFF";
                case SmsManager.RESULT_ERROR_NULL_PDU:
                    return "SmsManager.RESULT_ERROR_NULL_PDU";
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                    return "SmsManager.RESULT_ERROR_NO_SERVICE";
                default:
                    return "Unknown error code";
            }
        }

        String translateDeliveryStatus(int status) {
            switch (status) {
                case Telephony.Sms.STATUS_COMPLETE:
                    return "Sms.STATUS_COMPLETE";
                case Telephony.Sms.STATUS_FAILED:
                    return "Sms.STATUS_FAILED";
                case Telephony.Sms.STATUS_PENDING:
                    return "Sms.STATUS_PENDING";
                case Telephony.Sms.STATUS_NONE:
                    return "Sms.STATUS_NONE";
                default:
                    return "Unknown status code";
            }
        }
    }
}

<小时>

注意事项:


Notes:

  • 请记下我们用于获取交付状态的方法.Receiver 中的结果代码不是一个可靠的指标.我们必须检查从 Intent 上的 PDU extra 中获得的 SmsMessagegetStatus() 返回,以获得实际结果.

  • Do make note of the method we're using to get the delivery status. The result code in the Receiver is not a reliable indicator. We must check the getStatus() return of the SmsMessage obtained from the PDU extra on the Intent to get the actual result.

另请注意,并非所有运营商都提供交付结果,在这种情况下,交付 PendingIntent 将永远不会触发.不要依赖交付结果.

Also be aware that not all carriers provide delivery results, in which case the delivery PendingIntents will never fire. Do not rely on a delivery result.

这个例子使用了一个正确的"方法,虽然很简单,但它顺序发送多条消息,因为它等待当前发送完成后再继续下一个.对于短列表,您可能能够在循环执行时尽快触发所有发送,但如果系统跟不上,这可能会导致一般性故障.

This example uses a "correct", albeit simple, method to sequentially send multiple messages, in that it waits until the current send is compete before proceeding to the next. For short lists, you might be able to get away with a loop firing all of the sends as quickly as it executes, but this can result in a generic failure if the system can't keep up.

如前所述,这是一个非常简单的例子.它并不真正适合生产,因为动态注册的 Receiver 与 Activity 的生命周期相关.理想情况下,您希望实现在清单中注册的静态 Receiver 类,并使用显式 Intent 来定位它.还推荐使用 Service 来处理结果,这些结果可以通过多种机制传递到 UI;例如,LocalBroadcastManager、另一个事件总线实现、Intents、Notifications 等

As noted, this is a very simple example. It is not really suitable for production, as the dynamically registered Receiver is tied to the Activity's lifecycle. Ideally, you'd want to implement a static Receiver class, registered in the manifest, and use explicit Intents to target it. Using a Service to process the results is also recommended, and those results could be delivered to the UI through any number of mechanisms; e.g., LocalBroadcastManager, another event bus implementation, Intents, Notifications, etc.

这篇关于如何为android中的每个联系人/人发送短信确认?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆