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 visiting family over the holidays and am a big fan of Castle Crashers.  Unfortunately, V’s brother didn’t have it installed (nor any Microsoft Points).  I figured this would be a pretty simple affair: Add my card, buy the points, remove the card and call it a day. I am pleasantly surprised to see that I now cannot remove the card from his account.  From what I’ve researched, as long as auto-renewal is off there shouldn’t be any problems.  Though, still I get some kind of 80xxxxxx error.

Alternatively there’s a web portal you can access to remove payment methods as well.  Unfortunately, this also doesn’t allow me to remove the card.  Instead we need to log into the ‘parental account’ which is essentially a dead account.  What I find curious is how easily I could add a card to this account (without ‘parental’ permission or whatever), yet to remove the card is a whole different story.  I would love to know how many 12 year olds have added their mom’s credit card to their Live account for those sweet, sweet MS points.

So, here I am with my Credit Card tied to a Live account with no ability to remove the card whatsoever.  I can say that I’ve learned a few things from this; one of those being that I won’t be giving Microsoft (at least the Xbox division) any of my business until they clean up their half-working practices.

 

Earlier this week I finished reading my copy of The Net Delusion by Evgeny Morozov. I’ve always been rather skeptical of the claims about how Twitter and Facebook are being used as tools for revolutions. The Net Delusion is extremely critical of this very western assumption and uses several examples from the cold war (Samizdat, Radio Free Europe, etc.) as how these technologies really aren’t that effective.

Morozov also talks about the hypocrisy of the west (primarily America) in regards to censorship and monitoring of ones people. America has been very critical of authoritarian states in regards to freedom, but then allows various industries to censor its citizens when someone’s bottom line is at risk. These acts essentially put cards in the authoritarian states hands; “If you (America) can sensor its citizens when it’s convenient why can’t we?”

When I was nearing the end of the book it felt like it had run out of a bit of steam. Although it made going through the last few chapters a bit tough it is still an excellent read.

If you are looking for an interesting read over the holidays, or simply want to learn about the other side of “Internet freedom” then you probably won’t be disappointed.

 

I’ve recently started using spine for a project I’m working on at Shopify and I realized that there were some deficiencies in the framework. These were primarily around dealing with prefixed API responses and finding items that weren’t necessarily available locally (yet). I had been working on fixing the prefix issues several times, though I was informed by Alex (the maintainer) that he was going to be dropping support for prefixed responses anyway. Also, for finding items Spine made an assumption that on your fetch call everything would be retrieved from the server. This works for tiny applications, but when dealing with large datasets (such as those that can be retrieved in the Shopify API), you may not get everything you want in a single call. This required being able to defer a call off to the server to see if it exists there before reporting an item as unknown/not found.

Hence, bring on the plugins project that I’ve started. Currently the only plugin is the ajax.find plugin that solves the problems mentioned above. Hopefully it will help anyone using spine with any issues they may be having in the future when their server responses are non-standard (in the rails sense) or simply legacy from old rails applications.

The code is available on github and I really hope that it helps with any problems you may have been having. I’m definitely willing to accept contributions, though it would be preferable that they are tested.

 

It’s really not as bad as you might think actually. It’s just important to know if you are doing something like User Agent sniffing to determine what kind of browser is hitting your site. Typically everything will work fine, except when the user decides to add your web application as a bookmark to their Springboard.

If I remember correctly, when you launch a springboard web app the application then gets contained within a UIWebView instead of being launched from within Mobile Safari. This means that your UA string has changed; but only slightly.

Here is the UA string for Mobile Safari:

Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_3 like Mac OS X;  en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2  Mobile/8J2 Safari/6533.18.5

And here it is for a Springboard Launched Application:

Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8J2

If you are going to be doing UA detection, it’s probably safer to look for the iPhone OS string instead of something like Mobile/*** Safari/***

 

First PourSo my first brew is completed, and after all the worries I’d have to say everything has turned out alright. When I think about how to describe what making the first brew is like I kinda want to draw parallels to have a kid. It seems that you try to follow whatever directions you have to the best of your ability but always question yourself during the process. Did I sanitize enough? Did some of that water that had store bought ice in it get in my wort? Why does this warm, uncarbonated beer taste horrible? Though, I may be completely wrong since I don’t actually have children but it feels like the sort of questions I would ask while raising a child.

As for the beer itself, it’s actually pretty decent. Although it’s not as complex as what you’d get from craft breweries, it’s drinkable. Now that my first batch is complete I’m going to be starting my second which will be an APA this time.

In case you are curious to see what the end result looks like, here is a picture I took after opening my first bottle.

 

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.

 

Well so do I! Here’s a good article that covers how to setup your emacs configuration so you can become a more effective developer.

Effective Emacs

 

A little over a week ago I decided to figure out if there were emacs modules which would allow me to do all my Android development with. Of course there were, and it was just a matter of getting my environment setup in order to have everything working.

Much of this required actually getting Java tools installed, which is a fairly large pain. There are several dependencies, and for a somewhat new Emacs user somewhat complicated. As such my entire environment isn’t fully set up yet (still no auto-completion and auto-detection of libraries are glaring omissions right now) but I’m pretty satisfied so far. I find I’m a smidge slower than on Eclipse, but considering how I would have eclipse fully lock up on me for several seconds every once in a while I’m confident it balances out.

Although I haven’t gotten into anything crazy yet (debugging, testing) I’m pretty satisfied with the tools I have available to me. By simply typing in M-x android-ant-compile I can run the ant tasks for my project. I also get some nice features like logcat output in an emacs buffer as well. I’ll continue to update my experiences in using emacs for Android development in the future.

References:
© 2011 Christopher Saunders Suffusion theme by Sayontan Sinha