So you’re interested in doing some Android development? Awesome, let’s get you set up and rolling out some apps. Everything is typically going well until you need to work with the SQLite database, then shit hits the fan. You’ve rolled out 2 or 3 versions of your app and because of the demos you’ve seen from places like the Android samples, changes are impossible to make without slightly breaking your brain.

Wouldn’t it be nice if we could represent our changes in a way that’s sane? We’ve seen this done in numerous frameworks such as Active Record or South.  Now, we don’t have to go this crazy with ORMs and having the code know how everything is related to each-other (though that is pretty awesome).  For now, let’s just focus on representing how our data model changes throughout various versions of our software.  So we could come up with some kind of Domain Specific Language for this problem, but this is still going overboard and may be a bit too complicated, let’s go simpler.  Instead, why don’t we simply use SQL and have a few rules (or conventions) that we need to follow to ensure that our databases migrations get applied properly?

Interestingly enough this is very easy to do and also results in database code that is easier to understand since well, it’s just SQL files!  Another advantage of this is you could simply have the SQLite binary installed on your system and load these files into a local database.  So you’ve also decoupled your database code from your Android application.  Sure, it’s still tied to the SQLite database, but at least you can play around with your database locally instead of in the emulator or on a device which can get a bit hairy if you don’t have the proper permissions (read: root access).

So, first let’s set up our migration files.  We’ll go with the convention of having them stored in assets/migrations. It will be our responsibility to ensure that our migrations are in that folder, and then our code will simply grab all migration files from that directory and load them. Now, we need to ensure some kind of ordering. We could go with the rails way of doing it, which is to add some kind of way to ensure all migrations are unique such as by using a very fine grained timestamp, but again, too complicated. Let’s simply go with a convention like NNNN_my_description_for_my_migration.sql where NNNN is a number between 0001-9999 (hopefully this will be enough for now!).

Awesome, so now we have a place to look and a way to order the migrations properly. Let’s actually figure out how to get these files loaded. I went with the simple approach of having the migrator do all of it’s work in the SQLiteOpenHelper.

First, let’s look at our DatabaseMigrator

public class DatabaseMigrator {
    private Context context;
    private SQLiteDatabase db;
    private AssetManager manager;
    private String[] migrations;

    public DatabaseMigrator(Context context, SQLiteDatabase db) {
        this.context = context;
        this.db = db;
        this.manager = context.getAssets();
        this.migrations = manager.list("migrations");
        Arrays.sort(this.migrations);
    }

    public void migrate(int from, int to) {
        for(String migration : migrations) {
            int version = DatabaseMigrator.version(migration);
            if(version > from && version <= to) {
                String migrationSQL = load(migration);
                apply(migrationSQL);
            }
        }
    }

    public static int currentVersion(Context ctx) {
        String[] migrations = ctx.getAssets().list("migrations");
        return version(migrations[migrations.length - 1]);
    }

    public static int version(String migration) {
        return Integer.parseInt( migration.substring(0, 4) );
    }

    public void apply(String sql) {
        db.execSQL(sql);
    }

    public String load(String migration) {
        ByteArrayOutputStream migrationBytes = new ByteArrayOutputStream();
        InputStream migrationStream = getMigrationStream(migrationStream);
        byte[] buffer = new byte[0x4000];
        int bytesRead = 0;
        while( (bytesRead = migrationStream.read(buffer)) > 0 ) {
            migrationBytes.write(buffer, 0, bytesRead);
        }
        return new String(migrationBytes.toByteArray());
    }

    public InputStream getMigrationStream(String migration) throws IOException {
       return manager.open("migrations/"+migration);
    }
}

Now for our actual database open helper.

public class MyApplicationsDatabaseOpenHelper extends SQLiteOpenHelper {
    private DatabaseMigrator migrator;
    private Context context;

    public MyApplicationsDatabaseOpenHelper(Context ctx) {
        super(ctx, "myAppsDatabase.sqlite3", null, DatabaseMigrator.currentVersion(ctx));
        this.context = ctx;
    }

