Three calls cover most needs. getLastKnownPositionAsync() answers at once from the system's cache, possibly stale or null. getCurrentPositionAsync({ accuracy }) waits for a fresh fix; Accuracy.Balanced (about 100 m) is enough for a store list and spares the battery, while High and BestForNavigation wake the GPS. watchPositionAsync() keeps reporting until you remove the subscription:
sub = await Location.watchPositionAsync(
{ accuracy: Location.Accuracy.High, timeInterval: 2000, distanceInterval: 50 },
({ coords, timestamp }) => {
const text = `${coords.latitude.toFixed(4)}, ${coords.longitude.toFixed(4)}` +
` at ${Math.round(coords.speed ?? 0)} m/s`;
console.log(new Date(timestamp).toISOString().slice(11, 19), text);
setLast(text);
});
})();
return () => sub?.remove(); // stop the GPS when the screen goes awayThe emulator takes fake fixes from its console: adb -s emulator-5554 emu geo fix <longitude> <latitude> (longitude first). A script walked south through Mountain View, one fix every three seconds, including one step of about 11 m; once the watch had started, it logged:
'19:43:35', '37.4160, -122.0815 at 0 m/s' '19:43:38', '37.4120, -122.0800 at 0 m/s' '19:43:43', '37.4050, -122.0795 at 0 m/s'
The 11 m step (to 37.4121) never arrived, because distanceInterval: 50 filtered it, and the speed is 0 because geo fix sends positions without a speed. Always remove the subscription on unmount, or the GPS keeps running for a screen nobody sees.