Skip to main content

π Time, the coolest way to tell time since the Sundial

I have written a small application for Android called π Time. π Time is a widget for the Home Screen which displays time in radians. Why would I write such a thing? Well... because radians are cool, so cool that a bunch of physicists at Otago University thought it would be cool too. Actually they, with the help of my creative consultant PhyPhoFu had the initial idea "Hey! We should use radians to tell the time of the day!" I am merely the monkey that made it real.

The Feature Graphic for π Time


The Technical Details (In Procedural Form)
"One does not simply write custom UI widgets for the home screen."
Okay this will get confusing quickly unless I clarify something. On Android there are widgets... and widgets. I mean, there are the kind of widgets programmers talk about, a piece of code which displays graphics and can be interacted with on the screen. Then there are widgets of the kind everybody talks about which is the result of a bunch of programmer widgets and a bundle of application logic. The thing you put on an Android Home Screen is the second kind. The programmer widget thing I'll call a UI widget just to be clear. You'll find this naming convention in the Android docs... sometimes.

On an aside Microsoft had a pretty good solution to the whole mess. Call the first kind, the uh... programmer widgets, a widget and the second kind, a um... widget, a gadget. Actually it works pretty well and you might have noticed this with Vista and 7, but since this is about Android, a decidedly non-Microsoft property, I'll stick to the UI widget/widget naming scheme.

Left: A home screen with a widget - π Time.
Right: An application composed of a whole bunch of widgets... sorry UI widgets.



Widgets clarified I'll get on to π Time. To write π Time I first had to overcome some, by design, limitations in the Android SDK. Somehow I had to write a whole new kind of clock UI widget that would display on the home screen, doing which is somewhat analogous to "...simply walking into Mordor". Actually I'll rephrase that since it is cool. "One does not simply write custom UI widgets for the home screen."

The reason why you cannot write a custom UI widget for the home screen is because you didn't write the home screen. Somebody else wrote the home screen and you are not allowed to execute code as somebody else. Normally to write a widget you are basically describing it to somebody else and they then draw the widget based on that description. You say, here I'll have a button, and over here, there and everywhere an image. You also say you have a bunch of things you want to be told about, say when a user touches that button or something, and eventually you'll get told about those events. Why is this bad, well it isn't, unless you want a UI widget that has dynamic content, like a clock. 

You know, I was always wondering why all the widgets for the Android home screens were all so static. I mean, where were all the scrolling widgets? Well Google solved the missing lists and things in Honeycomb and Ice Cream Sandwich (Android versions 3.x), that means we will be seeing dynamic content on our home screens in the future. But unfortunately I still don't have my custom clock that counts time in radians. So what to do? Well if you think about it a UI widget is largely a bunch of code to draw some graphics, and it turns out we can draw graphics to a widget, in a roundabout fashion. I am not meaning the typical blit some pre-rendered image to the screen, obviously home screens widgets are already doing that because we see them every time we unlock our phones. This is the read deal! Dynamic images! Okay so it isn't that exciting, but by drawing to a buffer in memory I can then push that to the widget on the home screen.

Wait slow down... push images to the widget? That sounds easy. Yeah okay so we can update the widget arbitrarily from the original application. It is easy... except the images I wanted to push were actually pretty big because the image buffers Android uses in memory are uncompressed. This resulted in messages in the device log something like
!!! FAILED BINDER TRANSACTION !!!
If you do a bunch of Googling you might find out what this means, but you have to filter plenty of noise to get there. In this case it meant that I was pushing too much data between my application and the software drawing the widget. In Android there is an upper limit of 1MB for IPC (Inter Process Communication) and I was pushing images of about 300k at that time. It worked well for when a user had one widget running but quickly fell over when a user wanted more. Also there seemed to be resolution issues that I didn't explore because I quickly thought up a better solution. Save the damn image to file!

To put it simply I had to write the π Time widget by having my application simulate a new kind of UI widget by drawing a whole new frame every given interval of time, saving that image to the disk and then telling the widget to load the image. In the end it works well enough, there are some issues, for example the next alarm icon can't be updated in real time, instead it has to wait till the next frame is drawn. However that has nothing to do with the custom UI widget issue. Another issue for another day!



Comments