More Android Development – Taking a Picture From Your App

Ok folks – many Bothans died to bring you this information (along with a good number of my brain cells and sanity points) so I hope you appreciate it.

Let’s say that you’re developing an app and you want to let your users take a picture from inside of the application. Maybe you’re writing an app that will let you take a picture of your friend and then superimpose a rainbow halo over their head. Or maybe you’re writing an app to let people track their comic book collection by cover art. Or maybe you just wanna let people post pictures of food. Whatever, I dunno.

If you google for something obvious like “Android development camera” you’ll hit a bunch of links like this one that will describe a process so arcane that you’ll end up waving a dead chicken over your device while intoning verses from an ancient book written in a dead language just to get it to work properly.

I tried those solutions and ran into a serious problem – right now, Android devices are slowly but surely being upgraded to the 2.1 api, but most phones are still running 1.6. The issue here is that the camera api has changed quite a bit between 1.6 and 2.1. Unless you want to fork your code and release 2 different versions (hint: you don’t) you need to code to the lowest common denominator, API-wise.

After a weekend of threatening, cajoling and finally pleading with the API to just TAKE A DAMNED PICTURE, I came across a solution. Feel free to use this code in your own projects. If you DO use it, I’d love a shoutout or at least an email saying thanks.

Android Development – I Wish Someone Had Told Me This

If you’re a developer, you’ve no doubt spent hours chasing down bugs that have you completely baffled.  You change a few things, throw a few outputs, log EVERYTHING, recompile and re-run your test cases only to be greeted by the same NullPointerException.  This weekend I spent some time building the android application for a certain web property and ran into one of those time vampire bugs that should have been obvious, but is never actually stated in any of the documentation that I found.  If you are going to write an Android app, please read this.

Designing your screen layout is incredibly easy.  All layout definitions are done with xml files and they actually make sense to normal people.  Here is an example of a layout file for a simple little screen that has a text box and a button:

main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:orientation="vertical" >
             <EditText android:id="@+id/my_text"
                       android:layout_width="fill_parent"
                       android:layout_height="wrap_content"
             <Button android:id="@+id/my_button"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:text="CLICK ME!!!!111eleven" />
</LinearLayout>

This defines a Linear layout and adds two controls – a text box (my_text) and a button (my_button). In order for this to actually get displayed, we create a java file like this:

MyAwesomeApp.java:

package com.dinstuhl.MyAwesomeApp;

import android.app.Activity;
import android.os.Bundle;

public class MyAwesomeApp extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

Upon startup, your application will start the MyAwesomeApp activity and set the content view (i.e. the screen) to the main.xml file. Go ahead and save it, compile it, start the emulator and then begin watching the first 3 seasons of “Lost”. If the android emulator boots up and loads your app before you want to bitch slap Benjamin Linus, you’re lucky. If it happens before you get to see what is inside the hatch, you’re lying.

You should see a screen with a text box and a button. If not you did something wrong. Let’s just assume that you’ve got a button and a text box. Looks great! But it doesn’t do anything. Let’s re-visit our MyAwesomeApp.java file and I’ll show you where I went wrong:

MyAwesomeApp.java:


package com.dinstuhl.MyAwesomeApp;

import android.app.Activity;
import android.os.Bundle;

public class MyAwesomeApp extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //Let's add an onClickEvent to the button!
        Button myButton = (Button) findViewById(R.id.my_button);
        myButton.setOnClickEvent(new OnClickEvent(
          public void onClickEvent(View v){
            //DO SOMETHING AWESOME!
          }
        ));

        setContentView(R.layout.main);
    }
}

Pretty easy, right?

WRONG!

Go ahead and compile this – I’ll wait.

Did you see what happened? You got an error message that basically says, “OH HAI! ADROID DEVELOPMENTS – UR DOIN IT WRONG. XOXO, GOOGLE”. Can you guess what the problem is? Ok, I’ll tell you. Check out the line where we instantiate the button. Instead of declaring a new Button we use the findViewById() method. The argument that we pass is R.id.my_button. What happens is this – there is a java file that is generated based on the contents of your view called R.java. This file creates a reference for every object defined in your main.xml file so that you can get a handle to it at design time. What is NOT obvious is that these objects are not actually created until AFTER the setContentView method has been called. The correct way to do it is like this:

package com.dinstuhl.MyAwesomeApp;

import android.app.Activity;
import android.os.Bundle;

public class MyAwesomeApp extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main); // <-- Do this first or you will make the Baby Jesus cry.

//Let's add an onClickEvent to the button!
Button myButton = (Button) findViewById(R.id.my_button);
myButton.setOnClickEvent(new OnClickEvent(
public void onClickEvent(View v){
//DO SOMETHING AWESOME!
}
));

}
}

So there. Hopefully I’ve just saved you a few hours of screaming. As I learn more I’ll post more. ESPECIALLY pitfalls like this.

Early Cryptography: Leather Belts and Walking Sticks

Earlier today I posted a crypto challenge to my followers on Twitter. The encrypted message was this:

wtrhhoagutoghdhawt

The history of cryptography is a subject that I personally find fascinating, mostly because it extends much further into the past than most people know. The cipher used to encrypt the message above was taken from the Spartans. Back in the day (600-400 BC), the ancient Greeks used runners to transport messages between military units and their central command. Knowing that the messengers were in constant danger of being intercepted by enemy forces, they created an interesting form of cryptology.

Each runner wore a leather belt. On the inside of the belt, the message was printed in an encrypted form. Example: wtrhhoagutoghdhawt. Anyone that captured the messenger could steal the message but they could not understand what it said. This is where the “walking stick” comes in.

Once the runner reached the recipient of the message, the leather belt would be wrapped around the stick (or Scytale) and the message could be read thusly:

W T R
H H O
A G U
T O G
H D H
A W T

or:
WHAT HATH GOD WROUGHT

(side note: this was the first message ever transmitted by electronic means)

Congrats to John Dugan at Coroutine for being the first twitter follower to answer correctly!

Techno Nostolgia

Dream Machine!

Intel Pentium (586) 166 mHz CPU
32 MB RAM
800 MB Hard Drive
4x CD-ROM
Hecules SVGA Graphics card
US Robotics 14.4 Internal Sportster modem
Soundblaster AWE32 Sound Card
Thrustmaster Flight Stick
15″ Monitor

Software bundle:

MS-DOS 6.22
MS-Windows 3.11
Telex
Doom
Novell Netware client for 3.11 networks
TIE Fighter
Borland Turbo C++

Last of the sports models, baby!

What was your first home-built dream system?