Writing an Open-Source Android Library
(and possibly regretting it..)

So you decided to write an open-source library, and here you are. What have you got yourself into now, and what’s that header image got to do with anything? Well that lovely header picture up top is a photo I took from my desk of a seagull caring for its young; it has just vomited up some slugs that it collected earlier, and the fledgling gulls are hoovering it all up as if it’s…not a disgusting pile of slugs because they don’t know more delicious things exist in the world, because they’re still too young to even fly off and find food for themselves.

And that, in a metaphor, is a third-party open-source library. End of article.

I’m joking, but I’m only half joking, because that is a pretty good metaphor for some OS-libs I’ve seen, and I still have more software-development-flavoured snark to deliver before my desire to write wanes and I go back to swearing at the habitual, almost wilful, illogic of Facebook SDK developers, under my breath of course – as they still kinda pay the bills for me these days..

So you might be wondering at this point when I’ll just get to the code dump that you can copy-paste somewhere, and rename awesome-omni-util-lib, so that you can become the next Jake Wharton, well hold your horses there young buck. First in order to decide whether or not we should even be making such a library, we must do a little exercise I like to call, the Super Fun Dunning Kruger Stage Self-Assessment Quiz Fun Quiz!

Here ’tis:

1. Are you writing this library because you actually need it? Or because you think that you or someone else might need it at some point, maybe?

If the latter. Abort. You are wasting your time. YAGNI alert! At very least you should need this library that you are creating right now, because the only way that you “shake down” a dependency is when it’s used. In addition, if nobody uses it (not even you), nobody finds the bugs, and the dependency remains rubbish and unusable. Just search the sea of single-commit library repos on GitHub that are tagged android-library to see what I mean.

2. Have you been using the techniques that are in heavy rotation in this library for more than a couple of weeks?

Let’s assume that your library will be a great success, and used by thousands in the first few months. Congratulations! Your repo will be acquired by Google in no time, and your future Silicon Valley career path is a sure thing! Think of all of the people looking at and scrutinising your code in great detail, and adding that unique flavour of warm, supportive and constructive feedback that the internet is known for. Take some time to think about that one for a while and ask yourself if you really want to open up that door.

Do you really want this thing out in the open? Or could it live quite happily as a project-scoped library module, ugly in form and absent in test coverage, but works fine on your machine so who cares?

3. Does a similar thing already exist, written by a developer people have actually heard of/has done a conference talk or two so has dev clout (not to be confused with dev competence, as they are very different things – see Facebook SDK comment above..)

If your library is insufficiently niche, someone else will have already done it better, or is about to. You will never be the smartest person around, and if you think otherwise you, padawan, are so far left on the holy curve of Dunning Kruger that you should stop reading right now and go and do a hard thing that you will fail at, because the world has more opportunities for failure and moments of humility to dish out than you could ever dream of, and if you haven’t fallen hard on your face and had your code quality ego unceremoniously stripped from you, you are missing a crucial lesson in life in general. Certainly one in software development. So you should go and experience said humiliation such that you can be a better, more modest and balanced developer on the other side of that formative experience.

Un-requested life lesson segue aside, do you want to write a second, tenth, or fiftieth best library that does a common thing that other people have done a better version of? To compete with people whose dev clout attracts hundreds of stars and tens of genuinely helpful PRs, which add technological distinctiveness to their own, and makes them look like a competent leader of devs, even if they’re just Developer Advocates who couldn’t hack an actual production-code writing job so retreated to telling other people how to do it, like a school careers advisor – like, dude. Look at yourself. What advice do you have to give me?

4. Do you seek to boil the ocean with a library of such full-functionality that it will serve all purposes?

Everyone who grew up coding, has at some point had that thought – when they were about 13 years old, and the optimism of youth, blissful ignorance of feature creep has yet to rob the ambition from them: I’m going to write my own Operating System! Very, and I mean very few ever actually got something useful working. I’d go as far to say that if you managed to load a hardware driver and get something to work from a line of interpreted code, you’re in the 1%.

Bear in mind that it’s 2020, and there are still only three viable OS’ for personal desktop use – Windows, MacOS and Linux, and that last one is still for nerds, and the guy who “wrote” the first one stole it anyway; come on Bill you’re fooling nobody here, we know you Zuckerberged it. Come clean!

You can keep the money.

5. Do you have a strong (and justified) opinion about how the thing that you’re making this library to do, should be done?

This might be the most important in this super fun quiz fun. If you don’t have a strong opinion about how to do this arbitrary chunk of logic that you’ve cooked up in your head, you’re going to follow the ruts in the road like a SUV on summer tyres on a crisp January morning in Quebec; getting pulled left and right where the tracks cross, and get sidetracked every new article you read on Medium, RayWenderlich or that YouTube one whose name I always forget. You know, the German guy.

If you want to write a LiveData-based random pun generator that updates a ViewModel and punts it out to a TextView element that only displays Comic Sans text in #F00, then you make that library, kid. Don’t let anyone on the issues tab tell you it should support other typefaces.

