So this article wraps up our 5 part series to broadcast receivers and up to now we’ve learnt all about them and coded up various broadcast receiver scenarios.  Today I wanted to just add a few extra things into the code to help your application run super smoothly!

One of the outstanding issues with our application is that we can register our broadcast receiver dynamically but it will then not run when the app is closed.  Or, we can register it statically in the manifest but then we can’t switch it off.  There are 2 ways we can deal with this:

Receiver energy consumption

So the easiest way of showing the user that the receiver is on or off is perhaps to simply use a toggle.  I’ve used in many apps before a simple ON/OFF master toggle, usually stored in a DB or preference value that is referred to by the onReceive() method of the broadcast receiver.  If ON then it runs, if OFF then it just stops there and goes back to sleep.

It’s a nice easy technique to use but at first glance I thought this way would be using CPU and battery resources as your app checks, runs but then says, “Nah, not actually interested right now!” every time the message you are waiting for happens, however it turns out from quite a few discussions I have had that this isn’t often the case.  The OS will be sending the broadcasts out anyway so you’re not polling for anything at all and the onReceive() method has to be kept small or it won’t run (More on that later) means that at most it’s a very thin usage of resources.  i you think about it, most events aren’t happening all that often anyway.  Think of BATTERY_CHANGED or BATTER_LOW, however the one caveat here is to always make sure you’re receiver isn’t listening to too many events or your particular event is not waking your app up too often.  having something happens every 0.5s is probably going to kill your phone’s resources.  however I wanted to point out this technique as it seems a lot of apps are doing things this way.

Using the BOOT_COMPLETED Event

However there is a way to get better control over your broadcast receiver and when it is on or off and this is by using another technique that involves listening for the BOOT_COMPLETED event on the device.  When any Android device boots up, it’ll sort itself out and then once completed it will broadcast the BOOT_COMPLETED event.  You can actually set your app up to listen for this and handle it with a broadcast receiver.

We can use the same receiver as before but all you need to do is change your manifest file to the below:

        <receiver android:name=".Battery_bcr" android:enabled="true" android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

All I did here was to change the intent filter in the code.  We also need to add in a uses permission in this case as the BOOT_COMPLETED event requires a special permission to run.  So add in:

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

At the top of your manifest file too.

Now every time your device boots up, it will run the Battery_bcr Broadcast receiver in your app.  You can now tweak the code in here so that it runs a service or another receiver that can be registered dynamically and this you can now switch it ON or OFF in code.  We do still have a permanent broadcast receiver here but the fact that it only ever runs after a reboot means it’s using very little resources anyway.

So there we have 2 techniques that should wrap up running broadcast receivers in any way you want to.

Intent Services

So I do keep on going on about “Services” so lets explain these and why we need them sometimes when using broadcast receivers.  A service is simply a class of code that will run in the background and to be honest in this scenario, they run just like the onReceive() event of your broadcast receiver.  However the onReceive() event is a very thin event and it will only run so much before it times out, much like a web service does on a website and if you run too much code in here it can tie out or you can get some odd app behavior.  Add to that that a couple more gotcha’s here:

  1. Firstly you can’t do things like call a broadcast receiver from within the onReceive() event of another broadcast receiver so in this example a service of some nature is definitely required.
  2. This whole technique is also required for some Intent types that cannot actually be registered using the static manifext.xml style.  Indeed the one we’re playing with here (BATTERY_CHANGED) will not actually work if registered statically.

This is where a service can come in and Android has a special IntentService type that is designed to be called fro an onReceive() event and will then happily run in the background until complete, however you can also run a simple service aswell in the same way here.  Services can run much more complex code so if your broadcast receiver is struggling, get your code into a service and simply call that service from your onReceive() event.  Here’s how we do it:

Firstly create another new “Java class” file and call it something relevant, like myService, now extend the class to use the IntentService type and use alt+Enter to run the auto complete methods.  You should see something like the below:

package com.raptorhub.dktestbcr;

import android.app.IntentService;
import android.content.Intent;

public class MyService extends IntentService {

    public MyService(String name) {
        super(name);
    }

    @Override
    protected void onHandleIntent(Intent intent) {

    }
}

There’s the onHandleIntent() event that is basically the same as the onReceive() event and is where you’ll put your code.  We need to create a constructor for the service too and the auto complete nearly gets it right.  You just need to tweak this to look like the below:

    public MyService() {
        super("MyService");
    }

Not sure why to be 100% sure but that’s what you need to do to get it working!!

Now you have a service that runs on boot, and you can use this to essentially register a public broadcast receiver dynamically that you can then fully turn ON or OFF in code.

Notifications

The last thing I wanted to mention was that so far we could have a broadcast receiver running and handling a message fro the Android OS, but if this happens when your app is closed you might not even know it’s happening.  This could be fine for all kinds of things, maybe you’re using the GPS to track silently in the background and don’t want the user interrupted every time he or she moves! However often you do want to just let the user know and maybe you want to give that user the ability to easily pop into the app.  The best way to do this is by using a notification.

Because notifications require a blog of their own i’ll put this into the next blog for those of you who need a little bit of help!

So that ends this series on Broadcast receivers.  I hope you found it useful, comments are open so if you need any more help i’ll try my best below!!

 

 

About The Author

Dave's one of the founders of Raptor, his rants are memorable, his thoughts are stimulating and his heart is set on helping, entertaining and making things like mobile, Android, ruggedness, 3D printing and IOT simple.

Related Posts