Sharing some of the useful snippets of code i stumble across with the world. It will mostly be Android, cloud computing, ColdFusion, SQL, Amazon AWS and other web technologies.
If you like what you read or it helps, drop in a comment and say so, it will be appreciated.

31 July 2013

Last time I blogged about this, I'd managed to dual boot Windows 8 and Ubuntu. Both were running off the large capacity HDD on my zenbook, Windows was using the 24Gb SSD as a cache drive. Ubuntu wasn't using it at all, and I noticed this in boot speeds. After a few weeks of this I hadn't booted into Windows 8 once so I decided to make the leap of faith and re-install Ubuntu over top of everything. Death to Windows 8!

I used the same method as before, go into UEFI, plug in the Ubuntu install key, change nothing and save and exit. Then immediately hold escape. This gave me the option to boot from USB and of course select install Ubuntu.

Ubuntu install started and I had to pick my language, wifi and a few other normal things. Then came the selection screen for where to install Ubuntu, this is the step I was more interested in. Ubuntu offered the choice to erase everything, or dual boot, etc etc. I was after "something else" down at the bottom. Basically the advanced setup. This allows you to customize where each piece of Ubuntu is installed, what extra partitions are setup and how.

This was quite advanced, a little tricky and quite a bit of background reading was required. This is a page I leaned heavily on for some advice:

I basically decided to install the OS on the SSD and install other crucial parts on the HDD. My reasoning being from what I've read and experienced, the SSD isn't bootable (which is lame). However booting off the HDD and then utilising the SSD for important file system reads works just as well.

To cut a long story short, after a considerable amount of time experimenting with partitions, I've now settled on, and have working the following partitions:

SSD - filesystem. Whole thing set up as /

HDD

10Mb - BIOS Boot

250Mb - EFI Boot

200Mb - /Boot

3Gb /Linux Swap file

Free space

That's about it, I had to repeat the method I did last time of finishing the install, then booting off the USB again, going into try Ubuntu and running boot repair. However that was easy this time and after that it all seemed to work!

29 July 2013

I created a cute little test app today to try out a few database concepts on Android. Thankfully it's really easy and there are some great tutorials out there. Anyway some of the concepts are really useful so I thought I'd jot down my findings.

First I created my new Android project ignore the MainActivity for now. I create a pretty standard Muppet.java class. I shan't patronise you with the code, int ID, String name and getters and setters for each. Then I create a new class called MySqlLiteHelper.java this is what will do the db interaction for us.

MySqlLiteHelper - This function is the constructor, on initialization it will create the DB.

onCreate - This function created the database table by executing the static string at the top.

onUpgrade - I think this function is pretty clever, if you change the db version number, it'll self upgrade! Amazeballs!

addNewuser - This is an ugly way to insert a user, I'll change this later.

getAllUsers - Here we're creating a cursor and querying the db for all the users. Then we're reversing through the cursor and putting the user object into a list. I opted to reverse the list so new Muppets show up at the top. Although it's quite easy to traverse it normally and have new users at the bottom.

One quick thing that's important to mention is we're using a function in Muppet.java to force the fragment to show the muppet name, instead of the object id.

@Override
public String toString() {
return name;
}

Our next step is to create the layout file. As an additional step I've included a fragment. This lets us compartmentalise our layout neatly. If you want to just dump a listView on the layout, you could also do that quite easily.

This should be pretty straightforward. OnActivityCreated we get the database instance, then call showAll. showAll() calls getAllUsers and puts the results in a List. This List is then converted to an adapter and we use setListAdapter to show the results in the fragment.

Bingo!
The main activity doesn't do anything special, it has a couple of buttons for adding new muppets, basic listeners which call

24 July 2013

I've previously created my own custom built high scores add on for my Android app, frankly it was pretty rubbish. It was local only, not very pretty and had no public competition element. There are a few third party apps but they cost money. That is until at Google IO Google announced Google Play Game Services. I thought I'd take a look and I was incredibly impressed.

Game Services allows you to instantly integrate a leaderboard into your app. It does this using Google + which means your users can share their scores with their circles, specific friends or of course with the public. I love this because just thinking about creating a user id for every user and a server side backend to deal with all that makes me shudder. Plus you can add in achievements which is pretty cool too.

So if you want to get started adding play services I very much recommend downloading Google's sample app "Type-a-Number":

