gpsd4j is a Java library that allows you to communicate with a gpsd server.
- JRE 8 or higher at runtime
- JDK 8 or higher to compile the library from source
Step 1. Add the JitPack repository to your pom.xml
file:
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
Step 2. Add the dependency:
<dependency>
<groupId>com.ivkos</groupId>
<artifactId>gpsd4j</artifactId>
<version>1.3.1</version>
</dependency>
Step 1. Add the JitPack repository to your root build.gradle
at the end of repositories:
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
Step 2. Add the dependency:
dependencies {
compile 'com.ivkos:gpsd4j:1.3.1'
}
Javadocs can be found here.
An example is worth a thousand pages of Javadocs.
// Create a client for connecting to the gpsd server at localhost, port 2947
GpsdClient client = new GpsdClient("localhost", 2947);
// You can pass an options object if you wish to configure connection handling
GpsdClientOptions options = new GpsdClientOptions()
.setReconnectOnDisconnect(true)
.setConnectTimeout(3000) // ms
.setIdleTimeout(30) // seconds
.setReconnectAttempts(5)
.setReconnectInterval(3000); // ms
GpsdClient client = new GpsdClient("localhost", 2947, options);
Because of the asynchronous nature of the client, you can dynamically add or remove handlers with no unexpected side effects, no matter if the client is running or not.
// Adds a handler that prints received gpsd errors to stderr
client.addErrorHandler(System.err::println);
// Adds a message handler that handles incoming TPV messages
client.addHandler(TPVReport.class, tpv -> {
Double lat = tpv.getLatitude();
Double lon = tpv.getLongitude();
System.out.printf("Lat: %f, Lon: %f\n", lat, lon);
});
// Adding handlers can be chained
client.addHandler(TPVReport.class, tpv -> { ... })
.addHandler(SKYReport.class, sky -> { ... })
.addHandler(GSTReport.class, gst -> { ... });
// Suppose you use a generic handler for multiple types of messages
Consumer<? extends GpsdMessage> genericHandler = msg -> {
System.out.println("Got a message: " + msg);
};
client.addHandler(TPVReport.class, (Consumer<TPVReport>) genericHandler)
.addHandler(GSTReport.class, (Consumer<GSTReport>) genericHandler);
// You can remove it from a specific type of message
client.removeHandler(TPVReport.class, (Consumer<TPVReport>) genericHandler);
// Or you can remove it altogether from all types of messages
client.removeHandler(genericHandler);
// After you have created a client and (optionally) added handlers, you can start it
client.start();
// As long as the client is running, you can send commands to the gpsd server
// More on that later...
client.sendCommand(...)
.sendCommand(..., result -> { ... });
// Send a command to the server to enable dumping of messages
client.watch();
// To stop the client:
client.stop();
Device settings and watch mode settings may be lost if the connection drops or the gpsd server restarts. In order to persist them, you can set a connection handler that gets executed upon each successful connection the gpsd server, including reconnections.
new GpsdClient(...)
.setSuccessfulConnectionHandler(client -> {
DeviceMessage device = new DeviceMessage();
device.setPath("/dev/ttyAMA0");
device.setNative(true);
client.sendCommand(device);
client.watch();
})
.addHandler(TPVReport.class, tpv -> { ... })
.start();
There are multiple ways of sending commands to the server. In order to send commands,
the client must be started and running. Otherwise, an IllegalStateException
may be thrown.
// The response is the same type as the command message (subtypes of GpsdCommandMessage)
client.sendCommand(new PollMessage(), pollMessageResponse -> {
Integer activeDevices = pollMessageResponse.getActiveCount();
});
// Setup the GPS device to run in its native mode
DeviceMessage device = new DeviceMessage();
device.setPath("/dev/ttyAMA0");
device.setNative(true);
client.sendCommand(device);
new GpsdClient("localhost", 2947)
.addErrorHandler(System.err::println)
.addHandler(TPVReport.class, tpv -> {
Double lat = tpv.getLatitude();
Double lon = tpv.getLongitude();
System.out.printf("Lat: %f, Lon: %f\n", lat, lon);
})
.addHandler(SKYReport.class, sky -> {
System.out.printf("We can see %d satellites\n", sky.getSatellites().size())
})
.setSuccessfulConnectionHandler(client -> {
DeviceMessage device = new DeviceMessage();
device.setPath("/dev/ttyAMA0");
device.setNative(true);
client.sendCommand(device);
client.watch();
})
.start();