Wednesday, August 25, 2010

What You Can Do With Your Modal Dialogs and Splash Screens (and the Horse They Rode In On)

Every time I'm presented with a splash screen, what I actually see is the app developer giving me the two fingered salute. The only thing more hostile is the use of a modal "loading" dialog: a UI metaphor used exclusively to save developers time at the expense of every single one of their users.

The apps which make me want to do something out of character start with a splash screen before segueing directly into a modal "loading" dialog. It's like they're spitting directly into my face. Why? Why do you hate me so much? I just want to use your app, I don't deserve this kind of hostility. No one does.

The 90s called, they'd like their UI metaphors back

Modal windows have always been a crutch. Windowed operating systems are by nature multithreaded, so to avoid apps "freezing" you execute time consuming tasks on background threads. This introduces complexity as the user can potentially interact with the UI between expected states.

The easiest solution for developers is to stick up a modal window that steals focus from the application and prevents users from interacting with the UI until the app completes the background task.

With great latency comes great responsibility

The ascent of the web as a platform largely eliminated these anachronisms. Page load times have a dramatic influence on how quickly people navigate away from a site. When page load latency is being measured in 10s or 100s of milliseconds, it's not surprising that splash screens and "loading" dialogs have all but disappeared.

The good news is that users have also gotten used to content being loaded dynamically. Most people won't bat an eyelid at a page which loads text first and updates the images afterwards. It's expected behaviour.

Users will use the time it takes getting past your splash screen uninstalling your app

It's ironic that a platform that has even less allowance for delay has seen the reintroduction of the dreaded "loading" dialog. Sadly too many devs have gotten lazy. It's harder to develop a UI that works smoothly and intuitively while data is loading or processing is being done, so many don't bother.

Don't be the lazy guy - "it's hard" isn't a valid excuse. Mobile users are incredibly impatient, phones are used on the move and users constantly switch between applications. To be successful you need to make startups and transitions fast and seamless.
  • Asynchronous tasks. Make sure anything that could take longer than a small fraction of a second happens in a background thread (use ASyncTasks to help). Use a Service to run tasks that should be completed even if the Activity is killed.
  • Branding fail. You want your app to seem an integral part of the device. Every time you show a splash screen you're reminding people that they're using an add-on -- an add-on they can replace with something less annoying.
  • Lazy loading. Loading data takes time, particularly if you need to download it first (particularly over a mobile network). It's important that you have something to show as quickly as possible, so take the browser approach by displaying what you can get quickly.  Follow that up with slower items such as images. Load additional content as required when users start scrolling down your list, taking the same approach of text first, images later.
  • In-place updates. Don't clear all your data every time you pull an update from the server. Update, add, and remove items from your UI as new data becomes available. Same with updating existing layouts with images once they've been downloaded.
  • Pre-fetching. If you've got multiple tabs or even Activities within your app, there's no reason to wait until the user changes their selection to start loading data. Pre-fetch the first page of data so that it's ready when the user switches to it.
  • Save your state. Switching between apps should be seamless and instant. Save all your Activity state so your app can resume instantly.
  • Caching. There's no reason to download the same image multiple times. Likewise, it's often better to show out of date information and update it quickly than showing nothing at all.
  • Background loading. Use Services to perform updates and download data while your app isn't in the foreground. This can extend from small amounts of pre-fetching to regular updates, or complete offline support.
  • Visual "loading" elements. Use visual elements like progress bars to indicate that you're in the process of getting an update.
  • Disable unsupported actions. Some actions within your app might not make sense until all the data is loaded. Rather than block interactivity, disable actions that aren't possible.
To see some good examples of how to present no information (or updating information) without splash screens or loading dialogs check out the Gmail and News & Weather apps. Neither use a splash screen (or loading dialogs), and both begin with no information. Once they have data, updates and changes are integrated into the existing data being displayed.


If you're creating a fully immersive experience you may have good reason to use both splash screens and loading dialogs

There's always an exception. If you're engaging in an immersive experience (like a game or turn-by-turn navigation), you don't want to start until the environment is fully constructed. Developers can't use many of the tricks above like dynamic lazy loading, because users want to enjoy the complete experience right from the start. This is especially true of 3D environments like a FPS or Google Earth that rely on an OpenGL environment.

I remember playing California Games on a friends C64. It was loaded via the tape drive, so if anyone quit the game we'd spend the 15 minutes it took to reload in a diverting game of "beat the moron". While it's important to ensure the environment is fully complete before allowing users to explore it, there are still a few tricks you can use to ensure the wait isn't quite as painful.
  • Cache any downloaded content.
  • Dynamically pre-load as much data as possible during gameplay.
  • Save and cache as much state data as possible to ensure players can resume from where they left off.
  • Try to provide useful information (hints? instructions? cut scenes?) in inter-level "loading" screens or splash screens.
  • Delay the longest pauses as long as possible. I should be able to start the game, change the settings, and navigate to "load saved game" without a significant wait.
In conclusion

For most apps, splash screens and modal loading dialogs now belong in the 1990s with 9600 baud modems and pashminas.  Embrace the now.

Tuesday, August 17, 2010

Beyond Mobiles: Android as a Universal Development Platform

Early next year GoogleTV will include the Android Market, meaning that it will be a compatible device. A GoogleTV is unlikely to include telephony support, or a camera, microphone, vibration, compass, GPS, or LED. And it likely won’t be the first Android device that isn’t a phone.

This suggests that there are some changes in store for the Android compatibility definition.

If you were an apps developer when the first desktop computer was released – what would you have built?

25 year ago, when I was writing code in my parents living room, I held little expectation that anyone but me would ever use any of it. Sharing an app meant copying it onto a 5.25” floppy disk and biking it over to a friends house where, CRC errors permitting, we’d run it.

There was also the issue of OS fragmentation. I had an IBM compatible PC-XT, my school housed a collection of BBC Micros and most of my friends had Amigas and C64s.

Over the next decade “IBM compatible” became “PC” and the Internet provided an unprecedented distribution mechanism that lets your apps span the globe in a heartbeat.

Right now there are more than 60 different compatible Android devices

Until recently the only way to get your mobile apps onto a phone was through a relationship with a carrier or device maker. Today, every day, 200,000 more people are activating Android compatible devices and searching the Market for your apps.

