Android service with START_STICKY crashes on killing app - android

This is my Service getting called on button click from an Activity. If I swipe my Activity left while Service is running it crashes. I have also tried running it in separate process by putting in android:process=":remote" in the manifest but it is still the same.
#Override
public void onCreate(){
super.onCreate();
Log.d("Service", "Creating");
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
#Override
public int onStartCommand (Intent intent, int flags, int startId)
{
super.onStartCommand(intent, flags, startId);
Log.d("Started", "Service");
type = intent.getIntExtra("Type",-1);
mode = intent.getIntExtra("Mode",-1);
rank = intent.getIntExtra("Rank", -1);
latitude = intent.getDoubleExtra("Lat", -1.0);
longitude = intent.getDoubleExtra("Long", -1.0);
startTime = intent.getLongExtra("Start", 0);
endTime = intent.getLongExtra("End", 0);
The error I am getting is:
java.lang.RuntimeException: Unable to start service com.routofy.routofytest.MyLocationService#374afe93 with null: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.content.Intent.getIntExtra(java.lang.String, int)' on a null object reference
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2913)
at android.app.ActivityThread.access$2100(ActivityThread.java:148)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1390)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5312)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.content.Intent.getIntExtra(java.lang.String, int)' on a null object reference
at com.routofy.routofytest.MyLocationService.onStartCommand(MyLocationService.java:89)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2896)
at android.app.ActivityThread.access$2100(ActivityThread.java:148)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1390)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5312)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)
That is null pointer on type = intent.getIntExtra("Type",-1);
I understand that killing the app is killing the process and Intent this Service is getting is coming out to be null. But how to handle such cases that even if Activity is killed Intent is handed over to Service?
I want service to be totally independent of Activity. Also I am running it like:
Intent pickIntent = new Intent(getApplicationContext(),MyLocationService.class);

I understand that killing the app is killing the process and intent this service is getting is coming out to be null.
Since you haven't posted the return value of onStartCommand() I believe that it's START_STICKY meaning that the service is recreated by the system with null Intent passed in.
But how to handle such cases that even if activity is killed intent is handed over to service.
Just return START_REDELIVER_INTENT flag, which means that:
"If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand() with the last intent that was delivered to the service."

Related

Stop a service after MainActivity is closed (EDITED)

I think im not clear at all, i do want the service to persist even if the main activity is destroyed via user action or android system does it, it does it well, but when the app is reopened at certain point i will want to check if a bg activity exists and stop it using a action button, THX in advance.
I launch a background service, in my MainActivity I can stop it and rerun it, the service persists when the app is closed from the running apps list, the problem is when I relaunch the closed app an try to stop the service with a button I have the app crashes cause it obviously tries to stop a service from which it no longer has a reference.
private void startBg(){
if (!hasPermissions() || mScanning) {
return;
}
clearLogs();
BgServiceIntent = new Intent(MainActivity.this, BgScanService.class);
startService(BgServiceIntent);
}
private void stopBg(){
stopService(BgServiceIntent);
}
Calling stopBg() after reopening the app fails, because BgServiceIntent no longer points to this service and thus I get this:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: mobile.link.imbera.apsys.imberalink, PID: 20104
java.lang.NullPointerException
at android.app.ContextImpl.validateServiceIntent(ContextImpl.java:1568)
at android.app.ContextImpl.stopServiceCommon(ContextImpl.java:1628)
at android.app.ContextImpl.stopService(ContextImpl.java:1589)
at android.content.ContextWrapper.stopService(ContextWrapper.java:499)
at mobile.link.imbera.apsys.imberalink.MainActivity.stopBg(MainActivity.java:180)
at mobile.link.imbera.apsys.imberalink.MainActivity.lambda$onCreate$1$MainActivity(MainActivity.java:124)
at mobile.link.imbera.apsys.imberalink.MainActivity$$Lambda$1.onClick(Unknown Source)
at android.view.View.performClick(View.java:4463)
at android.view.View$PerformClick.run(View.java:18770)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5333)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
at dalvik.system.NativeStart.main(Native Method)
If the service already running in background then you need to call stopSelf() on same instance of that service .
Now as per service life Cycle onCreate() only call once in the lifetime of service .
WhereAs onStartCommand get called each time you call startService() with new intent. So what you can do is to pass a flag in intent to stop it .
Intent BgServiceIntent = new Intent(MainActivity.this, BgScanService.class);
BgServiceIntent.putExtra("close",true);
startService(BgServiceIntent);
And in Service .
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
boolean shouldClose=intent.getBooleanExtra("close",false);
if(shouldClose){
stopSelf();
} else {
// Continue to action here
}
return START_STICKY;
}
Maybe all you need to do is check to see if it's null before attempting to stop it:
private void stopBg(){
if(BgServiceIntent != null)
stopService(BgServiceIntent);
}
First of all start a service in START_NOT_STICKY.
Override this method in your Service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
and add this in your MainActivity.class
#override
private onDestroy() {
stopService(YourActiveService);
finishAffinity();
super.onDestroy()
}

