Thursday, August 26, 2010

Google App Inventor and node.js

My invite to Google's new, easy to use App Inventor for Android came through recently and within minutes I had hello world running. Even better, after a few more minutes of playing with the programming toybox I had an easy to use tool.

For awhile now I've wanted a simple tool that would let me go around scanning the barcodes of books that I own and saving them into a text file for importing into LibraryThing but I haven't had the spare time to learn enough Android programming to build one. A combination of a simple client built with App Inventor and a simple server written with Node and I had the tool I've been wanting in a matter of minutes.

The AppInventor Client

AppInventor comes in two parts - an "Interface Builder" website and a visual coding environment where you connect up blocks of code (that sits on top of the Kawa dialect of Scheme - which makes App Inventor coding a lot like a combintation of Lego and Lisp). I quickly added a label (to display the scanned ISBN number), a button (to start the scan) and then two non-visible components: a barcode scanner and a TinyWebDB. Once the UI was done it was off to the coding environment to wire everything up.

The only not quite straightforward part of all this is the TinyWebDB component as it's App Inventor's only built in way of accesing a web service (other than Twitter, which has it's own component). However, TinyWebDB isn't a generic web service client, it's meant for storing and retreiving simple key/value pairs so I needed to write my server with that in mind.

As the coding environment is visual, it really doesn't lend itself to a blog post. Fortunately, you can download the app source code in a zip file and marvel at the underlying code. The meat of the app is:


;;; Screen1
(do-after-form-creation (set-and-coerce-property! Screen1 'Title "Screen1" 'text)
)
;;; Label1
(add-component Screen1 Label Label1 (set-and-coerce-property! Label1 'Text "Text for Label1" 'text)
)
;;; Button1
(add-component Screen1 Button Button1 (set-and-coerce-property! Button1 'Text "Scan" 'text)
)
(define-event Button1 Click()
(call-component-method 'BarcodeScanner1 'DoScan (list)
*no-coercion*)

)
;;; BarcodeScanner1
(add-component Screen1 BarcodeScanner BarcodeScanner1 )
(define-event BarcodeScanner1 AfterScan( result )
(call-component-method 'TinyWebDB1 'StoreValue (list "isbn" (get-property BarcodeScanner1 Result)
)
'( text any)
)

(set-and-coerce-property! Label1 'Text (get-property BarcodeScanner1 Result)
'text)

)
;;; TinyWebDB1
(add-component Screen1 TinyWebDB TinyWebDB1 (set-and-coerce-property! TinyWebDB1 'ServiceURL "http://192.168.1.101:8765" 'text)
)
(init-runtime #f)

While that's not quite the entire source, it does give some idea of what goes on underneath.

Node(.js)

TinyWebDB will post a key/value pair to whatever server you want. So I needed a simple server that would sit there, extract the value and output to stdout (which will then get piped into a file). This seemed like the perfect opportunity to try Node (I can't tell if it's supposed to be called node or node.js), which is a Javascript execution environment based on the V8 engine for writing network programs. A quick and dirty Javascript hack produced:

var http = require('http');
http.createServer(function (request, response) {
request.on('data', function(chunk) {
var b = chunk.toString('ascii', 0, chunk.length);
var v = b.split("&")[1];
var vv = v.split("=")[1];
var vvv = vv.replace("%22", "");
var vvvv = vvv.replace("%22", "");
console.log(vvvv);
});
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello, World\n');
}).listen(8765);


Undoubtedly a regexp could have been used, but would have required more mental effort than I really wanted. In case you're wondering about the response, TinyWebDB apparently essentially disregards it, so sending back Hello, World doesn't hurt.

Conclusion

In a matter of minutes I had a useful (at least to me) tool. I have a feeling that this is what App Inventor will mostly be used for - simple apps that satisfy a single person's needs. It's not going cause the "Animated Cat App Apocalypse" in the Android Market that some commentators have worried about. I have no idea if it will be of any use as the "Logo for the modern age" that was the original reason for it's existence (there are still references to "Young Android" in the generated code and the application icons are of an adult and child robot). I would call it the "Visual Basic for the modern age" except that it feels wrong comparing something that "is part of an ongoing movement in computers and education that began with the work of Seymour Papert and the MIT Logo Group in the 1960s" with Visual Basic.

2 comments:

Anonymous said...

Nicely written and informative review of the product. I still need to know the exact linkage to use js, but this clears away some of the fog.
Thanks,
Pete Gregorio gregoriogallery@gmail.com

Magento themes said...

@ anonymous if the HTMl tage are allowed i will forward tou th URL and you will get what you want