Android BroadcastReceiver in Service giving null pointer exception when sending broadcast to it

Cyogenos picture Cyogenos · Jul 5, 2016 · Viewed 8.8k times · Source

I have a broadcast receiver in my service, and when I send a broadcast to it from my activity to stop the service for example, I get the following error:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.content.BroadcastReceiver.onReceive(android.content.Context, android.content.Intent)' on a null object reference

Here is my Service class:

public class PhraseService extends Service{

public static List<Phrase> phrases;
private Context context;

private static final String PHRASE_SERVICE_BROADCAST_ID = "com.cryogenos.safephrase.PHRASE_SERVICE_BROADCAST_ID";
private BroadcastReceiver command_broadcast_receiver;


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    this.context = getApplicationContext();
    LocalBroadcastManager.getInstance(this).registerReceiver(command_broadcast_receiver, new IntentFilter(PHRASE_SERVICE_BROADCAST_ID));

    Log.i("COS", "STARTED SELF");

    /* Handle any command sent by the app here */
    command_broadcast_receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.i("COS", "CALLED?");
            try {
                String command = intent.getStringExtra("command");

                /* Based on the command given, perform an action */
                switch (command) {
                    case "RESTART RECOGNIZER":
                        break;
                    case "STOP":
                        Toast.makeText(context, "Phrase Listener Stopped", Toast.LENGTH_SHORT).show();
                        stopSelf();
                        break;
                }
            }
            catch (Exception e){}
        }
    };
    Intent notif_intent = new Intent(this, Home.class);
    PendingIntent pi = PendingIntent.getActivity(this, 0, notif_intent, 0);
    Notification notif = new NotificationCompat.Builder(this)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle("Phrase Listener")
            .setContentText("Listening for Phrases")
            .setContentIntent(pi)
            .build();

    startForeground(34994, notif);
    return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {
    LocalBroadcastManager.getInstance(this).unregisterReceiver(command_broadcast_receiver);
    super.onDestroy();
}


@Override
public IBinder onBind(Intent intent) {return null;}
}

Here is the activity from where I'm sending the broadcast from:

public class SettingsModel {

private Context context;
private static final String PHRASE_SERVICE_BROADCAST_ID = "com.cryogenos.safephrase.PHRASE_SERVICE_BROADCAST_ID";
private LocalBroadcastManager local_broadcast_manager;

public SettingsModel(Context context) {
    this.context = context;
    local_broadcast_manager = LocalBroadcastManager.getInstance(context);
}

public void handleSwitch(SettingsSwitch settings_switch, boolean status){
    switch (settings_switch){
        case POWER:
            if(status) {
                Intent i = new Intent(context, PhraseService.class);
                context.startService(i);
            }
            else{
                Intent i = new Intent(PHRASE_SERVICE_BROADCAST_ID);
                i.putExtra("command", "STOP");
                local_broadcast_manager.sendBroadcast(i);
            }
            break;
        case VIBRATE:
            break;
        case RING:
            break;
        case TIMER:
            break;
    }
}
}

My service is suppose to be continuously running, and only when I tell it, it should stop. This is why I have set it up as a foreground service. The problem here is that I keep getting an error when I try to broadcast to it.

Answer

hanif picture hanif · Jul 5, 2016

You are registering your brodcastreceiver before initializing it. So try to move the registration after initialization as below:

/* Handle any command sent by the app here */
    command_broadcast_receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.i("COS", "CALLED?");
            try {
                String command = intent.getStringExtra("command");

                /* Based on the command given, perform an action */
                switch (command) {
                    case "RESTART RECOGNIZER":
                        break;
                    case "STOP":
                        Toast.makeText(context, "Phrase Listener Stopped", Toast.LENGTH_SHORT).show();
                        stopSelf();
                        break;
                }
            }
            catch (Exception e){}
        }
    };
LocalBroadcastManager.getInstance(this).registerReceiver(command_broadcast_receiver, new IntentFilter(PHRASE_SERVICE_BROADCAST_ID));

Also, your SettingsModel is not an activity since it does not extend Activity.