Then run through the steps to get the API set-up on Google's developer console and of course provides a sample app and code to study. I really recommend you study this and get a good grasp on how it all works. I'm not going to run through all the code here, as Google have already done that. The same applies to the API, you do need to do a bit of setup on Google's developer console. Just make sure you copy the IDs of your game service and your leaderboard into your android project. Preferably in the same way Google suggest with an ids.xml file.

You're going to need to set-up eclipse and your project with Google Play Services Library which I already had for Google Maps anyway. The sample app uses the Base Game Utils library, which isn't totally necessary, but it does make things a little simpler. Again, all steps are covered in the quickstart.

The first thing is to get the Google Plus button working. This is a simple case of adding in the com.google.android.gms.common.SignInButton button to your layout file.
Then add a listener:

Be very wary of your certificate. You'll need to make sure the SHA1 hash you use is the same you export your Android project as the one you enter on the game services API.

When you come to release this, if you've been using your debug certificate you'll need to delete your game services on the API and start it all over again. I've tried many times to tweak the SHA1 in an active game service but it always breaks. So best to start fresh with a production ready certificate and use it for the API as well.

The IDs you get from play services must be copied exactly to your ids.xml file and your manifest must have a line like this:

If you want to delete your scores or change the IDs you use for the game services or leaderboard you need to goto:Settings -> Google -> Google + -> Apps With Google + Sign In -> xx_AppName_xx -> Disconnect AppYou'll get the option here to delete your scores. This can be a bit temperamental, so change IDs only if you're really stuck.

One last thing worth mentioning, and its addressed to Google, whom I'm sure study my blog every day! When one looks at the achievements board, you can't expand the achievement to get the full description of what is required. On a phone, this means you'll never know what's required.

15 July 2013

I recently bought a shiny new Asus Zenbook, which which I'm delighted. However it came with Windows 8 and try as I might the sales guy wouldn't offer me anything else. I've recently blogged about my intense hatred for all things Windows 8 related. So I've decided to put Ubuntu on it, for now I'm dual booting. With past experience Ubuntu is so awesome, plus quick and easy to install I might decide to go back and clobber Windows 8 altogether.

The following are a few hints and tips I picked up if you try something similar. The bulk of the problem arises around the new version of BIOS called UEFI. This feels like an Intel thing that's been designed specifically for Windows and the rest of the world now has to catchup. Anyhow, I digress.http://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface

The first thing I did was backup Windows 8. Just in case I needed to roll back. Then of course create a Ubuntu USB Install Key.

That's the easy bit. In the good old days of BIOS that was basically it. You could insert your USB Ubuntu key and reboot, possibly tweaking BIOS boot order slightly. Sadly this is where UEFI makes things very difficult.

First I had to hold delete to get into UEFI which can easily be missed as the setup window gets smaller all the time. Then you need to disable fast boot and secure boot.Now plug in your Ubuntu USB key and save and restart. As soon as you're out of UEFI hold down the escape key. This brings up the boot options. Hopefully your USB key will be listed there. If not select "Enter Setup" and try again. Sometimes this takes a few goes.

Once you've got the USB Key to boot, you can install Ubuntu as a dual boot or "Full Windows annihilation" mode. This is all pretty self explanatory.

When you finish you'll be asked to reboot. When I did this I went straight back into Windows. Lame.

To combat this I went back into UEFI, didn't change anything, but did a save and exit (F10). Then again held the scape key and selected my USB key from the boot menu. Instead of install, this time select trial, or run from usb key. This gets you running a version of Ubuntu without installing anything. From there follow these instructions:https://help.ubuntu.com/community/Boot-Repair

This will re-install the boot loader that windows 8 has interfered with. As I mentioned I did a dual boot, so it re-installed GRUB and allowed me to select my desired OS on boot.

That should be it. Remove your USB key and you should be running Ubuntu.

08 July 2013

In all the languages I've used I've had need for a drop-down. However they all seem to call it something different. .net calls it a combo box, html calls it a select tag and Android appears to call it a Spinner. Oh well! Normally I've used it as a key value pair. That is to say the string you select, isn't normally the same as the value you pass in the result. For example

Setting up the hashmap is fairly trivial using the put method. In this example I used a set of if statements with hard coded values. Normally you'd get your values from a web service or a db call.

