WWDC keynote wrapup

As is usual around WWDC an endless amount of ink has been spilled criticising, praising and analysing the various announcements. As an Android developer its only natural for me to view what has been announced through an Android prism. There are two bits of commentary which I thought summed up things up from the Android point of view pretty well. Firstly Chris Lacy, the developer of Action Launcher and Link Bubble posted this very good summary to google plus. One nice point I think he makes is:

It’s easy (and mostly accurate) to point at a great many of the features announced and say “Android had them first and Apple are playing catchup”. This misses the point on a few levels. Firstly, Apple’s M.O. is to be the best, not necessarily the first. Also, as of the day iOS 8 releases publicly, it doesn’t really matter that Android users have had feature X for Y years previously. iOS devices now have these features, and their users are going to be delighted.

Geek.com seemed to have its finger on the pulse of the bigger strategic direction of what apple is trying to do in terms of the war against google:

Smartphone fanboys will spend the next few days arguing about whether or not Apple did anything interesting yesterday. Third party keyboards? Welcome to 2011, Apple. Calling from my laptop or tablet? Do you even AirDroid, bro? How about Google Voice? The conversation isn’t all that interesting, and usually ends in slinging insults or moving goalposts, and that’s because the larger point is being missed. Apple isn’t just taking the best parts of Google and sewing it into iOS. Let’s be honest, each of the smartphone OS designers have been taking cues from one another for years now, and for the most part that is a good thing for everyone. What Apple did yesterday was a lot more deliberate, and a lot more targeted. Apple took to the stage with a single goal in mind, to categorically replace the need for Google in your life.

2014 Android design competition

Anybody interested in Android design should have a look at the results of Taylor Lings Android UIUX Redesign Challenge

Last year Taylor ran a similar Challenge and got some really great entries.  This year I decided to sponsor some additional prizes for the winners.

In my mind some of the standout entries are:

 

My Battery Saver

https://plus.google.com/110734967177394893462/posts/BB1tdGCYjts

1

While it is obviously inspired by timely, this entry reminded me that the kind of flat transparent style which timely used hasn’t really taken off much on Android.  It would be great to see more apps taking inspiration from this.

RunPee

https://plus.google.com/+Andr%C3%A9Goersch/posts/8qC8ukjGo7X

runpee_001---IntroThis is a very well thought out re-design of an app obviously in much need to some design love.  A lot of attention has gone into the design and the end result is great.

Dribble

https://plus.google.com/+ChrisBasha/posts/DcQakcBnW3z

Item

This is a very thoughtful design, which makes good use of Android design patterns to produce an elegant app.  Its not ostentatiously showy like some other designs, but the end result is a solid design which would be a pleasure to use.

TweetLanes

https://plus.google.com/+JamesJun/posts/4T7GNCX4veJ

Files

I knew James Jun would produce something special – he seems to have a knack for making crisp clear designs.  I particularly like the use of the 3 tabs in this app replacing the action bar.

What Android devices should I test on?

Customers often ask me for suggestions as to what devices they should buy to test their applications on.  In the iOS world you can have every single device your app will ever run on sitting on your desk.  In the Android world things are not quite so simple – as of early 2014 an app targeting phones and tablets, from 2.3 up will have to run on over 4722 different devices!

Given the number of different devices anybody looking at doing Android development will have to limit themselves to testing on a representative sample.  When looking at on device testing there are typically a few boxes you want to tick:

  • Android version: 2.3, 4.0, 4.1, 4.2, 4.3, 4.4
  • Device size: small, med, large, xlarge
  • Screen density: ldpi, mdpi, hdpi, xhdpi, xxhdpi
  • Device manufacturer: Samsung, HTC, Google, Motorola, etc
  • If at all possible you want to cover the most popular phones such as the S3

Now if you do a bit of naive maths, you might say hang on, thats still 400 devices!  Fortunately you can use one device to tick multiple boxes – for example Samsung Galaxy Y will allow you to test on a 2.3 device, with a small screen size, in ldpi resolution running  Samsung’s version of Android.  Also many combinations don’t exist – good luck finding a 2.3 device, with a xlarge screen in xxhdpi density for example!

