live wallpaper + OpenGL ES 2

I’ve been messing around a bit with OpenGL ES 2, and I thought a neat project might be to try and recreate one of the default wallpapers that ships with Google’s Nexus 4:

Nexus 4 Wallpaper

In my limited experimentation, it actually looked a lot cooler than I expected, so I thought it might be a good idea to implement it as a live wallpaper. As it turns out, I am not the only dedicated fan of the Android 4.2 wallpaper set; developer Chickenbellyfinn has released the excellent Nexus Triangles LWP (http://bit.ly/11D2Jnc) based on one of the others.

I’ve put together a very basic version of it and uploaded it to Google Play. It’s functional and stable, but lacks any configuration options, and doesn’t work on tablets (every triangle renders at least one vertex at the origin, which sounds like I’m doing something wrong in OpenGL). These drawbacks will be remedied eventually, but in the meantime, I wanted to talk about how I implemented an OpenGL ES 2 rendering environment in a live wallpaper, because it’s far from obvious and not well-documented in the Android API docs. The following should work with APIs 14 and above.

As a side note, I will not be uploading the source code for the wallpaper to my Github, because there are already do-nothing clones of the wallpaper on the Play Store with loads of ads, and I’d rather not make their stealing any easier.

GLWallpaperService

In general, Android LWPs consist of a service subclass called WallpaperService, which serve to manage instances of WallpaperService.Engine. I subclassed both to allow for interaction with a Renderer class and a State class which I created for my update thread.

On instantiation of an OpenGLES2Engine, I instantiate a Renderer and a State if necessary. I also instantiate a WallpaperGLSurfaceView, which is defined as an inner class of the Engine:

Within the WallpaperGLSurfaceView class, the most important things are to override the superclass’s getHolder() method in order to change where it gets a SurfaceHolder from, and to define another method that allows for manual destruction of the View:

 

In addition, there are some lifecycle methods that need to be implemented, though in my case they mostly amount to starting and stopping my update thread. My Renderer is configured for dirty rendering, so as long as my update thread stops, no rendering occurs; battery life and UI performance should be minimally impacted if at all.

More

You can find a more detailed skeleton of my GLWallpaperService class at my Github.
You can also find some more details on how to work OpenGL ES 2 into a LWP here, although this article has not been updated in a while.
Finally, you can install my Nexus Circles Wallpaper from the Play Store.