Android 1.5 to 2.0 Support in EDGE

After spending a day with Java reflection, I believe that we are now at the point where PhoneGap Android can now be supported on 1.5, 1.6 and 2.0 versions of Android. This wasn’t incredibly hard, except for the fact that I was unfamiliar with reflection, and the example on the Android site is less than helpful, since it deals with the Debug static methods, and not a real world object that can have things like instances. Also, reading Sun’s documentation made me realize how useless examples that use the word Class is as a classname.

The result of this is that we may have a JAR that can be used on Android 1.5, 1.6 and 2.0, which solves the divergence issue. However, this doesn’t mean that we have SQLite database storage that doesn’t exist on Android 1.5 or 1.6. It means that if you are using Android 2.0, you have access to the SQLite Database if you are running the Edge version.

After pairing down PhoneGap to a jar, it appears to be weighing in at under 200k. I’m thinking about distributing it as an installable library on Android so that if you have it installed, you can download PhoneGap compatible APKs. This would be similar to the Text-To-Speech API functionality. This may encourage Google to close the browser gap, or it may just get ignored if people just use their own stand-alone PhoneGap + app apps.

More info on this will come shortly.

PhoneGap.jar

Hey

Recently, we’ve been making changes similar to the iPhone code so that we can make it even easier for people to write Android Applications. We’ve encapsulated the PhoneGap source code into a JAR file, so that your Android Application can literally be as short as this:


import android.os.Bundle;
import com.phonegap.*;
public class TestApp extends DroidGap {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.loadUrl("file://android_asset/www/index.html");
}
}

Of course, you’d have to have the AndroidManifest setup correctly to accomodate the activities, but this is minor in comparison to how messy everything’s been before this change. We’ll have to do more restructuring of the repository to demonstrate how to use the new library in Android Applications, and this should allow for the Java code to be abstracted away and made even easier. Of course, we’d have to do more work to figure out how this will work on Android 2.0, but it’s some exciting stuff.

Android Splintering

*EDIT*: Apparently Rogers didn’t push an upgrade to Android 1.6, and it’s very possible that they may never push up this update. Since I still use the phone I received from Google IO, I was not aware of this.

Recently, there’s been talk about Android splintering. This isn’t a rumour, it’s a fact. Here’s a short list of the Android Devices that are either in Canada right now or are slated to arrive and what they support:

  • HTC Magic (Rogers): Android 1.5 (Upgradeable to 1.6)
  • HTC Dream (Rogers): Android 1.5 (Upgradeable to 1.6)
  • HTC Hero (Telus): Android 1.5
  • LG Eve (Rogers): Android 1.5
  • Motorola Milestone (Telus): Android 2.0 (Coming: Early 2010)

OK, this sucks! Android 1.6 introduced one MUST HAVE feature for Android, and now we’re excluding ALL the Canadian carriers? Now, it’s clear that Telus didn’t really have Android to begin with because of the fact that they were stuck with CDMA so long. However, that being said, this is not theoretical splintering, this is something that’s happened. Now, while I don’t care about the LG Eve, since it looks like a piece of crap (I can actually walk into stores and look at these devices!), I do care about the HTC Hero not being able to run PhoneGap.

Now, I could downgrade, but I lose support for the Sony Ericsson Xperia X10 and the Motorola Droid, but I can tell you right now that we’re not going to downgrade. This trend of shipping devices with a sub-standard version of Android needs to stop. I don’t expect people to ship with 2.0, because while it has nice, new features, it’s clearly got some issues that need to be resolved. However, shipping without the latest minor version (1.6), or at least pushing an OTA update is stupid. Hardware manufactuers and carriers need to keep in line with latest, which should be pushed to the Android Open Source Project repository. If that doesn’t happen early, and often, it’s going to keep frustrating developers.

It's the end of the Nokia Symbian world as we know it, and I feel fine

So, after hearing the news that Nokia will be dropping Symbian from their High-End N-Series phones by 2012, and adopting Maemo, I decided that I would do a bit more research into the platform. I heard good things about it being open and it having an actual mature Linux stack (as opposed to what is running on Android and Palm), and I wanted to see how much effort it would take to get a PhoneGap prototype to run on it. At around 4 PM, I have this to show for it:

PhoneGap Maemo

