How to use services in Android for background tasks Android 21.10.2016

Introduction to services

Android Services are processes that run in the background and do not have a user interface. They can be started and subsequently managed from Activities, Broadcast Receivers or other Services. Android Services are ideal for situations where an application needs to continue performing tasks but does not necessarily need a user interface to be visible to the user. Although Services lack a user interface, they can still notify the user of events through the use of notifications and toasts and are also able to issue Intents.

Android service is used to perform tasks in the background without user interaction. Android service by default runs in the main UI thread. If you have background task that takes long time to complete, it is better to create a thread within the service to perform long running tasks so that user operations are not blocked.

AsyncTasks provide a reasonable solution for noncritical background tasks (on behalf of the UI) that are completed in under one or two seconds. Broadcast Receivers are intended to perform a task quickly and then exit. Services are designed to perform tasks that take a long time to complete (such as downloading a file over an internet connection or streaming music to the user) but do not require a user interface.

Services are given a higher priority by the Android runtime than many other processes and will only be terminated as a last resort by the system in order to free up resources.

Using a Service we can implement multitask in Android. Example situations where a Service might be a practical solution include:

  • Implement multi-task (downloads of file, perform non-user input requiring I/O operations like backup, etc.)
  • Enable Inter-Process-Communication (IPC) (handle network transactions, play audio/music in background, etc.)

Remember that a service is not bound to the Activity and cannot modify views within the UI directly. Instead, a service tends to have very specific outputs after running that are not directly associated with the UI. The outputs created by services are notifications (creates a dashboard notification to alert the user), broadcasts (triggers a broadcast message to be received), SQLite (write data received into the local database), files (cache blob data such as images or json to file), shared preferences (save key-values to shared preferences).

There are different types of services

  • Started services
  • Intent services
  • Bound services

Started services are launched by other application components (such as an activity or even a broadcast receiver) and potentially run indefinitely in the background until the service is stopped, or is destroyed by the Android runtime system in order to free up resources. A service will continue to run if the application that started it is no longer in the foreground, and even in the event that the component that originally started the service is destroyed.

Started service runs in the background until it is stopped and doesn’t return results to the caller.

By default, a service will run within the same main thread as the application process from which it was launched. It is important that any CPU intensive tasks be performed in a new thread within the service.

Started services are launched via a call to the startService() method, passing through as an argument an Intent object identifying the service to be started. When a started service has completed its tasks, it should stop itself via a call to stopSelf(). Alternatively, a running service may be stopped by another component via a call to the stopService() method, passing through as an argument the matching Intent for the service to be stopped.

Services are given a high priority by the Android system and are typically amongst the last to be terminated in order to free up resources.

The IntentService class is a convenience class (subclassed from the Service class) that sets up a worker thread for handling background tasks and handles each request in an asynchronous manner. Once the service has handled all queued requests, it simply exits. All that is required when using the IntentService class is that the onHandleIntent() method be implemented containing the code to be executed for each request.

For services that do not require synchronous processing of requests, IntentService is the recommended option.

A bound service is similar to a started service with the exception that a started service does not generally return results or permit interaction with the component that launched it. A bound service, on the other hand, allows the launching component to interact with, and receive results from, the service.

Bound service allows callers to interact with it using the provided client-server interface. Bound service stops when all clients are unbind.

There are two points to keep in mind. First, the duration of a bound service is the same as the Android component to which it is bound. Second, the bound service destroys itself as soon as it is unbound from its Android component.

A component (also referred to in this context as a client) starts and binds to a bound service via a call to the bindService() method and multiple components may bind to a service simultaneously. When the service binding is no longer required by a client, a call should be made to the unbindService() method. When the last bound client unbinds from a service, the service will be terminated by the Android runtime system. It is important to keep in mind that a bound service may also be started via call to startService(). Once started, components may then bind to it via bindService() calls. When a bound service is launched via a call to startService() it will continue to run even after the last client unbinds from it.

A bound service must include an implementation of the onBind() method which is called both when the service is initially created and when other clients subsequently bind to the running service.

Local and Remote Service

Components (activities, broadcast receivers or other services) start a Service through intents. These components are also referred to as client components sometimes. Now this invocation can happen in three ways:

  • Local Service – both the component and service of the application runs in the same process.
  • Private Remote Service – the service runs in a different process from the component but only accessible to components that belongs to only that particular application.
  • Global Remote Service – pretty much similar to Private Remote Services but also accessible to other applications, not through the class name (as they won’t know it) but through Intent Filters.

Life cycle of a Service