The open nature of Android means hardware manufacturers are using Android to power an increasingly diverse range of connected devices. At the same time, the Android Compatibility Program is expanding to make more of these devices compatible.

People talk a lot about the dangers of fragmentation

Where some might complain, I see a unique opportunity. Suddenly we’re presented with a blank slate on which to innovate, a rare opportunity to consider new ways for people to interact with devices with which they are already familiar.

If you, as a developer, want to avoid dealing with fragmentation it’s easily done. Pick a single device and develop only for that (I’d suggest the Motorola Droid). You’ll miss out on an order of magnitude of users, but you won’t have to make your apps resolution independent.

The same code will do the same thing on any compatible hardware

The Android Compatibility Program eliminates the real risks of hardware fragmentation. As a developer, all you need to do is make sure that your software doesn’t make assumptions about the underlying hardware.

So what are the assumptions you need to avoid?

  • Screen size, resolution, and aspect ratio.
  • The existence of particular hardware.
Screen size, resolution, and aspect ratio

Android developers have been accounting for different screen sizes since Android 1.6 and the release of the Verizon Droid and HTC Tattoo. There is an excellent writeup describing how to support multiple screen resolutions on the Android Developer Guide, aptly titled Supporting Multiple Screen Sizes.

At the risk of providing spoilers, it will tell you to:
  • Use density independent pixels rather than hard-coding pixel values in your code.
  • Use layouts such as Relative Layout, that don’t assume screen sizes, aspect ratios, or resolutions.
  • Provide alternative layouts (if required) for small, normal, or large screens.
  • Provide alternative drawable assets for low, medium, or high resolution displays.
  • Use the emulator to test, test, and test.
The existence of particular hardware

When it comes to hardware dependencies, there are two questions you need to address. Does your app:
  • Need any specific hardware in order to function?
  • Use some hardware features if they’re available, but which aren’t strictly necessary?
Apps like Layar aren’t very useful on a device without a camera and compass. If the answer to question one is yes, you need to create a manifest entry declaring the hardware features your app requires. The Android Market will then filter those apps out for devices that don’t have the required hardware.

  <uses-feature android:name="android.hardware.sensor.compass"/>
  <uses-feature android:name="android.hardware.camera"/>


As I described in Future Proofing Your Apps, the Market will make some aggressive guesses even if you don’t specify all the hardware you require, so if the answer to question two is yes, you need to tell the Market.

Specify optional hardware when you will use it if it’s available, but your app doesn’t depend on it.

Google Places uses cool compass arrows to show the direction of a place on interest. Even without the compass the app would still be useful on my TV, so it should declare the compass hardware as optional.

  <uses-feature android:name="android.hardware.sensor.compass"
                android:required="false" />


Within your app you will still need to find the code that uses the optional hardware and modify its behaviour accordingly.In this example, I’d want the app to simply hide the compass arrow if the compass isn’t available.

You can determine the availability of any hardware feature using the Package Manager and modify the UI or behaviour of your app accordingly.

  PackageManager pm = getPackageManager();
  pm.hasSystemFeature(PackageManager.FEATURE_SENSOR_COMPASS);


To make your life easier, all compatible devices will maintain the APIs used to monitor and control all supported hardware, they simply won’t return useful results when the required hardware doesn’t exist.

Be a launch partner for future Android devices

As an Android Advocate I’m regularly asked by developers how they can have their app available as a launch partner for future devices. You can consider this blog post as my answer.

Monday, August 09, 2010

The Future of Mobile: Invisible, connected devices with infinite screens

The history of smartphones looks something like this: At the end of 2008 the very first Android handset was available on T-Mobile in the US. The iPhone has existed for 3 years. The very first Blackberry featuring push email came out in 2002.

From WAP and push email to iPhone in 5 years. From one iPhone to 60 different Android handsets in under 3 years. At that rate it's challenging to create a credible mobile roadmap that extends as far as 6 months - and the rate of change is increasing.

At the current rate, nearly anything is possible in 20 years

Lately a lot of people have asked me what I think is the future of mobile. Some people just want to know what device they should buy at Christmas, but others are looking for a 20 year outlook. 20 years!  The first GSM network had barely launched 20 years ago! Predication at that scale is destined for failure and embarrassment. But I won't let that stop me.

Bigger screens are better

Mobile devices are morphing. Tablets have been talked about for years, and the iPad and Kindle provide the kind of experience people have been waiting for. Browsing pictures, watching videos, and reading books work really well on a screen that size.

Still, I find the iPad heavy and bulky. The ultimate device would be the size and weight of my mobile but include a screen that could be unfolded or rolled out to provide a better display for watching movies and playing games.

Actually, the ultimate device would be entirely virtual. I’d put on my glasses (or contact lenses) and look at any surface to see an augmented version of reality. Anything from interactive holographs, to augmented reality, or a cinema screen that stretches across the horizon. Everyone could see their own version of reality on a screen the size of their visual field.

1 year  High res screens, tablet devices, and HD output from mobiles.
5 years  Flexible displays and built in HD projectors.
10 years  Transparent LCD patches that can be applied to regular glasses.
20 years  Contact lenses that project a visual feed directly onto your retina.
Full keyboards are better. No keyboards is best

Keyboard designs (like the that on the SE Mini Pro) continue to improve, as do on-screen keyboards with technologies like Swype.

The Nintendo Wii and Microsoft's Kinect suggest that gestures might largely take the place of keyboards and touch screens for some interactions. Better multi-touch and increasingly accurate voice input will make physical keyboards almost entirely redundant.

For those who want to write something longer than an email, gesture recognition (capable of tracking fingers), combined with eye-focus tracking will provide virtual full-size keyboards.

If we’re thinking long-term, we can look forward to research like this letting us control our devices using our minds.
1 year  Wireless keyboards, voice input, and gestures.
5 years  Larger multitouch screens, better gesture input, and flawless voice recognition.
10 years  Full virtual keyboards and voice input eliminate physical keyboards entirely.
20 years  Mind control.
Smaller devices that last longer

The Sony Ericsson X10 Mini is a ridiculous 83x50x16mm and weighs less than 100g. When screens stop being a primary consideration for device size, the devices will shrink dramatically.