    public void onCreate(SQLiteDatabase db) {
        DatabaseMigrator migrator = new DatabaseMigrator(context, db);
        migrator.migrate(0, DatabaseMigrator.currentVersion());
    }

    public void onUpdate(SQLiteDatabase db, int oldVersion, int newVersion) {
        DatabaseMigrator migrator = new DatabaseMigrator(context, db);
        migrator.migrate(oldVersion, newVersion);
    }
}

Now we do have a few caveats we should take note of first. The big one is that execSQL only runs the first SQL statement, which can cause some funky issues if we want to have a migration that creates several tables or makes many modifications. All we simply need to do is add something to ensure that our migrations can be cut up properly.

For example:

CREATE TABLE people(firstName, lastName);

/** Separator **/

CREATE TABLE animals(species, genus, class);

Turning this migration file into properly executable statements is left as an exercise for the reader.

 

I’ve been using a certain Podcast application for a while, and I have it configured in such a way that it will only do updates on wifi and at 9:30 in the morning.  I have a tendency to only be connected to 3G so this leads to some pretty frustrating experiences.  Primarily, I’m getting notifications that updates couldn’t happen then I’m directed to a screen with no way of actioning on these problems.  Alright, so the software isn’t that great… but it’s sadly the best for what I need.

Though, I feel this software could be vastly improved if only the developer took a few steps to gracefully handle things such as connectivity (let’s admit it, lack of connectivity isn’t an exceptional case, it’s an expectation).  Add in configuration such as “Only download over WiFi” well now you’re going to need to elegantly handle how an update is performed.

In my app, STO on the Go I needed to perform daily updates though there’s a good chance that when the scheduled task hits the user may not have an internet connection (or only want to download updates over WiFi).  Awesomely, Android is a really loud system.  It’s yelling things **all** the time about various status changes, one of these being connectivity status changes.  I figured I would tie into this.

Tying into these services is extremely straightforward, first we need to tell our manifest that we want to listen in on some BroadcastIntents:

<receiver android:name=".receiver.ScheduleUpdateReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>

So now our <pre>ScheduleUpdateReceiver</pre> will get called each time the state of connectivity changes on the device. Keep in mind, you are going to need to keep the code as lean as possible until you are absolutely sure you need to do some heavy lifting! Nothing is more frustrating than an app that appears to be doing nothing but kills your battery.

Now it’s time for our service to actually do some stuff, this is where we will be asking a few questions.

 

public void onReceive(Context context, Intent intent) {
	ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
	TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
	String doUpdateOnNextWifiConnection = context.getString(R.string.doUpdateOnNextWifiConnection);
	SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);

	if(!prefs.getBoolean(context.getString(R.string.performDownloadsInBackground), true)) {
		// User configuration -- No background Updating
		Log.d(DEBUG_TAG, "Updates are not permitted to run. Aborting");
		return;
	}

	boolean hasActiveWifiConnection = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected();

	// Check to see if the intent that was fired was created by Android itself
	if(intent.getAction() != null && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
		// Did the last check fail due to lack of connectivity?
		boolean performUpdateOnNextWifiConnection = prefs.getBoolean(doUpdateOnNextWifiConnection, false);
		if(performUpdateOnNextWifiConnection && hasActiveWifiConnection) {
			runUpdate(context);
			// Alright, our update has run, time to reset our state so we don't attempt to download
			// another update next time the device gets an internet connection.
			prefs.edit().putBoolean(doUpdateOnNextWifiConnection, false).commit();
		} else {
			Log.d(DEBUG_TAG, "Update for connection to wireless access point will be ignored");
		}
	} else {
		// This is our scheduled update
		boolean canDownloadWithMobileData = prefs.getBoolean(context.getString(R.string.usenetworktype), true);
		boolean hasMobileDataConnection = (telephonyManager.getDataState() == TelephonyManager.DATA_CONNECTED);
		if((canDownloadWithMobileData && hasMobileDataConnection) || hasActiveWifiConnection) {
			runUpdate(context);
		} else {
			// So, we either don't have an internet connection or the user wasn't connected to WiFi when the scheduled
			// update was supposed to happen.
			// I chose to store this information in the shared preferences because it's pretty easy to do.  This could get
			// a little bit out of hand if you have more complex rules than what I have here.
			Log.d(DEBUG_TAG, "Cannot do a download over data and we don't have a wifi connection. On the next wifi connection, we'll do the download then");
			prefs.edit().putBoolean(doUpdateOnNextWifiConnection, true).commit();
		}
	}
}

