tags:

views:

426

answers:

2

Hi

I am in the process of creating an app that is similar to the build-in SMS app.

What I need:
- a service that is always running in the background
- every 5 min. the service checks the current location of the device and calls a web service
- if certain criteria are meet, the service should generate a notification (just like the SMS app)
- when the notification is clicked, the user is taken to the app (just like the SMS app)
- when the app is installed the service should be started
- when the device is rebooted, the service should be started

What I have tried:
- running a regular service which worked just fine until android kills the service
- using the AlarmManager the make the 5 min. interval call to a service. But I was not able to make this work.

Any help would be greatly appreciated...

-Thomas

+2  A: 

One of my apps does something very similar. To wake the service after a given period I recommend postDelayed()

Have a handler field:

private final Handler handler = new Handler();

and a refresher Runnable

private final Runnable refresher = new Runnable() {
  public void run() {
    // some action
  }
};

You can fire your Notifications in the runnable.

On service construction, and after each execution start it like so:

handler.postDelayed(refresher, /* some delay in ms*/);

In onDestroy() remove the post

handler.removeCallbacks(refresher);

To start the service at boot time you need an auto starter. This goes in your manifest

<receiver android:name="com.example.ServiceAutoStarter">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
  </receiver>

and the ServiceAutoStarter looks like this:

public class ServiceAutoStarter extends BroadcastReceiver {
  @Override
  public void onReceive(Context context, Intent intent) {
    context.startService(new Intent(context, UpdateService.class));
  }
}

Stopping the OS from killing the service is tricky. Also your application can have a RuntimeException and crash, or your logic can stall.

In my case it seemed to help to always refresh the service on screen on with a BroadcastReceiver. So if the chain of updates gets stalled it will be resurrected as the user uses their phone.

In the service:

private BroadcastReceiver screenOnReceiver; 

In your service onCreate()

screenOnReceiver = new BroadcastReceiver() {

  @Override
  public void onReceive(Context context, Intent intent) {
    // Some action
  }
};

registerReceiver(screenOnReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));

Then unregister your service on onDestroy() with

unregisterReceiver(screenOnReceiver);
Jim Blackler
I usually like your answers, but this one...not so much. :-( For example, you are proposing that the service register a receiver to resurrect itself once killed. The receiver will be killed along with the service; hence, this should have no effect. Moreover, the whole concept of an everlasting service is awful on Android and is the reason users are fighting back with task killers or the Running Services screen in the Settings app. There are very few cases where a truly everlasting service is needed -- the vast majority of the time, `AlarmManager` will suffice.
CommonsWare
Thanks CWare, I should probably have made it clearer the resurrector is to protect against logic failure and the many things that can stall the chain of events that wake the service, as what is attributed to system shutting down the service can often be something else. I will look into the alarm manager approach, I vaguely recall trying this some time ago and not being able to get it to work.
Jim Blackler
+3  A: 

a service that is always running in the background

This is not possible in any real sense of the term, as you have discovered. It is also bad design.

every 5 min. the service checks the current location of the device and calls a web service

Use AlarmManager.

using the AlarmManager the make the 5 min. interval call to a service. But I was not able to make this work.

Here is a sample project showing how to use one, along with the use of WakefulIntentService so you stay awake while trying to do the whole Web service thing.

If you have continued problems with it, open up a new question about the specific things you are encountering with AlarmManager that are giving you grief.

CommonsWare