I finally found a little time to do some Android coding. The result is a new sign-in flow for Yoke:

Here I’m trying to make it as simple as possible for users to establish an identity with an application. The activity is part of a generic Android library I’ve developed that matches an app’s look using style declarations to override the default appearance.

There’s also a nice technique in use here: The explanatory text is in a ScrollView. To bottom align it when the text doesn’t fill the view I combine the attribute android:fillViewport with a vertical LinearLayout (to hold the text) that contains a trivial zero-height View of weight 1. The result is that, when the text is smaller than the ScrollView, the trivial View soaks-up all of the empty space, pushing the text downwards, and when the text is larger than the ScrollView, the trivial View get squeezed to nothing.
The Google favicon is a placeholder — does anyone know of an approved icon I can use?
I’ve been working on a project called Yoke. It’s a server application for enhancing mobile applications and it’s accompanied by an Android library that takes most of the effort out of using Yoke in Android applications.
I started working on Yoke because there were a number of features that I really wanted to add to my Android applications for which I lacked a good approach. My key problem was:
How to make user generated content shareable?
Mobile devices typically have spotty internet connections, so if you want to make the user generated content accessible in a reliable way it needs to be copied to a server. And unless you want to prevent users from editing their content after they have shared it, you need a way to update content that’s already been uploaded. And since it would be quite annoying for a user to request these updates manually, it needs to be done automatically on their behalf (without failing “annoyingly” if the network fails). And since users might use the application on more than one device it’s necessary to synchronize the user content between all devices and the server, in both directions. Using the application across multiple devices in this way further implies that each user needs some form of identity within the application.
Then there’s the actual user mechanics of sharing to consider. Although sharing within an application can be as simple as making content visible to all the other users, the reality is that, for even mildly popular applications, the volume of content generated requires indexing and sorting to make it navigable. And because user generated content naturally varies in quality you need a mechanism for surfacing the best content. Approaching this (as I have) by allowing users to ‘like’ or ‘favorite’ the content of other users involves many other considerations: how to cope with flurries of ‘likes’ on extremely popular content, how to provide a stable ordering for browsing by popularity when it is constantly fluctuating, how to accommodate content that isn’t public, etc.
Simple sounding problems can hide a lot of complexity. Yoke is my attempt to write a reusable platform that does only as much as I need to let users share content via my mobile applications. I just want to give them an easy way to:
in a way that doesn’t constrain the applications I can write.
I think I’m almost there now, Metaglow has been my testbed which I’m looking forward to releasing soon, after that I’m going to try and find time to write a few posts about what I learned by implementing Yoke.
I take accessibility very seriously, so I’m really glad that new guidance on accessibility on Android has been made available to developers.
One of the problems with designing accessible applications is that it’s very easy to overlook the needs of users when you don’t share those needs. This is compounded when users have diverse needs which is the case when considering accessibility; the blind or partially sighted have completely different needs from the deaf or those who are hard of hearing.
It also doesn’t help when you make mistakes like this (from my Metaglow app). This all looks okay on the surface (but not especially great): simple layout, Dpad navigable, labelled buttons.

Until I considered the implications of my general design for this activity:

Which I belatedly realized leaves no way of navigating to the tabs at the bottom of the screen, except by touch: with focus falling naturally on the first element in the grid, the user can never move down far enough to reach the tabs because the list of favorites is effectively infinite for UI purposes.
Fixing that mistake involves too much re-work for the first release, so I’ll have to stick with the misdesign for now. Here’s a tip: don’t combine heavily populated AdapterViews with bottom-tabbed activities.



Since two people have made the same comment, I have to take it seriously, but I’m still having difficulty seeing the similarity to M&Ms. Yes, it’s an M in a circle - but so is the sign for the Paris Metro.
Am feeling all coded-out at the moment, so I’m trying to stay productive with a bit of icon design. I’m not content with either of the possible designs I have at the moment.
Thankfully, I’m a much better programmer than I am a designer.
Metaglow promo image (work in progress)
I’ve been unable to code for the past week, so as I started to ease myself back in today, I took time to investigate a phenomenon I first noticed months back.
Reto Meier has been a strong advocate for the use of analytics, his code and all the available sample code indicate that you call the analytics tracker on the UI thread. But if you use the Google Analytics SDK for Android like this, calling the tracker on the UI thread, it can make your app very unresponsive. I noticed this after adding the library to my Metaglow application, buttons that had felt very snappy immediately felt sluggish, even though I’d taken care to keep the UI thread ‘hygenic’.
Today I sat down and wrote a little stub of code that collects some basic call-time statistics for the GoogleAnalyticsTracker class from version 1.1 of the SDK. I made a few runs on my Nexus One by proceeding to use Metaglow over an extended session. In each run I collected timings for approximately 100 calls to the trackPageView and trackEvent methods.
Of the three runs, these were the most typical numbers (one set slightly was slightly faster, one set was significantly slower):
So, you can expect users to occasionally encounter UI glitches of 1/5th* of a second or more just from queuing an analytics event; and (admittedly I don’t have figures for this) it’s my experience that the pauses are more significant than this; infrequent, but long when they occur; this gives a bad user experience.
It’s documented that the analytics data is queued into batches and dispatched separately from the call that records them, so this behaviour (infrequent but lengthy pauses) can’t be due to network I/O. But it is what we are told to expect when we are performing writes to Flash storage. So I used traceview to peek inside the execution of the analytics code and confirm that this was the cause.

Those green blocks, which are just about visible, are writes inside Sqlite3 and this explains the uneven performance.
Since I want to keep analytics I will probably write my own event queue around the Google analytics tracker, to decouple it from the UI thread. If you use Google analytics and want to give users a smooth experience, you may need to do this work too.
(*) this figure is based on 2 standard deviations above the mean
In a previous post, I described how I could dynamically generate a continually evolving logo by masking and layering several different bitmaps.
This worked well enough, but failed to look convincing when the rendered texture was light. I overcame this by creating a halo effect, to make brightly textured emblems appear to luminesce. Again, the 2D rendering apis in Android made this very easy.
I start the process with the rendered texture in a Bitmap:

Using a Canvas over a tiny 3x3 Bitmap I produced a scaled copy of the texture.

Using the Bitmap.getPixels() method, I created a SweepGradient through the eight outermost colours.

Finally using a black-to-white-to-black RadialGradient applied with a PorterDuff.Mode of MULTIPLY a circular ring is of compatible colours is created:

This ring can then be overlayed separately onto the existing image, using the useful TransitionDrawable class to smoothly switch halos.
The final effect can be seen in this video
I’ve just posted a very early preview version of Metaglow - an android application for creating backgrounds. It features the animating emblem that I described in my last post.

Anyone who wants to take a look can download it using Betan which is available via the Android Market (just search for Betan). The password is simply metaglow.
This is a very early release, here are some things to watch out for:
There we go, if there’s anyone left who does want a look:
There are more detailed instructions on using Betan if you need them.