To use the metaphor from up-top, instead of giving-in to the baby seagulls demands for juicy slugs that you don’t want to puke up, I suggest that you:

Tell them to fork off and do it themselves

Conclusion

Oh right, that code that you wanted to copy paste so you could actually make an Open-Source Android Library module.

Here you go.

No, I didn’t write it myself, because do you really think I can write an example better than the JitPack team already has? Because I don’t.

Thanks for reading. Good day to you. 👋

Keeping it Clean

I made a conscious decision to just use a laptop as my main machine back in 2004, so for more than a decade now I’ve been living without a PC “tower” as part of my essential kit. Whilst the advantages of being able to carry around your main machine with you all day every day are clear, one of the major disadvantages of a portable computer is storage space.

I have two external drives that I use to back up the machine and to keep important things like my photos backed up in duplicate between bulk uploads to my main backup server, but carrying those around with me in the same bag as the laptop is sort of defeating the point of having a backup…so I don’t. You shouldn’t either. I keep them locked away wherever I happen to be staying, and just take the aluminium slab with me. That means day-to-day I only have half a terabyte of storage space to play with, which used to be a lot…but once upon a time people said the same thing about half a megabyte; it’s a fact of digital life that data bloats.

I’ve accumulated a few tools over the years that I always come back to when keeping my MacBook tidy, here’s the rundown:

CleanMyMac 2

Screen Shot 2015-07-19 at 09.36.06If you only want to use one tool to keep your mac clean, this is the one I’d recommend. I got it in a MacHeist bundle a while back and since then have used it a couple of times a week without fail. Its ease of use is what keeps me using it, along with the reminder that you can enable that tells you when there’s a load of crap that you probably don’t need any more.

You needn’t define which files you want to keep or what you don’t upfront, it provides guidance about the common places to tidy things up; the trash can being a common and obvious one, but less obvious are unused large files that you might have forgotten about, browser and OS extensions that aren’t enabled, and even photos kept in iPhotos recycle bin!

You can also use it to cleanly remove apps that don’t support the Mac standard “drag to bin” method of uninstallation, and also makes it easy for you to reset an app to a clean install setting without having to actually reinstall it (I found this handy for resetting Eclipse after various rogue plugins ruined my setup, before I ditched it entirely for Android Studio!).

The last cool little feature, is that it keeps a running total of how much space it’s freed up since you started using it; my count is well over 3 terabytes now! Feels good.

CleanMyMac from MacPaw

 

DiskInventoryX

Screen Shot 2015-07-19 at 10.01.29This tool ventures a little into the realm of geekery in terms of its aesthetic and ease of use, it’s certainly not as pretty and straightforward as CleanMyMac. I sought out this tool following my original cleansing pilgrimage away from the poisonous gospel of Microsoft Windows, where I travelled into the remote mountains on a brain debugging retreat to cleans the last of the carcinogenic digital toxins left by years of traumatic spontaneous BSODs and the generalised corruption of my workflow by Visual Basic’s bastardised Hungarian System notation…

Too dramatic? Well I used to use a tool called WinDirStat for visualising hard disk space, and wanted the equivalent for my Mac. That tool is DiskInventoryX, and is very similar in style to WinDirStat in that it gives you colour-coded visual representations of whichever storage volumes that you have plugged into your machine, thereby making it easier to find and remove the bloaters. I cannot stress how useful it is to be able to see blocks of different sizes rather than just numbers in a list; it directly led to me moving all of my VMs (I can’t unfortunately completely escape Windows…) to external drives when I saw that the files that Windows creates when it suspends running state were bigger than my entire documents folder!

It’s somehow more meaningful when you see a big pink tumour of wasted space.

Disk Inventory X by Tjark Derlien

 

Dupe Guru

Screen Shot 2015-07-19 at 10.23.50I download a lot of stuff. Code, documents, images, screencasts of bugs, all sorts of things, all day as and when I need them. As soon as I’ve viewed them I immediately forget where they are, if I’ve seen it before and whether I’ve already deleted it. When they all end up in the same folder, then it’s easy – the little (1) gives me the clue that I already have that file, but what if like me you tend to use different folders on different drives for different projects and clients? That’s when it gets tricky. Fortunately I stumbled upon DupeGuru at some point in the past year and since then those issues have vanished for me.

It’s low-weight, fast and super easy to use. You can select individual folders or even entire disks. Hit scan, wait for it to do its stuff, and choose an action to take either individually or in bulk. As I wrote this section on dupeGuru, I set it off scanning an external drive with just under 2TB of data on it. By the time I’d finished writing, and at some point between then and me going to make a second coffee for myself, it had created me a list of stuff I could get rid of. Manually trawling the same folders would’ve taken hours (a conservative estimate) to do manually.

dupeGuru from Hardcoded Software

 

Finally, sometimes the simplest things…

Sometimes all of these fancy GUIs can blur the real issue at hand. If you’re not scared of the odd terminal command or bash script, check this, the simplest of simple Terminal commands, out:

mv ~/Downloads/* ~/.Trash/

I set this up as a shortcut when I got my first MacBook Air, and still use it to this day. All it does is move the contents of the current user’s Downloads folder to Trash. You can even automate it on login/logout, and CleanMyMac will collect it next time it runs.

Create a shortcut to it on your tray, or if you’re brave set it up to run automatically, and you’ll start to think more carefully about whether you should leave the single copy of that important document in your Downloads folder next to the cat memes in future. Because they’ll all end up in the digital landfill together!

5 Open Source Android libraries that you should be using

Not much of a preamble here, the title says what this is. If you’re new to Android development, or if you’re just still relying on Google APIs to do everything, these might make your life a bit easier.

The titles all link to the corresponding project pages where you can download/view the source, but if that seems like too much like hard work, just copy-paste the Gradle dependencies (below the name of each library), sync your project, and start playing.

But I use Eclipse, where are the Jars?

*slap* No! Bad developer.

As you appear to have been under a rock recently, you should know that Eclipse is no longer the official IDE for Android, which means you’re making life harder for yourself for no good reason. All of the nice new stuff has moved to a lovely IntelliJ-based IDE. It still can turn a MacBook’s 9hr battery life into a 3hr one, whilst doing a pretty good impression of a hotplate, but hey, that’s Java…

So download Android Studio, then read this, no need to thank me, then read on.


Picasso

compile 'com.squareup.picasso:picasso:2.5.2'

Network image loading made really, really easy.

You probably know this one already, as it’s the easiest solution to loading up an image from a network location, and is the de-facto response to the thousands of “how do I load an image from a url” questions on StackOverflow.

There are tons of tweakable methods and callbacks to use, but if you just want to load an image, it’s as simple as this:

Picasso.with(context)
    .load(url)
    .into(imageView);

Retrofit

compile 'com.squareup.retrofit:retrofit:1.9.0'

If you have an app that connects to a RESTful API (which you do obviously because this is 2015, I think my electric razor has a RESTful API) retrofit makes it easy to turn said server-side interface into a Java interface by using annotations, so that you never have the headache of manually handling every method and call interaction yourself.

These examples are quicker to grok than it would take me to explain it, so check them out.


NexusData

compile 'com.github.dkharrat.nexusdata:nexusdata:0.1.3'

iOS, whilst almost comically flawed and restrictive as an operating system, is a whole lot easier to develop a robust app for due to the well thought out restrictions that Apple place on their developers.

I’ve often seen terror on the faces of iOS developers who try to ‘dip in’ to Android, assuming the SDK-provided libraries to be as well thought out and clean as those they play with in XCode.

It can be summed up thusly:

iOS

It just works

Android

It just works

(for API > 14, except for JellyBeanMR1, or devices that don’t support this undocumented API which we will rename next release anyway, if you’re not using proguard, which is now minify, but has these libraries that are back-ported by the manufacturer, on screen densities that are sort of big, but not landscape, except if they’re fixed aspect, and running the support libraries. On Tuesdays, when it’s not raining.)

…usually. But not on Samsung devices, or older HTCs.

So I’ll freely admit, as an Android developer I am envious of the iOS toolset; GCD, CloudKit, Multipeer Connectivity and last but most: CoreData.

Why can’t we have nice things like that? Oh, we can! (the last one anyway)

Whilst there are a lot of options available that mean you never have to meddle directly with SQLite in your app, NexusData is my personal favourite due to its high-level nature and simplicity of use.

So stop messing around with data persistence code, and get on with making your app.


ButterKnife

compile 'com.jakewharton:butterknife:6.1.0'

If you develop Android apps, you will have typed findView(R.id.something) more often than is healthy.

Stop that.

Jake Wharton’s (if you’re new to Android, you’ll see this name a lot) ButterKnife does away with the need for that extra typing by providing a simple way to generate boilerplate code for the UIs that you define, all via the magic of annotation processing.

 


GSON

compile 'com.google.code.gson:gson:1.7.2'

I use this constantly, and so should you wherever you use JSON in your Android app. I’ve found no better method for turning POJOs into JSON, and back again.

It’s hard to believe, but I’ve seen some very recent examples of code where the developer is still manually writing methods that do this, and in once case a minor mistake that somehow got through to production untested, led to the users of the app being unable to log in at all…

Don’t be that person. Use GSON.

A “make something cool in <2hrs" experiment.

What’s this?

I’ve been working my arse off the past few weeks on various projects for clients, and feel the need to write. I’m not sure what I want to write about so I just opened up WordPress and decided to experiment. This post is that experiment.

This morning (a Sunday morning – internationally recognised as me time), I’m taking time away from that for a couple of hours to do what I used to do before “playing on the computer” turned into “making a living”. I’m going to write this as I go, so it’ll probably be terrible. But meh, that’s not a good enough reason not to do it.

Prep coding fuel (actually from a few weeks ago, but representative of liquid requirements):

Ahh, that’s the stuff. #firstcoffee

A photo posted by Matt Fenlon (@nolnefm) on

Oh..kay? So what are you actually doing then?

I’m going to make something with OS OpenSpace; Ordnance Survey’s Google Maps-alike API for using OS map imagery in a manner familiar to developers. You can read about it here.

It’s been on my list of rainy day play-around projects for ages, and whilst I keep getting emails about cool new stuff they’ve done with it, I never seem to have that spare time to actually try it out. This morning that changes. It sounds cool, I want to make something, so I am.

Getting Started

The first part of using any new API is getting something working. I normally do this by setting up an empty project in Android Studio, importing any required libraries and setting up the API keys, secrets tokens or whatever the API uses for authentication.

As I’ve signed up for an API key already, I went to the Manage My Sites page (which is for apps too, despite the “sites” title) on the OpenSpace site to see what my API key is, and to find out which package name I originally used when I signed up – I’ll need to use the same one for this mini-project. I called it com.mattfenlon.osmap, so that’ll be my package name.

Screen Shot 2015-01-25 at 10.35.33

Easy.

Integrating the SDK

Next bit is to integrate the Android SDK if they have one, which they do. Cool.

But bloody hell…not the most straightforward quick start guide I’ve ever seen! To save you skimming time if you want to just get the jar file, it’s here. Import it into Android Studio (or Eclipse if you’re a masochist and haven’t switched yet). Not covering that step here. GIYF.

Getting something to happen…

By this point I’ve got the jar file set up as needed in my AS project, and it’s syncing fine. I’ve loaded up a Genymotion emulator (because the Android SDK emulators suck…); a Nexus 6 configuration, running Lollipop. Because shiny. The app builds and loads the bog “Hello World” with no errors, we’re in business.

Incidentally I’m using Fragments not Activities, because they’re efficient, super-flexible and best practice. Anyone who tells you otherwise is either too lazy to learn the new way, or is recycling old projects from the days that they used to use Activities and cba to update their base projects. Sorry, it’s my opinion of course, but there’s no downside to using Fragments for even simple projects like this if you’re a half-decent developer. /rant

Setting up permissions

From the example app, it looks like it needs Internet, External Write and Access Network State. Also Open GL ES 2, presumably for some map rendering shenanigans.

Adding a MapFragment

This is done in XML. Nothing fancy, just a <fragment> of name:

android:name=”uk.co.ordnancesurvey.android.maps.MapFragment”

It has a label too, not sure if that’s needed yet.

Setting up the MapFragment in Java

Similar but not the same as a Google Maps setup. I’m using the demo app they provide in GitHub to get the map object instantiated. The only difference being that I’m doing this within a Fragment rather than an activity, so getFragmentManager() becomes getActivity.getFragmentManager() etc. No biggie.

Now I’ll try running it to see if it’s all good so far…

Screen Shot 2015-01-25 at 11.12.14

Cock… Right, to LogCat. What have I done wrong?

Screen Shot 2015-01-25 at 11.13.07

Right. I don’t think I’m jumping to conclusions to guess that it’s something to do with that OpenGL ES 2.0 reference from earlier…

How do I find out what went wrong then?…

Best bet is usually check out the documentation/comments within the library that you’re using. I just did and found this from here.

Screen Shot 2015-01-25 at 11.24.33

There’s talk of emulator issues with hardware acceleration. I’ll try on actual hardware to see if that’s the issue.

Screenshot_2015-01-25-11-22-58

Sure enough. Works fine on hardware! Rather than implement a workaround as suggested, I’ll just crack on with my physical Nexus 5. Life’s too short, and this is just a hobby session.

Adding a marker

This looks very familiar, very Google Maps like, which is what I’m sure they were going for in order to reduce boundaries for adoption to existing developers – don’t make us work too hard, always a good idea.

Screen Shot 2015-01-25 at 11.29.20

Rather than read docs or do trial-and-error to see what the format is of such a grid point. I’ll just punt it out from a touch input in that OnMapClick listener method, straight into LogCat.

Screen Shot 2015-01-25 at 11.34.26

Then I’ll run the app on my phone and tap it a couple of times to see what I’ve got.

Screen Shot 2015-01-25 at 11.34.06

Interesting. So it’s a six-figure reference with no decimal accuracy as far as I can see. Every tap yields a .0 on the end. Reckon that’s just an OS grid reference stored as a Double? I’ll have a look here.

Screen Shot 2015-01-25 at 11.37.04

Confirmed! Progress then. It should be trivial then to add markers. I’ll find somewhere interesting, get the grid ref and try it out.

It needs a string for a label, and a BitmapDescriptor for an icon. I’ve borrowed an icon from here for that. Free for personal use (I’m not selling this little app, so I think that counts). What’s that look like then.

Screenshot_2015-01-25-11-45-35

Ah…that’s a bit big. I pulled it straight from a Drawable. I’ll make it a Bitmap and resize it. I also need to make it zoom and centre on the marker that I just made, as I have to scroll to it at the moment.

Screenshot_2015-01-25-12-05-00

Better.

Adding more stuff…

At this point, I got lazy with the typing and just ploughed on with a little demo app… So this last bit is brief. (you can skip to the GitHub repo at this point and read the comments)

I thought the helmet and Silverstone was a good start, so I went on Wikipedia and found the locations of all of the permanent UK racing circuits, converted the listed Lat/Lon to OS Grid references using this handy site again, and manually added them to an ArrayList.

The array list is then parsed and adds the markers to the map. I set a 3000m per pixel value for the zoom, so it sort of pops out when you open up the app.

That’s it. Check it out on the GitHub repo if you want to see the super-simple implementation.

Screenshot_2015-01-25-12-45-45

5 essential apps for backpackers

The whole point of my little trip to Canada was that I wanted it to be almost entirely unplanned. Having worked in an office where I knew I was going to be every day and what I needed to be doing ages in advance, I wanted my travel to be a little more unpredictable. Fortunately technology makes that sort of trip both easy and economical.

The following are the apps that I find myself using on a daily basis; I have no association with any of them, I am sharing this info because I genuinely find them useful. I hope you do too!

1. Skyscanner Flights

This is hands down my favourite way of booking a flight, on a mobile or otherwise. It works like the flight comparison sites, but it far slicker than most and is optimised for mobile use.

You can create multiple tabs for specific searches to refer to later, so if you are planning a series of ‘hops’ and want to tweak the specific dates and airlines, you can do so by creating a tab for each journey and switch back and forth between them for comparison.

By far the best feature of this app is the price comparison chart (see vid above), especially if you aren’t constrained by when you have to fly. Enter the origin and destination airports, select ‘Any’ in the Depart date field and hit search. You get a horizontally scrollable chart showing dates along the bottom, and bars of different heights representing flight prices on each date.

For the ultimate in random, cheap flight searches, choose ‘Everywhere’ as your destination airport and see the cheapest place that you can fly to on any date from whichever departure location that you choose! Great for an unplanned, last minute weekend getaway.

2. TripAdvisor

TripAdvisor app gives you the same information as the website, but uses less mobile data
TripAdvisor app gives you the same information as the website, but uses less mobile data

This is no secret really, and every hotel or hostel I’ve been to has had a sticker in the window, such is the pervasive reputation of this tool. The app is better for limited bandwidth connections, because… *geek-out alert, skip to the next app if you’re not interested*, the mobile app uses a text-based API, so it only exchanges the data that is needed to update the information that is seen in the app, whereas the website version also loads images and background JavaScript libraries required to make the site work, making the required download much larger. So if you’re on a roaming data plan, download the mobile app over WiFi before you leave, and use the app rather than the website when you’re out and about using mobile data.

You’ll save mb’s, and it’ll be a much smoother experience.

3. Evernote

Screenshot of Evernote location-based notes screen
Evernote location-based notes

Nothing beats this for keeping track of little snippets of information that you learn from people that you meet along the way. You could use a Moleskine if you’re an analogue type, but if you lose that little book, it’s gone. Evernote backs everything up, and can record where you were when you took down the note so making it easier to refer back to to later: “Which hotel did that guy in Tofino recommend again?..”

I also use it for keeping track of touristy maps and leaflets, partly so that I don’t end up with a bag full of paper, but also because it makes you look less like a tourist if you’re just checking your phone, as opposed to unfurling some A1 sized glossy map on a bench somewhere (I prefer to blend in and not look like a tourist where I can, especially when traveling solo).

Check out Bod for tea’s great crowd-sourced post on other uses if you’re blogging about your travels as you go.

4. Google Drive (desktop and mobile combo)

I use Drive for keeping hold of reservations, confirmations and electronic boarding cards for flights, which are increasingly used at airports to reduce the amount of wasted paper involved in frequent travel.

I sync my ‘Travel’ folder from my desktop, so when I make any bookings with my laptop, the PDF print-outs are synced to my phone automatically, so when I get to the baggage check I can just get the QR code on the screen scanned rather than having to dig around for a crumpled card pass jammed somewhere in a side pocket.

It’s a great feeling to check in online, from a WiFi-enabled shuttle coach en route to the airport, then walk past the check-in queues straight to the departure gate with a smartphone boarding pass, fifteen minutes before take-off. That’s how air travel should always be.

Worried about privacy? Please…you’re using the internet to book flights. Google already knows where you’re flying. 😉

5. OwnCloud

OwnCloud screenshot

For photo-backup. This is a bit trickier to set up, but worth the effort. OwnCloud is a Dropbox-like cloud storage system that you install on your own machine; be that server or home machine that’s always-on. Once set up, you can install the app and have your phone camera photos backed up automatically when you’re in range of WiFi (or even over mobile data, if you’re really brave/have unlimited data!).

Unlike Facebook or Google+, the full-sized image file is uploaded, with all of the extra EXIF data, geolocation and original timestamps, so you don’t lose detail or resolution when it syncs. It reassures me that if my phone breaks or goes walkies, I’ll still have all of the photos that I took with it on a server back in England. It also allows me to delete all of my photos from my phone to free up space to take more!

Saving time by coding consistently

[Disclaimer: I wrote and published this on my phone whilst sat waiting in a café; if it reads a bit slapdash, it’s because it is! If you’re after a code rip, the snippets are in helpful little boxes. You’re welcome. :-P]

When working on projects that don’t have a set of “house rules” on logging, it is dangerously easy to be lazy.

I am also an advocate of making life easier for your future self; who hasn’t cursed “yesterday me when their groggy barely-conscious self is confronted with a tight morning schedule and a glowing fuel light? Amiright?

Um, ok… Well aside from arriving on time to appointments, creating good coding habits frees up brain bandwidth for creating cool new things, and produces the collateral benefit of reducing silly mistakes.

As a developer who specialises in object-oriented languages, I’ve been creating my own classes and libraries since I learnt how, back in my early Java days. In my opinion, objectifying code is an incredibly powerful productivity tool, and it worries me when I see beginner tutorials that don’t focus on this aspect; anyone can make a long class containing every function needed, and make it work, but in a production environment you’re doing it wrong! OO language compilers are optimised for object handling and memory clearing methods that favour small, granular components, not vast memory hog objects that are basically procedural.

Procedural is not the way that the world works. If you had a car that failed to start because the wing-mirror had broken off, it wouldn’t sell (in fact it wouldn’t even get through DFMEA analysis prior to a prototype build; I digress). Why then would you write a program that mixed UI functions (wing mirror) with network/data handling (ignition circuit)?!

In the same way that I like to use my favourite pencil when sketching (a Mitsubishi Kuru Toga propelling type, if you’re wondering), I have some little bits of code that I put into every Android app that I develop to make my life easier. It’s not quite boilerplate code, as it’s not part of a template, but a utility library that allows me to give my code consistency without bloat.

Consistent Logging

I know that a lot of people like to bring in external logging libraries to  their apps, indeed I’ve used Log4J a lot in larger pure Java projects, but a  lot of the popular frameworks don’t play nice with Android, and in some cases  (being designed for server-side/desktop applications) are detrimental to  responsiveness and battery life on a mobile device. So I prefer to use the  provided base classes and functions where possible. In fact, my logging function  is tiny.

When you’re logging in Android, you’d normally have something like this:

// This goes where you put your other class-scope declarations.
private static String LOG_TAG = "MyClassTag";

// This goes where you actually log stuff.
Log.i(LOG_TAG, "What I want to say.");

This leaves you wide open for laziness, as a helpful log entry like:

02-28 12:33:47.636: I/MyClassTag(988): Instantiating required variables for MyClass map component.

Rapidly deteriorates into:

02-28 12:33:47.636: I/MyClassTag(988): vars done

This is sloppy, but not technically a problem. However that sloppiness costs you time when you want to try something out quickly, or start to get tired and lose your eye for detail (~3am in my experience). Once you start  copying and pasting code around, you can end up with the wrong log tag appearing  in a class;  if you start to get two classes reporting identical tags, you’re in  for a really frustrating debugging session…

My solution, is this little function.

// This goes where you put your other class-scope declarations.
private String getLogTag(){
    this.mResources.getString(R.string.app_name);
    String log_tag_output = "";
    if (LOG_TAG!=null) log_tag_output = ":" + LOG_TAG;
    return this.mResources.getString(R.string.app_name) + log_tag_output;
}

// This goes where you actually log stuff.
Log.i(getLogTag(),"Stuff you want to say.");

Rather than being a dumb variable, ripe for a fat-fingering, the log tag becomes a mini report of which class it has been called from, and can show you at a glance if you’ve got an erroneous LOG_TAG declaration in a class where it shouldn’t be.

[Note] If you intend to keep logging enabled in a production version, you can reduce the memory cost of this function by assigning the “mResources.getString” response to a string variable in the class constructor. I switch logging lines off for production however, so am ok with the load incurred during the resource retrieval.

[Optional] In addition, I put the usual static string declaration in the class if I want to add  additional information to the tag – this works well if you have more than one  version of an identically-named class; if you’re detecting a tablet as opposed  to a phone form factor device for instance.

// Additional log tag info for this class.
private static String LOG_TAG = "NXD-version";

On its own, this doesn’t save me a lot of time. If I add up how much time I must have saved in aggregate from not having misleading logging errors in my LogCat trace, it comes in at days.

Repairing “org.eclipse.mylyn.tasks.ui” Eclipse start-up freeze on Mac OSX

Excuse the shameless “fishing for a search string” title, but it just took me over an hour to find a fix for this so, so I’m paying it forward.

The problem

This issue appears as you start Eclipse after an incomplete shutdown on a previous session – i.e. if it was force closed. If you search for this problem you’ll see a lot of sledgehammer fixes suggested:

“Delete your workspace and reimport your projects.”

“Delete your metadata directory and reimport.”

“Delete all of the hidden files in your workspace.”

etc.

The very worst recommends completely removing Eclipse and starting again. To be clear DO NOT DO ANY OF THESE! The solution is far too aggressive, and it loses your workspace configuration settings.

The problem occurs because Eclipse quits before it is able to delete a hidden “.lock” file in the workspace metadata. Upon restart it scans the metadata and sees this lock file, and as there is no pending task to clear it in the current instance, it awaits a deletion that will never happen.

The fix

Force quit Eclipse from the Dock if it’s still hanging; the damage is done, you can’t make it worse by closing it.

Open up Terminal, and navigate to the folder that contains your Eclipse workspace, then use this line to remove the hidden file lock.

sudo rm workspace/.metadata/.lock

Next, launch Eclipse with the clean and refresh arguments, so that the instance knows to regenerate any metadata that looks weird.

cd /Users/YOUR USER NAME/Development/eclipse/Eclipse.app/Contents/MacOS
./eclipse -clean -refresh

That’s it!

If you think that this might happen a lot (or if you’re just really into scripting for fun… What?) you can record the above actions as an automator script, and create a shortcut to it in your Eclipse folder so you can quickly repair the problem again in future.

The credit for finding this fix should go to sulai on StackOverflow.com, as I learnt about it from his comment on this thread, so do head over there and up-vote their answer if it helps you.

Downloading an entire file via the Storage Access Framework

I’ve been working on an app that works with image files that the user selects using the Storage Access Framework (SAF) that was introduced with the release of Android 4.4 (API level 19). Whilst the new selector UI provides the user with an easy way to access files stored on their device and in the cloud seamlessly, it doesn’t necessarily give developers the same ease of use.

It was straightforward to access the images and display them in an ImageView, but I found that it wasn’t the file that I was working with but a cached version of that file in memory. Whilst that’s great for memory management and responsiveness, I was after the Exif data that was stored within those files; that meant I needed to pull the file from its current location and reconstitute it on the device itself.

This part was lifted straight from the developer documentation. It’s provided here without comments in case you want to do a quick rip-n-run to try it out.

private static final int READ_REQUEST_CODE = 42;

public void performFileSearch() {

	Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
	intent.addCategory(Intent.CATEGORY_OPENABLE);
	intent.setType("image/*");

	startActivityForResult(intent, READ_REQUEST_CODE);
}

This is the juicy bit that writes the item that the user selects to a local file on the device.


/** We're overriding this function, which is called when an Activity result is
 * returned to this class. */