I used QtWebView to implement this, and it took more time to get the SDK started and working than it took to actually write the app and run it. I think getting the SDK for Maemo was the biggest hurdle for developing for the device so far. Of course, this is ONLY for Nokia phones, and not for many other phones, but the fact that the N900 was a device that I was considering until I found out it couldn’t support Canadian HSPA frequencies, I figure it was worth messing with. Also, QtWebKit is a part of Qt, and in theory can run on Windows Mobile with mostly the same codebase. With the uncertainty of whether Maemo would get Symbian WRT running on the device in some way, this may be an option.

At the end of the day, I’ll probably stick with my Android Phone, but this was rather interesting.

Where Data Lives on Android

Recently, I’ve been looking at the old Audio Handler code that was contributed a while back and why it can only play on the SD Card. I assumed that there was some weird permission issue that didn’t allow for data to be written in other parts of the device, but I didn’t look into it too closely until recently.

In PhoneGap, the files that are being loaded are stored in the assets directory. The decision to do this was because they could be accessed through file://android_assets, and this seemed to be rather convenient for the time, since I wanted to prove that you could in theory take the HTML and Javascript from an iPhone PhoneGap app, and put it into an Android App and have it still work. However, the issue is that this is not really a file location.

All files in the Android solution are zipped up and compiled into an apk, which is signed and installed on a phone. Dalvik comes across this package, and runs this package much like a traditional Java VM runs a JAR. The big difference is that if you’re trying to do things like access a file natively, store data into a database, or run an executable, this doesn’t work. Now, in the past, we just used the SD card for when we needed file storage, BUT last week when figuring out the WebKit SQLite Support for Android 2.0, I discovered where the data actually was being stored on the device, in the /data/data/package_name/ directories.

I then decided to look at how other people are using this storage, and I checked out the Orbot project. A while back, I had a passing interest in porting Cryptographic tools such as OTR and Tor onto Android so that I could have this on my phone. However, other people who are more dedicated to making awesome things, actually made this happen with Orbot, and shared the source. I saw that they were grabbing an executable written in C, and storing it in the data directory. This allows for ARM code to be run on the device, and allows people to get around the Android SDK, and the problems that it has.

So, I’m faced with a dilemma. Do I keep with storing the data in the assets directory, or do I copy the www directory to the /data/data/app_name/www directory and allow the files to sit in the Application FS storage? Will there be an issue on initial install? Will Android PhoneGap require a loading screen where we do this sort of heracy? Putting layout and executable code in the /data/data directory herasy? What do you think?

How To: Implement HTML5 Storage on a WebView with Android 2.0

So, after many days of using DDMS to poke around the Emulator subsystem I saw the way the new com.android.browser activity interacted with the data. I’ve took a TestCase code (which is like PhoneGap for Android, but stripped donw with only the WebView component), and hacked around with the old stickies example so that I can get it to work. So, here’s the steps to do it:

Step 1: Create a WebView, similar to the one in the PhoneGap source.
Step 2. Get the webSettings, and set the Database Path. The path should be the path to your databases, which will be /path/path/your_package_name/.


appView.setWebChromeClient(new WebClient(this));
WebSettings settings = appView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setDatabaseEnabled(true);
settings.setDatabasePath("/data/data/org.infil00p.testcase/app_database");

Step 3: Create a WebChromeClient, and override the onExceededDatabaseQuota method. This is called when you first open the application because there’s initially no database setup. This will allow you to set the quota in Java. Since this was test code, I just threw an arbitrary value in here.


final class WebClient extends WebChromeClient {
Context mCtx;
WebClient(Context ctx)
{
mCtx = ctx;
}
public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize,
long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater)
{
Log.d(LOG_TAG, "We exceeded the quota");
quotaUpdater.updateQuota(100000);
}
}

OK, we now have a database that we can store things in. When dealing with Android Databases, remember to do all your database debugging on the device or a rooted phone, since you can’t get access to the SQLite Databases from adb with the standard firmware on consumer devices, and this includes the latest images for the Android ADP1 and the Google Ion phones. I’ve just gotten this to work now, and I haven’t tested this method with the Geolocation Database, but I would assume that it would be similar, except that there would just be the Cached Location. What I found odd about this setup was the fact that I couldn’t write the database directly to the emulated SD Card on the device, which would make sense. I’m definitely going to play with this more, and refine it so that it’s less hacky and more polished. However, the stickies example works now, and we will try porting existing iPhone Applications that use this SQLite storage soon.