Service applications in Android, part 1

Download the source code of this article.

A service application in Android is an application that runs in background. Service applications does not have user interface. Service application runs in the background and performs some long-running tasks such as playing an audio file, download files from internet, etc. A Service application can also be used to extend the functionality of a normal application. For example a download manager may accept download requests from the user and send it to a service which actually performs the download. An application can use Context.startService() and Context.stopService() to start and stop a service.

Service lifecycle

When an application calls Context.startService(), the system first call the Service.onCreate() method, then call the Service.onStartCommand() method. At this point the service is running. When the application calls Context.stopService() method, the system calls the Service.onDestry() method. This is true in case of Android 2.0 or above. In Android version prior to 2.0, there is no onStartCommand() method, the system will call Service.onStart() instead. If the service is already running the system will not call Service.onCreate() method in both cases. In all version when the service is destroyed, the system will call Service.onDestroy() method.

A service can also be started by using Context.bindService() method. Binding is used by an application to communicate with the service. In this case system will first call Service.onCreate() method and then call the Service.onBind() method. Note that if binding is used the system will not call the Service.onStartCommand() or Service.onStart() method. For this part of the article let’s forget about the binding and concentrate on the Context.startService().  I will explain the binding in the next part of the article.

Creating a service

A service application can be created by extending the Service class. Following code snippet creates a service:

public class GPSLoggerService extends Service
{
	public GPSLoggerService() {
		AppLog.logString("GPSLoggerService.GPSLoggerService().");
	}

	@Override
	public IBinder onBind(Intent intent) {
		AppLog.logString("GPSLoggerService.onBind().");

		return null;
	}

	@Override
	public void onCreate() {
		AppLog.logString("GPSLoggerService.onCreate().");

		super.onCreate();
	}

	@Override
	public void onStart(Intent intent, int startId) {
		AppLog.logString("GPSLoggerService.onStart().");

		super.onStart(intent, startId);
	}

	public int onStartCommand(Intent intent, int flags, int startId) {
		AppLog.logString("GPSLoggerService.onStartCommand().");

		return Service.START_STICKY;
	}
}

This creates a service called GPSLoggerService (from sample application).  Note that from onBind() method we are returning null because we are not using binding in this example.

The Service.onStart() is called for pre 2.0 versions. There are two arguments for this method, first one the intent supplied to start the service and second one is a unique identifier to represent this specific request. In most cases we need only the Intent parameter. The Intent parameter can be null in case of restarting a service by the system. This normally happens after the service is crashed in the middle or after the system kills the service to make more memory (this happens very rarely because the system gives more priority the service than the normal applications). If the intent parameter is not null we can use it to get some data (if any) that may have passed when starting the service. The onStart() method does not return any values.

The Service.onStartCommand() is called for 2.0 or later. There is one additional parameter flags, this can either be 0, START_FLAG_REDELIVERY or START_FLAG_RETRY. This parameter is rarely used, for more information about these flags please follow this link. The onStartCommand() method returns and integer value. This can be Service.START_STICKY, Service.START_NOT_STICKY, Service.START_STICKY_COMPATIBILITY, etc. Normally a service returns Service.START_STICKY and this means that the service will be restarted if it is killed before returning from Service.onStartCommand(). For a more explanation of return commands from service please follow this link.

You may have noticed for the onStartCommand() method, I haven’t used @Override, this is because I want to make this service compatible to Android versions prior to 2.0. In Android versions prior to 2.0 there is no Service.onStartCommand() method. So if you use @Override and run it on Android 2.0 or below, it will result in application crash. So please not this point while you are creating a server targeted for all version including below 2.0. If you are targeting only 2.0 or above you can use safely use @Override.

Declaring service in AndroidManifest.xml file

To use the service you have to specify the service in your AndroidManifest.xml file otherwise the system will not recognize the service. Following snippet declares the GPSLoggerService in the manifest file.

<service android:name="com.varma.samples.gpslogger.service.GPSLoggerService"/>

