Hello, World!
So, I got an Android. Heck yes.
Having played with the Recovery image, I was hooked in. So I rooted it. Then Fixed up the install to Cyanogen 6 ( Upstream 2.2 Froyo ).
Well, then I got done with that. Lame. So, I thought to myself, what’s next?
I settled on trying to program the thing. I downloaded the SDK and installed everything nice and neat. I got it fired up and figured out that the Android VM is almost identical to the Java VM, with some small ( SMALL ) differences. Not watered down Blackberry Java, but real Java. This’ll be easy!
So, because it’s Java, I decided to skip Hello, World. So, I figured I would design “GeoLoc” — a Socket-based bridge to the GPS system on my Android.
But it’s all text if there’s nothing to tie into. A quick rewind to some old code I wrote for Flight Gear, and I had myself a KDE Marble interface to my GPS location. Although it’s super late, I’d really like to thank jmho, who did some really amazing work to help me make the interface work. Thanks, jmho!
This code does is accept connections on port 20017, and watch for input. When the system on the remote end requests either “lat” or “lon” it returns data in the format “data:information until end of line”.
A simple session would be:
lat
lat:12.34567
lon
lon:12.34567
So, our GUI tickles for information every few seconds, and re-draws the map.
So, let’s get down to some ‘droid programming!
My basic class ( GeoLoc.java ) looks like this:
import java.io.IOException;
import java.net.ServerSocket;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;
public class GeoLoc extends Activity {
TextView tv;
MyLocationListener mlocListener;
boolean running;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
this.running = true;
int port = 20017;
this.mlocListener = null;
this.tv = new TextView(this);
tv.setText("Waiting on port " + port );
setContentView(tv);
/* Use the LocationManager class to obtain GPS locations */
LocationManager mlocManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
try {
this.mlocListener = new MyLocationListener( port );
mlocManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 0, 0, this.mlocListener);
} catch (IOException e) { }
}
public class MyLocationListener extends Thread implements LocationListener { /* Inner class */
ServerSocket s;
ArrayList
This uses a server thread that looks like:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import android.location.Location;
public class ServerThread extends Thread {
Socket s;
BufferedReader input;
OutputStreamWriter output;
Location location; //location
double lat;
double lon;
boolean running;
ServerThread( Socket s ) throws IOException {
//System.err.println("[ ST ] Connection rcvd, " + s.getInetAddress() ); // REMOVE ME
this.running = true;
this.lat = 0;
this.lon = 0;
this.location = null;
this.s = s;
this.input = new BufferedReader(
new InputStreamReader(
s.getInputStream()
)
);
this.output = new OutputStreamWriter(
s.getOutputStream()
);
}
public void pipeout( String s ) {
try {
this.output.write(s + "\r\n");
this.output.flush();
} catch ( IOException e ) {
this.running = false;
}
}
public void outputLat() {
if ( this.location == null ) {
this.pipeout("error:latitude being aquired");
} else {
String output = "lat:" + this.lat;
this.pipeout(output);
}
}
public void outputLon() {
if ( this.location == null ) {
this.pipeout("error:longit being aquired");
} else {
String output = "lon:" + this.lon;
this.pipeout(output);
}
}
public void sendLoc( Location loc ) {
this.location = loc;
this.location.getLatitude();
this.location.getLongitude();
this.lat = this.location.getLatitude();
this.lon = this.location.getLongitude();
//System.err.println("[ ST ] Lat: " + this.lat );
//System.err.println("[ ST ] Lon: " + this.lon );
}
public void backPort( String s ) {
if ( s != null ) {
String input = s.trim();
if ( input.matches("lon" ) ) {
this.outputLon();
} else if ( input.matches("lat" ) ) {
this.outputLat();
} else {
this.pipeout("error:error working out command");
}
} else {
this.running = false;
}
}
public void run() {
String s;
while ( this.running ) {
try {
s = this.input.readLine();
this.backPort( s );
} catch (IOException e) {
this.running = false;
}
}
}
}
Remember, folks. There are some missing bits. If you want the full code, check it out on Github — here
So far, I took it out for a spin in the car, and it looks good!
Viva La Open-Source!
No Comments