Starting an Android service after boot

 
After some consideration we decided that we should have a post about adding a regular Android service at boot and not just consider the cases where you have to modify the platform itself.

Simple boot service example

The key to this is the broadcast action android.intent.action.BOOT_COMPLETED that is sent out once the platform boot is complete. To perform an action on boot you need to include a broadcast receiver in your application that registers for this intent. The rest of the implementation follows the standard design for Android services and applications.
I have a small example that adds an Android service to perform a similar task as the native service that we had in the blog post about the init process. The service will start up at boot and then write something to the log at regular intervals. The first part we need is the broadcast receiver to take care of the boot intent:
package com.enea.training.bootdemo;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

/**
 * Simple receiver that will handle the boot completed intent and send the intent to 
 * launch the BootDemoService.
 * @author BMB
 *
 */
public class BootDemoReceiver extends BroadcastReceiver {
 @Override
 public void onReceive(final Context context, final Intent bootintent) {
  Intent mServiceIntent = new Intent();
mServiceIntent.setAction("com.enea.training.bootdemo.BootDemoService");
  context.startService(mServiceIntent);
 }
}
This component is basic and it will just create an intent to start our background service when it receives the boot completed intent.

The service will create a Timer task to write to the log at a preset interval. Once it is started the timer task will be registered and the service will keep running in the background.
package com.enea.training.bootdemo;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

/**
 * Simple demo service that schedules a timer task to write something to 
 * the log at regular intervals.
 * @author BMB
 *
 */
public class BootDemoService extends Service {
 /**
  * Delay until first exeution of the Log task.
  */
 private final long mDelay = 0;
 /**
  * Period of the Log task.
  */
 private final long mPeriod = 500;
 /**
  * Log tag for this service.
  */ 
 private final String LOGTAG = "BootDemoService";
 /**
  * Timer to schedule the service.
  */
 private Timer mTimer;
 
 /**
  * Implementation of the timer task.
  */
 private class LogTask extends TimerTask {
  public void run() {
   Log.i(LOGTAG, "scheduled");
  }
 }
 private LogTask mLogTask; 
 
 @Override
 public IBinder onBind(final Intent intent) {
  return null;
 }
 
 @Override
 public void onCreate() {
  super.onCreate();
  Log.i(LOGTAG, "created");
  mTimer = new Timer();
  mLogTask = new LogTask();
 }
 
 @Override
 public void onStart(final Intent intent, final int startId) {
  super.onStart(intent, startId);
  Log.i(LOGTAG, "started");
  mTimer.schedule(mLogTask, mDelay, mPeriod);
 }
}
There is one more important thing to consider for this simple demo application and that is to add the correct intent-filters to the Android.xml file. We need to register for the BOOT_COMPLETED intent but also for the intent that will start the actual service.
< ?xml version="1.0" encoding="utf-8"?>
< manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.enea.oresund.training.bootdemo"
      android:versionCode="1"
      android:versionName="1.0">
      < uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    < application android:icon="@drawable/icon" android:label="@string/app_name">
       < service android:name=".BootDemoService">
       < intent-filter>
       < action
       android:name = "com.enea.training.bootdemo.BootDemoService">
       < /action>
       < /intent-filter>
       < /service>
       < receiver android:name=".BootDemoReceiver">
       < intent-filter>
       < action
       android:name ="android.intent.action.BOOT_COMPLETED">
       < /action>
       < /intent-filter>
       < /receiver>
    < /application>
    < uses-sdk android:minSdkVersion="3" />
< /manifest> 

Summary - adding functionality at startup

With this post I think that we have covered the alternatives for adding functionality at some point during the boot process. To sum things up there is three possible places to do something like this:
  1. Modifying the init.rc script for native services
  2. Modifying the system server to include a separate thread
  3. Writing a standard Android service and register to launch it through the BOOT_COMPLETED intent
There may be other tricks you could use but they are more far-fetched. Unless you are building your own hardware or playing with the open source project for fun the third alternative is the only possible option. This is useful to register alarms or maybe an IM-client running in the background. 
I would however like to add a word of caution since running services in the background will take some resources from the system. Think carefully about if you really need to automatically launch your service every time the system has booted up. It may be better to let the user choose when to start your application in order to save some system resources.
arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()