@Override
public void onActivityResult(int requestCode, int resultCode,
	Intent resultData) {

	/** 	This conditional statement ensures that we only run when the SAF has
	 *	returned us a result successfully (Activity.RESULT_OK) and that the
	 *	request code matches the one we used to request a file via the SAF
	 *	Activity (resultCode == READ_REQUEST_CODE). */
	if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {

		Uri uri = null;		// Instantiate a Uri object to hold the image's Uri.

		/**	We need to make sure that the data returned isn't null, to prevent
		 *	any nasty null pointer exceptions. */
		 if (resultData != null) {

		 	try{
			 	/** Here we keep it all in a try-catch in case, so we don't
			 	 *	force-close if something doesn't go to plan.
			 	 *
			 	 *	This finds the location of the device's local storage (don't
			 	 *	assume that this will be /sdcard/!), and appends a hard-
			 	 *  coded string with a new subfolder, and gives the file that
			 	 *  we are going to create a name.
			 	 *
			 	 *  Note: You'll want to replace 'gdrive_image.jpg' with the
			 	 *  filename that you fetch from Drive if you want to preserve
			 	 *  the filename. That's out of the scope of this post. */
			 	String output_path = Environment.getExternalStorageDirectory()
			 							+ "/MyNewFolder/gdrive_image.jpg";

			 	// Create the file in the location that we just defined.
			 	File oFile = new File(output_path);

			 	/**	Create the file if it doesn't exist; be aware that if it
			 	 *	does, we'll be overwriting it further down. */
			 	if (!oFile.exists()) {
				 	/**	Note that this isn't just mkdirs; that would make our
				 	 *	file into a directory! The 'getParentFile()' bit ensures
				 	 *	that the tail end remains a File. */
			 		oFile.getParentFile().mkdirs();
			 		oFile.createNewFile();
			 	}

			 	/**	The 'getActivity()' bit assumes that this is being run from
			 	 *	within a Fragment, which it is of course. You wouldn't be
			 	 *	working outside of current Android good practice would
			 	 *	you?... */
			 	InputStream iStream = getActivity()
			 							.getContentResolver()
			 							.openInputStream(uri);

			 	/**	Create a byte array to hold the content that exists at the
			 	 *	Uri we're interested in; this preserves all of the data that
			 	 *	exists within the file, including any JPEG meta data. If
			 	 *	you punt this straight to a Bitmap object, you'll lose all
			 	 *	of that.
			 	 *
			 	 *	Note: This is reallt the main point of this entire post, as
			 	 *	you're getting ALL OF THE DATA from the source file, as
			 	 *	is. */
			 	byte[] inputData = getBytes(iStream);

			 	writeFile(inputData,output_path);

			} catch (Exception e){
				/** You'll have to forgive the lazy exception handling here...
				 * I'm keeping it clean for the sake of the post length! */
				e.printStackTrace();
			}
		 }

	}

}

