Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Use A Broadcast Receiver For Background Services In Android

TwitterFacebookRedditLinkedInHacker News

As an Android developer, you’ll often run into the scenario where you need to perform tasks and display notifications for your app in the background.

To retain battery power on our users device we are going to run background tasks using a broadcast receiver. This will prevent a thread from constantly running in the background draining the battery quickly over time. Instead, the task will be run on defined intervals of the alarm.

package com.nraboy.example;

import android.app.*;
import android.content.*;
import android.os.*;

public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent background = new Intent(context, BackgroundService.class);
        context.startService(background);
    }

}

The above code is our broadcast receiver. Every time it is called, our background service is executed.

So how do we enable our broadcast receiver to work on Android’s alarm service? That is easy, and can be seen in the following chunk of code:

package com.nraboy.example;

import android.app.Activity;
import android.os.*;
import android.content.*;
import android.app.*;

public class ExampleActivity extends Activity {

    private Context context;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        this.context = this;
        Intent alarm = new Intent(this.context, AlarmReceiver.class);
        boolean alarmRunning = (PendingIntent.getBroadcast(this.context, 0, alarm, PendingIntent.FLAG_NO_CREATE) != null);
        if(alarmRunning == false) {
            PendingIntent pendingIntent = PendingIntent.getBroadcast(this.context, 0, alarm, 0);
            AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 1800000, pendingIntent);
        }
    }

}

The above code will prepare our broadcast receiver and then check to see if it is already running. If it is already running, do nothing because we don’t want to register it multiple times. If the receiver is not already running, we will register it to repeat every 1800000 milliseconds, or every 30 minutes.

So what exactly is the broadcast receiver doing when it wakes up? It is just calling our background service intent where we do all of our heavy lifting.

package com.nraboy.example;

import android.app.*;
import android.content.*;
import android.os.*;

public class BackgroundService extends Service {

    private boolean isRunning;
    private Context context;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        this.context = this;
        this.isRunning = false;
        this.backgroundThread = new Thread(myTask);
    }

    private Runnable myTask = new Runnable() {
        public void run() {
            // Do something here
            stopSelf();
        }
    };

    @Override
    public void onDestroy() {
        this.isRunning = false;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if(!this.isRunning) {
            this.isRunning = true;
            this.backgroundThread.start();
        }
        return START_STICKY;
    }

}

You can see in the above code that all of our variables get initialized in the onCreate and the service starts to run in the onStartCommand method. To prevent the users device from blowing up, all service work is going to be done in a thread. When the thread is complete, the service will be stopped until the broadcast receiver fires it up again. You’ll also notice that the service thread will not re-fire if the service is already running. We wouldn’t want threads to get jammed up and end up with 100 running in the background. Your users wouldn’t be too pleased with this.

To tie everything together, you need to add the broadcast receiver and background service to your AndroidManifest.xml file. The following lines must be added to your file:

<application>
    <service android:name=".BackgroundService" />
    <receiver android:name="AlarmReceiver"></receiver>
</application>

So why might you want to use a broadcast receiver and background service? Well, if you ever want to display notifications to your user based on events or calculations you’re going to need to do this from the background. You can for example have your background service execute a RESTful request to a web service and display a notification depending on the response. Or maybe just update your apps database in the background so users don’t need to wait when they open their application. There are many different possibilities.

A video version of this article can be seen below.

Nic Raboy

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in C#, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Unity. Nic writes about his development experiences related to making web and mobile development easier to understand.