As “Black Friday” approaches everyone is searching for a bargain, and I like to think TechRepublic readers are no exception. That’s why this week my Android tutorial twofer: I’ll explain how to get the current charge state of a device and demonstrate the progress bar widget.
Why would an application be interested in the battery state of the phone? Well, you should already know that by going to Settings | About Phone | Battery, users have the ability to get a top 10 list of battery-hungry applications running on their device. If your app shows up in the list, then you should definitely be paying attention to power consumption.
Even if your app doesn’t make the naughty list, it might still be worth considering how much charge remains on a phone. It depends on your apps, but if you are starting up services to do intensive background transfers for example, the responsible course of action might be to postpone the activity when battery juice is at a premium.
Last but not least, if like me you’re a smartphone-o-phile, creating your own battery indicator is kind of fun. It’s also surprisingly easy thanks to something the Android documentation calls a “sticky” intent. Unlike standard broadcasts that only invoke your receiver when a change occurs, the BatteryManager broadcast holds onto the last intent, and the framework automatically calls your receiver at registration. The net result is your variables can be initialized using the same method that updates them.
The example that follows is short and sweet. You can follow along with the tutorial or download the project here and import it directly into Eclipse.
1. Using Eclipse create a new Android Project targeted at SDK 1.6 or greater.
2. In the /res/layout folder we will create a very basic layout containing two elements: a text view and a progress bar. Note the style attribute of the progress bar. We are overriding the default style, which is the indeterminate spinner, with the system defined horizontal indicator. Something else you might have noticed is the minimum height and width being set on the widget. This is not required, but doing so gives us a rectangular progress bar that rather looks like a battery, which I thought was appropriate in this instance.
main.xml<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=http://schemas.android.com/apk/res/android
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textfield"
android:layout_marginTop="40dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
<ProgressBar
android:id="@+id/progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:layout_gravity="center"
android:minWidth="200dip"
android:minHeight="100dip"
android:max="100"
style="?android:attr/progressBarStyleHorizontal"/>
</LinearLayout>
3. Just as our layout is pretty straightforward, thanks to the sticky intents I mentioned, so too the Main.java file in our /src folder is not very involved. We must define a global broadcast receiver, override the receiver handler, and in our on create register the receiver.
Main.java package com.authorwjf; 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.widget.ProgressBar; import android.widget.TextView; public class Main extends Activity { private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver(){@Override
public void onReceive(Context c, Intent i) { int level = i.getIntExtra("level", 0);ProgressBar pb = (ProgressBar) findViewById(R.id.progressbar);
pb.setProgress(level);
TextView tv = (TextView )findViewById(R.id.textfield);
tv.setText("Battery Level: "+Integer.toString(level)+"%");
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);setContentView(R.layout.main);
registerReceiver(mBatInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));}
}
Congratulations, we’re done! There are a number of advanced options the BatteryManager supports, but for reporting charge levels, the SDK does all the heavy lifting for us. Combining the BatteryManager with the no muss, no fuss ProgressBar class, we’ve got a functional battery monitor with only a few lines of code. What a deal!