1

こんにちは、Android SMS を送信し、配信レシーバーを動的に構築しました。アクティビティを切り替える前にレシーバーの登録を解除する必要があるため、漏れエラーが発生しています。応答を受信したときに受信者の登録を解除したい。

さらに、このクラスはライブラリであり、ダイアログを拡張し、レシーバーをコードで構築する必要があるため、onPause と再開をオーバーライドすることはできません。

コードは次のとおりです。

private void sendSMS(String msg, String msisdn, String func) { 

   String SENT = "SMS_SENT";
   String DELIVERED = "SMS_DELIVERED";
   log("SMS FUNCTION: RUN");


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

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

    BroadcastReceiver smsReceiverD=new BroadcastReceiver(){

        @Override
        public void onReceive(Context arg0, Intent arg1) {
            log("SMS FUNCTION: SMS DELIVER CHECK");
            switch (getResultCode())
            {
                case Activity.RESULT_OK:
                    break;
                case Activity.RESULT_CANCELED:
                    sendEventLog("Failed(SMS not delivered)"); 
                    break;
            }
        }

    };

    BroadcastReceiver smsReceiverS=new BroadcastReceiver(){

        @Override
        public void onReceive(Context arg0, Intent arg1) {
            log("SMS FUNCTION: SEND CHECK");

            switch (getResultCode())
            {
                case Activity.RESULT_OK:
                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    log("Failed(Generic failure)");
                    sendEventLog("moFailed(Generic failure)");  
                    break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                    sendEventLog("Failed(No service)");     
                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:
                    sendEventLog("Failed(Null PDU)");   
                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    sendEventLog("Failed(Radio off)");  
                    break;
            }
        }

    };

   SmsManager MySmsManager = SmsManager.getDefault();
   sendEventLog("Send("+keyword+":"+msisdn+")");         

   if (msg != null) {
    log("SMS FUNCTION: SMS SEND");
       MySmsManager.sendTextMessage(msisdn, null, keyword, sentPI, deliveredPI);
       mContext.registerReceiver(smsReceiverD,new IntentFilter(DELIVERED));
       mContext.registerReceiver(smsReceiverS,new IntentFilter(SENT));
    }
   }

追加したい

mContext.unregisterReceiver(smsReceiverS);

smsReciverS.

それは言う

Cannot refer to a non-final variable smsReceiverS inside an inner class defined in a different method

そして、私がそれを最終的にする場合:

The local variable smsReceiverS may not have been initialized

誰か助けてください。

4

3 に答える 3

0

Waqas の解決策は間違いなく可能ですが (onReceive() はレシーバーが実行されるコンテキストで呼び出されます)、Evos の解決策は私には意味がありません (コードは、 を呼び出すことによってHandler()、それが存在する正確なコンテキストで実行されることを前提としています)。その後、後で実行することになっています)、両方の回答は元の質問に対応していません。これは、最終変数に関するエラーに関するものです。

ポイントは、mContext を final にする必要があるため、オンザフライで BroadcastReceiver が変更されないようにする必要があります。これは、匿名の内部クラスであるため、mContext への暗黙的な参照を保持します。ただし、最終変数に関して制限が適用されます。一度だけ初期化する必要があります。

これを強制するための分析はコンパイル時に実行され、Android のメカニズムに関する深い知識はありません。そのため、重要なのは宣言、コンストラクター、および今後の使用だけです。

おそらく、あなたは宣言しています

Activity mContext = null;

もう一度値を割り当てるため、後でエラーにつながりますか?

Waqas のソリューションは機能しますが、 を理解したい場合final、および私の仮定が間違っている場合は、 の使用に関するコード スニペットで Q を更新する必要がありますmContext

于 2013-01-30T08:00:27.580 に答える
0

のメソッド内で instanceofをよく使用arg0.unregister(this);しますarg0ContextonReceive(Context arg0, Intent arg1)smsReceiverS

于 2013-01-30T07:48:12.010 に答える