Gallery

BMW i3 Review


Can BMW’s innovative ‘megacity vehicle’ justify the £25,000 price tag?

The BMW i3 is probably the most innovative mass produced vehicle to come out of the car industry since the Mini in the 1960’s. The Mini’s designer Alec Issigonis famously revolutionised small car packaging by transversely mounting the engine and gearbox in order to create a car that was small in exterior dimensions but big on interior space.  It was a brilliant and innovative solution that has stood the test of time. Even now, 55 years later, most cars are designed with exactly the same layout.

The innovation in the i3 is not the engine layout (it’s an electric vehicle or ‘EV’, so it doesn’t have one in the conventional sense) but it’s no less revolutionary. The i3 is innovative because of the materials used to build it. It’s the first mainstream vehicle to use a carbon fibre body shell. Carbon fibre is a big deal. It’s expensive to manufacture but it’s extremely strong. In the i3 it’s been bonded to an equally lightweight aluminium chassis for one reason, and one reason only – to save weight.

The elephant on the road.

You see weight is the nemesis of all modern cars. As safety, equipment and interior space have all improved, so has weight. In 1960 the original Mini would have weighed in at around 690 kg but it’s modern 2015 equivalent tips the scales at nearly double that at around 1146 kg. The main problem with this additional weight is that the heavier the car, the more energy is required to fling it down the road at a decent pace – and energy is a big problem for electric vehicles.

The batteries used to power electric cars are heavy, really, really, heavy, and yet they have a far lower capacity for storing energy than a conventional fuel tank does. So even though the i3 uses carbon fiber and aluminium extensively to save weight, these savings are immediately used up by the large battery pack. The BMW tips the scales at 1195 kg but fully charged the i3 can only cover around 70 miles whereas a modern F56 Mini could easily cover over five times that on a full tank of fuel. So you see, energy capacity and weight are problematic because of the effect they have on range.

Let’s talk about range then…

Seventy miles doesn’t feel like a lot does it? In most modern cars having only 80 miles of range is enough to activate the fuel reserve warning light, so psychologically we’re conditioned to believe short range is a problem.  It’s such a significant fear that the term ‘range anxiety’ was invented to describe it – the feeling that you’re not going to be able to complete your journey because of the range remaining.

However, in real life I often find I can often last several days with the fuel reserve light on before I need a visit to the pumps. With an electric car your home is ‘the pumps’, so personally I think this fear is largely over-stated. Plus everyone now understands that electric vehicles are short range vehicles, so most purchasers probably plan to use their electric vehicle accordingly. You do hear about some long distance heroics, but EV’s are ideally used for short trips, pottering about and daily commuting. Longer trips and epic commutes are still best served by petrol, diesel or hybrid power.

What you don’t want with your EV is the feeling that it will change it’s mind about the remaining range at the drop of a hat. In this regard I found the BMW to be flawless. Its on board range calculations seemed fair and reliable at all times. During my test, after an overnight charge the range reading indicated that 67 miles of travel was available. I then did a 47 mile round trip and at the end of the journey the i3 claimed it had a remaining range of 19 miles. So it was accurate to within a mile, and still had plenty juice left for another short trip.

Charging is simple too, just plug it into a standard 13 amp wall socket and wait. Getting to fully charged from 20% takes around 6 hours. Most would do this overnight and I calculated it cost me about £2.50 in total – less than half the cost of the same 47 mile trip in a BMW 320d. In addition, if you do leave it plugged in overnight you can set a timer so it’ll be fully charged, toasty warm and frost free when you open the door the next morning!

The on-road performance of the i3 is pretty good but not flawless. Lots of reviews emphasize the way the instant torque of the 170 bhp electric motor gives you strong acceleration at any speed. Acceleration is indeed stronger than average, but it’s only ‘hot hatch’ fast rather than ‘holy crap’. The automatic gearbox is great, mainly because there’s only one forward gear, so there are no awkward pauses while the software hunts round the ‘box for the right cog. In terms of agility changes direction easily, but body roll is significant compared to a normal saloon and the i3’s sit-up-and-beg driving position means it all ends up feeling a bit ‘boat like’ when pressed hard – similar to what you’d find with your average family SUV. The ride is comfortable, and never too firm or crashy.

