This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.
How to get the GPS position (latitude/longitude)
Purpose. Get the device’s latitude/longitude. For a one-off read use Location
retrieveGPSData(); for continuous tracking useGPSThread, which manages the thread for you.
APIs used
new Location() throws IOException— opens the GPS (high precision by default). There’s alsonew Location(int precision)withLocation.HIGH_GPS_PRECISION(GPS only) orLocation.LOW_GPS_PRECISION(GPS + Google Play Services / radio / wifi).boolean retrieveGPSData()— updates the static fields; returnstrueif it got valid data,falseon low signal (reason inLocation.lowSignalReason).Location.getLatitude()/getLongitude()(static) — coordinates; equalLocation.INVALIDwithout signal.Location.velocity(in knots),Location.pdop(precision dilution),Location.satellites,Location.direction— static fields.void stop()— mandatory: closes the native API and releases the single instance. There can only be oneLocationopen at a time (the constructor throwsIOExceptionif one already exists).GPSThread(boolean highPrecision, int intervalInMS, Runnable onLocation, RunnableWith<Exception> onError)— daemon thread that starts on its own in the constructor;stopGps()stops it and waits for it to finish.
Cautions. The coordinate fields are static — only one active read at a time. Always validate against
Location.INVALIDand check thepdopbefore trusting the position (LOW may return 30m–1500m+). Callstop()when done (theGPSThreaddoes it for you on every cycle).
Complete example (copy, paste, and run)
package com.exemplo;
import dev.crossfly.ui.*; // Window, Component, Button, Label
import dev.crossfly.ui.layout.*; // VerticalLayout
import dev.crossfly.device.*; // Location, Device
/** Runnable main screen. Point the launcher (classname) and run: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
Label resultado = new Label("");
add(LAY_AUTO, resultado);
Button acao = new Button("Obter GPS");
acao.onAction(c ->
{
// One-off reading (outside the paint thread) — always in try/finally to guarantee stop()
new Thread(() ->
{
Location loc = null;
try
{
loc = new Location(); // opens the GPS (only 1 at a time)
for (int i = 0; i < 120 && !loc.retrieveGPSData(); i++)
Device.sleep(500); // waits up to ~60s for a fix
double lat = Location.getLatitude();
double lon = Location.getLongitude();
if (lat != Location.INVALID && lon != Location.INVALID)
Component.onUI(() -> resultado.setText("Lat " + lat + " / Lon " + lon));
else
Component.onUI(() -> resultado.setText("Sem sinal de GPS"));
}
catch (java.io.IOException e)
{
// a Location was already open, or failed to open the GPS
Component.onUI(() -> resultado.setText("Erro: " + e.getMessage()));
}
finally
{
if (loc != null) loc.stop(); // REQUIRED
}
}).start();
});
add(LAY_AUTO, acao);
}
}
The snippet below shows only the core. To run it, place it in the
MainWindowskeleton above.
Minimal snippet
// verified at source: Location.java (Location(), retrieveGPSData, getLatitude/Longitude, INVALID, stop); GPSThread.java (constructor, stopGps)
import dev.crossfly.device.*; // Location
import dev.crossfly.core.*; // GPSThread
import dev.crossfly.ui.*; // Component (onUI)
// 1) One-off reading (outside the paint thread) — always in try/finally to guarantee stop()
new Thread(() -> {
Location loc = null;
try {
loc = new Location(); // opens the GPS (only 1 at a time)
for (int i = 0; i < 120 && !loc.retrieveGPSData(); i++)
Device.sleep(500); // waits up to ~60s for a fix
double lat = Location.getLatitude();
double lon = Location.getLongitude();
if (lat != Location.INVALID && lon != Location.INVALID)
Component.onUI(() -> mostrarPosicao(lat, lon)); // return outside the paint thread
} catch (java.io.IOException e) {
// a Location was already open, or failed to open the GPS
} finally {
if (loc != null) loc.stop(); // REQUIRED
}
}).start();
// 2) Continuous tracking — GPSThread starts on its own; callbacks outside the paint thread
GPSThread gps = new GPSThread(true, 5000, // high precision, every 5s
() -> {
double lat = Location.getLatitude(), lon = Location.getLongitude();
Component.onUI(() -> atualizarMapa(lat, lon));
},
err -> Component.onUI(() -> mostrarErro(err.getMessage())));
// ... when finished:
gps.stopGps();
Go deeper
- Location guide: Location & GPS
- Sibling recipe: escolher-local-no-mapa.md
Was this page helpful?Thanks for the feedback!