getLastKnownLocation 僅返回**上次其他 App 或系統記錄的快取位置**。Nexus 等裝置若近期無其他 App 請求定位,快取為空,返回 null。Galaxy Tab/HTC 可能因預載地圖/天氣 App 有快取,故能取得值。
LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);
LocationListener listener = new LocationListener() {
@Override public void onLocationChanged(Location location) {
// 這裡拿到即時位置
double lat = location.getLatitude();
double lng = location.getLongitude();
updateUI(lat, lng);
// 若只需一次,可在此移除監聽
lm.removeUpdates(this);
}
@Override public void onStatusChanged(String p, int s, Bundle e) {}
@Override public void onProviderEnabled(String p) {}
@Override public void onProviderDisabled(String p) {}
};
// 請求 GPS 更新(或 NETWORK_PROVIDER)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
public void requestSingleLocationFix(Context context, OnLocationFix callback) {
LocationManager lm = (LocationManager) context.getSystemService(LOCATION_SERVICE);
LocationListener listener = new LocationListener() {
@Override public void onLocationChanged(Location loc) {
lm.removeUpdates(this);
callback.onFix(loc);
}
// ... 其他方法空實現
};
// 同時請求 GPS 與 Network,先到者勝出
if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER))
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
if (lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, listener);
// 設定超時保護(如 20 秒)
new Handler(Looper.getMainLooper()).postDelayed(() -> {
lm.removeUpdates(listener);
callback.onTimeout();
}, 20000);
}
fused.getCurrentLocation(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY, null)
.addOnSuccessListener(location -> { /* 直接拿到 */ });
無需管理 Listener、Provider、權限檢查更簡潔,新專案首選。