Wednesday, January 27, 2010

Android App Optimization: Using Reflection to test if an Android device is using 'Live Wallpapers'

I agree this may be a a pretty rare usecase, but I've just spent an hour figuring the details out so I thought it only polite to share them. Oneday, someone, somewhere may benefit.

What is Reflection?
It's been around almost as long as Java, described here and examples from Sun here

Why bother?
We've been receiving complaints that our Buzz Widgets are lagging on the Google Nexus One when Live Wallpapers are enabled. A little testing showed that this was down to the apps blurring out the desktop and rendering the content on top of it. If the desktop has a Live Wallpaper running on it, then blurring it eats some serious processor cycles. I understand that Reflection is more costly than directly calling the APIs, but this is just one simple call.

Why use reflection, not the actual API?
I'd much prefer to only have one version of each of our apps in the Android Market and the APIs for this only became available in the 2.1 SDK. Reflection enables us to use the APIs where available, whilst still letting the app run on devices with older firmwares.

How?
Well to get to the point we want to perform the test

if(WallpaperManager.getInstance(this).getWallpaperInfo() != null){//Live Paper, don't blur}

To do this with Reflection we have to use the methods Class.forName(""), Class.getDeclaredMethod() and Object.invoke() a little like this:


boolean blurBackground = true;
//get the WallpaperManager Class
Class classWallpaperManager = Class.forName("android.app.WallpaperManager");
if(classWallpaperManager != null)
{
//find its .getInstance(this) method
Method methodGetInstance = classWallpaperManager.getDeclaredMethod("getInstance", Context.class);
//invoke the WallpaperManager's .getInstance(this) method to get one
Object objWallpaperManager = methodGetInstance.invoke(classWallpaperManager, this);

//discover the WallpaperManager Object's .getWallpaperInfo() Method
Method methodGetWallpaperInfo = objWallpaperManager.getClass().getMethod("getWallpaperInfo", null);
//invoke it
Object objWallPaperInfo = methodGetWallpaperInfo.invoke(objWallpaperManager, null);
if(objWallPaperInfo!=null)
{
Log.d("WidgetDroid","WallpaperInfo not null");
blurBackground=false;
}
}

Also to ensure it is only run on Android 2.1+ devices I also wrap it in a quick Android Version check and a try/catch block for future safety:
if(Double.parseDouble(android.os.Build.VERSION.RELEASE)>=2.1){...}

Job done, now if the device is using a Live Wallpaper the apps background isn't blurred and all is well again in our Widget World.

Monday, January 25, 2010

The Android Market sweet spot & USW hits the 'final milestone'


The Ultimate Stopwatch & Timer for Android has just made it passed the 'final milestone' of 250,000 installs, great stuff. It's my second app to have reached the dizzy heights so far, the next is a couple of months away yet at around 150k. Seems like new device sales are keeping the install rates strong. Reaching 250k has a bizarre effect of dramatically increasing install rates. It is apparently a far more complelling proposition to install an app with >250k installs, almost as if the user starts believing they're missing out on something great. Battery Widget has rocketed from 250k to 450k installs in less than 2 months.




It seems, even though the Android Market is getting pretty busy these days, that if you focus on users desires it is still possible to get decent traction. Live Wallpapers are the sweet spot at the moment, they are being searched for by Nexus 1 users and a decent one will get thousands of downloads in the first week. I spent an hour creating 'Duck Paper' last week and it is now at 3,500 downloads. Content apps are a little trickier, especially if you don't have a recognised brand behind you, make them specific and easy to use, then update weekly.

Tuesday, January 12, 2010

Creating an Android 2.1 Live Wallpaper

Quick disclaimer: this isn't a tutorial, but a brief guide of what Live Wallpapers actually are and how I went about creating 'Duck Paper' - my first Android 2.1 Live Wallpaper. There are tutorials here, from Arno den Hond and here, from AndroGames.net

The Android 2.1 SDK was released today and the only major update was Live Wallpapers, so I thought I'd better find out what they are all about. What I found was quite surprising, I'd imagined that they would be some sort of animation or video playing on the desktop, a bit like MS DreamScene, but actually they are more akin to a an Android application open as the desktop. Live Wallpapers extend the WallpaperService class and the animations and interactions are handled in code, just like in a game. Realising this it seemed reasonable to try and port the only game I've written for Android, Duck Hunt, into a Live Wallpaper.

After less than an hour the first version of 'Duck Paper' was ready - as the ducks fly past in the background you can touch them to shoot them, then they fall off the screen.



Fortunately there is an example Live Wallpaper in the 2.1 SDK called CubeLiveWallpaper. This is definitely the starting point for anyone looking to create their own Live Wallpaper. I opened up this sample project, played with CubeLiveWallpaper1 and merged its Engine with Duck Hunt's SurfaceView code, et voila we have a Live Wallpaper.

Unfortunately I don't have an Android 2.1 device to try it on and it runs pretty slowly in the emulator. Once I've had it tested on a real device I'll put it in the Android Market.

Update: I've had it tested by a friend with a Nexus One and all seems well, so it is now live in the Android Market