Latest Tweets

 

Betan - sharing beta Android apps

This weekend I finished work on the first version of Betan. It’s an application that allows me to easily distribute private copies of my Android applications to beta testers, clients and other developers.

Privately distributing Android applications to non-developers is something I’ve long found awkward and I’m really pleased to have a tool that makes it much more straightforward.

It consists of a small Java application to encrypt APK files for upload to a webserver, and a simple Android application for downloading and installing them.

I think the great thing about Betan is that it wouldn’t take much work to make it a shared tool for other Android developers; each developer would encrypt and upload their own apks; I would just need to maintain a list of publishers that I present to the user.

I’m currently gauging interest, so if any Android developers are interested in using Betan to distribute their Beta versions, just get in touch; it’s very basic at the moment, but with interest it could grow into something better.

Returning dynamically generated resources

As promised in an earlier post about intents I’m sharing a tip on how to return dynamically generated resources from a ContentProvider — though what’s written here applies equally well to an Activity returning a result.

The basic scenario is this: You have implemented a ContentProvider and you want to use it to return something that is too big to fit into a cursor, say an image. It’s clear from the relevant Android platform javadocs, though perhaps not from the general ContentProvider documentation, that this is done by implementing openFile and returning a ParcelFileDescriptor.

But now suppose that the image resource is being rendered on the fly. How do you implement openFile?

As per the contact of openFile you need to return a ParceFileDescriptor which means that the resource must be returned via an open file (or possibly a socket, which we’ll ignore). This means that the image must first be written to a file, which is then opened as a ParceFileDescriptor. The interesting question here is when do you delete the file?

You can’t wait until the calling process has finished reading the file because (a) you won’t get notified when that occurs and (b) it may never exhaust the stream anyway. You can’t rely on the calling process to delete the file for you either, also, the whole idea behind wrapping the resource in this way is to guard it from direct access by other processes. You could delete the file after a fixed time period — assuming that the caller will have finished reading the file by that time. But this is unnecessarily complex, because the answer turns out to be very simple:

You delete the file immediately after you’ve opened the ParcelFileDescriptor but before you return it from the openFile method. Here are the relevant lines of the PlantProvider class from my Daisy Garden application; the try/finally block is there to ensure the file gets deleted no matter what — the last thing we want to do is leak precious storage space.

The reason this works is down to the way that Linux filesystems operate: directories maintain links to files, when a process opens a file a new link is created, closing a file or removing it from a directory removes a link. When there are no links to a file, the file is deleted.

So by opening the file in our application, we create a link to it. Then ‘deleting’ the file actually unlinks it, but the file won’t really be deleted until the file descriptor is discarded (ie. the last link is removed). This will happen automatically at some point after the calling application has finished accessing the file and any associated ParcelFileDescriptor objects have become garbage.

So it’s a very simple solution, but only if you know something about how the filesystem can be expected to work on Android devices.

Froyo first impressions: All good

Although I’ve been building Android 2.2 (Froyo) from source, I’ve been too busy to play with it on a device. Yesterday evening, my phone got an OTA update and I’ve been using it intensively since. These are the first things I’ve noticed, and they’re all good*:

New home buttons

I really like the button combination at the bottom of the stock home application. Three things I commonly use my phone for: making calls, running apps and browsing, all clustered and available from every page of the home app.

Froyo home app buttons

Smoother UI

The scrolling in the UI is much much smoother. It’s across every application — so either ListView got some magic dust sprinkled on it by the Froyo fairy, or the JIT is demonstrating its effectiveness; swiping the home app is much smoother too.

Call log grouping

The Call log screen now groups sequential calls to the same phone, it prevents multiple attempts to call someone from cluttering-up the log. It’s visually a bit busier, but in practice makes the UI quicker because there’s less scrolling.

Android Market

It’s going to take developments on a number of fronts to resolve all the Android Market issues. But any improvements to the UI are welcome and there are definitely some. Comments can now be rated in addition to being flagged. Comments are now on a separate tab; I like this, it’s more intuitive, faster and fairer (the last 3 comments now hold less sway). A “Did you mean” feature has been added to the market search too. Undoubtedly useful for clumsy screen typists, it doesn’t appear to be on-a-par with the same feature for web searches.

Froyo Android Market

No upgrade issues

None of my applications broke (AFAICT) and all of the applications I use on a regular basis have continued to work seamlessly. This is a characteristic of the Android releases in general: as the platform has matured, fewer and fewer issues have arisen on each update (at least from my perspective as a developer).

Better punctuation

The stock keyboard now makes entering punctuation much easier. This was always a pain-point for me. Hitting space after a word now suggests common punctuation symbols. Perhaps reflecting the times we live in, the exclamation mark gets top billing (the amphora gets a place too). I’m slightly surprised by the presence of the underscore in the absence of the hyphen.