A service has life cycle callback methods that you can implement to monitor changes in the service's state and you can perform work at the appropriate stage. The following diagram on the left shows the life cycle when the service is created with startService() and the diagram on the right shows the life cycle when the service is created with bindService()

Android activity life cycle

A service must be created as a subclass of the Android Service class. As part of the subclassing procedure, one or more of the following superclass callback methods must be overridden, depending on the exact nature of the service being created:

  • onStartCommand() method is called when the service is started by another component via a call to the startService() method. This method does not need to be implemented for bound services.
  • onBind() methid is called when a component binds to the service via a call to the bindService() method. When implementing a bound service, this method must return an IBinder object facilitating communication with the client. In the case of started services, this method must be implemented to return a NULL value.
  • onCreate() method is a location to perform initialization tasks, this method is called immediately before the call to either onStartCommand() or the first call to the onBind() method.
  • onDestroy() method is called when the service is being destroyed.
  • onHandleIntent() method is applies only to IntentService subclasses. This method is called to handle the processing for the service. It is executed in a separate thread from the main application.

An android Service can be started from an Activity, from a Broadcast receiver and other services too. To start a service, startService() or bindService() need to be called. Starting a service with startService() creates started service meaning it runs until stopSelf() or stopService() method is called. Starting a service with bindService() creates bound service and it returns client-server interface for clients to interact with the service.

In order for a service to be useable, it must first be declared within a manifest file. This involves embedding an appropriately configured <service> element into an existing <application> entry. At a minimum, the <service> element must contain a property declaring the class name of the service.

<application ...>
    <activity...></activity>
    <service android:name=".MyService></service>
</application>

By default, services are declared as public, in that they can be accessed by components outside of the application package in which they reside. In order to make a service private, the android:exported property must be declared as false within the <service> element of the manifest file. For example:

<service 
    android:name=".MyService"
    android:exported="false">
    </service>

As previously discussed, services run within the same process as the calling component by default. In order to force a service to run within its own process, add an android:process property to the <service> element, declaring aname for the process prefixed with a colon (:):

<service 
    android:name=".MyService"
    android:exported="false"
    android:process=":myprocess">
</service>

The colon prefix indicates that the new process is private to the local application. If the process name begins with a lower case letter instead of a colon, however, the process will be global and available for use by other components.

Example of started service

Started services are those that are launched by other application components like an Activity or a Broadcast Receiver. They can run indefinitely in the background until stopped or destroyed by the system to free up resources.

We are going to create a custom service. Right-click the /src/java/ folder on the Project Explorer and select New -> Service -> Service. Leave the default values unchanged and click Finish to create the Service class.

We will implement the other callbacks. We will also add logging to understand the order of the calls.

public class MyService extends Service {
   public MyService() {}

   @Override
   public IBinder onBind(Intent intent) {
      Log.d(TAG, "onBind callback called");
      throw new UnsupportedOperationException("Not yet implemented");
   }

   @Override
   public int onStartCommand(Intent intent, int flags, int startId) {
      Log.d(TAG, "onStartCommand callback called");
      return super.onStartCommand(intent, flags, startId);
   }

   @Override
   public void onCreate() {
      super.onCreate();
      Log.d(TAG, "onCreate callback called");
   }

   @Override
   public void onDestroy() {
      super.onDestroy();
      Log.d(TAG, "onDestroy callback called");
   }
}

In its onStartCommand() method call, the service returns an int which defines its restart behavior in case the service gets terminated by the Android platform. You can use the constants, the most common options are described by the following table.

  • Service.START_STICKY. Service is restarted if it gets terminated. Intent data passed to the onStartCommand method is null. Used for services which manages their own state and do not depend on the Intent data.
  • Service.START_NOT_STICKY. Service is not restarted. Used for services which are periodically triggered anyway. The service is only restarted if the runtime has pending startService() calls since the service termination.
  • Service.START_REDELIVER_INTENT. Similar to Service.START_STICKY but the original Intent is re-delivered to the onStartCommand method.

If our task is hard for UI thread we can create new thread via following snippet. Always write your long running tasks in a separate thread, to avoid ANR.

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d(TAG, "onStartCommand callback called");
    new Thread(new Runnable() {
        @Override
        public void run() {
            // your logic that service will perform will be placed here

            // stop service once it finishes its task
            // stopSelf();
        }
    }).start();

    return super.onStartCommand(intent, flags, startId);
}

