setdataandtype putextra intent getintextra developer boot_completed action_send android android-intent

android - putextra - intent-filter



IntentRecieverLeakedException, ¿Te estás perdiendo una llamada para anular el registro de Receiver()? en Android (7)

El error es muy explícito sobre tu problema. No está llamando a unregisterReceiver() para el BroadcastReceiver que registró con registerReceiver() .

Estoy probando el siguiente ejemplo de SMS de: http://mobiforge.com/developing/story/sms-messaging-android pero recibo la siguiente excepción si intento enviar mensajes.

Exception: 02-07 12:38:15.447: ERROR/ActivityThread(839): Activity com.micro.MyTest has leaked IntentReceiver com.micro.MyTest$1@435a0c70 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 $1@435a0c70 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 com.test.MyTest$2@435a13b8 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 $2@435a13b8 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)

El método que envía 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); }


Lo resolví con esto:

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

Lo último que debe hacer es cancelar el registro de difusión en onReceive

completo:

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(); } };


Use las siguientes dos clases para evitar este problema

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; } } }

y este para el receptor enviado 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; } } }

y finalmente configura el receptor en tu archivo de manifiesto

<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>


en su clase de actividad, declare estas variables globales:

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

anular la creación de su actividad y registrar sus receptores:

@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)); }

a continuación, su método de envío de sms queda con solo 6 líneas de código:

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); }

por último, anule el registro de sus receptores al finalizar su actividad:

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


mientras se registra:

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

para evitar fugas del receptor:

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


tratar

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)); }


onCreate & onStop no siempre son los mejores lugares para register & unregister onCreate & onStop register & unregister cuando se mantiene el historial de actividad. Debe colocar registerReceiver & unregisterReceiver en 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(); }