That leaves the problem of  the battery. Mobile processors will become more efficient, and fuel cells may help battery life in the short term, but ultimately we’ll be powering mobile device using biology and ambient energy. Biokinetic and ambient energy will likely be the start, but the future suggests a move away from silicon and towards biological processors. The computer you inject is more likely to resemble a specialized virus than a tiny silicon chip.
1 year  Lighter, thinner devices that last longer.
5 years  Tiny devices powered by fuel cells.
10 years  Devices small enough to embed into watches and jewellery that never need charging.
20 years  You are the computer.
Connectivity will become ubiquitous

Cloud computing is already a reality. As even more of our data and processing is done in the cloud, continual and uninterrupted Internet connectivity will become increasingly critical.

The incredible growth of smartphones in countries with a mobile data infrastructure to support them is nothing short of phenomenal. It's easy to forget that the real powerhouses of mobile phone use are developing countries - countries that don't have a reliable infrastructure for traditional "wired" Internet access. Citizens there are likely to access the Internet exclusively via their mobile phones.

Over the next decade we'll see carriers (and new challengers) aggressively rolling out faster, more reliable networks and technologies that cover larger areas across the globe.

At the same time, you'll be using your mobile to control your TV, monitor your fridge, and start your car.
1 year  3G/4G and WiFi covers most of industrial world. Every mobile device comes with an unlimited (or high-cap) data plan. Mobiles start interacting with other consumer electronics and cars.
5 years  4G/5G and WiFi extend to cover the entire developing world.
10 years  Whitespaces or similar technology means everyone everywhere is connected at all times.
20 years  Connectivity is uninterrupted and ubiquitous. Losing connectivity is like losing power or running water.
What about calls!

Apparently some people use mobile phones to make and receive calls(!) As devices get smaller, keyboards become virtual, and screens move closer to your eyes, you'll need a separate piece of kit to sit near your mouth and ears. Bluetooth headsets will get smaller and more discrete, people apparently talking to themselves in public will become no less creepy or annoying.

Infinity screens, invisible devices, always connected

In 2030 you'll think of smart-phones as quaint anachronisms that died out about 10 years ago, now that all computing is mobile. You’ll be constantly connected to the Internet by a virus that lives in your bloodstream. Contact lenses will provide a truly infinite screen, and you’ll interact with your augmented environment through a combination of mental commands, physical gestures, and voice input.

We'll take all this for granted and complain that we still don't have jetpacks or flying cars.

Wednesday, July 28, 2010

How to Display the Android Status Bar in Full Screen Apps

Uninstall them. It's the only way they'll learn.

Of course to be constructive, you should also leave a comment that explains how much you dislike it when an app presumes to be the most important thing on your phone.

Let's talk about user experience best practices

If my talk on Best Practices at Google I/O and Roman's OSCON session on Android UI design tips weren't enough of a hint, let me spell it out - improving the user experience of Android Apps is a big priority for many of us in Android Developer Relations.

I've already talked about the use of exit buttons, and the next time the fires of hate are stoked to a white heat I'll harness the power of my fury to tell you how I feel about modal loading dialogs and splash screens.

Do not presume to know how I use my phone

One of the deadly sins from my I/O session was hostility. A hostile app is one that tries to force me to change how I use my device.  I use the status bar a lot, so hiding it instantly gets my hackles up. I use the status bar to:

  • Switch between apps. If I had to choose between the app launcher and the status bar, I'd choose the status bar. It's how I switch to most apps.
  • Determine connectivity. I live in London, commute on the underground, and most apps are Internet connected. This is a tricky combination. Knowing if (and how) I'm connected to the Internet affects what apps I use and how I use them.
  • Tell the time. Ok, so I also wear a watch - but if I'm already looking at my phone why make we look away to my wrist?
  • Be event driven. I treat incoming messages (email, SMS, Twitter) as hardware interrupts. Any app that hides that from me is going to have a short lifespan on my phone.
  • Listen to music. Good music apps have an ongoing notification that can be used to control playback.
Every pixels of screen real-estate on a 3.5" display is valuable, so I understand the temptation to reclaim each and every one for your user interface. Doing so, however, can be incredibly hostile.

Some excellent exceptions

Now before you start flaming me in the comments, I'd like to point out that there's a good reason the ability to hide the status bar exists. Hiding the status bar is vital if you want to allow your users to be fully immersed in your app.

But what's immersive enough? Consider going fullscreen to be equivalent to disabling incoming calls.

In the following examples going full screen is not only acceptable - it's preferable (if not necessary):
  • Immersive games. Games into which you place yourself (particular 1st person racers or shooters) are a great example.
  • eLearning. The brain is a machine with limited short term memory. Studies have shown that successful learning requires focus, so notifications and alerts will actively prevent you from learning effectively.
  • Watching Video. A full audio / visual experience. 
The following examples fail this test:
  • Casual games. Casual games are designed to require minimal concentration and are often used while waiting for something else to happen. Interruptions, while not welcome, are inevitable.
  • Just about every other app. I've seen List View apps that go full screen, apps that switch to full screen view only for the settings screens, and full screen splash screens. Please. Just. Stop.
In most cases it seems the developers figured "why not?"

If you're changing default behavour, the question should always be "why?".

A good app has as little friction as possible - it quickly becomes a part of your phone that you'd miss if it were gone. The easiest way to reduce that friction is to behave in a manner consistent with other apps, and complimentary to existing user habits.

Tuesday, July 20, 2010

Mobile App Analytics (or how I stopped guessing and started measuring)

The only things as important as figuring out your app's user journey and the resulting user experience are prioritizing the list of features and deciding where best to allocate your development resources. Unfortunately, it's hard to get this right the first time as the judgements are subjective and based on how you think users will use your app.

Listen to your customers

There are many ways to get feedback from app users.  Most telling (though least instructive) are your active installs - people seldom uninstall apps they use and like. This is supported by Market feedback ("Earthquake!" has over 1600 comments and 1700 ratings to go with regular emails sent to the support address published in the market).

This feedback is invaluable but, as Chris Pruett noted when reviewing feedback for the excellent "Replica Island", user feedback can be unreliable.

Mobile app analytics packages like Google Analytics for Mobile Applications or Flurry let you measure how users actually use your app to help you make objective decisions on where to focus your attention.

I recently added Google Analytics for Mobile Applications to Earthquake

It's a fairly simple process consisting of adding a dummy site to my analytics account (from which to obtain a tracking ID), downloading the Analytics JAR file, sticking it into my project's /lib folder and adding it to the build path (full instructions here).