One problem I encountered with this method is when you setup your OnItemSelectedListener it will get fired immediately when you start your application. Technically this is correct as something has been selected onLoad, but not normally desirable activity. So to combat this I've added in a --please select-- value and ignored this element. This is fairly common practice in HTML and works in Android too.

So this is the function that builds the spinner, note we're creating a new array with the zero value set to --please select--.

01 July 2013

If you decide to try and interact with AWS Glacier API or certain other AWS services you will need to interact with their signature version 4 authentication. Unfortunately in ColdFusion this is one of the hardest things I've ever had to do. Not really ColdFusion's fault, and not really Amazon's fault. Their documentation is comprehensive (although a little confusing) it is just incredibly fiddly. Hashing is a process where a single wrong character completely changes everything. So one slip up causes failures and it can be difficult to determine what you've done wrong.

AWS Glacier is a very low cost storage solution designed for archiving and backing up data. The basic idea is its cheaper than S3 storage but access is limited. So you don't necessarily have immediate access to your backups. Instead access can be requested and files retrieved within a given time period.

In order to keep costs low, Amazon Glacier is optimized for data that is infrequently accessed and for which retrieval times of several hours are suitable.
- AWS Website

In order to make an API request to Glacier you are required to authenticate each request using their V4 Signature process. Data in Glacier is stored in "Vaults", similar to an S3 bucket a vault is a storage container. For the purposes of this demo I've created a vault using the AWS web management interface. I will be using the API to list all available vaults. In time I hope to expand tutorials and code to cover more complex operations. However, once you've got the signature sorted that shouldn't be too hard.

Code Glorious Code

Again I just want to make the point that I'm just addressing the signature here. I hope to expand the CFC to better deal with making full requests. That will come in time though.

The string to sign is a little harder to explain out of context. It's basically the message we will hash which will authorize the request to AWS. It's a short and simple string with a very concise format.

OK Now it gets complicated. This is where we start running things through the HMAC function and problems quickly occur. If you do it right though, it'll all come together. AWS do this all in one step, but I think its easier as two.

I know I've not included the function in the other steps, but I want to highlight the importance of two things:

kSecret is "AWS4" + Secret Key, then cast into bytes. This is a very important step and where I was going wrong for quite a while.

variables.strSecretKey is the secret key you get from AWS in your account section. It's obviously secret and shouldn't be disclosed to anyone. In my example it's set in the variables scope of the cfc.

The function I use HMAC_SHA256_bin accepts a binary argument as param1. This is different from the example in my previous blog post on signature version 2, which used two strings as arguments.

So you can see with four HMAC steps, the tiniest mistake means a totally different response. Obviously AWS will be doing the same thing on their end, so if the two don't match, your request won't get approved.

Step 3b - Sign it!

OK Now we bring it all together

signature = HexEncode(HMAC(derived-signing-key, string-to-sign))

We take the signing key from step 3a and the string to sign from step 2:

Note we didn't hex encode our bSigniature from before, so I do that in the value. Probably better done elsewhere, but I'll get to it.

Also note the public key. Again this comes from AWS management console.

Note the three different dates, one is the strCanonicalDate we created at the top, the other is the short date and finally the hard coded glacier version date.

That's it. That should work! Obviously you need the cfc. Take a look below for that.

Advice

My advice to anyone attempting to do this in ColdFusion or any other language is as such:

Baby Steps - The documentation is presented in steps. Get each step working perfectly before moving onto the next. They all rely on each other, so a mistake early on will just cascade and waste time later.

Unit Tests - I'm a huge fan of unit tests anyway, but in this case they really helped. Setting up some great unit tests using AWS examples will help you define your input and your output and tweak your code until you get the response you're looking for.

Check Responses - If you actually make a request to AWS they will tell you in the response what the problem is. Plus they'll tell you the expected canonical request and the expected string to sign. These can really help iron out any tiny discrepancies

Try it in Java - CFML Doesn't have a native HMAC function (pre CF10), and converting too and from byte arrays caused endless problems. So I just did a few piecemeal functions in Java and learned from that.

The CFC

Ah of course one final step. The cfc. As I've said I hope to improve it a great deal and perhaps open source it and put it on cflib. I've also got a bunch of unit tests I wrote which may help people improve it.
Right now I'm just pleased to have got it working and don't want to forget it all so it's going on the blog.