如何在位置变化或定时更新Firebase实时数据库的当前经纬度
Hey there! Nice job getting the initial location saved to Firebase. To update the location either when the device moves or on a scheduled interval, here are two solid approaches tailored to your use case:
1. Update Location When the Device Moves (Location Change Listener)
Instead of just fetching the last location once, you can set up a continuous listener that triggers whenever the device's location shifts. Here's how to adjust your code:
First, define a LocationRequest to specify update frequency and accuracy:
LocationRequest locationRequest = LocationRequest.create(); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); // Use high accuracy for precise updates locationRequest.setInterval(5000); // Trigger update every 5 seconds (adjust as needed) locationRequest.setFastestInterval(2000); // Allow faster updates if the hardware supports it locationRequest.setSmallestDisplacement(10); // Only update if device moves 10 meters (optional, saves battery)
Next, create a LocationCallback to handle incoming location updates and sync them to Firebase:
LocationCallback locationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { if (locationResult == null) { Toast.makeText(getApplicationContext(), "Location update failed", Toast.LENGTH_SHORT).show(); return; } for (Location location : locationResult.getLocations()) { // Sync new location to Firebase updateFirebaseLocation(location); // Optional: Update your map camera moveCamera(new LatLng(location.getLatitude(), location.getLongitude()), ZOOM, "My Location"); } } }; // Helper method to handle Firebase updates cleanly private void updateFirebaseLocation(Location location) { mUserLocalStore = new UserLocalStore(getApplicationContext()); DatabaseReference mRef = FirebaseDatabase.getInstance().getReference("Location"); String locationData = mUserLocalStore.getDetails().getEmail() + " " + location.getLatitude() + ", " + location.getLongitude(); mRef.setValue(locationData); Toast.makeText(getApplicationContext(), "Location updated", Toast.LENGTH_SHORT).show(); }
Start the location updates in your activity's onResume (or wherever makes sense for your flow—just don't forget to check permissions first):
@Override protected void onResume() { super.onResume(); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { mFusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()); } else { // Request location permissions if not already granted ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 100); } }
Stop the updates when you don't need them (like in onPause) to save battery:
@Override protected void onPause() { super.onPause(); mFusedLocationProviderClient.removeLocationUpdates(locationCallback); }
2. Update Location on a Fixed Time Interval
If you need strict scheduled updates (e.g., every 15 minutes) regardless of movement, use one of these options:
Option A: Using Handler (Foreground Only)
Great for apps that stay in the foreground most of the time:
private Handler locationUpdateHandler = new Handler(); private Runnable locationUpdateRunnable = new Runnable() { @Override public void run() { if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { mFusedLocationProviderClient.getLastLocation().addOnCompleteListener(task -> { if (task.isSuccessful() && task.getResult() != null) { updateFirebaseLocation(task.getResult()); } }); } // Repeat after 15 minutes (adjust delay to your needs) locationUpdateHandler.postDelayed(this, 15 * 60 * 1000); } }; // Start the runnable in onResume @Override protected void onResume() { super.onResume(); locationUpdateHandler.post(locationUpdateRunnable); } // Stop it in onPause @Override protected void onPause() { super.onPause(); locationUpdateHandler.removeCallbacks(locationUpdateRunnable); }
Option B: Using WorkManager (Background-Friendly)
For updates that need to run even when the app is in the background, WorkManager is the reliable choice:
First, add the WorkManager dependency to your module-level build.gradle:
implementation "androidx.work:work-runtime:2.8.1"
Create a Worker class to handle the location update logic:
public class LocationUpdateWorker extends Worker { public LocationUpdateWorker(@NonNull Context context, @NonNull WorkerParameters params) { super(context, params); } @NonNull @Override public Result doWork() { FusedLocationProviderClient client = LocationServices.getFusedLocationProviderClient(getApplicationContext()); if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { Task<Location> locationTask = client.getLastLocation(); try { // Wait for location result (runs on background thread) Location location = Tasks.await(locationTask); if (location != null) { UserLocalStore userLocalStore = new UserLocalStore(getApplicationContext()); DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Location"); String locationData = userLocalStore.getDetails().getEmail() + " " + location.getLatitude() + ", " + location.getLongitude(); ref.setValue(locationData); return Result.success(); } } catch (ExecutionException | InterruptedException e) { e.printStackTrace(); return Result.retry(); } } return Result.failure(); } }
Schedule the periodic work in your activity:
// Schedule to run every 15 minutes (minimum interval for periodic work is 15 mins) PeriodicWorkRequest locationWorkRequest = new PeriodicWorkRequest.Builder(LocationUpdateWorker.class, 15, TimeUnit.MINUTES) .setConstraints(new Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) // Optional: only run if online .build()) .build(); WorkManager.getInstance(this).enqueue(locationWorkRequest);
Quick Tips:
- Permissions: Ensure you have
ACCESS_FINE_LOCATION(andACCESS_BACKGROUND_LOCATIONfor background updates) declared in yourAndroidManifest.xmland request runtime permissions properly. - Battery Savings: Avoid overly frequent updates—balance accuracy and battery usage based on your app's needs.
- Firebase Structure: Instead of storing location as a single string, consider using a structured object (like a POJO with email, latitude, longitude) for easier future querying.
内容的提问来源于stack exchange,提问作者Prabodha Manoranga