Starting a service

To start a service we can use Context.startService() passing Intent of the service. Following code snippet start the GPSLoggerService.

Intent intent = new Intent(context, GPSLoggerService.class);

context.startService(intent);

If you want to pass some data to the service, you can use the intent data and from the service we can retrieve this data using Bundle.

Stopping a service

To stop a service from an application, we can use Context.stopService() method by passing the service intent. Following code snippet stops the GPSLoggingService.

Intent intent = new Intent(context, GPSLoggerService.class);

context.stopService(intent);

To stop the service from the service itself, we can use the Service.stopSelf() method. This will stop the calling service.

Sample application

The sample application of this article is GPS Logger application, it logs the GPS coordinates of the device in specified interval of time. There are two components in this application, service component and the normal application. Some screenshots of the application is given below:

gpslogger

application screen

gpslogger-intervalsetting logging interval

When the ‘Start Logging’ button is clicked, an alarm is set using AlarmManager. AlarmManager.setRepeating() method is used to set repeating alarm with the specified interval. By default the application will use 5 minutes for the logging interval.

In the service component when started LocationManager is initialized and requests for the location updates. Once the location is received, the coordinates are written to a KML file in “/sdcard/gpslogger” folder. Before writing to the file, a reverse geocoding is performed to retrieve the name of the location. For more information about using GPS in Android refer to my article about using GPS in Android and for geocoding and reverse geocoding refer to my article about geocoding.

Happy GPS logging! Smile

12 Comments

Add yours →

  1. Please provide some comparision between IntentService and Service classes in Android.

    Please provide some comparison about other classes in the same package related to your articles. Because i am struggling while learning Android API some causes. If you are giving like that, I will be lucky.

  2. Thank you so much.

  3. This article is really good.
    But if you can explain more on the SD card storage it would be of great help.
    Where to store sdcard/gpslogger??

  4. Thanks for the article, very nice! I’m trying to understand the
    source code a little more. Can you please explain why you
    have two different timers (scheduleAtFixedRate called in GPSLoggerService.java and setRepeating called in MainActivity.java).

  5. Is it possible to have a service continuously take pictures in the background without a surfaceview ? EG: with or without a startpreview (which I believe is a requirement) so a preview has to occur somewhere not visible ?

  6. Hello,

    It is really very helpful blog and this is indeed very nice article. Can you please let me know where is the /sdcard/gpslogger folder located. I am checking SD card folder under files section of my android and it is empty.
    Do we need to change something in the code ?

    Please help me on this.

    Thanks

    • Hello,

      In internal phone storage , GPSLogger folder is getting created , but there is no kml file inside .
      Can you please help me in this.

      Thanks.

  7. I have just install Gpslogger on my samsung galaxy s2 I9100 but it does not run, not Alarm warning, not long/lat Write to Kml files on SD card. Please check again. Thanks for helps.

  8. i have just installed Gpslogger on my samsung galaxy s2 I9100 but it does not run, not Alarm warning, not Gps log write to KML file on SD Card. Please check again, Thank for your helps.

  9. Hi, I installed GPS Logger in my Galaxy tab 10.1, it runs but I modify the interval time to every 30 seconds and every 15 seconds, In both cases sometimes the Service crash. Viewn the LogCat it said “Android Runtime Error at … line…167” and if I go to this line is this: monitoringTimer.cancel();
    Complete context of the code:
    monitoringTimer = new Timer();

    try{
    monitoringTimer.scheduleAtFixedRate(
    new TimerTask()
    {
    @Override
    public void run()
    {
    if (longitude != 0.0 && latitude != 0.0)
    {
    monitoringTimer.cancel(); //LINE WHEN SERVICE CRASH
    monitoringTimer = null;

    What is the cause of this runtime Error ?. Could you help me.

    Thanks

  10. Hello,
    I ran your application on my device but it dosen’t created any file in the specified location.
    Please guide me how to solve this.

    Thanks

Leave a Reply