Audiomanager android error null reference

I have a GPSCheck Service which produces alert sound when gps is turned off. I am getting null reference error. There's something wrong with the context.
Where am I going wrong?
public class GPSCheck extends BroadcastReceiver {
public Context context;
public Ringtone ringtone;
#Override
public void onReceive(Context context, Intent intent) {
LocationManager locationManager = (LocationManager) context.getSystemService(context.LOCATION_SERVICE);
AlarmService obj = new AlarmService();
if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
stopSiren();
}
else {
Toast.makeText(context, "Please switch on the GPS", Toast.LENGTH_LONG).show();
blowSiren();
}
}
public void blowSiren() {
AudioManager audioManager = (AudioManager) this.context.getSystemService("audio");
audioManager.setStreamVolume(4, audioManager.getStreamMaxVolume(4), 0);
Uri path = Uri.parse("android.resource://" + this.context.getPackageName() + "/raw/alert");
RingtoneManager.setActualDefaultRingtoneUri(this.context, 4, path);
this.ringtone = RingtoneManager.getRingtone(this.context, path);
this.ringtone.setStreamType(4);
this.ringtone.play();
}
public void stopSiren() {
AudioManager audioManager = (AudioManager) this.context.getSystemService("audio");
audioManager.setStreamVolume(4, audioManager.getStreamMaxVolume(4), 0);
Uri path = Uri.parse("android.resource://" + this.context.getPackageName() + "/raw/alert");
RingtoneManager.setActualDefaultRingtoneUri(this.context, 4, path);
this.ringtone = RingtoneManager.getRingtone(this.context, path);
this.ringtone.setStreamType(4);
this.ringtone.stop();
}
}
This is the error I m geting : -
11-18 21:26:36.784 1411-1411/com.track.client E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.track.client, PID: 1411
java.lang.RuntimeException: Unable to start receiver com.pasupatigroup.client.GPSCheck: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2789)
at android.app.ActivityThread.access$1800(ActivityThread.java:154)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1468)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:234)
at android.app.ActivityThread.main(ActivityThread.java:5526)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
at com.track.client.GPSCheck.blowSiren(GPSCheck.java:35)
at com.track.client.GPSCheck.onReceive(GPSCheck.java:30)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2782)
at android.app.ActivityThread.access$1800(ActivityThread.java:154) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1468) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:234) 
at android.app.ActivityThread.main(ActivityThread.java:5526) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
First. I don't know if this is your problem but you should get AudioManager by calling using the constant Context.AUDIO_SERVICE, not rolling your own strings.
Second. Don't store the context, send it in via input parameter to blow and stop siren. Otherwise you might get freaky leaks (yep, you can leak memory in Java).
Dunno if this will fix your problem, but that's what I noticed right off anyway.
Probably your this.context.getSystemService("audio"); call fails because the this.context is null.
You probably meant to set it to the class member in onReceive(Context context, Intent intent):
this.context = context;
But like the other answer points out it's instead better to pass it to stopSiren() and blowSiren() when calling those methods.
That's covered in the BroadcastReceiver documentation:
A BroadcastReceiver object is only valid for the duration of the call
to onReceive(Context, Intent). Once your code returns from this
function, the system considers the object to be finished and no longer
active.