I personally own the following devices for testing:

Samsung Galaxy S2 and S3

The Galaxy S2 and S3 are both extremely popular devices with a massive portion of the Android market share.  Just testing on the Galaxy S3 alone will allow you to cover off a large portion of the android device market share.  The S2 allows me to test on an older device with a smaller screen size and density.  The S3 is still one of the most popular Android devices on the market, it features a very common screen size (4.8 inches) and runs in the popular xhdpi density.

Nexus 4, 5 and 7

Googles nexus line of devices allow you to test under googles unmodified stock version of the Android operating system.  Rapid software updates released from google mean you will always be able to test agains’t the newest version of Android.  In addition each of these devices have been very successful in the market place.  The Nexus 5 is probably one of the cheapest ways to get an xxhdpi class display to test your app on.

Samsung Galaxy Tab 2, 10″ model

The samsung galaxy Tab 2, is a now throughly outdated tablet device from Samsung, however it does allow us to cheaply cover off testing at a 10″ tablet size

Samsung Galaxy Y

The Samsung Galaxy Y it an extremely cheep low end device.  It allows apps to be tested under Android 2.3 on a small screen with the LDPI density.  Surprisingly the Galaxy Y is an extremely popular device!  Open Signals June 2013 report showed it was the 3rd most popular Android device, comming just behind the S3 and S2 in terms of market share!  Undoubtedly this is being driven by its price – the Galaxy Y can be picked up for $59 from Coles supermarkets.

Huawei Ascend Y201

The Huawei Ascend is another low end device, this time running android 4.0.3 with an mdpi, 3.5 inch sized display.  This allows me to test under another manufacturers version of Android.  The Ascend can be picked up over the counter at coles supermarkets for just $39 – a sunningly low price for a 4.0 android device.

Future Additions

This library of devices allows me to test under some of the most popular devices, running under some of the most common screen sizes, densities and versions of Android available.  However the Android devices space is constantly evolving and new devices are being being released all the time.  In the future I will be looking to add:

  • Samsung Galaxy S4 – Following in the footsteps of the S2 and S3 the S4 is bound to become one of the most popular android phones on the market
  • A LG and an HTC device – While the nexus 4 and 5 are produced by LG they are not running LG’s version of the Android operating system.  Likewise I have no HTC devices to test against.  I will be looking to add some midrange LG and HTC devices to my library
  • A more modern 10″ tablet – The galaxy tab 2 is definitely starting to show its age.  Perhaps if a new nexus 10 is released, running at a xxhdpi resolution it may be worthwhile adding it to my library

Building clean RPN part two – Calling native code using the NDK

This may be a surprise to some people who know me, but I am not particularly excited by the idea of writing my own arbitrary precision RPN parsing engine.  Thus when I started to build the Clean RPN calculator app I decided to reuse the C Mapm library, which already includes an example RPN engine capable of performing arbitrary precision calculations using a wide variety of mathematical functions.

Android has the ability to compile and call native C code via the android NDK, which makes use of the java’s JNI for the actual bridge.  There are many examples available on the internet of how to use the NDK to call into C code.  Unfortunately most of them are of the ‘hello world’ nature and only show how to call through to one C file, which is included in the android project and contains only a few functions.  The Mapm library is much more complex, and includes many header and source files along with its own set of build scripts based on make.  I decided to use the following approach:

  1. Modify the Mapm build to use the NDK toolcain and produce a version of libmam.a suitable for embeding in android apps
  2. Include the mapm header file and RPN calculator engine inside my android project
  3. Write a custom bridge using JNI to call through to the functions I need from mapm

Step 1 – Modify Mapm build

The first step is to modify the mapm build to use the android NDK toolchain.  The NDK contains a complete C/C++ toolchain suitable for runing on MacOS, inside the android-ndk-r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/ folder

The mapm library uses make and comes with several handmade build files, which are relatively simple to modify.  I created a copy of makefile.osx which is provided the mapm zip, and renamed it to makefile.android.  At the top of the makefile a variable is defined with the location of the c compiler.  I change this to point to the absolute path of the NKD’s c compiler and set the –sysroot parameter.

