dcsimg

Monitoring Android Events

Use dynamically registered BroadcastReceivers to create intelligent GUIS for Android

Smart GUI

In past articles our Android sample application GUIs have consisted of a simple button or two and the corresponding click-handler code.

What if some of those buttons are only supposed to be available under specific device conditions? Examples include providing a button only when a connection to a remote Bluetooth peripheral has been established or some other specific device condition.

Or let’s say your device is going to be used to compute pi to the … some really high precision value that is likely to take a lot of computational cycles. You might not want to perform that calculation if your device is not connected to power in the interest of battery life.

Or you may only want your device’s special features to be enabled when the device is “docked”.

The “easy solution” is to check, or poll, for this condition periodically in addition to checking at application start-up or even based on various user interaction. While this approach will generally work, the preferred approach is to let our applications be “event-driven”. Then the user interface may be updated as soon as the condition changes — without the reliance upon some sort of user interaction, or costly polling.

Performing constant polling of device conditions is poor programming practice as it can cause numerous problems with the application performance, user experience and battery life.

So, if polling is bad news, what are we to do?

Handling Events

The Android platform permits applications to “register” for various events of interest.

By registering for an event, we can free the application from polling or other tedious programming practices. The recipe is fairly simple:

  • Create a BroadcastReceiver
  • Register for an event of interest
  • Handle the event accordingly when it occurs

There are two basic approaches to handling events in Android.

The first approach is to implement a BroadcastReceiver as a stand-alone class. A BroadcastReceiver is one of the fundamental application types on the Android platform, along with Activity, Service and ContentProvider.

A BroadcastReceiver is typically implemented as a separate class and defined in the AndroidManifest.xml file with the <receiver> tag. The receiver has associated with it one or more IntentFilter instances. The IntentFilter declaration tells the operating system that this particular class is interested in notification when a particular event occurs. When the event occurs a method implemented in the BroadcastReceiver class named onReceive() is invoked. This is the basic approach used by applications to handle alarms and other asynchronous triggers as seen in a prior article which discussed launching Android applications.

The challenge with a distinct BroadcastReceiver is that this code is not always easy to integrate with your user interface code. If you want to have a tight integration between received events and the user interface there is another approach worth considering: dynamic registration of a newly created BroadcastReceiver from within an Activity. This article demonstrates this latter approach.

Demonstration code

In the balance of this article we construct a simple application which displays a different graphic on the screen depending on the presence of a power connection to the phone.

While not a heart-stopping, exciting application, it is enough functionality to demonstrate a very useful programming technique for Android. Let’s get started.

The application consists of a single Activity with a user interface defined in main.xml. The UI layout has a single view which is centered on the screen. At runtime we update the view’s background to have a different image, or as it is known in the Android world, a “drawable”.

The image below shows the project in Eclipse. Note the two files under the /res/drawable folder. These images are stored in the drawables folder because it wasn’t worth the trouble to make high, low and medium resolution versions of the images which would ordinarily be added to the drawable-hdpi, drawable-ldpi, and drawable-mdpi respectively.

Project setup in Eclipse
Project setup in Eclipse

Let’s look at the layout file to see our simple user interface. We have a single View instance within an encompassing LinearLayout. When the code runs this view’s background image is changed to match the detected events.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    >
<View
    android:layout_width="64px"
    android:layout_height="64px"
    android:id="@+id/powermeter"
    />
</LinearLayout>

The next listing shows the code for the application, which is discussed below the code listing.

package com.msi.linuxmagazine.lookforpower;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;

public class LookForPower extends Activity {

	private BroadcastReceiver powerMonitor = null;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // create an instance of a BroadcastReceiver
        powerMonitor = new BroadcastReceiver() {
        	public void onReceive(Context context,Intent intent) {
        		if (intent.getAction().equals("android.intent.action.ACTION_POWER_CONNECTED")) {
        			View v = findViewById(R.id.powermeter);
        			if (v != null) {
        				v.setBackgroundResource(R.drawable.green);
        			}
        		}
        		if (intent.getAction().equals("android.intent.action.ACTION_POWER_DISCONNECTED")) {
        			View v = findViewById(R.id.powermeter);
        			if (v != null) {
        				v.setBackgroundResource(R.drawable.red);
        			}
        		}
        	}
        };
    }
    @Override
    public void onResume()
    {
    	super.onResume();
    	// Register interest for two different actions related to power
    	registerReceiver(powerMonitor,new IntentFilter("android.intent.action.ACTION_POWER_CONNECTED"));
    	registerReceiver(powerMonitor,new IntentFilter("android.intent.action.ACTION_POWER_DISCONNECTED"));
    }
    @Override
    public void onPause()
    {
    	super.onPause();
    	// unregister
    	unregisterReceiver(powerMonitor);
    }