Froyo keyboard punctuation

Debugging Notification

The new debugging notification icon is far better than the warning icon it replaced which so generic it could become confusing. A small but very welcome improvement.

Auto brightness widget

The power control widget includes “Auto brightness” as an option. I don’t tend to use it, but it fills a hole in the widgets usability.

Froyo power widget

*Flash

There is one negative - which doesn’t really qualify as a mark against Android itself: Flash performance. I’ve maintained a disinterested perspective on the desirability of mobile devices running full-fat Flash. I can see that users want access to all the website content they are familiar with, and the value to individuals and companies who have already invested lots of development in Flash is obvious. But I’ve always been skeptical of its suitability for mobile processors. It seems this is a hurdle they have yet to overcome, combined with the repeated browser crashes the Adobe Flash plugin induced, my skepticism has only grown.

An Intent to Pick Daisies

One of my favourite things about the Android platform is how easily application can share data using Intents and ContentProviders. They provide a universal basis for Android applications to interoperate and I try to expose them whenever it’s practical, even for something as singular as my Daisy Garden application.

I’ve just published a new version of Daisy Garden and with it, Intents and ContentProviders that enable the users of other Android applications to choose flowers they have grown in Daisy Garden — assuming that the developers choose to support it. And the great thing is that supporting third-party intents is very easy to do (and even if no other developers use them, they will be heavily used to integrate my own applications).


An example of what the user sees when picking a flower.

The Java code embedded below is a self-contained Activity that responds to a tap on the screen by inviting the user to pick a flower and then displaying the flower as a bitmap. There are two basic parts: forming an Intent for the user to pick a flower and forming a Uri to the flower’s bitmap. Both of these aspects can be customized; messaging to the user, and the bitmap size for example.

It’s very simple — more than half the code is boilerplate and comments. And this is what’s really good: in a well structured Android application this functionality is simple to expose too — I’d go as far as saying it’s almost automatic, so there is very little reason not to share (non-sensitive) data between applications.

Having said all this, there is an interesting technical detail here that meant that I had to give some thought to exposing the bitmaps. Daisy Garden is generating the flower bitmaps “on-the-fly” when they are requested from the ContentProvider and it’s not obvious how to share these unless you know a little about how Linux filesystems work. I’ll try to find some time to outline the technique in a subsequent post.

Java code follows:

A poor bit of user interface design in the twitter widget for android in an otherwise a well designed and intuitive application.

What do you think the “Update” button is going to do?


Submit the text in the “What’s Happening?” box?
Refresh the current tweets?
Something else…

Yes, it’s 3.

It can’t be 1. As android developers will understand, you can’t usefully put an editable text view into a widget (the Google Search is not a bona-fide widget). So the designers/developers have followed the pattern of showing the “Create Tweet” activity when the text view is clicked. This works really nicely.

And it isn’t 2 either. Even though the twitter website, and the rest of the android application, refer to the action as “Tweet”, the “Update” button does exactly the same thing here. It duplicates the action of clicking in the textbox. This is wrong on three counts:


The language is inconsistent with the rest of the application, for no benefit.
It reinforces the expectation that the text box can be typed-into, it can’t.
It robs the user of space to perform a useful action, like actually updating the tweet stream

What prompted me to post this is actually a second (and I feel more significant) issue with the app: there is no “About” screen, no information about how to contact the developer, not even any confirmation that it was developed or licenced by twitter.

I would have emailed my observations instead of posting them, but they weren’t courteous enough to provide their contact details.

A poor bit of user interface design in the twitter widget for android in an otherwise a well designed and intuitive application.

What do you think the “Update” button is going to do?

  1. Submit the text in the “What’s Happening?” box?
  2. Refresh the current tweets?
  3. Something else…

Yes, it’s 3.

It can’t be 1. As android developers will understand, you can’t usefully put an editable text view into a widget (the Google Search is not a bona-fide widget). So the designers/developers have followed the pattern of showing the “Create Tweet” activity when the text view is clicked. This works really nicely.

And it isn’t 2 either. Even though the twitter website, and the rest of the android application, refer to the action as “Tweet”, the “Update” button does exactly the same thing here. It duplicates the action of clicking in the textbox. This is wrong on three counts:

  1. The language is inconsistent with the rest of the application, for no benefit.
  2. It reinforces the expectation that the text box can be typed-into, it can’t.
  3. It robs the user of space to perform a useful action, like actually updating the tweet stream

What prompted me to post this is actually a second (and I feel more significant) issue with the app: there is no “About” screen, no information about how to contact the developer, not even any confirmation that it was developed or licenced by twitter.

I would have emailed my observations instead of posting them, but they weren’t courteous enough to provide their contact details.

Change notification

Change notification

Change dialog

Change dialog

