Android does service stopSelf() still require return - android

Is it necessary to call return; if I have decided to call stopSelf() command in a onStartCommand() within a service?

Yes. The method must have a return statement because the signature for onStartCommand() indicates that it returns a value:
public int onStartCommand (Intent intent,
int flags,
int startId)

Related

When android service is restarted by the OS due to Sticky flag, is intent passed to it?

public int onStartCommand(Intent intent, int flags, int startId) {
}
When a service is started, I pass an intent to startService function. When service is restarted by the OS due to Sticky flag, is that very same intent that I passed to it to start the service be passed to onStartCommand again or will it be null?
Intent is only passed again if you request START_REDELIVER_INTENT
What is START_STICKY,START_NOT_STICKY and START_REDELIVER_INTENT Service

Why Android app crash when close app if I getExtras in Service?

In Activity I start a service
Intent serv=new Intent(this, MyService.class);
serv.putExtra("mac", "mac");
startService(serv);
In the service, I get the parameter
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String mac=intent.getExtras().getString("mac");
return super.onStartCommand(intent, flags, startId);
}
Then I kill the app, the app will crash, and the service will also crash.
If I remove this line, then it will be no problem, the service also alive after I killed the app.
String mac=intent.getExtras().getString("mac");
Why the app crash?
super.onStartCommand(intent, flags, startId) returns the START_STICKY flag by default which, according to the docs, mean that:
"if this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then leave it in the started state but don't retain this delivered intent."
Since the Intent isn't being redelivered you likely get NPE when calling intent.getExtras().
To redeliver the Intent return the START_REDELIVER_INTENT flag from onStartCommand():
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
...
return START_REDELIVER_INTENT;
}
You are putting extras to wrong intent bleService.putExtra("mac", "mac");
Instead you should write serv.putExtra("mac", "mac");
Also you should always check if there are extras
if(getIntent().hasExtra("mac"){
//do some stuff
}

Timer inside Android service

I have an Android service that starts a timer that does stuff:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
timer.scheduleAtFixedRate(new VeryImportantTask(), 0, RATE);
return START_STICKY;
}
I know Services are singleton but, does onStartCommand method called each time that I call startService()? If so, I should control that my timer is just started the first time, shouldn't I? I'm thinking in a static boolean flag in the service. Is there a better way?
In your case i.e START_STICKY you can simply check the intent value nullity
like this
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(null==intent){
// service restarted do what you want
}
return START_STICKY;
}
because first time the intent will not be null and it will be null every time in case of a restart with START_STICKY.

true usage of onStartCommand in Android

I am a little confused. I want to use a Service to register content Observer and prevent from stopping it. Where should I register contentObserver, in onCreate or onStartCommand? in other words, which one of these codes is true:
private ContentObserver smsObserver;
public void onCreate() {
super.onCreate();
smsObserver = new ObserverSms(getApplicationContext());
getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, smsObserver);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
or
private ContentObserver smsObserver;
#Override
public void onCreate() {
super.onCreate();
smsObserver = new ObserverSms(getApplicationContext());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, smsObserver);
return START_STICKY;
}
or in onStart()?
Does execute onCreate or onStart again each time the page opens with onStartCommand?
and Doesn't the "return" in "return START_STICKY;" cause stop the contentObserver in second codes?
The initialization flow of a service after startService is called:
Constructor -> onCreate -> onStartCommand
The onStartCommand will be called every time after startService is called.
However the onCreate will be only called once.
Normally, the onCreate is used like the constructor because we usually don't implement the constructor of a service.
And the onStartCommand is to handle every startService request from different packages/processes which are not sure if there is a second startService or not.
In your case, if you only call startService once, they will be the same.

Restart Android Started Service after application was killed

I'm trying to do a StartedService in android to send periodically the user location to a server.
Until this moment I managed to create the service and starting it from the 'parent ' application and I don't know how to keep it alive after the application was killed. From what I found on internet the 'StartCommandResult.Sticky' should restart the service if this one is killed but from some reason this is not restarted.
I overried the OnStartCommand:
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
locationTask = new Task(() =>
{
//stuff to do
});
locationTask.Start();
return StartCommandResult.Sticky;
}
And the service is started like this:
Intent intent = new Intent(this.Activity, Class.FromType(typeof(LocationService)));
this.Activity.StartService(intent);
Any suggestions what should I do in order to keep my service alive after the application was killed?
As observation I'm using xamarin to do it, but I won't mind an answer in android(java).
As stated in the official documentation:
A service is "started" when an application component (such as an
activity) starts it by calling startService(). Once started, a service
can run in the background indefinitely, even if the component that
started it is destroyed. Usually, a started service performs a
single operation and does not return a result to the caller. For
example, it might download or upload a file over the network. When the
operation is done, the service should stop itself.
So, starting the service like this
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
Will have your service running even while your app is destroyed.
Regarding Service.START_STICKY in the official documentation:
If the system kills the service after onStartCommand() returns,
recreate the service and call onStartCommand(), but do not redeliver
the last intent. Instead, the system calls onStartCommand() with a
null intent, unless there were pending intents to start the service,
in which case, those intents are delivered. This is suitable for media
players (or similar services) that are not executing commands, but
running indefinitely and waiting for a job.
This is how I do it but its in JAVA code.
in your service you should implement a LocalBinder, onStartCommand and onCreate methods.
public class LocalBinder extends Binder {
ServiceName getService() {
return ServiceName .this;
}
}
#Override
public void onCreate() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("LocalService", "Received start id " + startId + ": " + intent);
return START_STICKY;
}
The onStartCommand should return START_STICKY;. And also, include this code on your Service:
#Override
public void onTaskRemoved(Intent rootIntent) {
// TODO Auto-generated method stub
Intent restartService = new Intent(getApplicationContext(),this.getClass());
restartService.setPackage(getPackageName());
PendingIntent restartServicePI = PendingIntent.getService(getApplicationContext(), 1, restartService, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() +1000, restartServicePI);
}
This will restart your Service on 1 second from the time you close it. Also, dont forget to add your service in your AndroidManifest.xml
<service android:name=".ServiceName"
android:exported="false"
android:stopWithTask="false" >
</service>
Override onStartCommand like this
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
For me, everything in the code was right but the problem was with the use of debugging while checking if the service was on. When I use a release version (or just dev version without connecting to the debug), the process is not killed and the service is running normally.
No idea why though. I am using Xamarin Studio 6.0.

Categories

Resources