App crashes when closed while using a service android, as im trying to use intents

public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getExtras() != null) {
String temp = intent.getStringExtra("key");
temp1 = Integer.parseInt(temp);
counter = temp1;
}
}
I'm passing data to the service and it works perfectly when the app is open but crashes as soon as i close the app.. I've tried a lot of things and I'm new to android. Any help would be appreciated
Thanks in advance.
Here is the log
03-21 15:35:07.868 21818-21818/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.cs442.shash5259.assignment_6, PID: 21818
java.lang.RuntimeException: Unable to start service com.cs442.shash5259.assignment_6.Myservice#9d88461 with null: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Bundle android.content.Intent.getExtras()' on a null object reference
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3045)
at android.app.ActivityThread.-wrap17(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1452)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Bundle android.content.Intent.getExtras()' on a null object reference
at com.cs442.shash5259.assignment_6.Myservice.onStartCommand(Myservice.java:55)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3028)
at android.app.ActivityThread.-wrap17(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1452) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5443) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
Looking at the logs, it is clear that your Intent object in onStartCommand is null, when app is closed.
Looking at the documentation inside the source code of Service, it is mentioned that:
The Intent supplied to onStartCommand may be null if the service
is being restarted after
its process has gone away, and it had previously returned anything
except START_STICKY_COMPATIBILITY.
You can deal with this in at least 2 different ways depending on your app's requirement.
1.You can modify the code as below in your onStartCommand:
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent!= null) {
String temp = intent.getStringExtra("key");
temp1 = Integer.parseInt(temp);
counter = temp1;
}
}
This will prevent the crash but will not update the counter
2.Or you may return START_REDELIVER_INTENT in the onStartCommand() callback in service so that the entire intent is sent following a restart, thus preventing Intent from being null.

NullPointerException while retrieving Extras from Intent

I'm working on building a Location_Service for my Android App.I have a Service say , T_Service that starts on phone boot and checks for few conditions in its onStartCommand() to start my Location_Service. I want to send these conditions as an intent from a broadcast receiver associated to with the T_Service.
I do the following:
In the Broadcast Receiver
public class T_BroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context,T_Service.class);
i.putExtra("PARENT_ACTIVITY_NAME","com.example.helloworld");
context.startService(i);
}
}
In the T_Service class:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("APP","The intent has parent activity : "+intent.getExtras().getString("PARENT_ACTIVITY_NAME"));
}
I get a NullPointerException when my code reaches the above point that tries to print the value associated with the key that was set in the Intent.
Kindly advise me on how to go about the case of adding extras to an intent of a Service like T_Service that starts on phone boot.
The Stack trace for the Exception :
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start service org.abc.def.services.TService#41593b58 with null: java.lang.NullPointerException
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2387)
at android.app.ActivityThread.access$1900(ActivityThread.java:127)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1221)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4511)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at org.abc.def.services.TrackerService.onStartCommand(TrackerService.java:140)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2370)
            at android.app.ActivityThread.access$1900(ActivityThread.java:127)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1221)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4511)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
            at dalvik.system.NativeStart.main(Native Method)