/** This function puts everything in the provided InputStream into a byte array
 *	and returns it to the calling function. */
public byte[] getBytes(InputStream inputStream) throws IOException {

	ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
	int bufferSize = 1024;
	byte[] buffer = new byte[bufferSize];

	int len = 0;

	while ((len = inputStream.read(buffer)) != -1) {
		byteBuffer.write(buffer, 0, len);
	}

	return byteBuffer.toByteArray();
}

/**	This function rewrites the byte array to the provided filename.
 *
 *	Note: A String, NOT a file object, though you could easily tweak it to do
 *	that. */
public void writeFile(byte[] data, String fileName) throws IOException{
	FileOutputStream out = new FileOutputStream(fileName);
	out.write(data);
	out.close();
}

Here’s a screencast showing how it should look once you’ve got the example running.

The code is basic and outnumbered by the comments, so if you’ve worked with Android’s flavour of Java project before you shouldn’t have any problem understanding what’s going on. You can pull the full working example from the repo below; use it any way that you like.

Generating SVG with PHP

In one of my previous jobs, I had to develop a system that could automatically produce sheets of images that could be printed onto Avery type business card paper. The purpose was to create a ticketing system which could be used to distribute unique codes out to people so that they could log in with this unique key at a later date. It’s a fairly common use-case, and I’ve seen similar systems used at various conferences I’ve attended, in order to keep track of who’s accessing the free WiFi, or to track individual users to promo codes. In fact promo codes is probably the best analogy for it.

