Logo Icon Logo
A Crowd-sourced Cookbook on Writing Great Android® Apps
GitHub logo Twitter logo OReilly Book Cover Art

Keeping a Service Running While Other Apps Are on Display

Published? true
FormatLanguage: WikiFormat

Problem:

You want part of your application to continue running in the background while the user switches to interact with other apps.

Solution:

Create a Service class to do the background work; start the Service from your main application. Optionally provide a Notification icon to allow the user either to stop the running service or to resume the main application

Discussion:

A Service class (android.app.Service) runs as part of the same process as your main application, but has the property that it will keep running even if the user switches to another app or even goes to the Home screen and starts up a new app.

As you know by now, Activity classes can be started either by an Intent that matches their Content Provider, or by an intent that mentions them by class name. The same is true for Services. This recipe focuses on starting a service directly; a second recipe will cover starting a service implicitly. The example is taken from JpsTrack, a GPS tracking program for Android. Once you start tracking, you don't want the tracking to stop if you answer the phone or have to look at a map(!), so we made it into a Service. The service is started by the main Activity when you click the Start Tracking button, and stopped by the Stop button, Note that this is so common that startService() and stopService() are built into the Activity class.

    @Override
    public void onCreate(Bundle savedInstanceState) {
        ...
        Intent theIntent = new Intent(this, GpsService.class);
        Button startButton = (Button) findViewById(R.id.startButton);
        startButton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                        startService(theIntent);
                        Toast.makeText(Main.this, "Starting", Toast.LENGTH_LONG).show();
                }
        });
        Button stopButton = (Button) findViewById(R.id.stopButton);
        stopButton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                        stopService(theIntent);
                        Toast.makeText(Main.this, "Stopped", Toast.LENGTH_LONG).show();
                }
        });
        ...
    }

The GpsService class directly extends Service, so it has to implement the abstract onBind() method. This is not used when the class is started directly, so it can be a stub method. You will typically override at least the onStartCommand() and onUnbind() methods, to begin and end some activity. Our example starts the GPS service sending us notifications that we save to disk, and we do want that to keep running, hence this Service class.

public class TrackService extends Service {
        private LocationManager mgr;
        private String preferredProvider;

        @Override
        public IBinder onBind(Intent intent) {
                return null;
        }

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
                initGPS();      // sets up the LocationManager mgr

                if (preferredProvider != null) {
                        mgr.requestLocationUpdates(preferredProvider, MIN_SECONDS * 1000,
                                        MIN_METRES, this);
                        return START_STICKY;
                }
                return START_NOT_STICKY;
        }

        @Override
        public boolean onUnbind(Intent intent) {
                mgr.removeUpdates(this);
                return super.onUnbind(intent);
        }

You may have noticed the different return values from onStartCommand(). If you return START_STICKY, Android will restart your service if it gets terminated. If you return START_NOT_STICKY, the service will not get restarted automatically. These values are discussed in more detail in the online documentation for the Service class.