# GPS स्थिति (अक्षांश/देशांतर) कैसे प्राप्त करें

> Location + retrieveGPSData() के साथ डिवाइस के GPS से निर्देशांक पढ़ें, या GPSThread के साथ निरंतर ट्रैक करें।

Source: https://crossfly.dev/hi/docs/cookbook/device/obter-gps — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# GPS स्थिति (अक्षांश/देशांतर) कैसे प्राप्त करें

**उद्देश्य।** डिवाइस का **अक्षांश/देशांतर** प्राप्त करना। एकल रीडिंग के लिए `Location`
+ `retrieveGPSData()` का उपयोग करें; **निरंतर ट्रैकिंग** के लिए `GPSThread` का उपयोग करें, जो पहले से ही thread का प्रबंधन करता है।

## उपयोग की गई APIs
- `new Location() throws IOException` — GPS खोलता है (डिफ़ॉल्ट रूप से उच्च परिशुद्धता)। `Location.HIGH_GPS_PRECISION` (केवल GPS) या `Location.LOW_GPS_PRECISION` (GPS + Google Play Services / रेडियो / wifi) के साथ `new Location(int precision)` भी है।
- `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)` — daemon thread जो कंस्ट्रक्टर में **स्वयं शुरू होता है**; `stopGps()` इसे रोकता है और समाप्ति की प्रतीक्षा करता है।

> **सावधानियाँ।** निर्देशांक फ़ील्ड **स्टैटिक** हैं — एक समय में केवल एक सक्रिय रीडिंग। हमेशा
> `Location.INVALID` के विरुद्ध सत्यापित करें और स्थिति पर भरोसा करने से पहले `pdop` जाँचें (LOW
> 30m–1500m+ लौटा सकता है)। समाप्त होने पर `stop()` कॉल करें (`GPSThread` यह हर चक्र में आपके लिए करता है)।

## पूर्ण उदाहरण (कॉपी करें, पेस्ट करें और चलाएँ)

```java
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 के बाहर) — stop() सुनिश्चित करने के लिए हमेशा try/finally में
         new Thread(() ->
         {
            Location loc = null;
            try
            {
               loc = new Location();                              // GPS खोलता है (एक समय में केवल 1)
               for (int i = 0; i < 120 && !loc.retrieveGPSData(); i++)
                  Device.sleep(500);                              // fix के लिए ~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` ढाँचे में रखें।

## न्यूनतम अंश

```java
// स्रोत में सत्यापित: 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 के बाहर) — stop() सुनिश्चित करने के लिए हमेशा try/finally में
new Thread(() -> {
   Location loc = null;
   try {
      loc = new Location();                              // GPS खोलता है (एक समय में केवल 1)
      for (int i = 0; i < 120 && !loc.retrieveGPSData(); i++)
         Device.sleep(500);                              // fix के लिए ~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 स्वयं शुरू होती है; callbacks 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();
```

## और गहराई में जाएँ
- स्थान गाइड: [Location & GPS](/docs/data-and-services/device-location-gps)
- संबंधित रेसिपी: [escolher-local-no-mapa.md](/docs/cookbook/device/escolher-local-no-mapa)