The process I used was to determine the layout of one of the tickets, then generate a PNG using the graphics libraries available in PHP to make a single image. I then rolled that image into a function call, with the promo code value and value of the promotion as arguments passed to that function via its constructor. Once I’d got that far, it was just a matter of looping through the database of promo codes, offsetting the images as required into a document model, then turning it into a PDF file for download or print. All of which sounds easy. However it wasn’t is straightforward as I’d expected it to be…

For one thing, these tickets needed to look right, so the graphic designer on the project supplied me with assets showing how the tickets needed to look, with the text sections omitted so that I could overlay the unique codes onto the image. So far so good. The difficulty came when I was scaling and lining up the text with the other components on the ticket. Because the PNG function only yielded a result when the code was valid and complete, debugging became tricky; whenever something went wrong in my code, I’d just get a generic PHP syntax error with a line number, but I couldn’t always see what was happening behind that error. Long story short(ish), I fixed it eventually and rewrote the class to give me a text log so I could see what dimensions I’d left out or fat-fingered, to make debugging easier in the future.

If I were to attempt that project again, I’d forget the PNG generation idea completely, and use Scaled Vector Graphics; the SVG format. SVGs are generated by the browser render engine, and exist as markup, in the same way as a HTML page. In fact, SVG is based on XML, which is in turn based on SGML, just like HTML – so they’re consistent. Consistency is great in my opinion, because it means I can work with the same text editing tools, and come up with the same sort of time-saving scripts that I’d used with HTML. Less to learn, what’s not to like?

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
 <circle
 cx="100"
 cy="75"
 r="100"
 stroke="black"
 stroke-width="2"
 fill="red" />
 <circle
 cx="100"
 cy="80"
 r="40"
 stroke="black"
 stroke-width="2"
 fill="yellow" />
 <circle
 cx="300"
 cy="80"
 r="40"
 stroke="black"
 stroke-width="2"
 fill="yellow" />