Within my app I simply get an instance of the tracker:

myTracker = GoogleAnalyticsTracker.getInstance();

Start tracking:

tracker.start("UA-MY_CODE-XX", this);

And add a page hit for every event I wish to track:

EApplication.getInstance().getTracker().trackPageView("/map_view");

All the hits are stored in an SQL database, so you can batch the updates and dispatch them the next time your app accesses the Internet. I do it every time I update the earthquake feed:

EApplication.getInstance().getTracker().dispatch();

The page names you're tracking are totally arbitrary - letting you create a new page for every action you want to track.

This is relevant to my interests

There are three general categories of data I can analyze:

  • User demographics. I can track the geographic locations (and language settings) of my users and the speed of their connections. I can also track their screen resolutions and if they're viewing the app in landscape or portrait modes.
  • App usage patterns. The real value comes from finding out how people used the app. What options did they enable? Which Activities do they spend most time on? Which menu options were selected? Did anyone long press anything? Did they add the widget? In short: How does their usage confirm or contradict the assumptions I made in the design?
  • Exception tracking. I also tracked every caught exception. Now I can find out which unexpected edge cases are occurring regularly, and try to figure out why.
My Findings
  • My users are based predominantly in coastal areas near fault-lines. Los Angeles, San Francisco account for nearly 25% of my active user-base (with LA nearly half of that).
  • English accounts for 85% of my user-base. Followed by German, Japanese, and Spanish.
  • Less than 2% of my users have small screens.
  • The Map View is only marginally more popular than the List View (52% vs 48%).
  • Less than 10% of my users view the app in landscape mode.
  • 4% of users switch the map type. Of those, the average is to switch it twice - suggesting my default selection is the preferred viewing mode.
  • 4% of users center the map to their current position. Very few people do it more than once.
  • Of the users who have long-pressed an earthquake in the List View, almost none do it more than once.
  • 7% of users install the widget.
  • 0.1% of users use the Live Folder.
  • The average number of refreshes is one every 3hrs. The default is once per hour.
  • 10% of users manually refresh the earthquake list, but most do so only once.
  • The app is throwing exceptions when parsing the incoming earthquake feed for 20% of users. Those users are seeing an average of 6 exceptions daily each (approximately equal to the typical number of daily refreshes). There doesn't appear to be a connection between these failures and the user's country, network, or device (pivoting on the error page against these categories reveals similar proportions to overall users). 
My new priorities
  • I need to track down the cause of those exceptions!
  • It's probably not worth creating an optimized display specifically for small screens or landscape viewing.
  • I should consider advertising the Widget within the app.
  • If I choose to localize I should prioritize German, Japanese, and Spanish.
  • Both List View and Map View seem equally popular - this is counter to an assumption I made on likely user preference.
  • Most users are refreshing less often than the default, and very few people are regularly manually refreshing. Without a distribution, the average isn't particularly helpful in figuring out if the options need changing.
  • The menu options aren't being used. Perhaps I should try moving the most popular one to the main UI to see if discoverability is affecting use.
Conclusions

In truth I've probably performed this analysis a little early. To do a more thorough study it would be smart to collect a couple of weeks of data.

I'm now all set to perform A/B testing on future releases. By tracking a unique version number page within each release I can use Analytics' pivot functionality to track changes in behavior, demographics, and exceptions based on the changes I make for each release.

I also discovered some gaps in my tracking that need to be added to the next release: 
  • How many people click an earthquake to view it on the map.
  • Exactly which exceptions are being triggered in the parsing routine.
  • I need to add extra tracking to figure out the distribution of update frequencies.

Wednesday, July 07, 2010

Android App Surgery: "Earthquake!"

This week, rather than put someone else under the microscope, I'm going to do an Android App Surgery on one of my own apps: Earthquake!

I hope you'll excuse the indulgence, the distinct advantage of  reviewing my own application is that I can find and point out some of the things I should be doing differently that are harder to spot without access to the code.

In an effort to see if I practice what I preach, I'll evaluate my own app according to the criteria I set out in my Google I/O presentation on Android best practices.

The App: Earthquake!

Earthquake is a reference app that uses the USGS 24hr earthquake feed to keep users informed of recent earthquakes.

Like most apps based on a data feed, the UI is centered around a ListView. The main screen is a vertically scrolling list of recent earthquakes each displaying their magnitude, times, and locations. This is enhanced by a map that displays each earthquake's location and which uses shaded circles to indicate the area likely to be affected by each quake.


Sloth and Gluttony

First the good news. All non-trivial processing is done using ASyncTasks. There are no modal "loading..." dialogs, but incremental refreshes are indicated using the default indeterminate progress indicator. Changes to the quake list are handled dynamically at runtime with the list updated with new data as it's acquired.

The earthquake feed lookup and parsing is handled within a background Service that kills itself on completion.

On the flip side, the Service uses the pre-2.0 onStart method rather than onStartCommand (here's how to support both). Because of this the Service will restart as soon as sufficient resources become available. Instead, onStartCommand should return START_NOT_STICKY, knowing that the Service will be restarted within a reasonable period of time.

Updates are handled via regular background polling - with battery impact minimized through setInexactRepeating. There is scope for using C2DM to replace this polling approach with an event driven update approach.

Hostility and Arrogance

I know several of the engineers working on the Android framework; it didn't take long to decide that second guessing their decisions was likely to have a low ROI. Similarly, watching my friends suggested that some people actually use their phones for making calls and sending SMS message (who knew?!) .

In an effort to make this app seem as native as possible and allow the system to manage as much as possible it:
  • Uses the dialog mechanism to display dialogs.
  • Application preferences are handled using Preference Screens.
  • System icons are used (where possible) for menu items.
  • The back button behaves consistently and inline with user expectations.
That said, there are a couple of areas that annoy me as a user:
Discrimination

Arguably this app's biggest sin.

The manifest doesn't declare a target SDK, nor does it explicitly declare which screen sizes are supported. As a result it's unavailable to users of small screens (such as HTC Wildfire and Sony Ericsson X10 mini/pro users). Worse, it doesn't include assets for low or high resolution displays.

There's no internationalization support, which isn't great, what's worse is that I've gotten lazy with externalizing the strings. About half are defined in XML, the rest are string literals. There's no excuse for that.

The manifest doesn't declare which hardware features are mandatory, or which are used but optional. It uses (but doesn't require) both Location-based services and the vibrator, so to ensure it's available on the largest subset of devices both should be specified as optional in uses-feature nodes.

