Подтвердить что ты не робот

IntentRecieverLeakedException, Вам не хватает вызова unregisterReceiver()? в андроиде

Я пытаюсь использовать следующий пример sms: http://mobiforge.com/developing/story/sms-messaging-android но я получаю следующее исключение, если пытаюсь отправить сообщения.

Exception:
    02-07 12:38:15.447: ERROR/ActivityThread(839): Activity com.micro.MyTest has leaked IntentReceiver [email protected]
that was originally registered here. Are you missing a call to
unregisterReceiver()?
    02-07 12:38:15.447: ERROR/ActivityThread(839): android.app.IntentReceiverLeaked: Activity com.test.SendSMS has leaked
IntentReceiver com.test.SendSMS [email protected] that was originally
registered here. Are you missing a call to unregisterReceiver()?
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at android.app.ActivityThread$PackageInfo$ReceiverDispatcher.<init>(ActivityThread.java:707)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at android.app.ActivityThread$PackageInfo.getReceiverDispatcher(ActivityThread.java:535)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at android.app.ApplicationContext.registerReceiverInternal(ApplicationContext.java:748)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at android.app.ApplicationContext.registerReceiver(ApplicationContext.java:735)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at android.app.ApplicationContext.registerReceiver(ApplicationContext.java:729)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:278)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at com.micro.MyTest.sendSMS(SendSMS .java:98)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at com.micro.MyTest.onCreate(SendSMS .java:42)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2231)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2284)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at android.app.ActivityThread.access$1800(ActivityThread.java:112)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1692)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at android.os.Handler.dispatchMessage(Handler.java:99)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at android.os.Looper.loop(Looper.java:123)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at android.app.ActivityThread.main(ActivityThread.java:3948)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at java.lang.reflect.Method.invokeNative(Native Method)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at java.lang.reflect.Method.invoke(Method.java:521)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540)
    02-07 12:38:15.447: ERROR/ActivityThread(839):     at dalvik.system.NativeStart.main(Native Method)
    02-07 12:38:15.496: ERROR/ActivityThread(839): Activity com.micro.MyTest has leaked IntentReceiver [email protected]
that was originally registered here. Are you missing a call to
unregisterReceiver()?
    02-07 12:38:15.496: ERROR/ActivityThread(839): android.app.IntentReceiverLeaked: Activity com.test.SendSMS has leaked
IntentReceiver com.test.SendSMS [email protected] that was originally
registered here. Are you missing a call to unregisterReceiver()?
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at android.app.ActivityThread$PackageInfo$ReceiverDispatcher.<init>(ActivityThread.java:707)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at android.app.ActivityThread$PackageInfo.getReceiverDispatcher(ActivityThread.java:535)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at android.app.ApplicationContext.registerReceiverInternal(ApplicationContext.java:748)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at android.app.ApplicationContext.registerReceiver(ApplicationContext.java:735)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at android.app.ApplicationContext.registerReceiver(ApplicationContext.java:729)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:278)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at com.micro.MyTest.sendSMS(SendSMS .java:129)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at com.micro.MyTest.onCreate(SendSMS .java:42)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2231)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2284)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at android.app.ActivityThread.access$1800(ActivityThread.java:112)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1692)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at android.os.Handler.dispatchMessage(Handler.java:99)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at android.os.Looper.loop(Looper.java:123)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at android.app.ActivityThread.main(ActivityThread.java:3948)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at java.lang.reflect.Method.invokeNative(Native Method)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at java.lang.reflect.Method.invoke(Method.java:521)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540)
    02-07 12:38:15.496: ERROR/ActivityThread(839):     at dalvik.system.NativeStart.main(Native Method)

Метод, который отправляет sms:

publicvoid sendSMS(String phoneNumber, String message) {
  String SENT = "SMS_SENT";
  String DELIVERED = "SMS_DELIVERED";

  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, the following line (line 98) throws Exception

  registerReceiver(
    new BroadcastReceiver(){

      public void onReceive(Context arg0, Intent arg1) {
        switch (getResultCode()) {
          case Activity.RESULT_OK:
            Toast.makeText(getBaseContext(), "SMS Sent", Toast.LENGTH_SHORT).show();
            break;
          case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
            Toast.makeText(getBaseContext(), "Generic failure", Toast.LENGTH_SHORT).show();
            break;
          case SmsManager.RESULT_ERROR_NO_SERVICE:
            Toast.makeText(getBaseContext(), "No service", Toast.LENGTH_SHORT).show();
            break;
          case SmsManager.RESULT_ERROR_NULL_PDU:
            Toast.makeText(getBaseContext(), "Null PDU", Toast.LENGTH_SHORT).show();
            break;
          case SmsManager.RESULT_ERROR_RADIO_OFF:
            Toast.makeText(getBaseContext(), "Radio off", Toast.LENGTH_SHORT).show();
            break;
          }
        }

      }, new IntentFilter(SENT)); 

  // when the SMS has been delivered

  registerReceiver(
    new BroadcastReceiver() {

      public void onReceive(Context arg0, Intent arg1) {
        switch (getResultCode()) {
          case Activity.RESULT_OK:
            Toast.makeText(getBaseContext(), "SMS Delivered",Toast.LENGTH_SHORT).show();
            break;
        case Activity.RESULT_CANCELED:
          Toast.makeText(getBaseContext(), "SMS not delivered", Toast.LENGTH_SHORT).show();
          break; 
        }
      }
    },new IntentFilter(DELIVERED)); 

  SmsManager sms = SmsManager.getDefault();
  sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI); 

}
4b9b3361

Ответ 1

в вашем классе активности, объявите эти глобальные переменные:

private BroadcastReceiver sendBroadcastReceiver;
private BroadcastReceiver deliveryBroadcastReceiver;
String SENT = "SMS_SENT";
String DELIVERED = "SMS_DELIVERED";

override onСоздание вашей активности и регистрация получателей:

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    sendBroadcastReceiver = new BroadcastReceiver()
    {

        public void onReceive(Context arg0, Intent arg1)
        {
            switch (getResultCode())
            {
            case Activity.RESULT_OK:
                Toast.makeText(getBaseContext(), "SMS Sent", Toast.LENGTH_SHORT).show();
                break;
            case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                Toast.makeText(getBaseContext(), "Generic failure", Toast.LENGTH_SHORT).show();
                break;
            case SmsManager.RESULT_ERROR_NO_SERVICE:
                Toast.makeText(getBaseContext(), "No service", Toast.LENGTH_SHORT).show();
                break;
            case SmsManager.RESULT_ERROR_NULL_PDU:
                Toast.makeText(getBaseContext(), "Null PDU", Toast.LENGTH_SHORT).show();
                break;
            case SmsManager.RESULT_ERROR_RADIO_OFF:
                Toast.makeText(getBaseContext(), "Radio off", Toast.LENGTH_SHORT).show();
                break;
            }
        }
    };

    deliveryBroadcastReceiver = new BroadcastReceiver()
    {
        public void onReceive(Context arg0, Intent arg1)
        {
            switch (getResultCode())
            {
            case Activity.RESULT_OK:
                Toast.makeText(getBaseContext(), "SMS Delivered", Toast.LENGTH_SHORT).show();
                break;
            case Activity.RESULT_CANCELED:
                Toast.makeText(getBaseContext(), "SMS not delivered", Toast.LENGTH_SHORT).show();
                break;
            }
        }
    };
registerReceiver(deliveryBroadcastReceiver, new IntentFilter(DELIVERED));
registerReceiver(sendBroadcastReceiver , new IntentFilter(SENT));
}

Далее, ваш метод отправки sms остается только с 6 строками кода:

public void sendSMS(String phoneNumber, String message)
{
    String SENT = "SMS_SENT";
    String DELIVERED = "SMS_DELIVERED";
    PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(SENT), 0);
    PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED), 0);
    SmsManager sms = SmsManager.getDefault();
    sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
}

Наконец, отмените регистрацию своих приемников на остановке вашей деятельности:

@Override
protected void onStop()
{
    unregisterReceiver(sendBroadcastReceiver);
    unregisterReceiver(deliveryBroadcastReceiver);
    super.onStop();
}

Ответ 2

Используйте следующие два класса, чтобы избежать этой проблемы.

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class SmsDeliveredReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent arg1) {
        switch (getResultCode()) {
        case Activity.RESULT_OK:
            Log.d("httpmon", "SMS delivered");
            break;
        case Activity.RESULT_CANCELED:
            Log.d("httpmon", "SMS not delivered");
            break;
        }
    }
}

и этот для отправленного SMS-сообщения

import java.util.Collections;
import java.util.HashMap;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.telephony.gsm.SmsManager;
import android.util.Log;

public class SmsSentReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent arg1) {
        switch (getResultCode()) {
        case Activity.RESULT_OK:
            Log.d("httpmon", "SMS sent");
            break;
        case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
            Log.d("httpmon", "SMS generic failure");
            break;
        case SmsManager.RESULT_ERROR_NO_SERVICE:
            Log.d("httpmon", "SMS no service");
            break;
        case SmsManager.RESULT_ERROR_NULL_PDU:
            Log.d("httpmon", "SMS null PDU");
            break;
        case SmsManager.RESULT_ERROR_RADIO_OFF:
            Log.d("httpmon", "SMS radio off");
            break;
        }
    }
}