</svg>

The killer feature in my opinion, is the ability to view all of this markup when you’re debugging. Rather than getting random server errors and having to chase down the log files for your server, you can see if the syntax is wrong by opening up the source tab in your browser! Far less hassle, and would’ve been a major headache saver in the past.

It’s also really easy to learn if you’ve got experience, check out an I’ve put together here showing how to draw some basic circles with PHP and SVG.

Annoyances: Input box not accepting focus

I’ve been using the excellent JQuery core library and JQuery-UI libraries for a web application that I’ve been developing. As I wanted to have a desktop application feel to the app, I used a script that prevented the user from being able to select text in the interface, so that when drag and drop functions are used, the user doesn’t end up accidentally selecting swathes of UI text by accident.

I noticed however when developing a user text input box prompt, that I couldn’t get the inputbox in focus. I presumed at first that it was a browser glitch, but testing showed that it occurred in every browser and every text input box element. I set to trawling through my JavaScript (the most likely culprit when a web page suddenly breaks, well, assuming that you’re not using Flash…) and found that one of my drag and drop scripts was handling the “.mousedown” event, and munching the result with a “return false”. As the script had document-level scope, it munched all mouse clicks including the one to gain focus on the text input boxes.
http://blog.matthewashrafi.com/?p=101&preview=true
The solution then; ensure that you don’t have something like this anywhere in your code:

$(document).mousedown(function() {
    // blah
    // blah
    // blah
    return false;
});

A better way of handling the problem whilst still preventing the user from selecting UI text, is to use the “return false;” statement, but with a more specific scope. So for instance if you specified items that you explicitly didn’t want to allow users to click on with the class “no-select”, then you could use the following:

$(".no-select").mousedown{
    return false;
});

Thus the document level scope isn’t involved at all, and you can avoid the sort of annoying problem I encountered. This one also goes down on the list of reasons not to trust third-party scripts blindly, as it was within one of those that the problem originated…