Finally, we will add a couple of buttons on MainActivity. When the user clicks the buttons, we will invoke the services we have created above.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_service"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="me.proft.sandbox.ServiceActivity">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:orientation="horizontal"
        android:weightSum="2">

        <Button
            android:id="@+id/btnStart"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Start"
            android:onClick="startMyService" />

        <Button
            android:id="@+id/btnUpdate"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Stop"
            android:onClick="stopMyService" />
    </LinearLayout>
</RelativeLayout>

Now that we’re set with our service, it’s time to see how to trigger its execution. Here’s how a service is started:

public class ServiceActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_service);
    }

    void startMyService (View v ) {
        Intent i = new Intent(this, MyService.class);
        startService(i);
    }


    void stopMyService (View v ) {
        Intent i = new Intent(this, MyService.class);
        stopService(i);
    }
}

If the service is not yet running, then startService() triggers the onCreate() method of the service first. Once the service is started (or it is already running), then the onStartCommand() is called with the Intent object passed to startService(). Calls to startService() are non-blocking even if some processing has to be done in the Service class.

If you want to stop the service, then just call stopService() once:

// create the same explicit Intent
Intent i = new Intent(this, MyService.class);
// stop the service
stopService(i);

The service can also stop itself by calling stopSelf() when it finishes its work.

Example of intent service

As mentioned before a started service runs on the main thread, so we have to be very careful when we implement some logic in this service. We have to consider that if this logic is a blocking operation or it requires long time to finish a ANR problem could occur. In this case we have to move our logic to a separate thread, meaning we have to create a thread in onStartCommand method and run it.

There is another class called IntentService derived from Service that simplify our life. This class is useful when we don’t need to handle multiple requests at the same time. This class creates a worker thread to handle different requests.

Each intent is added to the IntentService’s queue and handled sequentially. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work. This "work queue processor" pattern is commonly used to offload tasks from an application's main thread.

This class performs this operation:

  • Create a separate thread to handle the request.
  • Create a request queue and pass one Intent at time.
  • Create a default implementation of onStartCommand.
  • Stop the service when all the requests are processed.

A few limitations of an IntentService to be aware of:

  • You cannot affect the user interface from this background service directly.
  • Requests are handled on a single worker thread and processes just one request at a time.
  • You cannot easily cancel an intent service once you start one.

If we want to create a IntentService we have to extend IntentService class instead of Service. In this case, we have only one method to implement called onHandleIntent. Here we implement out logic without caring if this is operation requires long time or not, because this method is called in a separate thread.

Let’s just simulate a long action that takes 10 seconds

public class LongTaskIntentService extends IntentService {
    public LongTaskIntentService() {
        super("LongTaskIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
       showToast("Starting long task ...");
       try {
           Thread.sleep(10000);
       } catch (InterruptedException e) {
           Thread.currentThread().interrupt();
       }
       showToast("Long task finished");
    }

    protected void showToast(final String msg){
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                // run this code in the main thread
                Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
            }
        });
    }
}

The service may not be running in the same UI context, so to show the toast (interact with the Android UI) we may need to run it on the same UI thread. We do it in the showToast method.

Android IntentService using BroadcastReceiver

BroadcastReceivers are used to transfer messages across applications or between a service and an activity. To transfer data between a service and an activity we need to use a LocalBroadcastManager. LocalBroadcastManager class comes with the support library and is used to transfer data locally only. You cannot transfer data outside the application.

In the following section, we’ll create an application that passes a string to the IntentService which returns it to the Activity. Thanks to IntentService, this happens sequentially.

Following is a code for MainActivity.

public class MainActivity extends AppCompatActivity {
    MyReceiver myReceiver;
    public static final String ACTION_KEY = "ACTION_KEY";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void btnClick(View v) {
        Intent intent = new Intent(MainActivity.this, MyIntentService.class);
        intent.putExtra("data", "boo");
        startService(intent);
    }

    private void setReceiver() {
        myReceiver = new MyReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ACTION_KEY);
        LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, intentFilter);
    }

    @Override
    protected void onStart() {
        setReceiver();
        super.onStart();
    }

    @Override
    protected void onStop() {
        unregisterReceiver(myReceiver);
        super.onStop();
    }

    private class MyReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String message = intent.getStringExtra("broadcastMessage");
            Log.d(TAG, "onReceiveResult: " + message);
        }
    }
}

Following is a code for MyIntentService.

public class MyIntentService extends IntentService {
    public MyIntentService() {
        super(MyIntentService.class.getName());
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        String data = intent.getStringExtra("data");

        LocalBroadcastManager.getInstance(getApplicationContext())
            .sendBroadcast(intent.putExtra("broadcastMessage", "OK"));
    }
}

