Johan's blog
JavaFX location example with GPS
One of the cool things about the JavaFX Mobile platform running on my HTC Diamond phone, is the easy integration with GPS. In this article, I will describe the most simple example I could come up with.
I have been working with GPS integration in Java code since more than 10 years
now. In most cases, I had to use the serial io provided in comm.jar
implementations (the one providing javax.comm.SerialPort and others).
Although this worked fine in most of the cases, the
amount of low-level code was high compared with the amount of functional
code.
I have been a big supporter of JSR 179, the Location API for J2ME. This
API provides a simple way for obtaining locations and it also provides some
common functionality (e.g. proximity listeners).
Until recently, I haven't seen much devices that contained a clean
implementation of this API. But this is changing.
The JavaFX Mobile 1.2 for Windows Mobile platform contains an implementation of
JSR 179, and it works very well with JavaFX.
The following code example shows a simple JavaFX example showing the status
of the built-in GPS and the latest known position. It probably violates some
patterns, but the only goal is showing how you can obtain position in
your JavaFX programs.
The main class
The main class is a typical JavaFX example containing a Stage with a Scene. The Scene contains 2 Text items. The contents of these text items are dynamically bound to some variables.
package com.lodgon.locationdemo;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.Text;
import javafx.scene.text.Font;
public var gpsStatus: String = "unknown";
public var lat: Number = 0.0;
public var lon: Number = 0.0;
var stage: Stage = Stage {
title: "Location demo"
width: 250
height: 120
scene: Scene {
content: [
Text {
font : Font { size : 16 }
x: 10
y: 30
content: bind "gps status: {gpsStatus}"
},
Text {
font : Font { size : 16 }
x: 10
y: 50
content: bind "position: {lat}, {lon}"
}
]
}
}
function run () {
stage;
var processor: LocationProcessor = LocationProcessor{};
processor.startReading();
}
No magic in here, notice the LocationProcessor class that
we instantiate and that will do the interaction with the GPS. This
instance will create a javax.microedition.location.LocationProvider
and register a javax.microedition.location.LocationListener
with it.
When the status of the GPS is changed, the providerStateChanged
method is called. The new status is assigned to the gpsStatus
variable in the Main class and shown on the device screen.
Similarly, when a new position is detected, the locationUpdate
method is called, and the lat and lon variables
in the Main class are changed.
package com.lodgon.locationdemo;
import javax.microedition.location.LocationListener;
import javax.microedition.location.Location;
import javax.microedition.location.LocationProvider;
import javax.microedition.location.QualifiedCoordinates;
public class LocationProcessor extends LocationListener {
var provider: LocationProvider;
public function startReading() {
provider = LocationProvider.getInstance(null);
provider.setLocationListener(this, 10, 5, -1);
providerStateChanged (provider, provider.getState());
}
override function locationUpdated(provider: LocationProvider, location: Location) {
if (location != null) {
var coords: QualifiedCoordinates = location.getQualifiedCoordinates();
if (coords != null) {
var lat = coords.getLatitude();
var lon = coords.getLongitude();
println ("[JVDBG] lat = {lat}");
Main.lat = lat;
Main.lon = lon;
}
}
}
override function providerStateChanged(provider: LocationProvider, stat: Integer) {
if (stat == 1) {
Main.gpsStatus = "Available";
}
if (stat == 2) {
Main.gpsStatus = "Temporarily Unvailable";
}
if (stat == 3) {
Main.gpsStatus = "Out Of Service";
}
}
}
For more information about JSR 179, see the
Javadoc pages. You can easily change the update frequency (currently 10 seconds),
timeout (currently 5 seconds), and other criteria.
Also note that we actually should not do any processing in the interface
callback methods. Since this is a simple example without much processing,
I didn't use the javafx async threading mechanism for simplicity.
