Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 722
Cyogenos Avatar asked Jul 05 '16 21:07

Cyogenos


People also ask

What is broadcastreceiver in Android?

BroadcastReceiver is one of the basic building blocks of Android components. In this article, let’s explore what broadcasts are, what broadcast receivers are, and how we can use them. If you want to jump directly to the code base, check out the GitHub repo. What Are Broadcasts?

How to use the broadcast receiver in your application?

The two main things that we have to do in order to use the broadcast receiver in our application are: override fun onReceive (context: Context?, intent: Intent?) { Below is the sample project showing how to create the broadcast Receiver and how to register them for a particular event and how to use them in the application.

How do I register the connectivity_action broadcast on Android?

Also, apps targeting Android 7.0 and higher must register the CONNECTIVITY_ACTION broadcast using registerReceiver (BroadcastReceiver, IntentFilter) . Declaring a receiver in the manifest doesn't work. Apps can receive broadcasts in two ways: through manifest-declared receivers and context-registered receivers.

What is the API level for implicit broadcast in Android?

As part of the Android 8.0 (API level 26) Background Execution Limits, apps that target the API level 26 or higher can no longer register broadcast receivers for implicit broadcasts in their manifest. However, several broadcasts are currently exempted from these limitations.


1 Answers

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.

like image 191
hanif Avatar answered Nov 14 '22 21:11

hanif