Beauty and User Experience

I am not a designer. If I were serious about turning this app into something I could charge for, I'd do well to seek out someone with skillz.

Even so, there's some simple improvements that would help:
  • The map is probably its most appealing aspect so it makes sense to make this more obvious. A Tab Layout might be a better option, together with the ability to horizontally swipe between views similar to the Calendar or News and Weather apps.
  • The list view lacks "sparkle" - replacing the standard header bar with something that includes the logo might improve this, as would a dynamic background for each quake. A LevelListDrawable that adjusts the background based on  the magnitude of each quake would be simple to achieve.
  • Long-pressing earthquakes should display a context menu that provides a wider range of alternative actions: such as viewing quake details (via a dialog or USGS.com), sharing a quake, or 'pinning' it to prevent it from being removed when it falls out of the 24 hour feed.
  • The map display has some unnecessary padding around the edges, and the quality of the map markers needs to be improved. Clicking on a quake marker should display an info window with actions (show details, etc.).
Generosity and Ubiquity

The app includes a Widget and a Live Folder for the home-screen, and it uses Notifications to announce new quakes. Search integration is missing though. Given that the quakes are stored in a Content Provider, it would be relatively simple to include it, both within the app and surfaced to the Quick Search Box.

It's worth considering using the send intent to let users share quake details with friends using other apps like email, SMS, Twitter, Facebook, etc.

Similarly, Earthquake doesn't expose and data or Intent Receivers, nor does it leverage Intents available from other apps. It might be worth exposing an Intent Receiver to allow other apps to show the earthquakes at a given location, or even plot the size of an earthquake on the map.

Utility

The utility of this app is likely to be in direct proportion with your distance from a significant fault line. If knowing when and where earthquake strike is useful to you, then so is this app.

Epicness

Epic is a high bar to aspire to, it's fair to say that this app does not reach such lofty heights.

Imagine your app was written by a competitor - what would you do to steal their users?

App developers take note: the easiest way to improve your app is to apply a critical and objective eye to it. I'm going to leave Earthquake as it is for a couple of weeks so that you can evaluate the app based on this review. I'll then look to implement the improvements I've suggested here.

Monday, June 14, 2010

World Cup Recipe Apps for Good from Hungary

Over the last couple of weeks I've used Twitter to ask for user recommendations on Hungarian, Recipe, and World Cup apps. It seemed unfair to keep the results to myself.

I also recently had the pleasure of working with a Apps for Good, a program from CDI Europe that teaches young people how to create apps that change the world - a philosophy I could not possibly agree with more. The class I was involved with recently graduated, and published 3 new apps to the Android Market in the process.

So, for your enjoyment (and with limited commentary) here are some of the apps I've been checking out recently.

Apps for Good

  • Stop and Search: Really useful reference app that walks you through your rights and obligations when you're stopped by the police in the UK. Bonus points for providing a mechanism for rating and mapping the experience, as well as viewing a map of other reported stops.
  • StudioPhly: For aspiring musicians, this app will let you find a local recording studio with the gear you need.
  • StudentVoice: Lets prospective students find out more about the prospective Universities.