Sounds interesting, what’s the catch?

The biggest problem with the i3 is in its practicality – or lack of it. Part of the “innovative” design is a set of over-complicated suicide doors that afford you access to the rear bench. However, because the seats don’t slide forwards like they would in a regular 3 door hatchback, the ludicrous door arrangement makes it nearly impossible to enter or exit the back seats in tight parking situations (such as supermarket car parks for example). Irritatingly for me as a family guy, it’s practically impossible to get a toddler into and out of a child seat comfortably.

Even adults find the doors confusing. I had to explain how to open and close them properly so that passengers could use them without hurting themselves or the car. You’d be better off thinking of the i3 as two-seater and forgetting about the rear seats altogether. Just fold them flat and have a larger boot instead.

What else do I need to know?

The build quality of the i3 is OK but not outstanding. The interior materials are admirably ‘recycled’ in nature but I felt that they may wear more harshly than regular materials over time. The i3 also felt a bit bargain basement in some areas compared to other BMW’s. The standard fit stereo has just 2 speakers for example (a first for me since my Vauxhall Nova in the early 90’s). The rear doors needed a good slam to shut properly or a warning light would come on. The interior was very quiet (near silent) at low speed but at higher speeds there is some tyre and wind noise, but it’s still better than your average clattery diesel.

The top spec trim should probably be avoided. The dark brown leather wasn’t a great color match to the rest of the interior; the seats felt firmer and less comfortable than cloth; and they’re cold in the winter (unless you waste power warming them up). Speaking of warmth, the Eco PRO battery saving mode turns the climate and heating controls right down, so be prepared to wear a thicker jumper if you need the extra few miles of range it gives you. Visibility is very good, especially at the front due to the large windscreen. You can have a parking camera and sensors fitted, but neither are really necessary in my opinion.

Should I buy one?

If you want a cheap to run, lot’s of fun electric vehicle for short trips or committing – and if you can stand the premium price tag, you should definitely check out the BMW i3. It is revolutionary, but this innovation comes at the expense of practicality. If you need something with more practicality and greater range but you still like the idea of an electric vehicle, then maybe the hybrid Volkswagen Golf GTE would make more sense.

Android: Unit Testing Apps with Couchbase, Robolectric and Dagger


This Android / Gradle project on GitHub shows how to integrate Couchbase, Robolectric and Dagger so that unit testing can occur without the need for a connected device or emulator.

Background

I need a database for my TripComputer app so that users can keep a log of their Journeys. I could use SQL Lite, but I prefer not to use SQL if possible. With SQL you’re forced to maintain a fixed schema and SQL Lite doesn’t offer any out of the box cloud replication capabilities, unlike most NoSQL databases.

Couchbase Lite for Android is an exciting new embedded NoSQL database, but because its ‘Database’ and ‘Manager’ classes are Final and require native code, it’s not trivial to mock them or integrate them into apps that utilise the popular Robolectric testing framework.

Therefore, in order to support off-device Java VM based testing with Robolectric it is necessary to write custom interfaces and use a dependency injection framework that will allow the injection of mock objects to occur when testing. To achieve this ‘dependency injection’ of mocks, I’ve used Mockito and introduced the Dagger framework into the code.

Software Versions

  1. Couchbase-lite 1.0.3.1
  2. Robolectric 2.4
  3. Dagger 1.2.2
  4. Mockito 1.10.19
  5. Android Studio 1.1 Beta 3 (optional)

About The Sample App

The App I’ve built here is very simple. When the user clicks the Save button on the screen, in the background a new document (technically a `java.util.Map`) is created and saved to the embedded Couchbase NoSQL database. While saving the new document, Couchbase automatically assigns it an ID and it is this ID that is ultimately displayed to the user on the screen after they’ve clicked the Save button. The document id’s in Couchbase take the form of GUID’s.

