Programmatically identifying DVDs by their barcodes from Android

Overview

A few Android code snipperts for how to identify a DVD by it’s barcode

Background

In November, I wrote a simple Android app that lets me add films to my LOVEFiLM list by taking a photo of a movie poster.

It also works by taking a photo of the front of a DVD case, as the DVD covers are essentially mini-posters. But a few people pointed out that using image recognition for the front of a DVD case is overkill, when DVD cases have a machine-readable barcode printed on them.

So I spent an evening adding the ability to scan barcodes to the app – and now you can add to your LOVEFiLM list either by photos of posters or barcodes.

I thought I’d quickly share how I did it, in case it’s useful to anyone else.

Scanning a barcode

No need to re-invent the wheel here. Although the ability to scan a barcode doesn’t come built-in to Android, there is a widely-used common library available: ZXing

If a user has installed their stand-alone barcode scanning app from the Android Market, they will have this library on their phone. (The app can be launched by an “Intent” – programmatically from another app.)

The first thing to do is to check whether the user has installed Barcode Scanner.

I do this by trying to call it, and catching the ActivityNotFoundException that will be thrown if they don’t.

If it’s not installed, I can launch the Android Market to the right place so that the user can install it. (It is free.)

If it is installed, then that code launches the barcode scanner. The mode tells the scanner what type of code to look for – e.g. QR codes vs barcodes. I want the sorts of 1D codes you get on products like DVDs.

Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "PRODUCT_MODE");

try
{
  startActivityForResult(intent, 0);
}
catch (ActivityNotFoundException exc)
{
  AlertDialog.Builder instDlg = new AlertDialog.Builder(this);
  instDlg.setTitle("Install barcode scanner?");
  instDlg.setMessage("Sorry - to do this, I need you install a barcode scanner. Is that okay?");
  instDlg.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                              public void onClick(DialogInterface dlgInt, int i) {
                                Uri uri = Uri.parse("market://search?q=pname:com.google.zxing.client.android");
                                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                                startActivity(intent);
                              }
                            });
  instDlg.setNegativeButton("No", new DialogInterface.OnClickListener() {
                              public void onClick(DialogInterface dlgInt, int i) {}
                            });
  instDlg.show();
}

Once the user has sucessfully scanned a barcode, onActivityResult is called with the barcode number.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent)  
{
  if (requestCode == 0)
  {
    if (resultCode == RESULT_OK)
    {
      String barcodeContents = intent.getStringExtra("SCAN_RESULT");
    }
  }
}

Identifying the barcode

I’m using Google Base as a source of info about barcodes.

(Annoyingly, the LOVEFiLM API doesn’t have support for barcode numbers, so I need to go from barcode to DVD title, which I can use with the LOVEFiLM API to add stuff to my rental queue.)

Google Base have a decent set of DVDs info in their database, and a straightforward API with no need for user authentication or API keys.

You can find a demo page to play with the Google Base Data API at google.com/base/api/demo/html/demo.html and a more detailed reference at code.google.com/apis/base/docs/2.0/reference.html.

For a barcode number of 8717418242275, I’m using something like this:
http://www.google.com/base/feeds/snippets?bq=[ean(text):”8717418242275″]&crowdby=title:1&max-results=1&content=none

Click on the link to see what it returns, but basically it returns me an XML document (you can add &alt=json if you prefer JSON) with the details of the DVD.

I’ve added arguments that reduce the amount of data returned to an absolute minimum – because I’m using it in a mobile app. Android comes with a decent XML parser, but even so – the less I have to download, and the less I have to parse, the quicker the app will be (as well as reducing the impact on the battery).

Eye for LOVEFiLM - screenshotThat’s it

That’s all there is to it.

I’m using this for DVDs, but the same approach will work for other products with barcodes.

An updated version of my LOVEFiLM app with this barcode support is in the Market now.

Tags: ,

Comments are closed.