Wednesday, April 10, 2013

Android C2DM to GCM

I'm trying... really trying to be nice, to give these guys a chance, but boy, they have done it this time...

Long ago, I've implemented a C2DM Module for Cyborg in less than a day, which was elegant tight, and generic... and a few(3) weeks later, Google has announced that C2DM is dying, and now there is GCM... terrific...

Since I'm short on time, I've implemented a GCM Module for Cyborg, happily using the gcm.jar, and its updates every now and again.

Today, I've actually looked at the code of the gcm.jar, and I was shocked, shocked to find out that this code violates nearly all of my basic coding conventions, this is a sort of code I would have written when I've just started to work with Java, and have tried then to challenge the language conventions.

I've been dealing with very bad code for the last years, but this... I cannot make heads or tails of it...
It is noodles all over the place, using too many static methods and members calling back and forth mixed with broadcast receivers and services all together throwing a swingers party... it is bad Java, mixed with bad Android, if Java could have spoken, it would have shouted "RAPE !!!", it is shamley unbelievable.

This is crazy, I know that "Anyone can cook", but would you actually eat anyone's cooking?
I'm expecting more from you Google!

I'm now in the middle of getting rid of this darn jar file, and I see that the basic registration to the GSF service remained practically the same, they have simply mapped some errors and some use cases, with nasty(ing) if statements.

...
After 2 days...
...

I've finally managed sending a GCM from a device to itself via my server, I've used my JSONer to serialize the and deserialize the JSON, and was surprised to discover that the actual GCM payload MUST be JSON Array...

WTF?

If you already force something, force it to be a JSON Object, and let the people use whatever stupid implementation they want within that object.

Force the payload to be an JSON Array, and to add a key - value extras in the intent which derived from the array... it is an unnecessary overhead!!

Any logical application would use a JSON Object as the payload, and use GSON or any other parser to serialize and deserialize the payload.

Friday, April 5, 2013

Check if an application is installed on the device

This is quite embarrassing... I've used to use the following to perform that check:

private static final String GooglePlayStorePackageName = "com.google.market";

void someMethod() {
    packageManager = getApplication().getPackageManager();
    List<PackageInfo> packages = packageManager.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
    for (PackageInfo packageInfo : packages) {
        if (packageInfo.packageName.equals(GooglePlayStorePackageName)) {
            googlePlayStoreInstalled = true;
            break;
        }
    }

Since I cannot stand my own stupidity, and I love to lecture people about how amazing exceptions are and how stupid it is to ignore them, I found that I have done it as well, although not in the same context I lecture people...

Following is the proper code to check whether an application is installed on your device:

protected final boolean isPackageInstalled(String packageName) {
    try {
        application.getPackageManager().getPackageInfo(packageName, 0);
    } catch (NameNotFoundException e) {
        return false;
    }
    return true;
}
As you can see, I've ignored the fact there is a method which throws an exception when it could not find the requested package, which is so dumb of me.

So now I wrapped the method with a boolean returning method, and do use the exception to determine whether the application package is installed or not.