So now we are able to handle the sort of special cases and deal with them almost immediately after a user has acquired a usable connection to the internet.

 
I’m working on a background service that is going to be triggered by the alarm manager.  I’ve set everything up for my broadcast receiver, though I’d like to test it without having to write a bunch of Java code.  After looking around a bit I’ve come across this am tool that appears to do what I need, though I don’t know how to create a specific broadcast intent.
Let’s say my BroadcastReceiver is com.foo.receiver.NiftyReceiver and I have it in my manifest file as <receiver android:name=”.receiver.NiftyReceiver” />
The documentation is a bit lacking on how to use the tool, but after a bit of confusion I’ve finally figured out how to get it working.
am broadcast -n com.foo/com.foo.receiver.NiftyReceiver
Note, you need to add the android:exported=”true” to your <receiver> otherwise android will spew this nifty little error message on you:
W/ActivityManager(16908): Permission denied: checkComponentPermission() reqUid=10066
W/ActivityManager(16908): Permission Denial: broadcasting Intent { cmp=com.foo/.receiver.NiftyReceiver } from null (pid=1411, uid=2000) requires null due to receiver com.foo/com.foo.receiver.NiftyReceiver
I’m pretty sure this isn’t anything new, but I personally found tools like am aren’t really documented that well.  Hopefully this will save someone else a bit of time in the future!
 

I gave myself a personal goal around mid to late November; to finish an STO Android app with the dataset that Phil Casgrain had given me access to.  The app is now available on the Android market as STO on the Go though it’s almost impossible to find using the search.

I’m selling the app for $1.00 though there is a good chance it will be getting an increase in the next version, which will have at least maps and favourites features.

 

I’m beginning to work on an STO application from an API that was created by Philippe Casgrain.  The data was stored in a pretty big JSON file, and I decided that instead of breaking it into smaller pieces I would simply insert everything into an SQLite database.  Previously the only time I had worked with Android databases had simply been via insertions with ContentValues, which is a lot slower than I had thought at first.

Previously this is what I was doing

void insertData(List objects, SQLiteDatabase db) {
    ContentValues cvs = new ContentValues();
    for(Foo obj : objects){
        cvs.put("FooStringColumn", obj.fooString());
        cvs.put("FooIntegerColumn", obj.fooInteger());
        long result = db.insertWithOnConflict("Foo", null, cvs, SQLiteDatabase.CONFLICT_REPLACE);
    }
}

This works alright, though when you are generating thousands of entries from your JSON data it results in something that’s so slow it’s painful. At first I thought my problems were stemming from using the org.json tools included in Android so I switched over to using Google GSON instead, which did help reduce a ton of unnecessary garbage collection. Though, everything was still slow.

My database knowledge isn’t extremely deep, and I recall being able to compile PreparedStatements to speed up interaction with the DB. After a bit of searching on the internet I came across an alternative way of doing database insertion using this thing known as an InsertHelper. Using an InsertHelper is pretty straightforward, though it requires writing a bit more code than ContentValues, but it’s way faster.

void insertData(List objects, SQLiteDatabase db){
    InsertHelper helper = new InsertHelper(db, "Foo");
    final int fooStrCol = helper.getColumnIndex("FooStringColumn");
    final int fooIntCol = helper.getColumnIndex("FooIntegerColumn");
    for(Foo obj : objects){
        helper.prepareForInsert();

        helper.bind(fooStrCol, obj.fooString());
        helper.bind(fooIntCol, obj.fooInteger());

        helper.execute();
    }
}

