Android Barometer Logger: Acquiring Sensor Data

Smartphones are full of hardware sensors, such as accelerometers, light sensors, gyroscopes, and so on. Learn how to gather data from these sensors by way of implementing a barometric logger.

In a continuation from the last tutorial, Picking App Components, this time we'll implement code for reading barometric sensor data on a regular basis. You'll learn to read the sensor data and how to schedule recurring events so the application, and its service don't have to remain running.


Getting Started

This tutorial assumes you have a basic understanding of Android and Java, that you have all of the Android tools installed and working, and that you are comfortable with loading and testing applications on an Android device. We'll be using the barometer hardware sensor in this application. If you don't have a device with this sensor, you can substitute with another, similar sensor for testing purposes, but the results or usefulness may not be equivalent.


Part A: Reading Sensors

The hardware sensors are accessed through the SensorManager class. Through an instance of this class an application can query various Sensor objects that represent the underlying hardware. Using these, an application can then start listening for data coming from the sensor hardware.


Step 1: Finding the Barometric Sensor

First, get an instance of the SensorManager class, like this:

Next, query for the Sensor.TYPE_PRESSURE sensor, which is the barometric sensor:

Using the SensorManager class and reading sensors doesn't require any special permissions.


Step 2: Registering for Sensor Events

Now you can register to receive events from the sensor. To do this, you must implement a SensorEventListener and tell the SensorManager class about it.

For example, here’s the structure for an implementation of a SensorEventListener:

Then register for events by telling the SensorManager about your listener:

You can register to receive event updates at different rates. The faster the rate, the more frequent the updates, but also the faster the device battery will drain. Here we use the default rate. Check the return value of the registerListener() call to see if it was successful or not. If true, the sensor is available and the listening has started. If false, the sensor may not be available (for whatever reason).


Step 3: Reading Events

The class to receive sensor events is generic for all sensors via the SensorEvent class. As such, the SensorEvent value field is an array to handle more data than our single numeric barometric sensor provides. We're only interested in the first value of the array and the timestamp:


Step 3: Stopping the Sensor Listening

Finally, to stop listening to the sensor, simply unregister it:

You should register only when your application is ready and needs the sensor data, and then unregister as soon as it is no longer needed. This helps use device resources like battery power wisely.


Part B: Running in the Background

You probably aren't interested in leaving the app running all the time to check sensor values. Instead, create a Service and have the Service launched regularly by using a repeating alarm via AlarmManager.


Step 1: Implementing the Service

A Service on Android is a way to have application code run that isn't tied to a particular Activity and needs no UI of its own. Like an Activity, code in a Service runs on the main thread, so normal background processing techniques must be performed for lengthy operations. A Service can be used either via an Intent or by binding and making remote method calls. The type of Service we're implementing is best done via Intent handling.

The core of a Service class has two methods to implement, the onStartCommand() method and the onBind() method. Since we're not handling binding, we'll handle onBind() simply. Here is the core of our Service, including implementing the SensorEventListener:


Step 2: Recording Data in the Background

Writing data to disk is a blocking operation and should be performed on a background thread. A simple way of doing this is through an AsyncTask. Within the Service, we can add an AsyncTask and pass it the SensorEvent for handling like so:


Step 3: Starting a Service

A Service is normally started through the Context method startService(). For example, the following would work from an Activity class:

This isn't what we want though. We want the Service to run only occasionally, even if the application isn't running, and even if the device is asleep. The AlarmManager class allows us to do this.


Step 4: Scheduling a Recurring Service

The AlarmManager class allows you to schedule events in a recurring way. It even allows for efficient scheduling of many different events, not just your own, which is a good way to lower the battery use.

Here's code, which you can place in an Activity under a button handler, for instance, to turn on the Service to repeat once an hour:

We use the setInexactRepeating() method with a specifically defined interval, INTERVAL_HOUR, to take advantage of the system waking up for more than just our work. In addition, we use the RTC_WAKEUP option to indicate that we want the device to be woken up for this alarm, rather than waiting until it wakes up for some other reason.

Also, for testing purposes, we used an interval of one minute so we didn't have to wait several hours to collect multiple data points.

Turn the alarm off with a call to the cancel() method using the same intent:

You can perform these calls any way you like. We created a couple of button controls that called methods in our Activity with these calls.


Conclusion

In this tutorial, you have learned to regularly check a sensor value in the background using SensorManager, Service, and AlarmManager objects. The series will continue with more information on storing and displaying the data.

As a challenge, implement this code on your own. Try some other sensor types that your device supports. Does it support TYPE_AMBIENT_TEMPERATURE? TYPE_RELATIVE_HUMIDITY? TYPE_LIGHT? Would it be useful to record the location of the measurements? Be creative and tell us what you come up with in the comments!


About the Authors

Mobile developers Lauren Darcey and Shane Conder have coauthored several books on Android development: an in-depth programming book entitled Android Wireless Application Development (now in it's third edition as a two-volume set) and Sams Teach Yourself Android Application Development in 24 Hours. When not writing, they spend their time developing mobile software at their company and providing consulting services. They can be reached at via email to [email protected], via their blog at androidbook.blogspot.com, and on Twitter @androidwireless.

Need More Help Writing Android Apps? Check out our Latest Books and Resources!

Buy Android Wireless Application Development, 3rd Edition, Volume 1  Buy Sam's Teach Yourself Android Application Development in 24 Hours, 2nd Edition  Mamlambo code at Code Canyon

Tags:

Comments

Related Articles