An Android App in Three Easy Pieces
In my last blog post, I showed you a little bit about Google's App Inventor software. I suppose since it has Leg Mindstorm capabilities it is at least marginally capable of building embedded code. Android itself has a lot of potential for building embedded systems, especially those that have GUIs, extensive network access, and don't need hard real-time performance. But will we ever get to drag-and-drop programming? And if we do, does it really change the skill set required to develop software?
I tested App Inventor on two different applications: one fairly simple to build because of built-in capability, and another that I thought would be a bit more of a challenge for App Inventor. In this blog I'll show you the simpler one — RecallNum (freely available on the Android market at https://market.android.com/details?id=appinventor.ai_al_williams.RecallNum). If I had not told you any details about how I created the program (and you didn't know anything about Android), you might be impressed. The program has speech synthesis and accurate speech recognition.
As much as I'd like to take credit for these features, the truth is both are very simple to build into App Inventor programs. Like many similar environments, App Inventor makes what it makes possible very simple. The downside of that is that things it doesn't make easy may be incredibly difficult (or even impossible) to pull off. In this case, the feature palette of App Inventor fit the program perfectly.
You can see a screen capture of the program below (Figure 1). It's a simple game to help train you to remember numbers. For the record, my wife has me beaten in this area. She can remember every significant number either of us has ever had plus any that apply to the kids. I can only blurt out my social security number in one long breath — I remember it as a sound, not as a string of digits. Same for phone numbers. I tend to convert them to words or sometimes physical patterns. I just can't remember numbers.
This game — maybe — will help me improve. The program speaks a single digit and then waits for you to repeat it. Then it speaks two random digits and again waits. The digit string keeps getting longer and longer until you can no longer remember it, at which point the game is over.
But the real point isn't the game. It's how was the game built using App Inventor. Laying out the screen itself is easy using the App Inventor website. You drag items over to the workspace and then you can edit their properties. Pretty standard stuff, as you can see in Figure 2:
However, compared to other graphical designers, App Inventor is pretty limited — perhaps because it is relatively new. For one thing, you are limited to one screen in your application (well, sort of — I'll talk about that next time). There are three layout containers (horizontal, vertical, and table), but if you want to center or space things, you have to use empty labels to eat up space. For example, to center a button in a horizontal layout, you'll need to put two "fill parent" labels with no text on either side of the button. Workable, but hardly intuitive. Tools like this are billed as allowing neophytes to create things, so odd workarounds don't really fit that model.
You'll notice in the Figure 2 that there are some non-visible components that appear when you drag things like timers or text to speech components onto the screen. You can also upload media files that get bundled with your program.
The real meat of the program, however, is the block editor. You launch it from a button on the web page and a Java application will open. I discussed the block editor a little bit last time, so if you want a general overview, you can read that.
The basic idea behind the program is to create one or more random digits and then speak them. Then the program has to listen for your response, compare them, and proceed accordingly. I discovered two little glitches. First, it appears that nothing ever blocks. So you can't kick off the text to speech action and then immediately start listening because you wind up trying to listen while the program is still talking. There's no way to really monitor the progress either. My solution was to schedule a timer event for a varying amount of time, based on the number of digits, and then start listening in the timer event. That seems to work.
The other issue I found was that there are some circumstances where playing wave or mp3 files apparently causes the current "chunk" of code to exit. I couldn't find that documented anywhere, but any steps that happened after playing a sound would never occur! At least some of the time. Again, confusing for the beginner (or, for that matter, the expert). And sometimes, without reason, short sound clips just don't play.
I won't reproduce the entire code here. Graphical tools often make very unwieldy source code listings. However, you can download the files here. Figure 3 shows the logic that executes a "turn":
Even after you work out the timer issues, things are still not as straightforward as you might like. For example, the speech recognition engine won't do anything if the user cancels it. To solve that problem, I added a button to relaunch the speech recognizer and I only enable it when I'm expecting speech. When the recognizer hears something, it drops an event on the program. Of course, if you say "94," it might hear it as "I'm bored," so I added code to check to make sure the result was purely numeric. If it isn't, the timer is reset so that the program will ask you to repeat the number (without repeating it to you).
The result is pretty good. If I had written the code from scratch, I'd have had more control over the elements and wouldn't have needed the user interface workarounds (like the restart button). Some of these problems are not inherent to systems like App Inventor, they are just specific to App Inventor, which is admittedly not very mature yet. My friend Jim McGlasson pointed out to me that numbers starting with zero don't print out right when you lose. I guess I'll have to fix that in a future release. Sorry Jim.
Luckily, it is easy enough to modify the above code snippet — another test for the environment. I just replaced the zero in the random number generation block with a “choose” block. The test of the choose block is “i=1” and the block returns 1 if the condition is true or 0 if the condition is false (the choose block is a bit like the ?: operator in C or C++ combined with an if/then/else statement).
By itself, App Inventor can package an APK file and download it to your computer or send it to your connected device. You can't get that APK in the market directly though. It needs to be signed and have a few other tweaks. I used a tool found at http://amerkashi.wordpress.com/ to automate the steps and it was pretty painless.
However, I still can't get that looking at pretty boxes is necessarily better than looking at lines of code. Perhaps if you are trying to visualize the flow of control. Perhaps. I would not mind an editor that let me switch between a full text view of, say, a Java program and a graphical representation of the logic flow.
However, I don't think that people who aren't programmers will grasp concepts like scheduling things on a timer, validating input, or efficient iteration any easier just because it is drawing pictures. Code Bubbles seems much more useful, even though I don't think it shows internal control structure graphically. Maybe it should.
So for a project of this complexity, App Inventor was certainly up to the task and not wholly unpleasant to use. While you might prefer a graphical environment (I don't), I don't think it really enables neophytes to write code without acquiring traditional skills. It just trades statements for little colored blocks. You still need to understand control flow, use of variables, and the like.
What about a more complicated program? Does it scale well to larger things? I'll let you know next time.