I haven’t been messing around with the Android SDK for too long but I’ve already found some things that I think are worth sharing. Android has a concept of Services, or a process that can sit in the background and run a task without needing to interact with the user. There’s plenty of reasons why a Service might not need to be running all the time (say an alarm clock app with no alarms scheduled), but for the most part, Services need to be started at boot. Here’s how, tested from Android 1.5 to 2.2, since no other example I could find on the Internet was complete for this ever-changing SDK.
This example Service, StartAtBootService, is a member of the package com.example.ssab (StartServiceAtBoot): Be careful with your Service implementation, as the onStart() method is depreciated in newer versions of the SDK!
import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; public class StartAtBootService extends Service { public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { Log.v("StartServiceAtBoot", "StartAtBootService Created"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.v("StartServiceAtBoot", "StartAtBootService -- onStartCommand()"); // We want this service to continue running until it is explicitly // stopped, so return sticky. return START_STICKY; } /* * In Android 2.0 and later, onStart() is depreciated. Use * onStartCommand() instead, or compile against API Level 5 and * use both. * http://android-developers.blogspot.com/2010/02/service-api-changes-starting-with.html @Override public void onStart(Intent intent, int startId) { Log.v("StartServiceAtBoot", "StartAtBootService -- onStart()"); } */ @Override public void onDestroy() { Log.v("StartServiceAtBoot", "StartAtBootService Destroyed"); } }
Use any Service you already have instead of the above. Within application in your AndroidManifest.xml define your Service with an intent-filter:
<service android:name="StartAtBootService"> <intent-filter> <action android:name="com.example.ssab.StartAtBootService"> </action> </intent-filter> </service>
Now the new part. The OS broadcasts ACTION_BOOT_COMPLETED when it has finished booting. Your app can ask to receive this notification by requesting permission in your manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"> </uses-permission>
Your app now gets the broadcast, but still needs to do something with it. This is done by subclassing the BroadcastReceiver class. As far as I know, ACTION_BOOT_COMPLETED is the only Intent broadcast to apps, but because this could change at any point (and I can all but guarantee it will), do yourself a favor and check the Intent in your onReceive() method:
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; public class StartAtBootServiceReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) { Intent i = new Intent(); i.setAction("com.example.ssab.StartAtBootService"); context.startService(i); } } }
The last thing you need to do is register your BroadcastReceiver in your manifest, within application:
<receiver android:name="StartAtBootServiceReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"> </action> <category android:name="android.intent.category.HOME"> </category> </intent-filter> </receiver>
That should do it. If you’re using Eclipse, run your app once and then exit the emulator. Then issue emulator -avd your_avd_name to launch your emulator without uninstalling your app. An adb logcat | grep StartAtBootService should show your app starting at boot.
Posted in: Technology | Tags: android, boot, broadcastreceiver, intent, manifest, service, start
13 comments for this post.
21 July 2010, at 03:39 pm
Hi,
Thanks for the article. I am wondering what you mean by “use both” in the comment.
* In Android 2.0 and later, onStart() is depreciated. Use
* onStartCommand() instead, or compile against API Level 5 and
* use both.
I mean is there way I can write the service which can run at startup on both 1.5 and 2.0+
thanks
Ali
22 July 2010, at 09:15 pm
@Ali Khan: Yes, it’s just that a different method will be called to start the service depending on the version. On API level <6, onStart() is called, while on API level >=6 onStartCommand() is called, meaning you’ll need to have similar code (or call another method that starts your service from) within both of these functions. For more info, check out the URL I link in the comment: http://android-developers.blogspot.com/2010/02/service-api-changes-starting-with.html (the paragraph starting with “You can also easily write a Service”). It all relies on the API level you’re compiling against. Make sure it’s correct, otherwise you will encounter errors.
03 September 2010, at 07:58 am
Hi there,
is it possible for you to supply a complete example for a service starting itself at boot time?
29 September 2010, at 02:05 am
Hi Greg,
Thanks for this sharing this article. I would like to ask you that why have you used
in your manifest?
What’s the purpose?
Regards,
Syed Ahmed Hussain
29 September 2010, at 07:00 pm
You can’t post HTML/XML directly in the comments, so whatever you copied got stripped out. Try again?
23 November 2010, at 10:16 am
Thanks Greg and thanks to droidVNCserver for naming their startup service StartAtBootService. Otherwise this would not have been the #1 result on Google. Very well done!!
28 January 2011, at 11:30 pm
Thanks for your wonderful article….
I am a android beginner. Please tell me how to start the service or how to run the StartAtBootServiceReceiver code which starts the service? (whether it should be in a activity?)
02 March 2011, at 12:27 am
I have done it for invoking a service Broadcast receiver code: package com.service;
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent;
public abstract class BootReceiver extends BroadcastReceiver{ @Override
public void onReceive(Context context,Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Intent i = new Intent();
i.setAction(“com.scubian.LocationService”);
context.startService(i);
}
} }
Service code package com.service;
import android.app.Service; import android.content.Context; import android.content.Intent; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.widget.Toast;
public class LocationService extends Service implements LocationListener {
private final static String TAG = “LocationLoggerService”; LocationManager lm;
public LocationService() { }
@Override public IBinder onBind(Intent intent) { return null; }
public void onCreate(Intent intent, int startId) { subscribeToLocationUpdates(); super.onCreate(); Toast.makeText(this, “service created”, Toast.LENGTH_SHORT).show(); }
public void onStartCommand(Intent intent, int startId) { // TODO Auto-generated method stub super.onStart(intent, startId); Toast.makeText(this, “service started”, Toast.LENGTH_SHORT).show(); }
@Override public void onDestroy() { // TODO Auto-generated method stub Toast.makeText(this, “service Destroyed”, Toast.LENGTH_SHORT).show(); super.onDestroy(); }
public void onLocationChanged(Location loc) {
Log.d(TAG, loc.toString());
}
public void onProviderEnabled(String s){
}
public void onProviderDisabled(String s){
}
public void onStatusChanged(String s, int i, Bundle b){
}
public void subscribeToLocationUpdates() {
this.lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
this.lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); } }
is the manifest file. I ran emulator once and restarted using emulator -avd testdevice command
when the emulator opened second time it said force close error.
I din’t know where I am making a mistake. Kindly post me back.
I am using Android 2.2 SDK
02 March 2011, at 12:41 am
I have done it for invoking a service Broadcast receiver code: package com.service;
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent;
public abstract class BootReceiver extends BroadcastReceiver{ @Override
public void onReceive(Context context,Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Intent i = new Intent();
i.setAction(“com.service.LocationService”);
context.startService(i);
}
} }
Service code package com.service;
import android.app.Service; import android.content.Context; import android.content.Intent; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.widget.Toast;
public class LocationService extends Service implements LocationListener {
private final static String TAG = “LocationLoggerService”; LocationManager lm;
public LocationService() { }
@Override public IBinder onBind(Intent intent) { return null; }
public void onCreate(Intent intent, int startId) { subscribeToLocationUpdates(); super.onCreate(); Toast.makeText(this, “service created”, Toast.LENGTH_SHORT).show(); }
public void onStartCommand(Intent intent, int startId) { // TODO Auto-generated method stub super.onStart(intent, startId); Toast.makeText(this, “service started”, Toast.LENGTH_SHORT).show(); }
@Override public void onDestroy() { // TODO Auto-generated method stub Toast.makeText(this, “service Destroyed”, Toast.LENGTH_SHORT).show(); super.onDestroy(); }
public void onLocationChanged(Location loc) {
Log.d(TAG, loc.toString());
}
public void onProviderEnabled(String s){
}
public void onProviderDisabled(String s){
}
public void onStatusChanged(String s, int i, Bundle b){
}
public void subscribeToLocationUpdates() {
this.lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
this.lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); } }
is the manifest file. I ran emulator once and restarted using emulator -avd testdevice command
when the emulator opened second time it said force close error.
I din’t know where I am making a mistake. Kindly post me back.
I am using Android 2.2 SDK
02 March 2011, at 01:18 am
When i restarted my emulator the error stated is Force close and when browsed i found force close error will occur when we try to reload on apk that is already available.
It’s contradicting..
Kindly provide me with a solution
25 March 2011, at 09:09 am
[...] die auf Phoneboot reagiert und den Service startet. Ich habe folgenden Tutorial zu Hilfe genommen: Starting an Android Service at Device Boot — Greg Fiumara So weit, so gut. 4) Jetzt kommt der schwierige Teil: StartAtBookServiceReceiver.class soll nur [...]
23 May 2011, at 02:06 pm
[...] Here is a tutorial on how to get the functionality of a service starting at device boot: http://blog.gregfiumara.com/archives/82 [...]
20 November 2011, at 01:29 am
where to start a new thread say some task or say counter like any thing in this app
Post a Comment!
Your email is never published or shared. Required fields are marked *