James Williams

Android talk at Tampa JUG

Tags: Android

Tuesday I gave a talk at the Tampa JUG and for the most part it went well. The projector in the JUG space didn't like my Hardy (Ubuntu) partition, nor my Windows partition. Nor the Xandros on my eee pc. After some playing with settings and rebooting, I got the projector to be recognized as a secondary screen for XP. Matters weren't helped by the fact that I live in Ubuntu and even my thumbdrive is formatted as ext3. Oh well...but I was able to show the demo and some of the code. Here's some of the random stuff I didn't get to show or I think needs a little bit more explanation.

General structure of a Android app

File or Directory Description
build.xml
AndroidManifest.xml Registration of Activities, Intents, and IntentFilters/Receivers
/src
/res
/res/drawable Images
/res/layout XML Layouts of Activities
/res/values Strings/Arrays for Spinners and such
/bin
/bin/classes
/bin/classes.dex
/bin/<Your Application>.apk Application file that is loaded to phone

Background Images

The background is set in the outermost layer tag with android:background. <AbsoluteLayout android:id="@+id/widget0" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android" android:background="@drawable/trafficviewer" >

The @drawable refers to the above drawable directory and also notice that the filename leaves off the extension.

TrafficViewer

TrafficViewer is a small Android application that allows a user to input a mile radius and a zip code or city and state to find accidents in that area. The input from the user is sent to the Yahoo! Traffic APIs and it returns geocoded lat/long points indicating accidents.

!Traffic Viewer Screenshot

The background image is a Creative Commons licensed(by-nc) by Thomas Hawk

Some of the files I didn't get to show as much were the YTrafficFetcher, TrafficRecord, YTrafficHandler, and TrafficMap.

YTrafficFetcher, like it's name states, is an interface to the webservices. It constructs the uri query strings, and acts as a buffer for the YTrafficHandler which parses the code and loads them into the POJO TrafficRecord.

URL url = new URL(this.query);
SAXParserFactory spf = SAXParserFactory.newInstance();

SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();

YTrafficHandler handler = new YTrafficHandler();
xr.setContentHandler(handler);

xr.parse(new InputSource(url.openStream()));
r = handler.getTrafficRecords();

YTrafficHandler walks the XML and has convenience methods for marking the start and end elements and gets the enclosed characters.

TrafficMap, as a MapActivity, wraps the functionality of a MapView. From it, I created a basic map and overlay reading in the location and the title of the incident. The map auto-zooms to the last point in the list. Actually it sets the zoom to each point as it is parsing them. I'll admit that this was lazy and a more elegant solution would have been to find an equidistant point between them but lack of time requires some compromises.

Here's the pertinent code that draws the overlays on the map [mostly borrowed from tutorials on anddev and helloandroid]

// Create a Point that represents our GPS-Location
Double lat = record.getLatitude() * 1E6;
Double lng = record.getLongitude() * 1E6;
Point point = new Point(lat.intValue(), lng.intValue());
TrafficMap.myMapController.centerMapTo(point, false);
int[] myScreenCoords = new int[2];
// Converts lat/lng-Point to OUR coordinates on the screen.
calculator.getPointXY(point, myScreenCoords);


// Draw a circle for our location
RectF oval = new RectF(myScreenCoords[0] - 7, myScreenCoords[1] + 7, 
     myScreenCoords[0] + 7, myScreenCoords[1] - 7);


// Setup a color for our location
paint.setStyle(Style.FILL);
paint.setARGB(255, 0, 0, 0); // reddish color
// Draw our name
canvas.drawText(record.getTitle(), myScreenCoords[0] +9, myScreenCoords[1], paint);


// Change the paint to a 'Lookthrough' Android-Green
paint.setARGB(80, 156, 192, 36);
paint.setStrokeWidth(1);
// draw an oval around our location
canvas.drawOval(oval, paint);


// With a black stroke around the oval we drew before.
paint.setARGB(255,0,0,0);
paint.setStyle(Style.STROKE);
canvas.drawCircle(myScreenCoords[0], myScreenCoords[1], 7, paint);

Slides

Source code (Yahoo Developer ID needed)