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. 👋

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.

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.

SL4A: Speech Recognition and Transcription

SL4A gives you access to a simplified Android API, but it’s still got plenty of functionality to make some functional apps using small amounts of code. The following Python script starts a speech recognition dialogue, then outputs that as text in the terminal.

# SL4A Demos - Transcribe Speech
# http://blog.matthewashrafi.com/

import android

droid = android.Android()

print "########################################"
print "# SL4A Demos - Transcribe Speech       #"
print "# From http://blog.matthewashrafi.com/ #"
print "########################################"
print "nSay something at the prompt."

speech = droid.recognizeSpeech("Talk Now",None,None)
print "You said: "
print speech[1]

transcribe-speech.py

Alternatively, you can use a barcode scanner to scan in the script from the following QR code:

Screenshots

The editor view within SL4A.

transcribe-speech.py in the terminal.

The voice recognition dialogue processing speech.

After the script has run, the transcribed speech,  in this case “cheat sheet”, is displayed after the “You said:” line.