Some things to note in this code:

  • We import a handful of classes from the android.content package including:
    • BroadcastReceiver — this is the class that allows us to be “called back” when an event occurs
    • Context — used all over the Android platform for providing… you guessed it: context for the running state of the application
    • Intent — an Intent is passed to the BroadcastReceiver to indicate that a particular event has occurred
    • IntentFilter — the IntentFilter is used to register for a particular action of interest
  • We dynamically create a BroadcastReceiver including its onReceive method
  • In the onReceive method we check for two specific Intent actions, both related to a power connection
  • The onResume and onPause Activity life-cycle methods are crucial for registering and unregistering specific IntentFilters
  • The code to update the view’s background is a simple call to setBackgroundResource()

Testng the application is simple: run the application and at first the screen will be blank. Why? Because no events have been captured yet.

Application startup.  Very boring!
Application startup. Very boring!

When the device is connected to power an Intent is passed to our powerMonitor BroadcastReceiver’s onReceive method and the green image is set as the background of the view.

Power connected.
Power connected.

Take the power away, i.e. unplug the USB connector and the green image is replaced with the red image because the POWER_DISCONNECTED event was detected.

Power disconnected
Power disconnected

That is about as simple as it gets for in-line, in-Activity Intent monitoring. There are a number of events which can be trapped — have a look at the Intent class definition on the Android developer site for a list of the different ACTIONs which may be observed.

That’s all for this installment. Please contact me at fableson-at-msiservices-dot-com and let me know what Android, iPhone or other mobile development topics you would like to see in future articles.

Comments on "Monitoring Android Events"

pushpkumar

Hi Frank,
Thanks very much for this useful article.
I am new Java newbie.
Can you advice , how can I introduce Excel editor functionality in android platform.

Waiting for your reply.

Pushp Kumar
pushp.kumar@gmail.com

Reply
dannybackx

You can buy the “Documents To Go” application suite from Dataviz. Contains apps compatible with Word, Excel, PowerPoint, and Acrobat Reader. For a mere $15.

Reply
fartshead

Do I need to do anything in the manifest to get this to work?
Thanks!

Reply
fableson

No, these dynamically registered BroadcastReceivers do not require an Intent-Filter in the manifest. What is cool about that is that you can have a dynamically registered, unique Intent action that you never need to know about during the development cycle!

Reply
subburaj88

hi frank,
thanks . i said to u this for the one who the beginner and this gave them the hope to do the things like u done above.even if it is correct or wrong

Reply
subburaj88

i m waiting here for ur reply with some more samples to android
contact me at

kmsubb@yahoo.co.in
harisiva@gawab.com

Reply

It’s appropriate time to make a few plans for the long run and it is time to be happy. I’ve read this post and if I may I wish to counsel you some interesting things or tips. Maybe you can write subsequent articles referring to this article. I want to read more issues about it!

Reply

Askibg questions are in faϲt nice thing іf ʏⲟu aге not understanding ѕomething
ᥱntirely, ɦowever tɦіѕ article provides pleasant understanding үеt.

Here iѕ mу weblog – topmobilespyapp.com

Reply

I found your weblog web site on google and check just a few of your early posts. Continue to maintain up the superb operate. I simply further up your RSS feed to my MSN News Reader. Looking for forward to reading extra from you later on!…

Reply

Greetings! Very useful advice in this particular post!
It’s the little changes which will make the biggest
changes. Thanks for sharing!

Reply

Hi there, after reading this awesome paragraph i am
too cheerful to share my familiarity here with friends.

Reply

I read this article completely concerning the resemblance of most up-to-date and earlier technologies, it’s amazing article.

Reply

Right now it looks like Movable Type is the best blogging platform out there right now.
(from what I’ve read) Is that what you’re using on your blog?

Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>