The App Code

Roughly speaking, in the `app` codebase you’ll see the following…

1. `MyActivity.java` is a simple Android action bar activity that extends a `BaseActivity` and requires a `PersistanceManager` to be injected at runtime so it can talk to the database.

2. `PersisitanceManager.java` is a class that acts as a DAO object to `MyActivity`, managing the persistence of ‘Map’ objects. It offers only INSERT and GET operations in this sample and requires a `PersistanceAdapter` implementation to be injected into it.

3. `PersistanceAdapter.java` is an interface that defines INSERT and GET operations on `Map` objects. This interface is required later when mocking & testing.

4. `CouchbasePersistanceAdapter.java` is a concrete implementation of the `PersistanceAdapter` interface. It utilises Couchbase and depends on a couchbase `Database` object which must be constructed by Dagger and injected into it.

5. The injectable objects that require non-trivial instantiation (like the Couchbase `Database` object for example) are defined by `@Provides` methods in a Dagger `@Module` in the `MyActivityModule` class.

At runtime, Dagger, `MyActivity`, `BaseActivity` and the `App` application classes take care of constructing an `ObjectGraph` for the application and inserting the required dependencies so that all the various `@Inject` requirements can be met. The “Instrumentation (integration) Tests” in the Android App gradle project test that this integration and dependency injection is working as expected.

The Robolectric Tests

Because it’s also desirable to perform testing without a device or emulator, there’s a set of Robolectric tests for the App’s `MyActivity` class that test the same ‘Save’ feature but without the need for a connected or emulated device and without the need for an embedded Couchbase database.

In the `app-test` gradle project you’ll see the following…

1. `MyTestActivity.java` extends the MyActivity class and `@Overrides` the `getModules()` method. This method constructs and returns a `TestMyActivityModule` instance. `TestMyActivityModule` is an inner class which defines an alternative (overriding) Dagger `@Module` that can also provide a `PersistanceManager` for injection into the `MyTestActivity` when testing. This module `@Provides` a fake, programmable `PersistenceManager` _mock_, not a real persistance manager as is expected under normal conditions.

2. `MyActivityRobolectricTest.java` is a standard Robolectric test, but it’s Robolectric controller builds a new `MyTestActivity`. The method `testClickingSaveButtonSavesMapAndDisplaysId()` tests that clicking the _Save_ button has the required affect by pre-programming the `PersistenceManager` mock with behaviours and then verifying that this mock has indeed been called by the Activity as expected.

Running the Sample

To run the tests for yourself just clone or download this repository and then execute the following gradle commands. For completeness, I’ve included some Android Instrumentation Tests as well and you can run them with `gradlew connectedCheck` (assuming an emulator or device is present).

gradlew clean
gradlew assemble
gradlew check
gradlew connectedCheck (this is optional and assumes a device is present)

Acknowledgements

Many thanks to Andy Dennie for his Dagger examples on GitHub. These were really helpful to this Dagger noob when trying to understand how to integrate Dagger with Android.

About the Author

Ben Wilcock is the developer of TripComputer, the only distance tracking app for Android with a battery-saving LOW POWER mode. It’s perfect for cyclists, runners, walkers, hand-gliders, pilots and drivers. It’s free! Download it from the Google Play Store now:- Get the App on Google Play

You can connect with Ben via his Blog, Website, Twitter or LinkedIn.

Working with Robolectric and Robotium in Android Studio and Gradle


I develop the TripComputer App for Android but I find testing apps using the standard Android Instrumentation framework is really slow and painful. Slow testing cycles can kill productivity and are a well documented disincentive to TDD. Therefore, most Android tutorials that talk about testing bestow the virtues of switching to something like the Robolectric framework when unit testing Android apps.

Robolectric is great because it allows you to test your App against a ‘simulated’ set of Android SDK API’s using your desktop’s java virtual machine (jvm) as opposed to either ’emulating’ these API’s in a pretend device or accessing them on a physical device which is what the standard Android Instrumentation Testing framework does.

