Tank Wars in G3D
Installing Xdebug for use with Eclipse or Netbeans on Linux
JQuery Venetian Blinds Transition Effect
Enforce Coding Standards with PHP_CodeSniffer and Eclipse IDE on Ubuntu Linux
Nice n' Easy JQuery Image Rotator
Symfony 2 Crash Course

Create a SQL Database for your Android App

Sunday, 25 September 11, 1:00 pm
If you want to store arbitrary amounts of structured data, you'll probably want to make use of Android's SQLite database support. SQLite provides a simplified subset of SQL statements for managing your data. Databases are stored on the device's public data area, either on the SD card or in the device's internal memory.

The documentation on this page discusses how to use a SQLite database in an Android app. In Eclipse, the procedure is this:
  1. Right-click your project in the treeview, and choose New > Class
  2. Enter a suitable package name - placing your data access class in a separate package to your main project is usually preferable.
  3. Enter the name of the class - I used SQLiteOpener
  4. Click the Browse.. button to the right of the Superclass box, start to type SQLiteOpenHelper in the 'Choose a type' box, and select the matching class when it appears in the box below.
  5. Make sure the 'Constructors from superclass' and 'Inherited abstract methods' checkboxes are ticked, and then click Finish.
After this process, you'll have a Java source file containing method stubs for your new class's constructor and the two abstract methods, onCreate() and onUpgrade().

First we should change the auto-generated constructor as the version number should be set by our class to indicate which version of the database we're working with. I've also dropped the third argument, cursorFactory which I'm simply going to pass in as null to use the system cursor factory.
public SQLiteOpener(Context context, String databaseName) { super(context, databaseName, null, 1); }
When an app wants to read or write data, it will first create an instance of this derived class using the above constructor. The super-class's constructor will try to open the named database, or create it if it doesn't exist.

When the database is first created, the onCreate() method is fired afterwards. So we have to override the onCreate() method to create the tables that we want our database to have. We use the SQLiteDatabase parameter 'db' to run SQL CREATE TABLE statements for each table in our database:
@Override public void onCreate(SQLiteDatabase db) { String sql = "CREATE TABLE times (" + "_id INTEGER PRIMARY KEY AUTOINCREMENT," + "title TEXT," + "timestamp INTEGER" + ")";   db.execSQL(sql); }
Note that there are only 3 column types in SQLite, namely TEXT (for strings of character data), INTEGER (whole numbers) and REAL (fractional numbers). Also, for Android apps, it is recommended to name your primary key column _id.

Getting Hold of An Actual SQL Database, Goddarnit

By inheriting from SQLiteOpenHelper, we get the methods getReadableDatabase() and getWritableDatabase() which return a SQLiteDatabase object that we can use to execute SQL statements on the database.

The constructor takes a Context instance as its argument, which is a reference to your application's Activity subclass. So in your activity, you can connect to a SQLite database called myData using 'this', like so:
SQLiteOpener dbHelper = new SQLiteOpener(this, "myData"); SQLiteDatabase db = dbHelper.getWritableDatabase();
The SQLiteDatabase class offers the methods insert(), update(), and delete() for inserting, updating and deleting, and query() for selecting. To insert an item into the 'times' table for instance:
db.insert("times", null, createContentValues("oh hai", timeNow.getTime()));
Deleting is pretty much the same. To delete all items from a table, you would use:
db.delete("times", null, null);
The query() method lets us select data from a single table. The first argument is, as before, the table name. The second argument lists the columns you want to retrieve in the form of an array of strings. The next two arguments let you set a WHERE clause. Arguments 5 and 6 are for GROUP BY and HAVING clauses. The last but one is ORDER BY, and the very last is the 'LIMIT'. All of these arguments are the string just as it would appear in an equivalent SELECT statement.

The following gets the most recent two rows from the 'times' table:
Cursor cursor = db.query("times", new String[] { "timestamp" }, null, null, null, null, "timestamp DESC", "2");
The query() method returns a Cursor instance, which lets us iterate over the result set with the moveToFirst(), isAfterLast() and moveToNext() methods. We can access columns using the getLong(), getInt(), getString() family of methods, which all take an int argument indicating which column to return.

This simple example below iterates over all rows in our 'times' table, and displays the timestamp field as a date along with the title in a pop-up Toast.
Cursor cursor = db.query("times", new String[] { "title", "timestamp" }, null, null, null, null, null); cursor.moveToFirst(); Date timeThing; String datemsg; while (cursor.isAfterLast() == false) { // Get time of current row timeThing = new java.util.Date(cursor.getLong(1)*1000) datemsg = new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(timeThing);   // Display it as a Toast Toast.makeText(getApplicationContext(), datemsg + ": " + cursor.getString(0), Toast.LENGTH_SHORT).show();   // Move to next row cursor.moveToNext(); }

Please enter your comment in the box below. Comments will be moderated before going live. Thanks for your feedback!

Cancel Post

/xkcd/ Metric Tip