Change dismissed

Change dismissed

The Android Market has its deficiencies. I don’t think anyone would deny that. One of the niggles is that there’s no place to list the changes between application versions.

I think this is very important in Android applications because the limited screen space often necessitates moving access to core application functions into the menu. Users who are already familiar with an application may never discover a new feature that has been added to a menu that they opened once and never since.

Instead of lamenting the Android Market’s inability to display my application changes to users, I decided that the information was important enough to move in-app; in the past I’ve simply logged changes on my website. The design I settled on was to introduce a small notification at the top of my main application activity - about the size of a mobile ad - that appears if there is change information to present to the user. The user can tap the notification to read details about the changes in the latest version.

Not all updates will need explanations, so the user may not receive a notification on every update, and users can cancel a notification without bothering to read it. Accidentally dismissing the notification isn’t much of a concern since on the next update the user can page backwards and see the descriptions of previous changes.

This functionality will be included in the next release of Daisy Garden. I think it works well and I hope users like it; the use of animations to show and hide the notification adds extra bit of polish. And I’ve implemented it as a library project, so I’ll be able to introduce it into my other Android projects.

I think every developer should consider adding something similar to their applications.

Sharing is hard to do (safely)

When I developed Daisy Garden for Android one of my goals was to build a simple environment in which people could share something, knowing that there was no possibility of being offended, or of giving offense. I certainly wanted an application where I never needed to be policeman to its users.

Imagining the phone in the hands of, say, a five-year-old child, it turns out that it is harder than one might expect to build something that permits safe and ready sharing; there are many constraints:

Now, collaborative filtering can certainly address these issues, but only after a number of individuals have flagged the offending content. Returning to my example of the five-year-old holding a mobile phone, that child’s parent might not feel that a “flag as inappropriate” link was adequate in this context.

Back to Daisy Garden. In addition to these constraints, sharing necessitates that there is something worth sharing. Further to this, if you want people to share across cultural boundaries, it has to be something universal, something that everyone can appreciate. This is what led me to the idea of flowers, and gardens.

And I’m not as authoritarian within Daisy Garden as the observations above might suggest - where individuals share outside of the application, I’m much more relaxed - for example, users can name their flowers when they share them with others. But now that I’m beginning to add features that will allow users to share their garden designs with all other users of the application, I’m very glad I considered these things before I released the early versions of Daisy Garden.

P.S.

I did want to post/tweet this under the title “How to keep your application genital free”, but didn’t want to offend anyone.

An dr oi d

I’m diving back in now, but I’ve been too busy in the past 6 months to engage in any serious Android development; I’ve only been able to admire all of the exciting new developments - new apps, new handsets, new services and, of course, new platform releases.

Reading Dan Morrill’s post on android compatibility prompts me to share my personal irritability at the constant reports one can read about android ‘fragmentation’. This exercised me quite a bit during the build-up to the iPad SDK release.

Firstly, most of the comparisons that writers make between Android and J2ME are lazy and bogus: J2ME is a specification and Android is a ‘codebase’. As a consequence, the scope for incompatibilities between Android devices is significantly smaller.

Secondly, the comparisons between Android ‘the platform’ and iPhone ‘the product’ often dwelt heavily on the fragmentation bogeyman. When a new device, the iPad, arrived and had hardware specifications at variance with those of the iPhone many developers expressed concern that they would need to modify their applications to take advantage of the new device.

I suspect that many of these developers, those who might once have regarded the iPhone’s defacto consistency as an advantage - a simplification and timesaver - now find themselves with more work than is necessary to support two devices than if they’d developed their application for a platform that supported them in the task. Say, like Android!

And now to the crux of my annoyance. I’m addressing developers here when I ask: Are you really serious providing LOTS of users with a rewarding experience of your application?

Because if you are, then you have to be ready to accommodate them, and they’re pretty a variable bunch. I don’t want to get preachy, but not everyone speaks or reads English. Some people can’t read at all. Many people have weak eyesight and some are completely blind or deaf for that matter. I could go on, but my actual point is this:

Not every possible user’s needs can be met by the same mobile phone. The user variability that application developers attempt to handle via good UI design, accessibility, and internationalization, extends outside of the software domain and into the hardware.

Most of the concerns that developers flag-up as being aspects of fragmentation are simply the realities of addressing the needs of these users, large numbers of them. Some users will be poorer than others; they can’t all afford the newest/best handsets. Some need larger screens for their bad eyesight. Perhaps their motor skills are poor and they prefer a real keyboard. etc.

Android is a single platform that is designed, within reason, to accommodate as many mobile phone users as possible, and it supports us developers by providing helpful libraries, tools and APIs that can make a single application binary accessible to them all.

