Android Barometer Logger: Recording Sensor Data

Android content providers are an easy way to manage and expose data from an application, especially when backed by a database. You'll see a fast way to provide a specific, quick implementation of both a database and a content provider in this tutorial.

In this continuation from the last tutorial, Android Barometer Logger: Acquiring Sensor Data, we'll implement code for reading barometric sensor data on a regular basis and storing it in a persistent fashion. 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.

You may have see database and content providers appear in some other tutorials; this one is presenting a fast, "quick-and-dirty" variant for the hobbyist or enthusiast wanting to quickly log some data in a structured database and display it later easily, all in an Android-friendly way.


Part A: Creating a Database

The fastest way to create a database on Android using SQLite is to use the SQLiteOpenHelper class. The data records we wish to log are very simple in structure: a timestamp and a value representing the pressure at that time.


Step 1: Determining the Schema

The schema for this database is simple. Beyond the two required data columns for the timestamp and pressure value, we'll also create a unique identifier--useful should we ever expand the schema or need to deal with the data on a row-by-row basis. Here is the schema definition for the SQLiteOpenHelper class:

SQLite can actually store timestamps in many ways and manipulate them internally. However, we may never need to manipulate them, so we can just store the value read from the sensor.


Step 2: Implementing the SQLiteOpenHelper Class

With the schema out of the way, the rest of the SQLiteOpenHelperclass is trivial:

Basically, we configure the database version and decide how we want to handle version changes and upgrades--in this case, we drop all data on an upgrade. We do not support data migration. However, you could easily add code here to migrate data on an upgrade as necessary.


Part B: Implementing a Simple Content Provider

Content providers are Android’s way of exposing structured data through Cursors while protecting the underlying data. Application data is queried through the content provider instead of accessed from the application database directly. Because this implementation is using a SQLiteOpenHelper, the task of creating a content provider is straightforward.


Step 1: Choosing What to Implement

While a fully functional content provider that handles all data operations like queries, inserts, updates, and deletes takes little more work than a partial one, for logging purposes all we really need to for input implement is the insert() method. Getting data out requires implementation of the query() method, which will also leverage the URIMatcher helper class. You can always go back and implement other features of the content provider later, should your requirements change. Most data logging, though, requires complete, unaltered records.


Step 2: Implementation Details

Let’s implement a content provider that works with our sensor logging plans. First, set up some useful constants and the URIMatcher to help us match URIs to the type of data they represent:

Most of what you see here is error handling. The main call, insertOrThrow(), uses data directly from the parameters to the insert() method.

And now the query() method:

The only change to the query() method is adding the identifier to the where clause if the URI contains a path to a specific record. Otherwise, the parameters to the query() method are also passed as-is to the query() method call. Very convenient.

We've used a helper method to get the SQLiteDatabase object instance. This is so we only create the SQLiteOpenHelper object when absolutely necessary. This is recommended to improve overall performance.


Step 3: Updating the Manifest

Finally, a content provider needs to be registered as a provider in the application’s manifest file in the <application> tag, like so:

This simplicity is one reason why we like the marginal overhead of implementing a content provider on top of a database.


Conclusion

In this tutorial, you have learned how to quickly create a simple application database and related content provider and use it for easily logging data--in this case the barometric pressure readings taken from the device at regular intervals.

As a challenge, implement this code on your own. Round out the implementation of the content provider by implementing the delete() and update() methods. Are they needed for your logger? Can leaving them out be used to enforce data integrity?


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