Saltar al contenido
CrossFly es 100% open sourceSíguenos en GitHub
CrossFlyCrossFly
Empezar

Esta página fue traducida automáticamente del portugués y puede contener errores. La versión en portugués es la canónica.

Cómo obtener la posición GPS (latitud/longitud)

Propósito. Obtener la latitud/longitud del dispositivo. Para una lectura puntual usa Location

  • retrieveGPSData(); para rastreo continuo usa GPSThread, que ya gestiona el thread.

APIs usadas

  • new Location() throws IOException — abre el GPS (precisión alta por defecto). También existe new Location(int precision) con Location.HIGH_GPS_PRECISION (solo GPS) o Location.LOW_GPS_PRECISION (GPS + Google Play Services / radio / wifi).
  • boolean retrieveGPSData() — actualiza los campos estáticos; devuelve true si obtuvo un dato válido, false con señal baja (motivo en Location.lowSignalReason).
  • Location.getLatitude() / getLongitude() (estáticos) — coordenadas; valen Location.INVALID sin señal.
  • Location.velocity (en nudos/knots), Location.pdop (dilución de precisión), Location.satellites, Location.direction — campos estáticos.
  • void stop() — obligatorio: cierra la API nativa y libera la instancia única. Solo puede haber una Location abierta a la vez (el constructor lanza IOException si ya hay una).
  • GPSThread(boolean highPrecision, int intervalInMS, Runnable onLocation, RunnableWith<Exception> onError) — thread daemon que arranca solo en el constructor; stopGps() lo detiene y espera a que termine.

Cuidados. Los campos de coordenada son estáticos — solo una lectura activa a la vez. Valida siempre contra Location.INVALID y verifica el pdop antes de confiar en la posición (LOW puede devolver 30m–1500m+). Llama a stop() al terminar (el GPSThread lo hace por ti en cada ciclo).

Ejemplo completo (copiar, pegar y ejecutar)

package com.exemplo;

import dev.crossfly.ui.*;                   // Window, Component, Button, Label
import dev.crossfly.ui.layout.*;            // VerticalLayout
import dev.crossfly.device.*;               // Location, Device

/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: 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 ->
      {
         // Lectura puntual (fuera de la paint thread) — siempre en try/finally p/ garantizar stop()
         new Thread(() ->
         {
            Location loc = null;
            try
            {
               loc = new Location();                              // abre el GPS (solo 1 a la vez)
               for (int i = 0; i < 120 && !loc.retrieveGPSData(); i++)
                  Device.sleep(500);                              // espera hasta ~60s por un 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)
            {
               // ya había una Location abierta, o falló al abrir el GPS
               Component.onUI(() -> resultado.setText("Erro: " + e.getMessage()));
            }
            finally
            {
               if (loc != null) loc.stop();                       // OBLIGATORIO
            }
         }).start();
      });
      add(LAY_AUTO, acao);
   }
}

El fragmento de abajo muestra solo el núcleo. Para ejecutarlo, colócalo en el esqueleto MainWindow de arriba.

Fragmento mínimo

// verificado en la fuente: 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) Lectura puntual (fuera de la paint thread) — siempre en try/finally p/ garantizar stop()
new Thread(() -> {
   Location loc = null;
   try {
      loc = new Location();                              // abre el GPS (solo 1 a la vez)
      for (int i = 0; i < 120 && !loc.retrieveGPSData(); i++)
         Device.sleep(500);                              // espera hasta ~60s por un fix
      double lat = Location.getLatitude();
      double lon = Location.getLongitude();
      if (lat != Location.INVALID && lon != Location.INVALID)
         Component.onUI(() -> mostrarPosicao(lat, lon)); // retorno fuera de la paint thread
   } catch (java.io.IOException e) {
      // ya había una Location abierta, o falló al abrir el GPS
   } finally {
      if (loc != null) loc.stop();                       // OBLIGATORIO
   }
}).start();

// 2) Rastreo continuo — GPSThread inicia sola; callbacks fuera de la paint thread
GPSThread gps = new GPSThread(true, 5000,                // alta precisión, cada 5s
   () -> {
      double lat = Location.getLatitude(), lon = Location.getLongitude();
      Component.onUI(() -> atualizarMapa(lat, lon));
   },
   err -> Component.onUI(() -> mostrarErro(err.getMessage())));
// ... cuando termine:
gps.stopGps();

Profundiza

¿Te resultó útil esta página?