# लोकेशन और GPS

> Location (लाइव), LocationService (बैकग्राउंड) और GPSThread (निरंतर) — सही इकाइयों के साथ।

Source: https://crossfly.dev/hi/docs/data-and-services/device-location-gps — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# लोकेशन और GPS

तीन घटक, तीन ज़रूरतों के लिए। कॉलबैक **पेंट थ्रेड के बाहर** ट्रिगर होते हैं → `Component.onUI(...)` के साथ
लौटें।

| क्लास | किसके लिए |
|---|---|
| `Location` | **लाइव** रीडिंग (singleton — एक समय में एक इंस्टेंस) |
| `LocationService` | **बैकग्राउंड** में संग्रह, फ़ाइल में रिकॉर्ड करते हुए ("पढ़ो और साफ़ करो") |
| `GPSThread` | कॉलबैक के साथ **निरंतर ट्रैकिंग** |

## `Location` — लाइव रीडिंग
```java
Location loc = new Location();          // GPS खोलता है (throws IOException)
try {
   if (loc.retrieveGPSData()) {         // false = कोई सिग्नल नहीं/त्रुटि
      double lat = Location.getLatitude();
      double lon = Location.getLongitude();
      double vel = Location.velocity;   // ⚠️ नॉट्स (knots) में
      if (vel != Location.INVALID) { ... }   // भरोसा करने से पहले INVALID जांचें
   } else {
      Debug.log(Location.lowSignalReason);
   }
} finally {
   loc.stop();                          // ⚠️ हमेशा रोकें — भूलना बैटरी खत्म करता है
}
```
स्टैटिक फ़ील्ड्स: `location` (`double[]` lat/lon), `velocity` (नॉट्स), `pdop`, `satellites`, `direction`,
`lastFix`, और मार्कर `INVALID = Double.MIN_VALUE`।

## `LocationService` — बैकग्राउंड में संग्रह
फ़िक्स को एक फ़ाइल में रिकॉर्ड करता है; आप पढ़ते हैं और फ़ाइल मिट जाती है ("पढ़ो और साफ़ करो" पैटर्न):
```java
LocationService.start();   // एकत्र करना शुरू करता है (डेस्कटॉप पर no-op)
// … बाद में …
List<LocationService.GPSLogEntry> fixes = LocationService.readAll();  // फ़ाइल पढ़ता है और मिटा देता है
for (LocationService.GPSLogEntry e : fixes) {
   double vel = e.velocity;   // ⚠️ यहां मीटर प्रति सेकंड (m/s) में — Location से अलग!
}
LocationService.stop();
```

## ⚠️ `velocity` की इकाइयाँ अलग हैं!
| स्रोत | इकाई |
|---|---|
| `Location.velocity` (लाइव) | **नॉट्स (knots)** |
| `GPSLogEntry.velocity` (इतिहास) | **मीटर प्रति सेकंड (m/s)** |

दोनों को भ्रमित करना एक मौन रूपांतरण बग है। दोनों "कोई रीडिंग नहीं" के लिए `INVALID` का उपयोग करती हैं।

## `GPSThread` — निरंतर ट्रैकिंग
```java
GPSThread gps = new GPSThread(
   true,                 // highPrecision: केवल GPS (false = GPS+सेल+WiFi)
   2000,                 // ms में अंतराल
   () -> Component.onUI(() -> label.setText(Location.getLatitude() + ", " + Location.getLongitude())),
   erro -> Debug.log("GPS erro: " + erro)
);                        // निर्माण के समय ही शुरू हो जाता है
// … स्क्रीन छोड़ते समय:
gps.stopGps();            // रुकता है और thread के समाप्त होने की प्रतीक्षा करता है
```

## अच्छी प्रथाएँ
- बाहर निकलते समय **हमेशा `stop()`/`stopGps()`** — GPS चालू रहने से **बैटरी खपती है**।
- स्थिति पर भरोसा करने से पहले `INVALID`/`pdop` जाँचें।
- `velocity` की **इकाइयों** पर ध्यान दें (नॉट्स बनाम m/s)।
- कॉलबैक `onUI(...)` के साथ UI पर लौटते हैं।

## आम गलतियाँ
- `stop()` भूल जाना → बैटरी खत्म।
- `Location.velocity` को m/s मानना (यह **नॉट्स** है)।
- `INVALID` जाँचे बिना स्थिति पर भरोसा करना।

## यह भी देखें
- [LocationPicker](/docs/ui/widgets/locationpicker) · [मैप](/docs/data-and-services/maps) · [प्लेटफ़ॉर्म अनुसार अनुमतियाँ](/docs/platforms)