To also help speed things up, I extracted all of my data first then inserted everything in a transaction. This helped reduce overhead and I was able to get the database initialized in about 10 seconds. Surely I can speed it up further, but for now this seems to solve my problems.

References

 

Last week at Shopify we had a this thing called FedEx Days (or something similar) where we were given 2 days to work on any project we wanted.  After having looked at the Jhopify library, and trying to patch it, I figured that API bindings for Shopify could be solved better.  I had worked with the Shopify API before when I first started working at Shopify while I was still doing Android dev there.  Since then though, nothing really came of it.

I had taken a few lessons from that experience and decided to use that knowledge to create a tool so that Android devs could spend less time writing boilerplate API code, and more time solving problems.  I also wanted to ensure that I could provide as much of a one-to-one mapping to the API as possible.  This meant one thing, Java Beans.  I looked at the API and looked at a blank Article.java file and cringed.  There has to be a better way to do this; and of course there is!  You see, I remembered reading something from the Pragmatic Programmer.  It’s something along the lines of “If you have to write repetitive garbage, why not have a computer do it instead? Voila! Code Generators!”.

Thankfully, the Shopify API provides some pretty good example output and I figured I would use this as a tool.  With the Shopify examples that I had so gracefully copy-pasta’d into some ‘fixtures’ that I was intending on using for tests I then proceeded to use them as training data.

So I fired up my default system text editor (TextMate, though emacs would’ve been preferable… no time!) and started hacking out some ruby.  First step was to get all the POJOs/beans written up, then I’d tackle actually getting the API to work.  This was pretty straightforward; read in the data, turn it into a hash, infer the data types and apply the various private members and their getters/setters, add annotations, etc.

But it dawned on me.  What if the Shopify API for say, Articles were to ever change? I could just manually add the new changes, but that sucks.  This reminded me of another problem I had when doing some iOS/core data work about a year ago which has much of the same problem, which was solved.  The tool that solved the iOS problem is known as MOGenerator.  The way the tool works is by inspecting your data model and creating intermediate classes with all the boilerplate, then adds a subclass where you can add custom code.  It makes the promise that if you ever put custom code in the _yourModel (or whatever syntax it uses), MOGenerator will gladly come in and overwrite all of it.  So I figured that taking a similar approach for the Shopify models would be fine, and would also save a bunch of time/worry.

With all that working and tests running green on some simple and more complex data types, I then proceeded to create the API bindings.  I decided to go with a tool called CRest which makes mapping API endpoints far simpler.  After writing the first endpoint I again realized that this could be generated as well, mind you not as elegantly.  Not all endpoints map out in a manner that is as simple as the beans, but I figured this is the best way to get at least some form of API wrapper working.  So making some really basic assumptions, I also generated all the endpoints.  These probably won’t work as elegantly as the beans did, but it should be a starting point for anyone wanting to work with the API.

So all in all, I was able to get hundreds of lines of code written up in about 200 lines of ruby.  Though we need to keep in mind that much of that ruby code consists of huge blocks of text and not actual logic.  If I were to remove all of that, I’d say this was accomplished in even fewer lines, perhaps 100?  I’m hoping to have the code publicly available on GitHub soon.  Just need to get a tutorial/demo app written up, unless you don’t care, then I may be able to convince some people to release it as is.

 

I recently discovered that although PhoneGap is pretty awesome, there are some things you should know before you go out and try to get it working on your melange of devices.

phonegap.js isn’t all that you expect it to be. That is to say, phonegap.js for an iPhone isn’t the same phonegap.js that is used on Android. So, if you are going to be dropping phonegap onto a bunch of different devices while testing, be sure that you are using the proper javascript file. Otherwise you will be stuck scratching your head wondering why the camera works on platform X but not platform Y.

