I am trying to start a Service in Android:
Log.d("BLE", "Start Service");
Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
startService(gattServiceIntent);
Log.d("BLE", "Service Started");
In the BluetoothLeService I override the onStartCommand() function which means I would see the log when the service is started
public class BluetoothLeService extends Service {
....
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
Log.d("BLE", "onStartCommand");
return START_STICKY;
}
However the log is the following:
07-14 21:30:23.676: D/BLE(28327): Start Service
07-14 21:30:23.676: D/BLE(28327): Service Started
but the onStartCommand() never appeared in the log. How can I start the service?
What you're trying to do is to bind to the service first and then start it. Documentation says:
A bound service is one that allows application components to bind to it by calling bindService() in order to create a long-standing connection (and generally does not allow components to start it by calling startService()).
The lifecycle of a service created by calling bindService() has different callback methods compare to the one created by calling startService() (see the flow diagram on the page provided). So for the service created with a bindService() call there is no onStartCommand() method, that's why it's never called.
The common practice is to start a service first and after that bind to it (all the hook methods must be appropriately implemented in this case). If you do it this way onStartCommand() will be called.
EDIT:
How can I start the service?
You did start the service. After calling bindService() it is running (of course if onBind() is properly implemented with IBinder returned).
... but the onStartCommand newer appeared in the log
It is so due to the reason described above.
Have you declared BluetoothLeService in the manifest?
<service android:enabled="true" android:name=".BluetoothLeService" />
A service will bot be runnable unless declared i manifest.
Also: are you sure you want to call both bind and start service?
bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
startService(gattServiceIntent);
it is possible but rather uncommon..
Comment out the Toast and try again. That may be the source of your crash.
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
Related
My Android application is activating a service that call an 'Activity.
On mainActivity:
startService(new Intent(getBaseContext(),MyService.class));
And then on service:
public int onStartCommand(Intent intent,int flage,int startId){
// Toast.makeText(this, "Yes please", Toast.LENGTH_LONG).show();
Intent mIntent=new Intent(MyService.this,trackingActivity.class);
mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(mIntent);
return START_STICKY; }
At the end of trackingActivity this line is written (Again):
startService(new Intent(getBaseContext(),MyService.class));
That's creates a lot of Services. Is there a better way to create a background service that repeats itself always without creating each time a new Service ?
I tried to do a while loop inside the Activity :
while(true){
Actions on activity
}
But with no success.
Context.startService(Intent) does not create a new Service for each call.
If there is already a matching service running, it passes the intent to that running service, but does not create a new one each time.
See the Android Developer Docs for Context.startService(Intent):
If this service is not already running, it will be instantiated and
started (creating a process for it if needed); if it is running then
it remains running.
Every call to this method will result in a corresponding call to the target service's onStartCommand(Intent, int, int) method, with the intent given here.
There is similar information in the Android Developer Docs about Starting a Service:
[When starting a service using an intent] the startService() method returns immediately and the Android system
calls the service's onStartCommand() method. If the service is not
already running, the system first calls onCreate(), then calls
onStartCommand().
...
Multiple requests to start the service result in multiple
corresponding calls to the service's onStartCommand(). However, only
one request to stop the service (with stopSelf() or stopService()) is
required to stop it.
As the title says I am having the following problem. My foreground service is being killed when the activity that started it is swyped away from recent tasks list.
I am starting a service with
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(notificationID, notification);
return START_STICKY;
}
Can someone please tell me why is this happening and how can I make it so the service stays running when user swypes the activity away.
I don't have access to public void onTaskRemoved (Intent rootIntent) for some reason but I don't know what to do in that method anyway...
I am starting the service like this this and it's not a bound service
serviceIntent = new Intent(this, RecordingService.class);
startService(serviceIntent);
If little use case description helps I am trying to control sound recorder from a remote view in the notification bar so restarting a service is not an option since it should continue to record even if activity is destroyed.
BTW.I did tried starting a service in another process by android:process=":recordingProcess" and the service does continue to run then but I am suspecting this is not how you should do it.
Even i had the same issue and i had access to onTaskRemoved() function.Please check this link, "Process life cycle" topic.
Try to return from onStartCommand() START_REDELIVER_INTENT, service will get start again.
From Android Developer Reference
A service can be both started and have connections bound to it. In
such a case, the system will keep the service running as long as
either it is started or there are one or more connections to it with
the Context.BIND_AUTO_CREATE flag. Once neither of these situations
hold, the service's onDestroy() method is called and the service is
effectively terminated.
How are you starting your service?
I made a remote service, this service is started by my activity the first time that boot, after that, the activity always look if the service is started to avoid start it again.
The service run some methods in the onCreate function. This service is running always and started on boot time also.
The problem (is not a big problem but I want to know why) is that once the service is created if I stop my activity the onTaskRemoved is called, this is correct, but after few seconds the oncreate method is called again and the service starts again.
Any idea why? And how can I control this?
<service
android:name=".Service"
android:icon="#drawable/ic_launcher"
android:label="#string/service_name"
android:process=":update_process" >
</service>
AndroidManifest.xml
if (!isRunning()) {
Intent service = new Intent(this, UpdateService.class);
startService(service);
} else {
//Just to debug, comment it later
Toast.makeText(this, "Service was running", Toast.LENGTH_SHORT).show();
}
When the service is started if it was not running
The problems is that you service is sticky per default, this means that it will be restarted when killed, until you explicitly ask for it to be stopped.
Override the onStartCommand() method in your service, and have it return START_NOT_STICKY. Then you service will not be restarted when killed.
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
return START_NOT_STICKY;
}
Although Bjarke's solution is valid, I would like to propose an alternate solution which covers cases where it might be necessary to perform any recovery in the Service.
Android is invoking onStartCommand() once again after restarting your service to inform you that the Service process crashed unexpectedly (because its task stack was removed), and is now being restarted.
If you look at the intent argument of onCreate(), it will be null (only for such restarts), which indicates that Android is re-creating your previously sticky service which crashed unexpectedly.
In some cases it would be wise to return NON_STICKY ONLY for such restarts, perform any needed cleanup/recovery and stop the service so that you exit gracefully.
When the service is started normally, you should still be returning STICKY otherwise your service would never be restarted to let you perform any recovery.
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
// intent is null only when the Service crashed previously
if (intent == null) {
cleanupAndStopServiceRightAway();
return START_NOT_STICKY;
}
return START_STICKY;
}
private void cleanupAndStopServiceRightAway() {
// Add your code here to cleanup the service
// Add your code to perform any recovery required
// for recovering from your previous crash
// Request to stop the service right away at the end
stopSelf();
}
Another option would be to request your service be stopped (using stopSelf()) as part of onTaskRemoved() so that Android does not even have to kill the service in the first place.
I created a service that can be started via the startService() method, but it also be bound by the applications. I wish that it can be started only via the startService() method, or in other words, applications should be able to bind to it only when the service is already started.
The service should be started manually and not when an application binds to it.
If the service is running, applications can bind to it.
If the service is not running, when an application tries to bind to it, the service should not start.
However, the default behavior is quite different: in fact, Android starts the service automatically when an application wants to bind to it. I would like to know if is possible to modify this behavior to achieve the above requirement.
If this is not possible, the only alternative would be to stop the service if it has been initiated as a result of a bindService(). Here are the changes to my service class in order to use this way...
// It says if the service was started manually.
private boolean mCorrectlyStarted = false;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(LOG_TAG, "onStartCommand()");
mCorrectlyStarted = true; // the service is started manually: ok!
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
Log.i(LOG_TAG, String.format("onBind(intent: %s)", intent));
if (mCorrectlyStarted) {
return binder;
}
else {
stopSelf(); // although I make this call, the service is not stopped
return null;
}
}
Why do my changes do not have the desired effect?
It might be good that the service starts when an application invokes the bindService() method, but after verifying that it was not started manually, it should stop itself.
The fact that something, like an Activity, called bindService() means someone is still bound to the service. Calling stopSelf() does not destroy the service since technically the service is still bound by the activity.
It will be destroyed once unbindService is called eventually by the Activity. Binding and starting a service are orthogonal.
I am not sure what you are trying to achieve with this design, maybe provide more info on why you want the service to be started before something can bind to it?
I am trying to create a service that will handle file I/O in the background. Activities that update the data will bind to the service and call the service's methods to perform the I/O. I am using the Android documentation for guidance.
My service does not seem to want to start, however. In the onCreate() method of my Activity, I have:
Intent smsIntent = new Intent(this, SurveyManagerService.class);
String surveyFilename = getIntent().getStringExtra("surveyFilename");
System.out.println(startService(smsIntent)); //testing if it starts
SurveyManagerServiceConnection connection = new SurveyManagerServiceConnection();
sms = connection.getSurveyManagerService();
At line 3 LogCat outputs a ComponentInfo object, so it would appear that the service is created; however, sms is null. Furthermore, the SurveyManagerService onStartCommand() method never seems to be called:
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
System.out.println("starting service");
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
openSurveyFromIntent(intent);
return START_REDELIVER_INTENT;
}
I never see any "starting service" output in LogCat, nor does the Toast appear.
My service is declared in my manifest as:
<service android:name=".SurveyManagerService" android:exported="false" android:enabled="true">
</service>
Am I missing something obvious? Let me know what other information I should provide to diagnose the problem.
Be sure to declare your service in AndroidManifest.xml
<application>
...
<service android:name=".path.to.service.MyService"/>
</application>
Maybe you've accidentally placed the service tag outside application tag? Then the service just fails silently. Although there should be a "Unable to start service Intent..." error in the log.
It seems the onCreate() method has to exit before the service can actually start. Once I removed the getSurveyManagerService() request, and once a bit of time had passed, I received the System.out messages indicating the service was starting.
Unfortunately that creates another problem: the Activity relies on the Service for its data, so I need to determine how to cause the Activity to wait for the service to start.
EDIT: My solution was to create a private subclass of my ServiceConnection in my Activity. I then overrode the onServiceConnected() method to provide the Activity with its data (populating a ListView, in this case).
In my case i refactored the service class & noticed that it was not automatically refactored in manifest. So i had to manually update the fully qualified name of the service in manifest.