2011-07-29 4 views
13

Я пытаюсь перехватить входящий SMS сразу после boot_completed, но у меня возникают проблемы с NullPointerException в этой строке:BroadcastReceiver не работает после BOOT_COMPLETED

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

Вот мой манифест:

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

приемник:

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

       } 



      } 
     } 
    } 

Спасибо.

ответ

15

Проблема заключается в том, что ваша реализация BroadcastReceiver была сопоставлена ​​с двумя намерениями - android.provider.Telephony.SMS_RECEIVED и android.intent.action.BOOT_COMPLETED - но в реализации onReceive вы не проверяете, какое намерение вы обрабатываете.

My Угадай что android.intent.action.BOOT_COMPLETED был получен и intent.getExtras() возвращает null. Вы можете подтвердить это, добавив некоторые методы ведения журнала и просмотрев окно logcat (если вы используете Eclipse).

Если вы пишете услугу или широковещательный приемник и сопоставляете ее с несколькими намерениями, это хорошая практика - не важно - проверить, какое намерение было получено, и обработать ее надлежащим образом. Лично я бы пошел на что-то вроде этого:

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 
} 

Вы не можете принять отказоустойчивое поведение. Для ясности, переместите пристальную логику обработки в отдельный метод:

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 - большинство (если не все) «родные» струна умысла действий проводятся как константы в соответствующем классе. Например, android.intent.action.BOOT_COMPLETED определяется как Intent.ACTION_BOOT_COMPLETED. Используйте константы там, где они существуют, это избавит вас от ошибок ввода.

+0

Спасибо, попробуем посмотреть, как это происходит. – bond

+0

Также укажите приоритет 999. –

Смежные вопросы