I previously had a Foreground service that I launched from one activity. The code to launch the service was contained within said activity.
Now I would like to launch this service with a non-activity class that can be called from different activities. In doing this I get an error:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.ComponentName android.content.Context.startService(android.content.Intent)' on a null object reference
The working code block was previously contained in the singular activity (let's call it 'ActivityClass') and looked like this:
private void serviceWrapper(String command){
Intent service = new Intent(ActivityClass.this, Recorder.class);
switch (command){
case "start":
service.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
service.putExtra("recordAudio", RECORD_AUDIO);
startService(service);
break;
etc...
}
}
My attempt to move this to a non-activity class looks like this:
public class ServiceWrapper extends AppCompatActivity {
// variable to hold context passed
private Context context;
public ServiceWrapper(Context context){
this.context=context;
}
public void serviceControl(String command){
Intent service = new Intent(context, Recorder.class);
switch (command)
{
case "start":
service.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
service.putExtra("recordAudio", RECORD_AUDIO);
startService(service);
break;
etc....
}
I'd like to call this from multiple activities like this:
private void startWrapper() {
//Instantiate the class
ServiceWrapper serviceWrapper = new ServiceWrapper(ActivityClass.this);
//Check for permissions needed
if (hasPermissionsGranted(Constants.PERMISSION_SETTINGS.VIDEO_PERMISSIONS)){
serviceWrapper.serviceControl("start");
}
else {
//kick off async request for permission
ActivityCompat.requestPermissions(this, Constants.PERMISSION_SETTINGS.VIDEO_PERMISSIONS, REQUEST_VIDEO_PERMISSIONS);
}
}
But unfortunately I get this error. I'm not a super knowledgeable programmer so forgive me if this is obvious.
Generally this isn't the way to start a foreground service on android.
Should be something like:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(new Intent(context, HelloService.class));
} else {
context.startService(new Intent(context, HelloService.class));
}
If you're outside an activity you need a way to retrieve application context. Generally that would be done by storing context as a variable via the constructor so you can use it later. E.g create a new class instance storing application context as a variable, start service using that context elsewhere in the application.
Or depending on what your class extends or implements
getActivity().getApplicationContext();
If you're using an intent service, you should first start the service so it's initialized and pass your intents after.