Monday, September 7, 2009

Officially a competence center

There was an announcement today that the Android team here at Enea have now officially morphed into the Enea Android Competence Center. Based on this it seems fitting to add a more general post here. Currently we are engaged in some external projects which I can't say very much about except the info on the new and expanded Android section on Enea's web site. But there is also a lot of other activity in the team.

We have some application work going on where we aim to have something useful to share in a month or so. We also use that project to explore some areas around testing for Android and it is our intention to have some testing and application articles up here on the blog soon.

In the lower layers we have been working a lot with the platform framework, build system and start up as you may know if you have been following the blog. Currently we are moving into the areas of performance and security and plan some activities around that in the coming months. This will probably reflect on the blog as well.

During the summer we have been preparing flexible Android training with a focus on the platform level and that will be a part of what we offer in the competence center. There are some great people from the team that will lead these trainings. This does not mean that we will stop sharing things here on the blog. It is a way to offer some personal hands-on training for those of you who want to know more.

The blog will remain a place for mostly technical articles and discussion but now you know a little bit more about us and what we aim to discuss here in the coming months. The team is very happy with this change since it means that we are now an official part of Enea and will be able to keep working on fun projects for that very interesting mobile technology platform known as Android.

/Mattias

Tuesday, September 1, 2009

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.

/Mattias