BroadcastReceiver no funciona después de BOOT_COMPLETED

Estoy tratando de interceptar SMS entrantes después de boot_completado pero estoy teniendo un problema con una NullPointerException en esta línea:

Object[] rawMsgs=(Object[])intent.getExtras().get("pdus"); 

Aquí está mi manifiesto:

  <uses-permission android:name="android.permission.SEND_SMS"></uses-permission> <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses- permission> <uses-permission android:name="android.permission.INTERNET"></uses-permission> <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <application android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar"> <receiver android:name=".SMSReceiver" android:permission="android.permission.BROADCAST_SMS" > <intent-filter android:priority="1000"> <action android:name="android.provider.Telephony.SMS_RECEIVED"></action> <action android:name="android.intent.action.BOOT_COMPLETED"></action> </intent-filter> </receiver> </application> 

Receptor:

 public class SMSReceiver extends BroadcastReceiver { private final LocationListener locationListener = new LocationListener() { public void onLocationChanged(Location location) { } public void onProviderDisabled(String provider){} public void onProviderEnabled(String provider) {} public void onStatusChanged(String provider, int status, Bundle extras) {} }; @Override public void onReceive(Context context, Intent intent) { LocationManager lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); //Get as fine grained location as possible, while saving battery life. Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); criteria.setAltitudeRequired(false); criteria.setBearingRequired(false); criteria.setCostAllowed(true); criteria.setPowerRequirement(Criteria.POWER_LOW); String provider = lm.getBestProvider(criteria, true); Toast toast3 = Toast.makeText(context, "Provider: "+provider, Toast.LENGTH_LONG); toast3.show(); Object[] rawMsgs=(Object[])intent.getExtras().get("pdus"); for (Object raw : rawMsgs) { SmsMessage msg=SmsMessage.createFromPdu((byte[])raw); SmsManager sms = SmsManager.getDefault(); if (msg.getMessageBody().toUpperCase().contains("LOC")) { Log.w("SMS:"+msg.getOriginatingAddress(), msg.getMessageBody()); Toast toast1 = Toast.makeText(context, "Phone Number: "+msg.getOriginatingAddress()+" Message: "+msg.getMessageBody(), Toast.LENGTH_LONG); toast1.show(); abortBroadcast(); if(provider!=null){ lm.requestLocationUpdates(provider, 0, 0, locationListener); if(lm != null) { Location last_good = lm.getLastKnownLocation(provider); if(last_good != null) { Toast.makeText(context, "Got Message from " + msg.getOriginatingAddress() + " , Sending" + last_good.toString(), Toast.LENGTH_SHORT).show(); //sendSMS(msg.getOriginatingAddress(), "http://maps.google.com?q=" + last_good.convert(last_good.getLatitude(), Location.FORMAT_DEGREES) + "," + last_good.convert(last_good.getLongitude(), Location.FORMAT_DEGREES), context); //sendSMS(msg.getOriginatingAddress(), last_good.getLatitude() + "," + last_good.getLongitude(), context); sms.sendTextMessage(msg.getOriginatingAddress(), null, last_good.getLatitude() + "," + last_good.getLongitude(), null, null); lm.removeUpdates(locationListener); } else { lm.removeUpdates(locationListener); sendSMS(msg.getOriginatingAddress(),"Location Not Available. Possible Reasons: Phone is Off, GPS is Off, No Satellites in sight", context); } } } else{ sendSMS(msg.getOriginatingAddress(),"Location Not Available. Possible Reasons: Phone is Off, GPS is Off, No Satellites in sight", context); } } } } 

Gracias.

El problema aquí es que su implementación BroadcastReceiver se ha asignado a dos intentos – android.provider.Telephony.SMS_RECEIVED y android.intent.action.BOOT_COMPLETED – pero en la implementación onReceive no está comprobando qué intención está procesando.

Mi conjetura es que android.intent.action.BOOT_COMPLETED ha sido recibido y intent.getExtras() está devolviendo null. Puede confirmar esto agregando un registro al método y viendo la ventana de logcat (si está usando Eclipse).

Si escribe un servicio o un receptor de difusión y lo asigna a múltiples intenciones, es una buena práctica, no esencial, comprobar qué intención se ha recibido y procesarla apropiadamente. Personalmente me gustaría ir a algo como esto:

 if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) { // boot-related processing here } else if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) { // SMS-related processing here } else { // intent not handled - log as a warning as you've registered to receive it } 

No puede asumir un comportamiento a prueba de fallos. Para mayor claridad, mueva la lógica de procesamiento de intenciones en un método separado:

 if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) { processBootCompletedIntent(intent); } else if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) { processSmsReceivedIntent(intent); } else { // intent not handled - log as a warning as you've registered to receive it } 

PS: la mayoría (si no todas) las cadenas de acción de intención "nativas" se mantienen como constantes en una clase relevante. Por ejemplo, android.intent.action.BOOT_COMPLETED se define como Intent.ACTION_BOOT_COMPLETED. Utilice las constantes donde existen, le ahorrará hacer cualquier error de mecanografía.

  • Selecciona los primeros SMS en la bandeja de entrada de la base de datos de Android
  • Crear PDU para Android
  • Android: Unicode / Charset problemas al enviar un SMS (sendTextMessage)
  • Android receptor SMS no funciona
  • Obtener id de id de mensaje o _id de onReceive android
  • Recuperación de los mensajes SMS desde la tarjeta SIM con android
  • Android - constantes de tipo sms
  • Envío de SMS en Android
  • Receptor de radiodifusión sigue funcionando después de cerrar la aplicación - Android
  • Detección de SMS entrantes y salientes
  • Android enviando muchos mensajes SMS
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.