CC = /Applications/android-sdk-mac_86/android-ndk-r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/arm-linux-androideabi-gcc --sysroot=/Applications/android-sdk-mac_86/android-ndk-r8b/platforms/android-8/arch-arm

Later in the make file comes the step which builds the actual mapm lib. This also needs modifying to use the NDK’s toolchain:

libmapm.a: $(OBJS)
	rm -f libmapm.a
	/Applications/android-sdk-mac_86/android-ndk-r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/arm-linux-androideabi-ar rc libmapm.a $(OBJS)
	/Applications/android-sdk-mac_86/android-ndk-r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/arm-linux-androideabi-ranlib libmapm.a

Running:

make -f makefile.android

at the command line will now produce a libmamp.a which is suitable for use in an Android project.

If mapm had made use of autotools it may have been simpler to use a tool such as Androgenizer to bridge the gap between autotools and the android NDK build process.

 

Step 2 – Include mapm headers and RPN calculator

To make use of C code and libraries in an android project the relevant code needs to be placed in a /jni folder in your project.  In this case there were 3 things that I copied across:

  1. The libmamp.a produced by the modified build.
  2. The mamp header file – m_apm.h
  3. The a modified version of calc.c from mamp which implements the RPN parser.

 

Step 3 – JNI bridge

So far there has been no JNI code written, which means there is no way to call into the mamp library from java.  To keep the JNI specific code out of the mapm sources a separate file called native_interface.c was created.  This file is maped to a ‘native’ method in a java class using JNI.  native_inferface uses JNI to convert an array of java strings into a  c array of c string, passes this into the modified version of calc.c from mapm to perform the actual calculation then converts the result from a c string back to a java string:

#include 
#include 
#include <android/log.h>
#include 
#include "m_apm.h"

/*  prototypes from calc_modified  */
char* runCalc(int argc, char *argv[]);

JNIEXPORT jstring JNICALL Java_au_com_lukesleeman_rpn_MainActivity_doMath(JNIEnv * env, jobject this, jobjectArray stringArray)
{

	// Convert our java array of strings into a c array of cstrings
	int stringCount = (*env)->GetArrayLength(env, stringArray);
    char *args[stringCount];
    args[0] = "calc";

	int i;
    for (i=0; i<stringCount; i++) {         jstring string = (jstring) (*env)->GetObjectArrayElement(env, stringArray, i);
        const char *rawString = (*env)->GetStringUTFChars(env, string, 0);
        args[i+1] = rawString;
        // Don't forget to call `ReleaseStringUTFChars` when you're done.
    }

    // Run the calculations
    char * out = runCalc(stringCount + 1, args);

	// Copy result into a java string
	jstring result = (*env)->NewStringUTF(env, out);

    // cleanup
    free(out);

    for (i=0; i<stringCount; i++) {         jstring string = (jstring) (*env)->GetObjectArrayElement(env, stringArray, i);

        (*env)->ReleaseStringUTFChars(env, string, args[i+1]);
    }

    return result;

}

On the java side, we hava a class called au.com.lukesleeman.rpn.MainActivity with a single  native method:

private native String doMath(String [] maths);

An android.mk file needs to be written to tell the NKD how to compile the code:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES := calc_modified.c , native_interface.c 

LOCAL_LDLIBS += libmapm.a -llog 
LOCAL_MODULE := mapm

include $(BUILD_SHARED_LIBRARY)

The last step is to run the NDK build tool from within eclipse following the process described here.  This will compile the JNI code and link it to the existing libmamp.a.

Conclusion

By splitting out the native C code from JNI specific C code we were able to use the existing mapm build system to compile libmamp.  It was simple to modify the build system to use the NDK toolchain to compile the library.  This allowed us to quickly integrate an existing C RPN calculation engine into the clean RPN app.

Don’t use splash screens – Make app launching gorgeous

Link

Cyril Mottier has a good write up of how to improve the experience of users when they launch your app:

http://cyrilmottier.com/2013/01/23/android-app-launching-made-gorgeous/

Essentially it comes down to theming your application properly, instead of using code to style it.  This will mean your app window appears with the correct styles, colours, etc before your code starts running.