Robolectric also allows the use of JUnit v4 style testing annotations rather than the older JUnit v3 style required by the built in Android Instrumentation testing framework.

However, there’s a problem: getting Robolectric to work in Android Studio is difficult.

I’ve been an Android Studio user ever since it first went public nearly 2 years ago. It’s an awesome IDE but one consequence of it’s use is that it promotes the Gradle build system to be the default choice for Android projects. This is good news for Android developers but unfortunately, getting Android Studio, Gradle, Robolectric, Robotium, AppCompat and JUnit to all work happily side by side is a real pain in the rear.

Over the past year or so it’s been a slowly improving picture, but now Android Studio has gone to a 1.0 release, I (and many others) have figured the time was right to try and bring these tools together.

The android-alltest-gradle-sample project on GitHub is my attempt to create a template project that can be used as a starting point for anyone who wishes to use these best of breed Android Testing tools together with Gradle and Android Studio in one project.

The tools integrated and supported by the sample project so far are:-

  1. AssertJ for Android. Makes the testing of android components simpler by introducing an android specific DSL for unit testing.
  2. Robolectric. Allows the the simulated testing of Android apps (i.e. device API’s are simulated, so there is no need for an emulator or physical device).
  3. JUnit. Used to simplify testing of core Java and simulated Android tests.
  4. Android AppCompat v7. Popular support library developed by Google to improve support for backwards compatibility in Android.
  5. Robotium. Used to augment normal Instrumentation Tests and provide black box integration testing from Android.

There are lots of blogs out there talking about doing a similar thing, but as far as I know, this sample project is the first to demonstrate the combined use of these tools without the need for any special Gradle or Android Studio plugins to be applied.

Instrumentation Tests do still have an important role to play. They are great when used to test how well ‘integrated’ the individual units of code are when combined together to form an App. I find that thinking of instrumentation testing as ‘Integration Testing’ allows me to appreciate it’s true benefit more. As a bonus, the sample project also includes Robotium, to make integration testing simpler and more productive.

To use the sample project & code, simply clone the repository (or download a ZIP). Import the project (as a Gradle project) into Android Studio, test it and then start running code. Check out the Acknowledgements section in the readme for further help, tips and advice (including how to execute your Robolectric tests from within Android Studio in addition to the cmdline).

For more information, check out the project on GitHub.

About the Author

Ben Wilcock is the developer of Trip Computer, the only distance tracking app for Android with a battery-saving LOW POWER mode. It’s perfect for cyclists, runners, walkers, hand-gliders, pilots and drivers. It’s free! Download it from the Google Play Store now:-

Get Trip Computer on Google Play

Event Tracking with Analytics API v4 for Android


As I’ve learned from developing my own mileage tracking app for cyclists and commuters, getting ratings and feedback from users can be challenging and time consuming. Event tracking can help by enabling you to develop a sense of how popular a particular feature is and how often it’s getting used by users of your app.

In Android, Google Play Services’ Analytics API v4 can be used to gather statistics on the user-events that occur within your app.  In this post I’ll quickly show you how to use this API to accomplish simple event tracking.

Getting started.

It’s important to say at this point that all of these statistics are totally anonymous. App developers who use analytics have no idea who is using each feature or generating each event, only that an event occurred.

Assuming you’ve set up Google Analytics v4 in your app as per my last post, tracking app events is fairly simple. The first thing you need is your analytics application Tracker (obtained in my case by calling getApplication() as per the previous post). Bear in mind that this method is only available in an object that extends Android’s Activity or Service class so you can’t use it everywhere without some messing about.

Once you have your application Tracker you should use an analytics EventBuilder to build() an event and use the send() method on the Tracker to send it to Google. Building an event is easy. You simply create a new HitBuilders.EventBuilder, setting a ‘category’ and an ‘action’ for your new event.

Sample code.

The sample code below shows how I track the users manual use use of the ‘START’ button in Trip Computer. I have similar tracking events for STOP and also for the use of key settings and features like the activation of the app’s unique ‘battery-saver’ mode (which I understand is quite popular with cyclists).