They are hoping to get that taken care of in the future, but for the time being you’ll have to be sure that you are using the proper file.

 

So DROIDHACK was this weekend, and I wasn’t exactly too sure what I wasn’t too sure what I was going to work on. I really wanted to get into the data layer of Mercury, but was really really dreading having to write all the data layer junk that comes with working with SQLite on Android.

Back when I first started working at Shopify I was initially going to be making an Android application. The first thing I knew I needed to do was find some kind of ORM that would make working with the database less painful. I had come across a few options, where the best was a proprietary one which I didn’t think was the best choice. Alternatively, there were a few open source projects that at first glance seemed like a good choice but were using way too much reflection and was kinda difficult to add features to. I really wanted a tool that would make it easy to create a database, but wouldn’t rely on reflection too much.

Another attendee, Don Kelly wasn’t too sure what kind of Android project he wanted to work on either so I bounced the idea off him and then we started hacking up some unit tests. My TDD process is pretty weak, and it was great working with someone who approached the problem from a test driven perspective. What I really liked about this was we were able to make API decisions right away. How do we want to get objects from the database? How do we want to interact with them? How would we create a table? I’ve read Becks’ book on TDD but have always found it tough to apply it when I’m actually working on something.

As for the project we worked on; it’s called velvet and the goal is to make working with databases on Android suck less. We haven’t really got much working with it yet, but the goal will be to have a simple data access layer, migrations and easy access to database cursors for presenting data in listviews and such. I’d have to say working with any kind of structured data with SQLite on Android requires far too much work already, wastes time and is often error prone.

 

So let’s say you have an application where you need to store the users password. Perhaps it’s a configuration setting that they need to use to log into some service you use or have created. The easiest (and most insecure) way to store the password would be to use the SharedPreferences for your application.

So in our preference XML we have an EditTextPreference which will be used to store the password. Though, we need to do a few things first otherwise the password will be plainly visible and there is the chance that the password might get saved in the auto-complete for the keyboard (SwiftKey is particularly bad for this).

For sake of argument, lets say our preferences xml is called “preferences.xml” and the key for the password is “password”.

What you will need to do is the following

import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.preference.Preference.OnPreferenceClickListener;
import android.text.InputType;
import android.text.method.PasswordTransformationMethod;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MyPreferenceActivity extends PreferenceActivity implements OnPreferenceClickListener {
    private Preference passwordPref;

    public void onCreate(Bundle icicle){
        super.onCreate(icicle);
        addPreferences(R.xml.preferences);

        passwordPref = findPreference("password");
        passwordPref.setOnPreferenceClickListener(this);
    }

    public boolean onPreferenceClick(Preference preference){
        if(preference.getKey().equals("password")){
            EditTextPreference pref = (EditTextPreference) preference;
            EditText field = pref.getEditText();
            // This informs the keyboard not to show up the autocomplete.
            // Ensure that you have set this input type, otherwise users
            // may complain that your application is saving their passwords.
            field.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
            // This gives us the masking that you see in your password fields
            field.setTransformationMethod(new PasswordTransformationMethod());
        }
        // We still return false so that the system will handle everything else.
        // We just needed to ensure that if this preference is the password pref
        // that it's properly protected from prying eyes.
        return false;
    }
}

And there you have it. With this in place, entering password with the on-screen keyboard won’t show any text or save it.

As I mentioned earlier, this doesn’t save the passwords safely to the device. On a normal device this isn’t that much of a concern, though you should probably inform your user that the passwords are not encrypted. This issue becomes a bit more serious if there is malicious software on a device that is also rooted, since the naughty app could scrape through all the data directories looking for usernames and passwords stored in preference files.

 

I’m going to be available for employment within the near future. If you are interested in any skills I have to offer or feel that I may be a good fit on your team, please feel free to contact me.

I have a resume up on StackOverflow where you can get more information about what skills I have and to learn a bit more about me if you’d like.

© 2011 Christopher Saunders Suffusion theme by Sayontan Sinha