Some Hungarian Apps
  • Ball Madness (by A-Droid): A satisfyingly difficult bouncing ball puzzle game. Recommended despite my difficulty in getting past level 3 :(
  • VibraSeq (by A-Droid): Love this. A sequencer to create complex device vibration patterns. But wait! You can export the recorded vibration patters for use in 3rd party apps that support them.
  • Names (by Elek, Márton): Simple widget that tells you what Hungarian name day it is. Bonus points for searching your contacts and triggering notifications to remind you of anyone's name day.
  • GPS Status (by EclipSim): There's a few apps out there that will show you the position, strength, and details from the GPS - but from what I've seen this is the best of them. Nice UI, lots of information, perfect for the data obsessives amongst us.
Recipe Apps
  • Cooking Capsules (by Smart Capsules): Recipes + shopping list + video of the recipe being made. An ADC1 winner, it's an oldie but a very goodie.
  • Epicurious (by Condé Nast Digital): This seemed a popular choice, and with 28,000 recipes I can see why.
World Cup Apps
  • Goal.com Mobile (by Handmark): Live scores, breaking news, good stuff.
  • World Cup News Pro (by Mippin): All the World Cup news for all the teams you follow, presented in Mippin's familiar flip-card UI.
  • Sun Football (by News International): Live scores, highlight videos, and world cup news from The Sun newspaper.

Wednesday, June 02, 2010

Google I/O Session Videos Available Now!

I had the honour of presenting the first Android session of Google I/O 2010, and it was clear very early on that Android was going to be a popular topic.

The room started filling about half-way through the day one keynote. By the time David Glazer was wrapping up, there were no empty seats. By the time I got started there were around 1,000 people packed into the 700 seat session room and the fire marshal had shut (and guarded!) the doors to stop anyone else from joining us.

A Beginner's Guide to Android

I was supposed to present "A Beginner's Guide to Android". I chose to interpret this title liberally, and quickly segued into "Android Best Practices for Beginners".



If you want to play along at home, you can download the slides.

Regular readers should recognize many of these tips as being remarkably similar to the suggestions I make during my Android App Surgeries.

Standing Room Only SOLD OUT!

The door guards never left. With people setting up camp once they found a seat, there were times when speakers found it difficult to gain entrance. With people locked out of each session, it's great that the video and slides for all the Android I/O sessions are now available.


There were some really great Android presentations this year. During my session I called out Justin's "Casting a wide net: how to target all Android devices", and "Android UI Design Patterns". Personally, I'm keen to find out more about the Android Cloud to Device Messaging Service and pick up some tips on building faster Android apps.

The Other, Other Sessions

All the I/O session videos will be made available over the next week or two.

As well as Android, you can already see the sessions for App Engine, GWT, and Enterprise. Chrome, Social, Geo, and Wave will all be available by next Monday.

What's in a Word?

There's some interesting discussion on ModeratorBuzz, Twitter, and in the comments of my last post asking you guys to tell me what you mean when you say "fragmentation".

My theory (stolen shamelessly from Dan Morrill) is that the term has been overloaded to the point of uselessness. The aim of my previous post is to unwrap the (genuine) concerns hidden within this term to allow us to discuss them without dissolving into an argument over the semantic meaning of one word.

I'm going to let the discussion continue for a while but I'll definitely respond to some of the most prominent / popular(?) issues soon. In the meantime I wanted to highlight some tweets I got from NinjaCyborg on Twitter.

He raises some interesting points, which I'll respond to, but I wouldn't have considered any of them to be good examples of fragmentation. For the most part you could happily substitute "openness" or "annoying" depending on your point of view:

  • Fragmentation is launching apps that only run on the new OS release when the previous one barely had a 6 month lifecycle.
  • Fragmentation is allowing licensees to ship hardware that isn't powerful enough to run your OS and makes web apps crawl
  • Fragmentation is changing the browser location API in between 1.6 and 2.0
  • Fragmentation is not including basic APIs for things like Bluetooth OBEX so we have to hit the hardware. OBEX is a basic, fundamental part of Bluetooth. Not complying with the standards == fragmentation
  • Fragmentation is pretending most Android users are on 2.1+ when there are still phones being sold on 1.5 and 1.6 with no upgrade
  • Fragmentation is letting your licensees choose whether to have browser chrome or fullscreen browsing
That doesn't make his questions any less valid, but it does demonstrate just how overloaded the term "fragmentation" is.

[To make keeping track easier, comments for this post are closed. Please use Moderator or the comments from the previous blog post to continue the discussion]

What Do YOU Think Fragmentation is?

Dan Morrill, Google open source & compatibility program manager extraordinaire, wrote a great post on compatibility on the Android Developer Blog yesterday. It explains - in some detail - why device and platform variety is a good thing for developers, and what the Android team are doing to make sure it stays that way.

Within the post, Dan makes what some might consider a bold claim:

Because [fragmentation] means everything, it actually means nothing, so the term is useless. Stories on “fragmentation” are dramatic and they drive traffic to pundits’ blogs, but they have little to do with reality. “Fragmentation” is a bogeyman, a red herring, a story you tell to frighten junior developers. Yawn.
If that pull quote makes you angry, I strongly suggest you go ahead and read the full article. Seriously. I'll wait.

By reading it you'll learn all about the Compatibility Definition Document [PDF] and how the Android Market and Compatibility Test Suite are used to ensure that the apps you write will work consistently across all compatible devices.

As an apps developer, Dan addresses my concerns completely. As long as there's a process in place to ensure I only need to write one app, launch it in one place, and know that it will behave as expected on any device for which it's available, I'm happy.

Judging from some of the abuse I get when I link to the updated platform distribution graph, or urge developers to start using new APIs when we release a new SDK, it seems some people have Strong Opinions on the matter. So, if having read Dan's explanation, you're still angry (or angrier still), I'd be interested in finding out why.

As Dan says, fragmentation has been used as a catch-all for "things that are different", making it impossible to have a meaningful conversation around any of the individual topics. I've created this Moderator page to find out what YOU think is a "fragmentation" problem on Android -- and more importantly why you think this does / could cause issues for developers -- hopefully while avoiding an argument over what "fragmentation" is or isn't.

Tuesday, June 01, 2010

Android App Surgery: Simple GPS

This review is part of my series of Android App Surgeries, you can vote for which app I should review next, or nominate your own app for review on the Android App Surgery Moderator page.
I've spent the last couple of weeks preparing for, rehearsing, and presenting at Google I/O. As a result, I skipped last week's App Surgery.

I'm going to ease back into things this week by taking a look at a very simple app: Simple GPS Info. It's a simple app that displays some additional information from the GPS - including the relative position of the satellites being used to triangulate your position, and the latest GPS fix accuracy.

Once you've been found, the app then lets you share that location.

Next week I'd like to tackle something a little juicier, so be sure to nominate your own app, or vote for something substantive on the Moderator site.

User Experience

The primary user experience for Simple GPS requires no user interaction. You launch the app, wait for it to get a GPS fix, and then observe the results. With limited user interaction it's particularly important that you find effective ways to engage the user and keep their attention.

GPS Status starts off well by keeping things simple. The screen is (relatively) uncluttered with the data displayed clearly and intuitively without any unnecessary distraction.


Generally speaking, there's too much blank space. The text could be bigger, as could the compass dial - there's no reason a third of the screen should always be blank. With no user interaction the data is the only thing engaging the user, so it needs to really stand out.

On the plus side, the latitude, longitude, and accuracy return values are all of predictable fixed length, so it should be easy to optimize the UI to make the data as visible as possible.

There are some specific UI choices that I think detract from the apps usability:
  • The app has hidden the standard title bar, and replaced it with a custom version. Generally users prefer familiarity, so given that the replacement bar offers no additional functionality I would avoid replacing it. 
  • Getting a GPS position fix can often take longer than your screen timeout, and with no user interaction you risk the device going on standby before your location is found. It's worth considering asking the Window Manager to hold a WakeLock until the first GPS position is found. Thereafter it would be a useful menu option for people who want to monitor changes.
  • It would also be good to know how far along we are at getting a lock. Perhaps show an overall signal strength that gives and indication of how many more satellites are needed before a result will be available?
  • Scientifically speaking, precision and accuracy are different things, GPS result quality is usually related as a measure of accuracy. 
  • Landscape mode has been disabled. As an alternative, I'd consider creating a different layout optimized for landscape orientation.
It would also be great to color-code the satellites, green if they were used to calculate the last position, red otherwise.

The one area of interaction is around sharing your current position. It's a pretty good idea, but the implementation could do with some more polish:
  • The share button looks out of place. I'd consider moving it into an Activity menu rather than cluttering the screen.
  • If you try to share a position before a GPS lock has been found, the toast displayed has a number of spelling and grammatical errors that make the app look significantly less polished.
  • Using a URL shortener adds a dependence on an Internet connection that isn't strictly needed. Currently the app fails if no Internet connection is found - perhaps a better alternative would be to fallback to the full-length URL?
  • The shared position page is hosted on a private domain. This is great for allowing customization of the data being shared, but it might put some heavy load on your servers! I'd consider making the sharing data more generic. Using the Google Static Maps API you can create a pretty good custom map-based landing page.
    Android Features

    I briefly considered suggesting a Live Wallpaper or Widget, but the power implications of such a thing would quickly make it untenable.

    Instead, I'd like to suggest use of the Reverse Geocoding Maps API. Using this API you could find the street address of your current location, adding additional context (and engagement) to the app, as well as additional information to "share".

    Stability / Performance / Risk

    Stability-wise -- no crashes, no failures.

    I did notice one possible issue. If you launch the app with the GPS disabled, it prompts you to allow it to force it back on.

    1. It's bad form to modify settings like this directly. It would be better if it displayed a message (similar to Market with background data disabled) suggesting that you can't use the app without GPS and offering a link to the appropriate settings page.
    2. If you say yes, then exit the application and disable the GPS, reentering the app doesn't prompt you to re-enable the GPS.
    Get Your App Reviewed!

    If you'd like to see your app reviewed, you can self-nominate at the moderator site. You can also go there to vote for which app you'd like to see reviewed.

    Monday, May 24, 2010

    Why GoogleTV Should Send Android Developers to Their Happy Place

    In another life, a touch over 4 years ago, a job opening on the Google jobs site caused me to speculate on the imminent arrival of GoogleTV - a cooperation between Google and hardware manufacturers that would bring the power of Google search to your TV viewing experience.

    I was a little ahead of myself, but it turns out I had the right idea!

    A regular TV that I can write code for? That sends me to my happy place.

    Let me start of by saying that I'm not a part of the GoogleTV team. I don't have any insights into their plans beyond what they talked about during the day 2 I/O keynote.

    The focus of that keynote was GoogleTV as a platform for the web - letting you consume web video, use apps, and surf websites on your TV. Obviously that will be cool, but web on TV isn't what excites me.

    What is? Android. Being able to write apps is what got me interested in computers to begin with. I didn't own a smartphone until Android provided a free / open opportunity to write apps for mobiles. Now GoogleTV promises to deliver a platform me to to code for my TV.

    GoogleTV is an opportunity to develop apps on one of the most widely used content consumption platforms on the planet.

    Over the last few years we've seen apps transform mobile phones into platforms for innovation - dramatically changing the way people use their phones. GoogleTV could do the same thing for the television.

    During the keynote we saw an app that added real-time translated subtitles. Seriously. How cool is that?

    Imagine the opportunities that gives you as a developer, particularly when combined with Cloud to Device Messaging? Shazam listening to your movie (in the background) to compile a soundtrack. A click of the remote can add the ingredients from a cooking show straight to your Ocado basket. Pandora (or Spotify) can let your TV play a collaborative playlist.

    That's not to mention the immersive experience for apps that already exist for Android. News, shopping, music, picture galleries, restaurant guides - and perhaps most importantly - games.

    I particularly like the idea of using my GoogleTV in combination with my Android handset. 

    In my experience, watching TV is communal. Rest assured, the first time someone interrupts my movie by loading Shazam or switches the playoffs into picture-in-picture to check the box score on the browser they will experience my displeasure by way of a shoe to the side of the head.

    That's where C2DM and background services come in. Apps can run silently in the background, waiting for me to "pull" (or push) information from / to the TV to / from my Android device.


    It's up to us to create innovative experiences that make people change the way they experience TV.

    Just as great apps and mobile websites have driven a transition towards internet connected smartphones – a different brand of apps and TV websites can drive users towards internet connected smart TVs.

    So I have two questions:

    1. What's more exciting for you: Web on TV or Android apps for TV?
    2. What apps (web or Android) are you going to create?

    Monday, May 17, 2010

    When to Include an Exit Button in Android Apps (Hint: Never)

    A couple of weeks ago I published my first Android App Surgery, a technical review of MySettings from JQSoft. One of my UX suggestions was that they drop the "Exit" menu item. This turned out to be more controversial than I expected and soon dominated the discussion in the comments.

    So, when should your app include an exit button?

    The Short Answer

    Never.

    The Long Answer

    Your app doesn't need an exit button. It really doesn't. Arguments to the contrary can generally be summarized as:

    • Users expect it.
    • It's a way to let users say "stop doing everything and stop consuming juice".
    Do Users Really Want It?

    Let me posit this assertion: no they don't.

    Of the apps that ship with the device (Gmail, Contacts, Maps, Gallery, etc.) exactly none of them include an exit button, and most users are comfortable with that. Nonetheless many developers are adamant, "I added it after users demanded it!".

    Fair enough, so why do some users demand an exit button? How do they cope with the bundled apps without an exit button? In my experience what they really want is:
    An unambiguous way to guarantee that an app will stop consuming resources (battery, CPU cycles, data transfer, etc).
    The Goggles Do Nothing!

    Many users perceive that an exit button implements this requirement and ask for it to be added. Developers, looking to please their users, obligingly add one. Shortly thereafter they both fail.
    • In most cases the exit button simply calls Activity.finish. This is exactly equivalent to hitting the back button. Exactly. Services keep running and polling keeps happening. Users may think they've killed the app but they haven't, and soon they'll be even more annoyed.
    • Exit behavior is now ambiguous. Should your exit button just close the Activity, or should it also stop all associated Services, Receivers, and Alarms? What should back do? What happens if they hit home instead? What happens if your app has a widget? Should the exit button stop that from updating too?
    The solution is to make the back button behave as you'd expect the exit button to. Better yet, simply stop consuming resources whenever the app isn't visible.
    Users: Consider this. If an app needs an exit button because the back button doesn't properly manage resource use, what do you think the chances are that this exit button will be implemented properly?

    Kill Everything When Not in Use

    As soon as an app isn't visible its onStop handler is fired, as soon as it's not the foreground Activity onPause is triggered. This happens no matter what the circumstance - including hitting the back or home buttons or selecting a notification.

    At this point (ideally within onPause) you should behave as though your user has hit exit. Location and Sensor Listeners should be removed, Services stopped and unbound, and Intent Receivers unregistered.

    Once your app moves back to the foreground - triggering onStart and onResume - you hook everything back up.

    "Sure," you're thinking, "but what about apps that need to run in the background?"

    Foreground Services and Ongoing Notifications

    Some applications, such as turn-by-turn navigation and music players, need to run (and use resources like GPS) while invisible. This is generally achieved using a foreground Service. It's also the only reason for creating a foreground Service.

    Users should always know if such a Service is running, and be provided with a simple way of unambiguously turning it off when it is. In navigation there's an "exit navigation" menu item. Pausing playback in a music player is enough to kill the playback Service. In both cases ongoing notifications provide a simple shortcut to the app, where you can easily stop the Service.

    As far as the user is concerned, if the app isn't visible and there's no notification icon it's not consuming resources. If there's an icon, it's running in the background and I can click the notification to go turn it off.

    Background Services and Polling

    Some applications (such as News & Weather) need to occasionally run in the background to get updates. Whenever possible use inexact repeating Alarms to schedule your updates, and then kill your service as soon as the update is complete.

    This will help with resource use, but is still only half the answer. How can a user demand the app stop using resources completely?

    What's the easiest way for me to prevent every app from transferring data?

    Settings > Accounts & sync > Background data

    Unchecking this should ensure that no app send or receive data while it's not visible. However: This needs to be enforced at an application level - so if this comes as a surprise to you have a fix to implement and an update to go push.

    Go ahead, I'll wait.

    Offer Users Options


    Provided the user is cool with background updates in general, you need to let them adjust the frequency - or disable them - for your app. Be conservative by default. If users aren't getting updates as quickly as they want they'll look for a way to increase the frequency.

    Be Adaptive

    A Twitter discussion from this post resulted in a suggestion that "Android should offer a way to listen for low battery so that an app can be more conservative with it's use of resources." Register a Broadcast Receiver and thou shalt receive.

    You can also monitor for things like connectivity status and type, so you can disable updates when there's no data connection, or modify the frequency based on the connection type.

    In each case it's always good practice to offer these tweaks as user configurable options.

    Conclusion

    If you build an application that's predictable, configurable, and unambiguous your users won't ask for an exit button. The first time they see an unknown background Service that's been running for an hour, or the GPS icon unexpectedly starts flashing, or the device gets hot while in their pocket they're going to get narky.

    Next on my hit list: Splash screens, task killers, and modal "loading" dialogs.

    Monday, May 10, 2010

    Android App Surgery: "AndCam3d"

    The second of my Android App Surgeries, you can vote for which app I should review next, or nominate your own app for review on the Android App Surgery Moderator page.
    This week's surgery looks at AndCam3d, a clever little app that lets you construct 3D images as wigglegrams, stereograms, or anaglyphs.

    User Experience

    Unlike last week's app MySettings, which provided shortcuts to existing functionality, AndCam3d offers something entirely new. Using a SurfaceView to show a live camera preview, it allows you to take multiple photos from different positions - using them to construct  3D images.

    There's a particular UX challenge associated with introducing a user to novel functionality while keeping it simple, intuitive, and easy to use.

    Unlike traditional software, it's unlikely that your users will know anything about your app beyond the title and the description from the Market.  So when introducing a new workflow users need to be able to get started quickly, before they give up and claim it "doesn't work".

    AndCam3d does this well by displaying up a set of instructions (with images!) the first time the app is run, an approach similar to that used by Google Goggles. In this instance Dialogs are used, overlaying the instructions over the camera preview. Personally, I feel that Activities might be a better fit, and have these additional observations on the instruction screens:
    • Having the camera on and displaying a preview in the background while I'm reading the instructions causes the app to take longer to start, and drains battery while I'm reading the instructions.
    • Using Dialogs over a landscape-only Activity restricts me to reading the instructions in landscape mode.
    • Consider renaming the "cancel" button to "continue" (or similar). You're dismissing the instructions, not canceling an action. 
    • There are links within the instructions to websites - use Linkify to make them clickable!
    • In Windows applications an ellipsis (...) at the end of a menu item means "opens a dialog". In mobile apps this isn't a well established metaphor. I'd suggest using an arrow, such as the one used in the system settings to indicate a dialog or new Activity.
    I really like the UI for taking photographs.
     Having the two stateful eyeball buttons in the bottom left and right corners is an intuitive way to guide user action. I think it could be even better with the following minor tweaks:
    • When taking my first picture I would have appreciated more guidance. A tutorial like on-screen guide ("click here to take the left-hand picture", "now click here to take the right side", "now click here to compose the stereograph!") - for the first picture only - would have helped me get up to speed more quickly.
    • The eyeball icons (particularly the hands) aren't high-res enough to look good on the Nexus One.
    This app is new, but the basic action (taking a photograph) is familiar. I like the way the new functionality has been incorporated, but I'd love to see some of the UX from standard camera app integrated here. The good news? The camera app is open source, so you can totally steal this stuff:
    • I'd like to review of each image I create, and an onscreen icon link to the last image I constructed. Clicking it should display the last image so that I can evaluate and manage it. Using the current UI it wasn't obvious to me where my new stereographic image had gone.
    • Like the camera app, I'd like to see the "Share" and "Send" menu items moved to the (new) image preview Activity. Neither of these verbs make sense without the context of an image.
    • The "Share" menu item links to a custom "share via Flickr" dialog. I'd love to see share use the standard sharing Intent (annoyingly named Send) based on the last / current image. To include the Flickr sharing, I'd create an Intent Filter to listen for the Send Intent to enable your app to share any image via Flickr, not just the stereograms I create.
    Finally, it's great to see the standard Menu system in action, and the Preference Screen too -- especially the use of the standard icons for preferences and help. Without being a pedant, I'd suggest being even more consistent with the system defaults by:
    • Sticking to greyscale images for menu icons.
    • Renaming "Preferences" to the more commonly used "Settings".
    Android Features

    It's a great app, and there are a couple of pretty cool Android features you might want to consider to make it sparkle a little more uniquely.

    Live Wallpaper. Why not allow users to set their latest wigglegram as a wallpaper? Live Wallpapers are dynamic, so you could easily create one that would quickly switch between two images to display a wigglegram.

    Camera Parameters. Android 2.0 supports modifying camera settings and effects. It would be great if it allowed users to set some camera parameters before taking each picture.

    Stability / Performance / Risk

    Stability-wise, I didn't have any problems. No crashes, no failures. Good to see that the manifest requires camera hardware be present.

    I did notice that on the Nexus One it requests an invalid camera preview size. To avoid potential hardware-related failures, always check to see which preview sizes are valid before setting one.

    Get Your App Reviewed!

    If you'd like to see your app reviewed, you can self-nominate at the moderator site. You can also go there to vote for which app you'd like to see reviewed.