// Get an Analytics Event tracker.
Tracker myTracker = ((TripComputerApplication) getApplication())
.getTracker(TripComputerApplication.TrackerName.APP_TRACKER);

// Build and Send the Analytics Event.
myTracker.send(new HitBuilders.EventBuilder()
.setCategory("Journey Events")
.setAction("Pressed Start Button")
.build());

Once the events are reported back to Google, the Analytics console will display them in the ‘Behaviour > Events > Overview’ panel and display a simple count how many times each event was raised within the tracking period. You can also further subdivide the actions by setting a ‘label’ or by providing a ‘value’ (but neither of these is actually required).

More information.

For more information see the following articles:-

https://support.google.com/analytics/answer/1033068?hl=en
https://developers.google.com/analytics/devguides/collection/gajs/eventTrackerGuide#Anatomy

About the Author

Ben Wilcock is the developer of Trip Computer, the only distance tracking app for Android with a battery-saving LOW POWER mode. It’s perfect for cyclists, runners, walkers, hand-gliders, pilots and drivers. It’s free! Download it from the Google Play Store now:-

Get Trip Computer on Google Play

Working with Google Analytics API v4 for Android


For v4 of the Google Analytics API for Android, Google has moved the implementation into Google Play Services. As part of the move the EasyTracker class has been removed, but it still possible to get a fairly simple ‘automatic’ Tracker up and running with little effort. In this post I’ll show you how.

Assumptions:
  • You’re already using the Google Analytics v3 API EasyTracker class and just want to do a basic migration to v4 – or –
  • You just want to set up a basic analytics Tracker that sends a Hit when the user starts an activity
  • You already have the latest Google Play Services up and running in your Android app

Let’s get started.

Because you already have the Google Play Services library in your build, all the necessary helper classes will already be available to your code (if not see here). In the v4 Google Analytics API has a number of helper classes and configuration options which can make getting up and running fairly straight forwards, but I found the documentation to be a little unclear, so here’s what to do…

Step 1.

Create the following global_tracker.xml config file and add it to your android application’s res/xml folder. This will be used by GoogleAnalytics class as it’s basic global config. You’ll need to customise screen names for your app. Note that there is no ‘Tracking ID’ in this file – that comes later. Of note here is the ga_dryRun element which is used to switch on or off the sending of tracking reports to Google Analytics. You can use this setting in debug to prevent live and debug data getting mixed up.

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="TypographyDashes">

<!-- the Local LogLevel for Analytics -->
<string name="ga_logLevel">verbose</string>

<!-- how often the dispatcher should fire -->
<integer name="ga_dispatchPeriod">30</integer>

<!-- Treat events as test events and don't send to google -->
<bool name="ga_dryRun">false</bool>

<!-- The screen names that will appear in reports -->
<string name="com.mycompany.MyActivity">My Activity</string>
</resources>

Step 2.

Now add a second file, “app_tracker.xml” to the same folder location (res/xml). There are a few things of note in this file. You should change the ga_trackingId to the Google Analytics Tracking Id for your app (you get this from the analytics console). Setting ga_autoActivityTracking to ‘true’ is important for this tutorial – this makes setting-up and sending tracking hits from your code much simpler. Finally, be sure to customise your screen names, add one for each activity where you’ll be adding tracking code.


Step 3.

Last in terms of config, modify your AndroidManifest.xml by adding the following line within the ‘application’ element. This configures the GoogleAnalytics class (a singleton whick controls the creation of Tracker instances) with the basic configuration in the res/xml/global_tracker.xml file.


<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="TypographyDashes">

<!-- The apps Analytics Tracking Id -->
<string name="ga_trackingId">UX-XXXXXXXX-X</string>

<!-- Percentage of events to include in reports -->
<string name="ga_sampleFrequency">100.0</string>

<!-- Enable automatic Activity measurement -->
<bool name="ga_autoActivityTracking">true</bool>

<!-- catch and report uncaught exceptions from the app -->
<bool name="ga_reportUncaughtExceptions">true</bool>