и, наконец, установить приемник в файл манифеста

<receiver android:name=".SmsSentReceiver">
            <intent-filter>
                <action android:name="SMS_SENT" />
            </intent-filter>
        </receiver>
        <receiver android:name=".SmsDeliveredReceiver">
            <intent-filter>
                <action android:name="SMS_DELIVERED" />
            </intent-filter>
        </receiver>

Ответ 3

Ошибка очень ясна в вашей проблеме. Вы не вызываете unregisterReceiver() для BroadcastReceiver, зарегистрированного в registerReceiver().

Ответ 4

при регистрации:

rec = new BroadcastReceiver()
{
....
}

чтобы предотвратить утечку приемника:

onStop()
{
super.onStop();
unregisterReciever(rec);
}

Ответ 5

Я решил с этим:

    @Override
public void onReceive(Context arg0, Intent arg1) {
    switch (getResultCode()) {
...
    unregisterReceiver(this);
}

Последнее, что нужно сделать, это отменить регистрацию Broadcast in onReceive

полный:

BroadcastReceiver smsReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context arg0, Intent arg1) {
                switch (getResultCode()) {
                case Activity.RESULT_OK:
                    if (Settings.registrarSucesso) {
                        ...
                    }
                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    ...
                    }
                    break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                    ...
                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:
                    ...
                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    ...
                    break;
                }
                unregisterReceiver(this);
                adapter.notifyDataSetChanged();
            }
        };

Ответ 6

попробовать

private void sendSMS()
{
    String SENT = "SMS_SENT";
    String DELIVERED = "SMS_DELIVERED";
    PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(SENT), 0);
    PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED), 0);
    SmsManager sms = SmsManager.getDefault();
    sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
    sendBroadcastReceiver = new BroadcastReceiver()
    {

        public void onReceive(Context arg0, Intent arg1)
        {
            switch (getResultCode())
            {
            case Activity.RESULT_OK:
                Toast.makeText(getBaseContext(), "SMS Sent", Toast.LENGTH_SHORT).show();
                break;
            case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                Toast.makeText(getBaseContext(), "Generic failure", Toast.LENGTH_SHORT).show();
                break;
            case SmsManager.RESULT_ERROR_NO_SERVICE:
                Toast.makeText(getBaseContext(), "No service", Toast.LENGTH_SHORT).show();
                break;
            case SmsManager.RESULT_ERROR_NULL_PDU:
                Toast.makeText(getBaseContext(), "Null PDU", Toast.LENGTH_SHORT).show();
                break;
            case SmsManager.RESULT_ERROR_RADIO_OFF:
                Toast.makeText(getBaseContext(), "Radio off", Toast.LENGTH_SHORT).show();
                break;
            }
    unregisterReceiver(sendBroadcastReceiver);//add here
        }
    };

    deliveryBroadcastReceiver = new BroadcastReceiver()
    {
        public void onReceive(Context arg0, Intent arg1)
        {
            switch (getResultCode())
            {
            case Activity.RESULT_OK:
                Toast.makeText(getBaseContext(), "SMS Delivered", Toast.LENGTH_SHORT).show();
                break;
            case Activity.RESULT_CANCELED:
                Toast.makeText(getBaseContext(), "SMS not delivered", Toast.LENGTH_SHORT).show();
                break;
            }
    unregisterReceiver(deliveryBroadcastReceiver);//add here
        }

    };
registerReceiver(deliveryBroadcastReceiver, new IntentFilter(DELIVERED));
registerReceiver(sendBroadcastReceiver , new IntentFilter(SENT));
}

Ответ 7

onCreate & onStop не всегда лучшие места для register & unregister, когда вы сохраняете историю деятельности. Вы должны поместить registerReceiver & unregisterReceiver в onResume & onPause.

@Override
protected void onResume() {
    registerReceiver(deliveryBroadcastReceiver, new IntentFilter(DELIVERED));
    registerReceiver(sendBroadcastReceiver , new IntentFilter(SENT));
    super.onResume();
}

@Override
protected void onPause() {
    try {
        unregisterReceiver(sendBroadcastReceiver);
        unregisterReceiver(deliveryBroadcastReceiver);
    } catch (IllegalArgumentException ex) {
        // If Receiver not registered
    }
    super.onPause();
}