How to Start on Boot


In porting S60 and Windows Mobile applications to Android, I have found a common requirement is to start a service on boot. This is used for applications that sit in background and listen and react to phone events. In this post I give a summary how to do this on Android and some tips when not to use this method.

Inherit your class from BroadcastReceiver and provide an onReceive(). Instantiate an Intent and use the call Context.startService(). The Android OS source for IM com.android.im.receiver.ImServiceAutoStarter provides an example how to do this…

public class ImServiceAutoStarter extends BroadcastReceiver {
    static final String TAG = "ImServiceAutoStarter";

    @Override
    public void onReceive(Context context, Intent intent) {
        // Received intent only when the system boot is completed
        Log.d(TAG, "onReceiveIntent");

        String selection = Im.Account.KEEP_SIGNED_IN + "=1 AND "
                + Im.Account.ACTIVE + "=1";
        Cursor cursor = context.getContentResolver().query(Im.Account.CONTENT_URI,
                new String[]{Im.Account._ID}, selection, null, null);
        if (cursor != null) {
            if (cursor.getCount() > 0) {
                Log.d(TAG, "start service");
                Intent serviceIntent = new Intent();
                serviceIntent.setComponent(ImServiceConstants.IM_SERVICE_COMPONENT);
                serviceIntent.putExtra(ImServiceConstants.EXTRA_CHECK_AUTO_LOGIN, true);
                context.startService(serviceIntent);
            }
            cursor.close();
        }
    }

You must also have something like the following in your manifest…

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name=".receiver.ImServiceAutoStarter"
            android:process="android.process.im">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

The ImServiceConstants.IM_SERVICE_COMPONENT is defined as com.android.im.service.RemoteImService in…

public class ImServiceConstants {
    /**
     * RemoteImService name, used for start or stop the IM service.
     */
    public static final ComponentName IM_SERVICE_COMPONENT = new ComponentName(
            "com.android.im",
            "com.android.im.service.RemoteImService");

The service itself is written by inheriting from Service…

public class RemoteImService extends Service {

Provide onCreate() and onDestroy() methods that are used when the service is started and stopped.

You must also define the service it its manifest…

        <service android:name=".service.RemoteImService"
            android:process="android.process.im"
            android:exported="true"
            android:permission="com.android.im.permission.IM_SERVICE">
            <intent-filter>
                <action android:name="com.android.im.IRemoteImService" />
                <action android:name="com.android.im.SERVICE" />
            </intent-filter>
        </service>

As I mentioned, the above is suitable for long running applications that have to sit in the background and listen and react to phone events. For ‘real’ services that provide functionality for zero or more activities, it’s better to use bindService() rather than startService() because the application manager is free to destroy the service, to save resources, when it isn’t being used. There’s a great example on bindService() at My life with Android.

An Android service can actually be both a background application and provide functionality for activities. In this case there’s only one service instance.

Comments are closed.