<!-- How long a session exists before giving up -->
<integer name="ga_sessionTimeout">-1</integer>

<!-- If ga_autoActivityTracking is enabled, an alternate screen name can be specified to substitute for the full length canonical Activity name in screen view hit. In order to specify an alternate screen name use an <screenName> element, with the name attribute specifying the canonical name, and the value the alias to use instead. -->
<screenName name="com.mycompany.MyActivity">My Activity</screenName>
</resources>

That’s all the basic xml configuration done.

Step 4.

We can now add (or modify) your application’s ‘Application’ class so it contains some Trackers that we can reference from our activity…


package com.mycompany;

import android.app.Application;

import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.Tracker;

import java.util.HashMap;

public class MyApplication extends Application {

// The following line should be changed to include the correct property id.
private static final String PROPERTY_ID = "UX-XXXXXXXX-X";

//Logging TAG
private static final String TAG = "MyApp";

public static int GENERAL_TRACKER = 0;

public enum TrackerName {
APP_TRACKER, // Tracker used only in this app.
GLOBAL_TRACKER, // Tracker used by all the apps from a company. eg: roll-up tracking.
ECOMMERCE_TRACKER, // Tracker used by all ecommerce transactions from a company.
}

HashMap<TrackerName, Tracker> mTrackers = new HashMap<TrackerName, Tracker>();

public MyApplication() {
super();
}

synchronized Tracker getTracker(TrackerName trackerId) {
if (!mTrackers.containsKey(trackerId)) {

GoogleAnalytics analytics = GoogleAnalytics.getInstance(this);
Tracker t = (trackerId == TrackerName.APP_TRACKER) ? analytics.newTracker(R.xml.app_tracker)
: (trackerId == TrackerName.GLOBAL_TRACKER) ? analytics.newTracker(PROPERTY_ID)
: analytics.newTracker(R.xml.ecommerce_tracker);
mTrackers.put(trackerId, t);

}
return mTrackers.get(trackerId);
}
}

Either ignore the ECOMMERCE_TRACKER or create an xml file in res/xml called ecommerce_tracker.xml to configure it. I’ve left it in the code just to show its possible to have additional trackers besides APP and GLOBAL. There is a sample xml configuration file for the ecommerce_tracker in <your-android-sdk-directory>\extras\google\google_play_services\samples\analytics\res\xml but it simply contains the tracking_id property discussed earlier.

Step 5.

At last we can now add some actual hit tracking code to our activity. First, import the class com.google.android.gms.analytics.GoogleAnalytics and initialise the application level tracker in your activities onCreate() method. Do this in each activity you want to track.


//Get a Tracker (should auto-report)
((MyApplication) getApplication()).getTracker(MyApplication.TrackerName.APP_TRACKER);

Then, in onStart() record a user start ‘hit’ with analytics when the activity starts up. Do this in each activity you want to track.


//Get an Analytics tracker to report app starts and uncaught exceptions etc.
GoogleAnalytics.getInstance(this).reportActivityStart(this);

Finally, record the end of the users activity by sending a stop hit to analytics during the onStop() method of our Activity. Do this in each activity you want to track.


//Stop the analytics tracking
GoogleAnalytics.getInstance(this).reportActivityStop(this);

And Finally…

If you now compile and install your app on your device and start it up, assuming you set ga_logLevel to verbose and ga_dryRun to false, in logCat you should see some of the following log lines confirming your hits being sent to Google Analytics.


com.mycompany.myapp V/GAV3? Thread[GAThread,5,main]: connecting to Analytics service
com.mycompany.myapp V/GAV3? Thread[GAThread,5,main]: connect: bindService returned false for Intent { act=com.google.android.gms.analytics.service.START cmp=com.google.android.gms/.analytics.service.AnalyticsService (has extras) }
com.mycompany.myapp V/GAV3? Thread[GAThread,5,main]: Loaded clientId
com.mycompany.myapp I/GAV3? Thread[GAThread,5,main]: No campaign data found.
com.mycompany.myapp V/GAV3? Thread[GAThread,5,main]: Initialized GA Thread
com.mycompany.myapp V/GAV3? Thread[GAThread,5,main]: putHit called
...
com.mycompany.myapp V/GAV3? Thread[GAThread,5,main]: Dispatch running...
com.mycompany.myapp V/GAV3? Thread[GAThread,5,main]: sent 1 of 1 hits