‘Pure Android’ – Adapting an iPad design to Android tablets

Introduction

For the past 3 months I have been working closely with the digital agency Involved to bring their iPad app ‘Accor Hotels & Resorts Asia Pacific’ to Android.  The Accor hotels iPad app works as an interactive catalog, allowing users to browse through the thousands of hotels that Accor Asia Pacific manage.  Users can view hotel details, browse a map and view galleries containing photos of each hotel.

Because it is primarily a marketing tool, the look and feel of the app is very important.  The iPad app has smooth animations, beautiful images and a premium, dark ‘navy blue’ theme.  It is obvious that Involved had put a lot of thought into its design and appearance.  While planning the project it became clear early on that successfully adapting the app’s appearance to Android would be one of the key tasks in the project.

Overview of the iPad app

The iPad app has the following design features:

annotated ipad in frame

1 – Tabs at the bottom, for switching views in the left pane

Large square tabs, with an icon and text are a common iOS design element.  In this case they switch between different views of the hotel list in the left pane.

2 – Left pane navigation bar

Inside the left pane users can drill down through various hierarchical lists of hotels.  To navigate back up the hierarchy a navigation bar, with a back button is displayed.  The navigation bar title shows the current country or state the user is viewing.

The navigation bar also contains a button which allows users to launch a map where they can browse through hotels.

3 – Premium blue theme

A key component of the iPad apps branding is the dark blue theme.  The app makes use of navy blue palette along with customised icons.  There is also heavy use of gradients throughout the ui.

4 – Custom buttons, including ‘more’ button

The Accor directory app features shiny silver buttons, with blue text.  In this case the more button displays a menu where the user can access additional information about the hotel, including business facilities, links to book online, etc.

5 – Accor branding, settings button

The Accor logo is featured throughout the app.  In this case clicking on the button displays an about screen.  Selecting the settings icon displays a dialog which allows users to download all the hotel galleries and perform an update of hotel data.

6 – Updates

The application downloads the list of hotels from a restful webservice and stores them in a database on the device.  This allows the app to be used offline.  Due to iOS restrictions with running background processes the app can only download hotel updates while it is being used.

An aside – What not to do

Before talking about what we did, it’s worth talking about what we didn’t do, namely this:

framed_IMG_3060

Yes, that is the original iPad ui stretched out and pasted into a Nexus 10.  There are a number of reasons not to do this, which I have explored in an earlier blog post, but the two most important ones when I discussed the issue with Involved were:

  • Users of the Android app would probably never see the iPad app.  They wouldn’t care if the two apps were exactly the same or different.  They would however care a lot if the Android version of Accor directory was totally different to the other apps they used daily.
  • Replicating the iOS ui exactly would cost a lot – it would be significantly cheaper to build using the standard controls that google provide, using the holo theme.

1 – Introducing the action bar

The first step in adapting the Accor Directory apps design to Android was to introduce the action bar to replace the iOS navigation bars.  In Android the navigation bar provides a dedicated area for app navigation and actions to live.  The settings button, map button and about button were all moved into the action bar.  Android’s stock icons were used instead of the iOS versions.

This only left the navigation tabs.  There were three different options for adapting them to Android:

tabs mockup 2

  1. Place them in the action bar
  2. Place them below the action bar at the top of the left pane
  3. Place them at the bottom of the left pane

Each approach had its own pros and cons, but in the end we decided to place them in the action bar using text with no icons.  Android users typically expect navigation tabs to live in the action bar.  This is the approach featured in the android design guidelines.  Android devices commonly have a wider aspect ratio than iOS (16:10 on the nexus 10  vs 4:3 on the iPad).  This means vertical screen space can get scarse.  Approach 2 and 3 would have used up a larger amount of it, while leaving a big empty area in the action bar.  Finally under Android it is rare to see icons and text combined on tabs.  It was felt that the icons used on the Accor directory tabs would be too obscure for the user to guess at their meaning.

The last action bar tweak was to the apps icon.  Android will by default place the applications icon in the left corner of the action bar.  We decided to instead replace this with a white Accor logo to provide a cleaner feel.

The final result:

action bar

2 – Navigating through hotels

Within the iPad app users can navigate up and down a a hierarchy of hotels, drilling down based on country, state and then city.  Under iOS the current location and back button were placed in a navigation bar at the top of the screen.  In Android this space had been replaced by the action bar and tabs.  After some experimentation it was decided to place the current location in a blue header at the top of the list, followed by a ‘back’ list item leading up the hierarchy.  The blue in the header tied in with the blue underline on the selected tab.  This helped to hint visually that the tab selection was linked to the content of the left pane:

left bar navigation

3 – Navy blue theme

As has already been seen, the dark navy blue theme forms a key part of the apps branding.   Using the Android Action Bar Style Generator and the Android Holo Colors Generator we were easily able to customise Androids ‘holo dark’ look and feel to match the Accor directory colours.

The original version of the theme I produced used a gradient for the action bar which matched the iPad app’s navigation bars:

old theme

After some thought it was decided to replace the gradient with a solid lighter blue colour.  This is because ‘holo’ look and feel apps tends to emphasise flat blocks of colour and makes minimal use of gradients.  Choosing a slightly lighter colour also helped to differentiate the action bar from the rest of the screen:

new theme

The difference is subtle, but important and contributes towards the apps ‘pure Android’ feel.

4 – Custom buttons

The iPad app makes use of custom buttons with a shiny metalic look.  We decided not to use the same look on the Android buttons, as holo apps typically have a very flat style.  Instead it was decided to use the standard Android buttons, but tweaked to follow the apps colour scheme.  The assets for the buttons were generated using the Android Holo Colors Generator.  In their normal state the buttons appear to be standard Android buttons, but in their pressed state the custom colour shows:

book hotel pressed

5 – Updates as a background service

iOS does not allow applications to run in the background.  Therefore the iPad app can only download updates to its hotel database while it is running.  Android has no such restriction, so it was an obvious improvement to add a background service which downloads hotels.  While the download is running a notification is displayed in the system tray:

updating

6 – Portrait view and managing different aspect ratios

The iPad version of Accor Directory only supports landscape view.  Coming into the Android project we knew the the screens would have to be designed in a flexible manner to support different screen sizes and resolutions.  This meant the app would also support both portrait and landscape views unless it was explicitly disabled.  We were unsure how much work would be involved in tweaking the application layout for portrait orientation.  We decided to do the development with only landscape in mind, then at the end of the project make a choice to either apply a few tweaks and make portrait view work better or to lock the app to only landscape orientation.

In the end the app worked remarkably well in both orientations.  We ended up performing two tweaks to enhance portrait orientation:

In portrait orientation the space for the hotels name was very limited.  This meant that the ‘more’ button simply wouldn’t fit.  We decided to replace the ‘more’ text with Android’s ‘three dot’ menu icon.

portrat hotel name

Secondly we adjusted the padding around dialogs to ensure they fit.  In landscape mode the apps dialogs have padding to the left and right.  We simply adjusted this in portrait so that the padding was above and below the dialog:

landscape dialog

Finally we found that the widescreen aspect ratio of Android devices meant some content that would fit in comfortably on the iPad didn’t fit on Android.  In particular the hotel view either had to have a letterbox sized image, or the text would not fix on the nexus 7.  After some playing around with font sizes and image heights we decided to instead introduce a scroll bar and have the user move down to view any additional text:

scroll bar

 

Conclusion

You can try out the end result in the google play store:

Get it on Google Play

I believe one of the key success factors is that Involved came to the Android port with an open mind – they were willing to alter the design of the application where ever necessary to ensure that it worked well on the Android platform.  They also realised early on, that time and effort would need to be invested in producing proper Android UI, rather than just copying everything wholesale from the iOS app.

Another important factor was attention to detail.  The kind of obsessive focus on design that is needed to create a great iOS app is often discussed in blog posts – however just as much attention and effort is required to build a great Android app.

The app has received fantastic feedback both from Involved, and Accor themselves.  By borrowing the most distinctive elements from the iPad version but carefully adapting them, we were able to build an app that is instantly recognisable as ‘Accor Directory’ but also is pure Android.