Colin's Journal: A place for thoughts about politics, software, and daily life.
Easy-to-use business expense tracker for Android.
It’s been a long time since I set out to learn a new programming language. All of my development recently has been in Java (Android) and Python (Django), both of which I’ve known for years. Although Go hit version 1 in 2012, it is only in the last couple of weeks that I’ve started to pay attention to it.
The number of people talking about moving to Go from Python was a big influence to try it out. I’ve been using Python for a long time and it remains my favourite language at this point. After my first try at Go I can see the attraction to Python programmers. I started by doing a short script to load in some values from a CSV file, process them and write out to another CSV file.
This is the kind of thing that I find Python perfect for. It takes very little time to write thanks to the built in library, no effort to setup the environment as it just requires a single text file, is easy to debug thanks to the edit / run cycle being so short, and so gets you to a result really quickly. The experience with Go was somewhat similar. You do need to setup the environment for the first time, but the
go run command means you can still have a short edit / run cycle. Like Python, the CSV library is built in and the resulting code is mostly free of boiler plate variable definitions, etc.
I’ve seen Go described as being 90% as expressive as Python. From my first encounters with it, that seems to hold true. There are a few tedious type casts required that Python avoids, but overall the feel is much closer to Python than to Java or C. The 10% given up buys a compiled, easy to deploy program that executes fast and can be more easily scaled than Python.
My initial experiments with goroutines and building a prototype TCP server resulted in compact code but with more type wrangling than I’d like. Having to think about when you are using values versus references (maps, slices and pointers) resulted in some subtle bugs only found in unit testing. This is probably down to too much time spent in Java and Python.
There are a lot of conveniences in writing Go. The source comments generated documentation system is trivial to use (far simpler than Javadoc) and the builtin unit testing framework is also very easy to use. The ability to have package level variables accessed from multiple files in the same package makes it very easy to build a modular set of code.
I haven’t tried any true OOO programming with Go yet. I’ve read much concern about the lack of generics and limited inheritance support. It’ll be interesting to see how much pain that causes in my code.
In previous releases of ExpenseClam I’ve introduced two major new features: mileage and attachments. Of the two, mileage proved to be the easier to do within the existing application structure.
When designing the mileage functionality I decided early on that I wanted to make mileage work the same way as other types of expense as closely as possible. Mileage expenses would appear in the same list of unclaimed expenses, be exported in the same spreadsheet file and be moved into claims in the same fashion.
The easiest way to do this would be to have a mileage specific screen that generated expense records using exactly the same format as normal expenses. This approach is used by a number of competitors and is very lightweight to implement.
The downside to this design is that once a mileage record has been entered it loses mileage specific fields (such as distance, mileage rate, etc). I decided on a slightly more involved way of solving the problem: extending the expenses records to have mileage specific fields and creating a specific set of screens for creating and editing mileage records.
The code that lists expenses required only minor tweaking in order to distinguish between the two record types. The export code required additional columns in the spreadsheet output for mileage records, and code for managing expenses in claims was unchanged.
When a new or existing expense is opened ExpenseClam determines which UI is required and launches the appropriate Activity. Both sets of screens have a common super class that contains all the common logic for managing the life cycle of creating, discarding and saving expenses. Code for handling receipts is restricted to the expense handling class, while distance calculation logic is restricted to the mileage class, hopefully making maintenance easy.
If I had dropped support for Android versions earlier than Honeycomb I could probably have maintained a common activity and used separate fragments to achieve the same effect. However to support Gingerbread and earlier I have most of the Actionbar logic in the Activities, along with code for coordinating interactions between other Activities.
During testing of the latest version of ExpenseClam (released just last week), I stumbled across a small issue that I’ve not seen before.
Until recently I was using a back port of the Jelly Bean keyboard on my phone. I really like the swiping of characters implementation and find the auto correct to be rather good, although the prediction is rather limited.
Since SwiftKey released their version of character swiping (called SwiftKey Flow), I’ve been using it on my phone, and it’s generally good enough that I’ve not switched back to the Jelly Bean keyboard.
Now on to the issue: trailing spaces. Having swiped across letters to form a word, SwiftKey populates the word, and adds a space ready for entering the next word. Unfortunately this space isn’t just for show, it is populated in the widget value, so when the contents of the field are saved it includes the trailing space.
In general this is mostly harmless, however if you spot the trailing space and delete it, you can end up with two database records that look the same, but are actually different. This makes auto complete on fields less useful and potentially confusing.
The fix is easy enough, I just trim the string before saving to the database, but it would have been better if SwiftKey had used the same approach as Google and inserted the space at the start of a swipe rather than at the end.
It took me two days of digging around to finally figure out why ExpenseClam was not working properly on the HTC One X. The symptoms were straightforward enough: taking a picture would show a blank result, and the expense record showed a warning icon saying that the image file could not be loaded.
By adding some debug cpde, and with the help of a friend who owns the device, I was able to confirm that the camera code was creating an image file and that it was successfully saved. By signing up to testdroid.com I could get access to the logcat output of a real device on the cloud, which gave me the next breakthrough. My call to BitmapFactory.decodeFile was failing to return a bitmap, in turn caused by SkImageDecoder returning null.
Searching online sent me chasing a few red herrings, but eventually I had the idea of removing the code which sets the thumbnail size before taking the photo. Suddenly it worked, the bitmap correctly loads. So what went wrong?
The API documentation for setJpegThumbnailSize is fairly unambiguous “If applications set both width and height to 0, EXIF will not contain thumbnail.” Further to this the method getSupportedJpegThumbnailSizes states “This method will always return a list with at least two elements. Size 0,0 (no thumbnail) is always supported.” Based on this I had chosen to disable thumbnails in order to reduce image file sizes.
It turns out that only most devices support this. The HTC One X accepts setting the thumbnail size to 0, but then produces a file that the BitmapFactory cannot read. Leaving the thumbnail settings to the device defaults works.
Hopefully this post will save someone else a couple of days investigation.
It’s been a long time since my last post, with the birth of our daughter taking up all of my nonworking time. I have however purchased a Nexus 7, now being able to see how the 7″ tablet running android compares to the playbook.
I haven’t yet tried travelling with the tablet, but for use at home, it blows away the playbook for usefulness. The experience is not perfect by any stretch. The BBC are yet to provide an iPlayer app that works without flash, so you have to use workarounds to watch TV. The Economist, fantastic publication though it is, have produced a rubbish android app that doesn’t support ICS, never mind Jelly Bean.
Putting to one side these niggles, most of the important apps are there and work well. The chrome web browser provides a good experience, with rendering much faster than the playbook. Games play fluidly on the Tegra 3 powered machine, with the vibrant screen providing an almost SciFi feel in such a slim form factor.
The keyboard is good, certainly the best soft keyboard I’ve used. It is a little sluggish at times, with some key taps not registering as well as you would hope. Strangely tapping quickly seems to work better than trying for accuracy.
While the bundled Transformers movie is a terrible film, it does show off the tablet to good effect, with the movie streamed in HD, and looking very crisp on the high resolution screen. It also further justifies having an unlimited broadband package as the one film weighed in at over 5GB of streamed data. Uploading my own DVDs was fiddly from Linux, but should be straightforward from windows or Mac OS.
In conclusion, while the Nexus 7 may not be a substitute for a laptop in the way that an Asus Transformer could be, it makes a great content consumption device. If the alternative for content creation is your phone, the 7 inch screen works far better, while retaining a lot of portability that a large device sacrifices.
The killer feature for me is the weight. Holding the tablet for extended periods is as comfortable as holding a paperback book, possibly more so. The Nexus is the first device for which I reach for most online tasks, with the desktop relegated to development and photo editing.
I’ve recently acquired a blackberry playbook by porting ExpenseClam to this platform. The physical format of a 7 inch tablet seems to work very well. It is still small enough that carrying the device around is very easy, and holding it in one hand is entirely comfortable. Meanwhile the screen is just large enough that websites can be viewed in their desktop format, without having to zoom in and scroll.
That’s the good news. The bad news is that the quality of available apps is very low. Most of the big name apps are missing (e.g. no Skype). There are many ported Android apps, but these work only partially. Native Android features are missing and they have a tenancy to hang.
Native apps that I have found suffer from a clunky keyboard implementation, and flaky UI widgets. The Web browser is reasonable, but occasionally suffers from unresponsive UI elements.
My overall impression is that the tablet would be far more useful and interesting if it was running Android ice cream sandwich. This leaves me wondering whether I want to get either a 10 inch tablet our something around the 7 inch mark.
To sum up: when writing this post, I started on the tablet, but the application hung, and I ended up retyping it on my phone. It is hard to see the playbook platform being a success given it’s current state.
For an app that only recently moved into the 100-500 downloads range, the paid version of ExpenseClam is doing remarkably well. As of writing this, ExpenseClam is number 65 on the list of top grossing apps in the Business category on the Android market.
Looking at the next lower ranked app however I think this is down to how the market treats apps that change categories. Number 66 is an app called SMS super faker, which appears to have always cost the same as ExpenseClam, but is in the 1,000-5,000 download range. According to AppBrain it switched from the Communication to the Business category on the 23rd of December 2010, 6 days before reaching the 1,000 downloads mark. The only explanation I can think of for having a lower gross revenue than ExpenseClam is that it has had far fewer downloads in its new category than previously.
Similarly number 70 (calendar scroll widget agenda) also has far more downloads than ExpenseClam, but has recently changed category.
The lesson to learn from this appears to be that changing category within the market is penalised, at least as far as the top grossing lists are concerned. Whether this impacts app exposure is another matter. How many apps are purchased as a result of browsing the lower echelons of the top grossing list, versus searching and picking from the featured and staff choices lists is unknown.
I’m struggling to decide on whether a NetBook or a tablet would be better suited for me. The tablet would be an Android one, probably the new transformer prime from Asus. It would allow me to test tablet specific designs for ExpenseClam and would provide a more convenient form factor for web browsing than my phone. The transformer also has a keyboard attachment, so writing blog posts and even some web site design should be easy.
A NetBook on the other hand would allow me to do Android development while travelling, and even at home on the sofa, rather than isolating myself away in the study.
In theory I could use VNC, or some other remote desktop software to control my desktop from a tablet, but in practise I expect this to be clunky at best. I could get both a tablet and a NetBook, however I know that when travelling I would only want to carry one, not two machines with me.
At the moment I’m leaning towards the tablet. While ExpenseClam works fine on tablets, it uses the same layout as for phones. I should be able to design a layout that really takes advantage of the extra screen space available on tablets. It also feels like a more modern investment than what is essentially a small laptop.
This post is a bit of an experiment as it had all been written on my phone using the latest WordPress app. Overall not a bad experience, mainly thanks to the Swype keyboard.
The Android Market continues to struggle in providing a great end user experience. To illustrate, here’s what I went through when purchasing Carcassonne tonight:
It’s fairly amazing that my own app (ExpenseClam) receives any purchases at all given the difficulty involved!
I should add that it was worth persevering – the game is rather good!
Yesterday I released ExpeneseClam, a business expenses tracking app for Android. Recording expenses on a smartphone can be a painful experience, typos are common, expense claims are not always made in chronological order, and there is usually little time to note down how much a taxi cost. ExpenseClam has a number of features to help make this easier. Simple things like auto-suggesting expense descriptions based on the amount entered can make it much quicker to record common recurring expenses.
One of the niftiest features in ExpenseClam is something that you will only stumble across if you travel a lot: it auto selects the default currency for a new expense based on the country you are in. This is done without needing user permission to determine location, carry out reverse geocoding or even internet access.
The secret sauce is Android’s TelephonyManager and it’s method getNetworkCountryIso(). This method returns the ISO code given by the mobile operator for the network that you are connected to (the Mobile Country Code). From this a Locale object can be created, which then allows the Currency instance to be created. None of this requires network traffic and it takes very little processing power to complete.
Changes in the default currency only happens when the country changes. This is to avoid frustrating users who have to enter expenses in a different currency to this default. The country derived currency is however prioritised in the list of currencies to make selection easier for what is likely to be a common choice.
Copyright 2009 Colin Stewart