Even better, if you’re logged into the Google Analytics console’s reporting dashboard, on the ‘Real Time – Overview’ page, you may even notice the following…

Real Time Overview page
Analytics Real Time Overview page

Next time…

In my next post I’ll show you how to use event tracking to gain extra feedback your users.

About the Author

Ben Wilcock is author of Trip Computer, the only distance tracking app for Android with a LOW POWER mode. It’s perfect for cyclists, runners, walkers, hand-gliders, pilots and drivers. It’s free! Download it from the Google Play Store now:-

Get Trip Computer on Google Play

Announcing: Trip Computer for Android


The reason that I’ve been so bad a posting recently is that I caught the Android development bug. I’ve been using all my spare time working on a new Android application called ‘Trip Computer’.

Trip Computer is a cost and distance tracker that you can use to help with business mileage expenses, or for leisure any time you want to know how far you’ve travelled, which direction you’ve been going in or how long you’ve been going. You can use it walking, cycling, running, in the car, on the train or even on boats or planes (subject to the usual flight restrictions).

TripComputer-app-framed-shadow

Working with Android has been the most brilliant experience, it really is very cool. I’ve also been exclusively using the new Android Studio IDE from Google (pre-beta) including it’s built in Gradle build system.

Android Studio is really good. Announced at last years Google I/O conference it’s based on IntelliJ Idea Community Edition and already it’s giving Eclipse a real run for its money with its strong integration into the Android eco-system. The learning curve has been quite forgiving and the IDE quality and stability are very surprising considering its not a fully released product.

Gradle is a different story. I can take it or leave it to be honest. As a Maven user, I can see lots of issues and nasty cludges (like the poor file ‘filter’ and replace experience which is really useful and much better in Maven). The learning curve has been steep, possibly because Android projects are not standard Java projects. But no pain no gain as they say and I do feel like I’ve come out the other side stronger and more flexible as a result.

I did pick up some handy Android hints and tips along the way, which no doubt I’ll share when I get more time.

You can download the full app for free and try it out for yourself. It’s fairly simple in UI / UX terms, but hopefully it’s got enough features to be a fun addition you your phone or tablet. I’ve tried to support the widest range of devices possible so anything with Froyo onwards and the right hardware should be just fine…

Get it on Google Play

My all-time top five posts


I’ve just been picking through the admin statistics for my blog and I thought I’d quickly share with everyone the top 5 posts from my SOA, Java and BPM blog.

Every year I’m astonished by the level of support that I receive from the architecture community, and yet looking at the stats one thing has surprised me. Considering that I’m a SOA specialist, none of the top 3 articles contain pure SOA content. It seems that it’s more likely that developers interested in SOA and service-oriented software are the most regular and common visitors to my blog and most often they’re after tips of a technical nature relating to application servers, cloud infrastructure and other service implementation tips.

In the more architectural content, my tips for getting started using Business Process Modelling Notation come out on top.

The top three articles to date were:

  1. Hyperjaxb3: XML to Java to Database (and back again)
  2. Commissioning Glassfish 3 application servers on AWS EC2
  3. Getting Started with BPMN
  4. RESTful service with HyperJaxb3 (Part 4 – Architecture)
  5. SOA Certified Architect: Module 1 – Fundamental SOA & Service-Oriented Computing

So if you haven’t seen them before, follow the links above. Several thousands visitors can’t be wrong.

In future I’ll try to post more development tips. Next on my R&D agenda is Android development, so we’ll see what inspiration that offers for future articles.

As ever, thanks for reading!

Want up to the minute news? You can follow me on Twitter, G+ and LinkedIn.