- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Email to a Friend
- Printer Friendly Page
- Report Inappropriate Content
The MOTODEV team held another of our "Live Office Hours" events today. That's where we sit round a table, and respond to handset and Android questions from developers, in a text chat format. It's quick, free, and a great way to get the most up-to-date information.
In the Live Office Hours this morning, one developer asked me how to write code to get air pressure readings from the barometer on the XOOM tablet. Well, am I ever ready to do that! When I first heard that the XOOM had a barometer sensor, I was very eager to try it. I don't know of any other mobile devices that have an ambient air pressure sensor. At the first possible opportunity, I coded up an app that listened for barometer events, and displayed them on the screen. Let me share the key code from that app with you.
Air pressure readings inside my office building, on the first floor, and the fourth floor
The XOOM barometer has enough accuracy that you can locate which floor you are on in a building. So the sensor could be used for mapping apps that guide someone through a shopping mall or a large building.
The first thing to note is that the barometer follows the same protocol as most of the other sensors - Android.app.Activity has a method that lets you get a sensor manager object, and with the sensor manager you can get hold of the barometer or any of the other sensors. This is one area of Android that is pleasantly consistent and intuitive. Here's the code to get a barometer sensor object.
SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor bar = sm.getDefaultSensor(Sensor.TYPE_PRESSURE);
Check that bar is non-null, and you are ready to start using it. The next thing is to register a listener to receive sensor events:
boolean running = sm.registerListener(this, bar, sm.SENSOR_DELAY_NORMAL);
Here, I've used "this" Activity as the event handler. There are several alternative ways to set up your event handler. For small simple things, I just make the Activity implement the android.hardware.SensorEventListener interface, by adding the required two methods to my Activity, like this:
import android.hardware.*;
public class main extends Activity implements SensorEventListener {
...
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) {
}
I don't really care about changes in accuracy in the sensor readings, so I'm going to leave that method with an empty body. I just want to get events, and print the values out on the screen. (Well, maybe it would be a good idea to slip a Log.i message in there, so I can keep an eye on how often accuracy changes - for these sensors, I am expecting it won't change at all). Your code might register for several other sensors (the gyroscope, the accelerometer, etc). For each sensor that you are listening to, your onSensorChanged() method will be called for each reading event. So the method needs to check the sensor type, and switch appropriately.
It's always handy to stay informed about your rotational torque, too, so my sample app registered for gyroscope events (code not shown). The onSensorEvent() method to handle events from the gyro and the barometer will look like this:
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_PRESSURE:
java.text.DecimalFormat df = new java.text.DecimalFormat("#.#");
String reading ="PRESSURE: "+ df.format( event.values[0] )+"millibars";
myTV.setText(reading);
break;
case Sensor.TYPE_GYROSCOPE:
handleXYZ(event);
break;
}
}
As you can see, we pick up the pressure reading from event.values[0]. Then we format it to have one decimal place, and put it in a string. A convenient TextView is then set to the value of the String, resulting in the string appearing on the screen. Gyroscope events are delegated to a method handleXYZ(), not shown here, but all it does is pull out the event.values[0], [1], and [2], format them, and display them in a second TextView.
Keep in mind there is a "gotcha" with onSensorChanged() -- you
don't own the event object that is passed in as a parameter. You
must not try to hold onto it, by keeping a reference to it.
The event object is part of an internal pool and may be reused by
the framework any time after returning from onSensorChanged().
For this reason, the class android.hardware.SensorEvent should implement
Cloneable, so it is cloneable. Alas, it does not, and is not.
Don't forget to stop the sensor when your activity pauses, so you don't waste battery power:
protected void onPause() {
super.onPause();
sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sm.unregisterListener(this);
}
Here are a few other points to note:
- the readings are in units of grams/cm^2, also known as hectopascals, or millibars
- "standard" air pressure at sea level is defined as 1013.25 mbar or 760 mm of mercury.
- The actual air pressure at sea level, or anywhere else, changes with the weather
- Air pressure has a twice daily cycle of highs and lows, caused by global atmospheric tides (yes! The atmosphere is affected by the pull of the moon, just like bodies of water are affected by it. In fact, the atmosphere acts like a big ocean blanketing the planet, only more bouyant and diffuse than water. The barometer sensor lets us take point measurements of this "ocean").
- Higher pressure means that a column of air is descending, which is associated with dry weather and mostly clear skies.
- Lower pressure means that a column of air is ascending, which often brings cloud and possibly rain.
- Air pressure gets lower, the higher your altitude. This table shows how air pressure changes with altitude.
- Some airplanes use a highly accurate barometer to measure their altitude.
So that's how you use the barometer on the XOOM. And I made it almost all the way to the end, without mentioning that lame old story about the student, the barometer, and the physics exam!
If you've written an app using the XOOM barometer, please follow up to this post, and tell me about it!
Cheers
Peter van der Linden
Android Technology Evangelist