From the documentation (onStartCommand):
Parameter "intent": The Intent supplied to startService(Intent), as given.
This may be null if the service is being restarted after its process has gone
away, and it had previously returned anything except
START_STICKY_COMPATIBILITY.
If you're running this on phone boot is likely that you will get null on the intent because the process that started it has gone away.
To receive the the same intent you would need to return START_REDELIVER_INTENT in the onStartCommand method, as follows:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("APP","The intent has parent activity : "+intent.getExtras().getString("PARENT_ACTIVITY_NAME"));
return Service.START_REDELIVER_INTENT;
}
Returning START_REDELIVER_INTENT will make the intent parameter to be passed again to the onStartCommand method whenever the service get restarted (e.g on phone boot).
For more details check the documentation.
START_REDELIVER_INTENT
Constant to return from onStartCommand(Intent, int, int): if this
service's process is killed while it is started (after returning from
onStartCommand(Intent, int, int)), then it will be scheduled for a
restart and the last delivered Intent re-delivered to it again via
onStartCommand(Intent, int, int)
Please read the javadoc for onStartService. It says that the intent parameter can be null, so you should always check it for null before calling methods on it.
My experience is that even when you think that an IntentSevice will never receive a null there, it is actually still possible in extremely rare circumstances. So you should still check it for null even if you don't think it will happen.
replace this
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("APP","The intent has parent activity : "+intent.getExtras().getString("PARENT_ACTIVITY_NAME"));
}
with this
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Bundle b = getIntent().getExtras();
if (b != null){
Log.d("APP","The intent has parent activity :"+b.getString("PARENT_ACTIVITY_NAME")); }
Per the Intent API documentation, you must include a package name in the extra's name.
public Intent putExtra (String name, String value)
Added in API level 1
Add extended data to the intent. The name must include a package prefix, for example the app com.android.contacts would use names like "com.android.contacts.ShowAll".
Parameters
name The name of the extra data, with package prefix.
value The String data value.
Returns
Returns the same Intent object, for chaining multiple calls into a single statement.
See Also
putExtras(Intent)
removeExtra(String)
getStringExtra(String)
Please check your intent and extra string before accessing. May be it is null
if(intent.getExtras()!=null && intent.hasExtra("PARENT_ACTIVITY_NAME")){
Log.d("APP","The intent has parent activity : "+intent.getExtras().getString("PARENT_ACTIVITY_NAME"));
}
To pass an intent, please refer older thread.
Pass data from Activity to Service using an Intent

Getting error while stopping foreground service in watch from mobile

From my mobile I am starting a foreground service in my android watch. I am able to do that correctly. But when I try to stop the service as well as the activity in watch , I am getting an error message( watch app is crashing). I am using message listener service to receive the message from mobile.
I also have a stop button in watch app which is running perfectly(if I try to stop the service from watch itself) and it has the same lines of code. I am not sure where I am wrong when I receive message from mobile app to stop the foreground service.
#Override public void onMessageReceived(MessageEvent messageEvent) {
Log.i(INFOTAG, "Stop msg received");
if(messageEvent.getPath().equals(STOP_MESSAGE_PATH_2)){
started = false;
Intent stopIntent = new Intent(
MainActivity.this, ForegroundService.class);
stopService(stopIntent);
this.finish();
}
}
Below is the error log I am getting:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.content.ContextWrapper.getPackageName(ContextWrapper.java:132)
at android.content.ComponentName.(ComponentName.java:77)
at android.content.Intent.(Intent.java:4160)
at com.magi.magidemo.MainActivity.onMessageReceived(MainActivity.java:464)
at com.google.android.gms.wearable.internal.zzcf$5.zza(Unknown Source)
at com.google.android.gms.wearable.internal.zzcf$5.zzs(Unknown Source)
at com.google.android.gms.internal.zzmn.zzb(Unknown Source)
at com.google.android.gms.internal.zzmn$zza.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
You need to get the Activity's instance from the override method.
Like this:
public MainActivity activity;
// in the override method
this.activity = activity;
Then use it:
Intent stopIntent = new Intent(
activity, ForegroundService.class);
Have a look: android.content.Context.getPackageName()' on a null object reference

Categories

Resources