跳到内容
CrossFly 是 100% 开源在 GitHub 关注我们
CrossFlyCrossFly
开始使用

本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。

如何获取 GPS 位置(纬度/经度)

目的。 获取设备的 纬度/经度。若只需一次性读取,使用 Location

  • retrieveGPSData();若需 持续跟踪,使用 GPSThread,它会自行管理线程。

使用的 API

  • new Location() throws IOException — 打开 GPS(默认高精度)。也有 new Location(int precision),可用 Location.HIGH_GPS_PRECISION(仅 GPS)或 Location.LOW_GPS_PRECISION(GPS + Google Play Services / 蜂窝 / wifi)。
  • boolean retrieveGPSData() — 更新静态字段;获取到有效数据时返回 true,信号弱时返回 false(原因在 Location.lowSignalReason 中)。
  • Location.getLatitude() / getLongitude()(静态)— 坐标;无信号时值为 Location.INVALID。
  • Location.velocity(单位为节/knots)、Location.pdop(精度因子)、Location.satellites、Location.direction — 静态字段。
  • void stop() — 必需:关闭原生 API 并释放这个唯一实例。同一时刻只能有 一个 Location 打开(若已存在,构造函数会抛出 IOException)。
  • GPSThread(boolean highPrecision, int intervalInMS, Runnable onLocation, RunnableWith<Exception> onError) — 守护线程,在构造函数中 自行启动;stopGps() 停止并等待其结束。

注意事项。 坐标字段是 静态的 —— 同一时刻只有一个活跃读取。始终 针对 Location.INVALID 校验,并在信任位置前检查 pdop(LOW 可能返回 30m–1500m+)。结束时调用 stop()(GPSThread 会在每个周期为你完成这件事)。

完整示例(复制、粘贴并运行)

package com.exemplo;

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

/** 可执行的主界面。将 launcher 指向此类(classname)并运行: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 ->
      {
         // 单次读取(在 paint thread 之外)— 始终用 try/finally 确保 stop()
         new Thread(() ->
         {
            Location loc = null;
            try
            {
               loc = new Location();                              // 打开 GPS(一次仅 1 个)
               for (int i = 0; i < 120 && !loc.retrieveGPSData(); i++)
                  Device.sleep(500);                              // 最多等待约 60s 以获取定位
               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)
            {
               // 已有一个 Location 打开,或打开 GPS 失败
               Component.onUI(() -> resultado.setText("Erro: " + e.getMessage()));
            }
            finally
            {
               if (loc != null) loc.stop();                       // 必须
            }
         }).start();
      });
      add(LAY_AUTO, acao);
   }
}

下面的片段只展示 核心部分。要运行它,请把它放进上面的 MainWindow 骨架里。

最小片段

// 已在源码验证: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) 单次读取(在 paint thread 之外)— 始终用 try/finally 确保 stop()
new Thread(() -> {
   Location loc = null;
   try {
      loc = new Location();                              // 打开 GPS(一次仅 1 个)
      for (int i = 0; i < 120 && !loc.retrieveGPSData(); i++)
         Device.sleep(500);                              // 最多等待约 60s 以获取定位
      double lat = Location.getLatitude();
      double lon = Location.getLongitude();
      if (lat != Location.INVALID && lon != Location.INVALID)
         Component.onUI(() -> mostrarPosicao(lat, lon)); // 返回在 paint thread 之外
   } catch (java.io.IOException e) {
      // 已有一个 Location 打开,或打开 GPS 失败
   } finally {
      if (loc != null) loc.stop();                       // 必须
   }
}).start();

// 2) 持续追踪 — GPSThread 自行启动;回调在 paint thread 之外
GPSThread gps = new GPSThread(true, 5000,                // 高精度,每 5s 一次
   () -> {
      double lat = Location.getLatitude(), lon = Location.getLongitude();
      Component.onUI(() -> atualizarMapa(lat, lon));
   },
   err -> Component.onUI(() -> mostrarErro(err.getMessage())));
// ... 结束时:
gps.stopGps();

深入了解

这个页面有帮助吗?