0

私のアプリからアプリへの SMS 送信には、電話番号のリストを反復処理し、SMSManager.sendMultipartTextMessage() を使用するかなり標準的なループがあります。

BroadcastReceiver (一意の PendingIntent を持つメッセージ パーツごとに 1 つ、レシーバーはそのインテントをフィルター処理します) は、失敗を記録するために使用されます。

問題を再現することはできませんが、一部のユーザーが複数の一般的なエラー (SmsManager.RESULT_ERROR_GENERIC_FAILURE) を取得していることはわかっています。

彼らの電話は、高速で届く複数の SMS を処理できないと思います。ループに遅延 (良い解決策ではありません) を入れても、SMS が何らかの形で電話にスタックし、突然フラッディングして、一般的な障害を引き起こしていると思います。

他の多くの人がこの問題を抱えていることは知っていますが、非常に単純なケース (エラーフローがないなど) 以外に役立つ解決策は見当たりませんでした。

各 BroadcastReceiver.onReceive() が報告されるまで待機する無限ループ (効果的にはリスナー) を考えましたが、無限ループのアイデアは嫌いです (そして、すべてのエラー フローに対してもそれを管理しようとします)。

SMS が一度に 1 つずつ処理されるようにする方法 (スロットル) に関するアイデアはありますか?

4

1 に答える 1

2

保留中のインテントを使用して、メッセージのステータス (一般的なエラー/無線オフ/null PDU/SMS 配信済み/SMS 未配信) を待ちます。

SmsManager smsManager=SmsManager.getDefault();
String SENT = "SMS_SENT";
String DELIVERED = "SMS_DELIVERED";     
public void sendSms(String phoneNumber,String sms){

 PendingIntent sentPI = PendingIntent.getBroadcast(this, 0,
            new Intent(SENT), 0);

        PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0,
            new Intent(DELIVERED), 0);

 //---when the SMS has been sent---
    registerReceiver(new BroadcastReceiver(){
        @Override
        public void onReceive(Context arg0, Intent arg1) {
            switch (getResultCode())
            {
                case Activity.RESULT_OK:
                    // do what you need to do if OK
                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    // do what you need to do if GENERIC FAILURE
                    break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                    // do what you need to do if no Service
                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:

                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:

                    break;
            }
        }
    }, new IntentFilter(SENT));

    //---when the SMS has been delivered---
    registerReceiver(new BroadcastReceiver(){
        @Override
        public void onReceive(Context arg0, Intent arg1) {
            switch (getResultCode())
            {
                case Activity.RESULT_OK:
                    // Send next sms when previous one delivered your choice

                    break;
                case Activity.RESULT_CANCELED:
                    //Do something if not delivered
                    break;                        
            }
        }
    }, new IntentFilter(DELIVERED));


    smsManager.sendTextMessage(phoneNumber, null, sms, sentPI, deliveredPI);

}
于 2013-05-12T09:18:53.183 に答える