If you’re serious about making a mobile phone application available to the greatest number of users possible, I think you should develop for android and embrace the tools it provides for coping with the diversity of its users, not exhibit every hardware variation it exposes as evidence for its present/eventual fragmentation.

ADC Judging

I’ve been meaning to post something about the Android Developer Challenge for a good while, but I’ve been so busy recently (architecting a multi-faceted e-commerce system at the moment) that I’ve had no time for anything else. In fact, I was so busy that the results almost passed me by.

Daisy Garden didn’t win. This was not surprising since I’d had an opportunity to judge a number of the applications in entertainment category. It’s not that I felt there were lots of significantly ‘better’ applications, but that so many of the applications were more suited to the challenge. Congratulations to all the winning entrants. My prediction had been for a music app 1,2,3 in my category and I was almost correct (it was a music app 2,3 instead).

But the results aren’t what prompted this post; I’ve been more interested in how the voting has been structured in both challenges, and I’ve had the opportunity to think about it: my entry into the first ADC flopped, then I joined a team that went on to win, this time round my entry made it to the shortlist but didn’t win - so I’ve pretty much run the gamut of possibilities.

I was mildly critical about the structure of the voting after the first ADC. In my opinion, it pretty much amounted to a map-reduce algorithm in which apps were distributed over judges. The ADC2 was essentially similar and introduced bucketing (perhaps ensure variety?) and pre-filtering with a public vote (to ensure the expert judges had a manageable task, I’m sure).

My basic criticism was, and remains, that such a voting scheme hampers people’s capacity to reach a good judgement because it doesn’t provide a medium through which they can influence each other’s evaluations. The judging process essentially atomizes the judges and fails to take advantage of their human strengths. And I think that understanding this has implications for my field of endeavour: creating software.

I think I’m paraphrasing Bjarne Stroustrup here when I say that software design involves balancing lots of subtle and complex considerations, and the best place to do that is inside the brain of a programmer. If one accepts this, there is an implicit assumption that all of the necessary considerations are known (and will fit into one brain*). I believe this perspective explains a lot about why ‘design by committee’ fails: a team of human’s can’t compete with synapses at transmitting and evaluating ideas. It also explains why ‘elite solo programmers’ may often fail: they can form good judgements but usually don’t have all the necessary data.

In trying to avoid the worst weaknesses of these two extremes, I look to encourage good design by:

With this approach I try both to preserve the clarity that solo-design frequently provides and avoid the narrowness that often accompanies it.

Back to the ADC judging. Forming an unqualified analogy between designing software and judging is application is clearly absurd, but there are similarities, and I think that a panel of judges who freely discussed their opinion about each application before recording individual ratings would provide fairer judgements than may have been the case in the Android Developer Challenge. For example, if there were five judges, and one judge knew that the application under consideration was a direct copy of an existing application, he could share that information with the other judges who could factor it into their rating. Without that exchange of information, the more knowledgeable contribution becomes marginalized.

The point is to target two human strengths: information sharing and individual decision making. Of course, the curse is that this approach doesn’t scale, but I’d love to find one that does, because I’m sure I’d learn a lot about designing software from it.

Thanks to Google for hosting and funding the Android Developer Challenges, it’s been fun.


(*) I think this is the simplest gauge of whether a software project will be successful: If the requirements can’t simultaneously fit into one brain then problems are unavoidable.

Daisy Chase gameplay

Daisy Chase gameplay

Moseycode registration

Moseycode registration

Scanning a Moseycode to get new levels

Scanning a Moseycode to get new levels

It’s been an extremely busy few weeks and I’m now looking forward to having a little more time to focus on Android development again. One thing I did achieve this week was to put live a very early version of a game I’ve been developing called Daisy Chase. It’s a “simple” game in which you have to capture flowers by linking them together. I say “simple” instead of just simple because I’m again humbled by how I can misjudge what users will really can understand simply. Nevertheless, I’m quite pleased, the game appears to work (no bug reports yet) and some users report really enjoying it. I would have liked to have entered it into the ADC2, but I had no time (and the competition in the game categories looks especially strong).

I’m really excited about two elements of this new Android application. The first is that it will be the first application that makes use of the Moseycode publishing API to allow users to publish, own and share their own levels. One of the screenshots above gives a preview of the user registration page (not yet incorporated into the application).

The second thing is that, as a big fan of the Intent system used in Android, I’m looking forward to the integration that game will have with Daisy Garden. For example, By achieving particular goals on a level, you will win one of the flowers that appears in the level and this will be added to your garden. In the full version of the game, levels will be collected into gardens and completing all of the levels in a garden will add that garden to the collection of gardens you can grow flowers in.

It’s all part a minor (but time consuming!) experiment in how games, and not just regular applications, can be broken down into separate units that have individual value. It’s a remarkably involved task to do effectively.

The alpha version of Daisy Chase is available from the Android Market.