QR Codes are a great way to share information with mobile phones. Originally used to track car parts, QR codes are now used to quickly and easily spread information to mobile users. For example a company can put a QR code in a magazine that contains the URL to their website. Instead of the user having to type in a long URL on their phone they can simply take a picture of the QR Code with their camera phone and have their decoding software open the link for them. For more uses of QR Codes check out this blog.

I am going to go through a quick example of encoding and decoding QR codes in Android.

Encoding

There are a number of services and libraries available for encoding QR Codes. The actual encoding process is a bit more involved than I would like to go through for this entry and we generally would not want to do the actual encoding on the client. Instead we will harness the power of the “cloud” to do the heavy lifting for us. In this case we will use the Google Charts API which just recently expanded to include QR codes. The API allows for a number of options such as size, error correction type, encoding type, and margins (the general rule for QR Codes is to have a 4 column/row white border around the barcode so that the decoding software can get a better “lock” on it)

The code below makes an http request to the Google Charts API with the URL encoded text we entered in the EditText view and populates our ImageView with the resulting image.


encodeButton.setOnClickListener(new OnClickListener(){

public void onClick(View arg0) {
    img.setImageBitmap(QR.this.encodeString(edit.getText().toString()));
}

});

private Bitmap encodeString(String input) {
     URL aURL;
     try {
      aURL = new URL("http://chart.apis.google.com/chart?chs=300x300&cht=qr&choe=UTF- 8chl="+URLEncoder.encode(input, "UTF-8"));
      URLConnection conn = aURL.openConnection();
      conn.connect();
      InputStream is = conn.getInputStream();
      BufferedInputStream bis = new BufferedInputStream(is);
      Bitmap bm = BitmapFactory.decodeStream(bis);
      bis.close();
      is.close();
      return bm;
      } catch (MalformedURLException e) {
       e.printStackTrace();
      } catch (IOException e) {
       e.printStackTrace();
      }
     return null;
}

Decoding

The ZXing library is an open source Java library for decoding numerous 1D and 2D barcodes. We will be using the core library but there is also an Android specific application that provides hooks into the camera. Since the emulator does not support capturing images just yet we will settle for using the image we just encoded. We will need one class specific to the Android ZXing library, RGBMonochromeBitmapSource which lets us convert Android bitmaps to the format that ZXing uses.

The code below takes the bitmap image from the ImageView and pushes it through the decoder populating a TextView.


decodeButton.setOnClickListener(new OnClickListener(){

public void onClick(View arg0) {

     try {
      tv.setText(((QR.this.decode(img.getDrawingCache()))));
     } catch (ReaderException e) {
      e.printStackTrace();
     }
}
});

private String decode(Bitmap bm) throws ReaderException {
     QRCodeReader reader = new QRCodeReader();
     Result r = reader.decode( new RGBMonochromeBitmapSource(bm));
     return r.getText();
}

We can use our friend Linkify to automatically make any text of the correct format (http://, mailto:, and even map locations) into a link that launches the appropriate application.


textView.setAutoLinkMask(Linkify.ALL);



I have even been experimenting with integrating the decoder with the built in WebView class which lets us decode images directly from the web browser. As you can see in this example I have clicked on a QR Code and a dialog pops up with the decoded information.

The code to do this is a little hackish but involves using the WebView.requestImageRef(msg) mechanism and calling decode from the handler that receives that message.

I know of a number of decoders being developed for android but hopefully there will be a standard one that can be called using Intents so that developers can just fire off an intent in their application and get text back, not having to worry about dealing with the camera or the decoder libraries.

Posted on August 25th, 2008 | filed under android, java, mobile | Trackback |

5 Comments

  1. Daniel Switkin:

    Good article, thanks for featuring ZXing. Have a look at the new Android client in the ZXing source tree. There are Intents documented there both for scanning and encoding using Chart Server. If you install this client, called Barcode Scanner, all other apps pick up this functionality for free.

  2. Sujith:

    Can you provide the full source code of the WebView (You have mentioned it later). I am exactly working on the same.

  3. Romain:

    I’m interest too by the full source code of the WebView,can you provide it ?

  4. Ricard:

    Can you give me the full source brother? I can pay…

  5. ntt:

    hi
    can you share simple source code of scanning QR code using zxing and getting back a result?
    there’s not much resources, turtorial and complete source code for doing this simple thing.
    very nice writeup.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>