Android IntentService using ResultReceiver

Android ResultReceiver is used to receive callback results from someone. It’s different from a BroadcastReceiver. A BroadcastReceiver receives all kinds of messages. It can receive messages from outside the activity too.

A ResultReceiver is specifically used for receiving messages internal to the application. It then can check the result type from the list of result types defined in it. Based on that it can forward the information to the Activity.

The IntentService can use the send method to pass on the data to the ResultReceiver. The ResultReceiver has the onReceiveResult callback method which gets called whenever a new result is received. Based on the result code in the onReceiveResult, it performs the action.

In the following section we’ll be creating an application in which we return string from IntentService and then send the results to the ResultReceiver where based on the result code (type) we’ll do the necessary action.

Do not forget to set the service in the Manifest file.

Following is a code for MainActivity.

public class MainActivity extends AppCompatActivity {
    MyResultReceiver resultReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        resultReceiver = new MyResultReceiver(new Handler());
    }

    public void btnClick(View v) {
        Intent startIntent = new Intent(MainActivity.this,
                MyIntentService.class);
        startIntent.putExtra("receiver", resultReceiver);
        startIntent.putExtra("data", "boo");
        startService(startIntent);
    }

    private class MyResultReceiver extends ResultReceiver {
        public MyResultReceiver(Handler handler) {
            super(handler);
        }

        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            switch (resultCode) {
                case MyIntentService.RESULT_ERROR:
                    Toast.makeText(getApplicationContext(), "Error in Downloading",
                            Toast.LENGTH_SHORT).show();
                    break;

                case MyIntentService.RESULT_SUCCESS:
                    String data = resultData.getString("result");
                    Log.d(TAG, "onReceiveResult: " + data);
                    break;
            }
            super.onReceiveResult(resultCode, resultData);
        }

    }
}

Following is a code for MyIntentService.

public class MyIntentService extends IntentService {

    public static final int RESULT_SUCCESS = 2;
    public static final int RESULT_ERROR = 3;

    public MyIntentService() {
        super(MyIntentService.class.getName());
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        String data = intent.getStringExtra("data");
        final ResultReceiver receiver = intent.getParcelableExtra("receiver");
        Bundle bundle = new Bundle();

        try {
            bundle.putString("result", "OK");
            receiver.send(RESULT_SUCCESS, bundle);
        } catch (Exception e) {
            receiver.send(RESULT_ERROR, Bundle.EMPTY);
            e.printStackTrace();
        }
    }
}

Example of bound service

Started services cannot return results/values or interact with its starting component. Bound services on the other hand can send data to the launching component (client). So for example a bound service might be playing an audio file and sending data regarding audio start/pause/stop and the time elapsed to the launching Activity component so that the UI can be updated accordingly.

So the client component starts the bound Service and binds to it. Multiple components can bind to the service simultaneously. Obviously when the client is done, it can unbind. When the last bound client unbinds, the runtime will terminate the service. Internally, the Service keeps a reference counter holding the number of bound components which on decrementing to 0 triggers the destruction of the Service.

Binding is done using the Context.bindService() method whereas it is terminated with Context.unbindService(). The binding is also destroyed if the client component’s lifecycle ends.

When a client component binds to a bound service it retrieves a communication interface for sending requests and receiving responses within the process or even across processes. It returns an IBinder interface implementation from its onBind() method through the ServiceConnection interface supplied by the binding client component when invoking bindService(). This IBinder is used as the communication channel by the bound component. The component invokes methods of the communication interface and the execution happens in the Service.

Here’s a sample service to which our component will bind to:

public class TestBoundService extends Service {
    private String TAG = "TestBoundService";
    private IBinder myBinder = new MyBinder();

    public TestBoundService() {}

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate called");
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind done");
        return myBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return false;
    }

    public class MyBinder extends Binder {
        TestBoundService getService() {
            return TestBoundService.this;
        }
    }

    // Methods used by the binding client components

    public String methodOne() {
        return "methodOne";
    }

    public String methodTwo() {
        return "methodTwo";
    }
}

The onBind() method is called when the client component binds to the Service for the first time through bindService(). It returns an IBinder implementation that the client can use to interact with the Service by calling methods in the Service class. This IBinder implementation is basically a communication interface to send requests and receive responses either within a particular process or across processes. On the other hand, onUnbind() is called when all bindings are unbound.

The IBinder is returned to the client through a ServiceConnection interface that the client has to supply while binding. Let’s see how the binding is done from the client component:

Intent intent = new Intent(this, TestBoundService.class);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

So the Intent defines the Service to bind to and shouldn’t contain any other extra data. The binding client has to provide a ServiceConnection implementation which would look like this:

TestBoundService testBoundService;
boolean isBound = false;

private ServiceConnection serviceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        TestBoundService.MyBinder binder = (TestBoundService.MyBinder) service;
        testBoundService = binder.getService();
        isBound = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        testBoundService = null;
        isBound = false;
    }
};

This way the binding client gets notify when the binding is established or disconnected. The last argument (flags) passed to bindService() defines the operation options. These options can either determine the restart strategy on destruction of the Service or the rank of the Service’s process. For instance BIND_AUTO_CREATE is used commonly which recreates the Service if it is destroyed when there’s a bounding client.

The onServiceConnected() method will be called when the client binds successfully to the service. The method is passed as an argument the IBinder object returned by the onBind() method of the service. This argument is cast to an object of type TestBoundService and then the getService() method of the binder object is called to obtain a reference to the service instance, which, in turn, is assigned to testBoundService. A Boolean flag is used to indicate that the connection has been successfully established.

The onServiceDisconnected() method is called when the connection ends and simply sets the Boolean flag to false.

Now that you’ve the testBoundService object, you can call important methods like methodOne() and methodTwo() for the sake of communication and receive responses. Note this execution happens on the thread of the calling client. Hence if it’s the UI thread, long running operations should be prevented and a new Thread should be spawned to handle them in background in methodOne() and methodTwo().

Although multiple clients can bind to the service, the system calls your Service’s onBind() only once when the first client binds to retrieve the IBinder. The system then won’t call onBind() again when any additional clients bind. Instead it’ll deliver the same IBinder.

Let’s create an activity to bind this service and access this method inside the client.

public class MainActivity extends AppCompatActivity {
    TestBoundService boundService;
    private boolean isBind;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ((Button) findViewById(R.id.btnStart)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getServiceMessage();
            }
        });
    }

    private void getServiceMessage() {
        String str1 = boundService.methodOne();
        String str2 = boundService.methodTwo();
        Toast.makeText(MainActivity.this, str1 + " " + str2, Toast.LENGTH_LONG).show();
    }

    ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            TestBoundService.MyBinder binder = (TestBoundService.MyBinder) service;
            boundService = binder.getService();
            isBind = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            boundService = null;
            isBind = false;
        }
    };


    @Override
    protected void onSart() {
        super.onStart();
        Intent intent = new Intent(this, TestBoundService.class);
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (isBind) {
            unbindService(serviceConnection);
        }
    }
}

So there are two recommended mechanisms for implementing interaction between client components and a bound service:

  • Local Bound Service. In the event that the bound service is local and private to the same application as the client component (in other words it runs within the same process and is not available to components in other applications), the recommended method is to create a subclass of the Binder class and extend it to provide an interface to the service. An instance of this Binder object is then returned by the onBind() method and subsequently used by the client component to directly access methods and data held within the service.
  • Remote Bound Service. In situations where the bound service is not local to the application (in other words, it is running in a different process from the client component), interaction is best achieved using a Messenger/Handler implementation because the remote service is running in a different process and, as such, cannot be reached directly from the client. Specifically, the service creates a Handler instance that will be called when a message is received from the client. In terms of initialization, it is the job of the Handler to create a Messenger object which, in turn, creates an IBinder object to be returned to the client in the onBind() method. This IBinder object is used by the client to create an instance of the Messenger object and, subsequently, to send messages to the service handler. Each time a message is sent by the client, the handleMessage() method of the handler is called, passing through the message object.

Starting service automatically

Many times we want to start our service automatically, for example at boot time. We know to start a Service we need a component to start it. We could use a Broadcast receiver that starts our service. If for example, we want to start it at the smartphone boot time, we create first a Broadcast receiver that listens to this event and then it starts the service.

public class BootBroadcast extends BroadcastReceiver {
    @Override
    public void onReceive(Context ctx, Intent intent) {
        ctx.startService(new Intent(ctx, MyService.class));
    }
}

and in the Manifest.xml

<receiver android:name=".BootBroadcast">
  <intent-filter
     action android:name="android.intent.action.BOOT_COMPLETED"/>
  </intent-filter>
</receiver>

How to check if Service is running

public static boolean isMyServiceRunning(Class<?> serviceClass, Context context) {
    ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}

Usage

if (!isMyServiceRunning(LocationService.class, contex)) {
    Intent i = new Intent(context, LocationService.class);
    context.startService(i);
}

Useful links