Search code examples
androidlocationalarmmanagerrepeatingalarm

update location to the firebase database every 15 minutes only if the location has been changed? Android


I have implemented location upload to the firebase database every 15 minute using Alarm Manager, But I need to stop next update if user is still on same place where he was, (next update), It is ok to use fused location API or Location manager in android. This should work when app is killed or Android system is deep seeping mode (Locked). So we need background location permission, that is also fine! But it should not turn on location service all the time because it will drain battery. So location service should be stopped until Alarm manager start for the next time.

This is the TimerService I used!

 public class TimerService extends BroadcastReceiver {
        public static final int REQUEST_CODE = 12346;
    
        // Triggered by the Alarm periodically (starts the service to run task)
        @Override
        public void onReceive(Context context, Intent intent) {
            Intent serviceIntent = new Intent(context, TrackingService.class);
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                ContextCompat.startForegroundService(context, serviceIntent);
            } else {
                context.startService(serviceIntent);
            }
        }
    }

This is method in TrackingService

private void requestLocationUpdates() {

        LocationRequest request = new LocationRequest();

        request.setInterval(10000);

        request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        client = LocationServices.getFusedLocationProviderClient(this);
        int permission = ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION);

        if (permission == PackageManager.PERMISSION_GRANTED) {

             locationCallback = new LocationCallback() {
                @Override
                public void onLocationResult(LocationResult locationResult) {

                    Location location = locationResult.getLastLocation();
                    if (location != null) {
                     updateFirebase(location);
                    }
                }
            };

            client.requestLocationUpdates(request,locationCallback,null);
        }else{
            stopForeground(true);
            stopSelf();
        }
    }

So I need to help to implement a new method something like this,

tryLocationUpdate(Location location){
    if(location==stillInSamePlace){
        //Do not upload to the firebase database
    }else{
        uploadLocation();
    }
}

Can anyone help me?


Solution

  • I found a solution for this. You can save a longitude and latitude in Shared Preferences and check whether user has gone more than 100m. If it is true you can update the server and you can update Shared Preferences also.

        SharedPreferences prefs = getSharedPreferences("code", MODE_PRIVATE);
        count = prefs.getInt("location_history",0);
    
        storedLat = prefs.getFloat("storedLat", 0);
        storedLon = prefs.getFloat("storedLon", 0);
        storedAccu = prefs.getFloat("storedAccu", 0);
    
        float distance = distanceBetweenEarthCoordinates(storedLat, storedLon, (float) location.getLatitude(), (float) location.getLongitude());
                                        if (distance > 100) {
                                            Log.d("TAG", "onLocationResult: New Point" + count + "Distance: " + distance);
                                            storedLat = (float) location.getLatitude();
                                            storedLon = (float) location.getLongitude();
                                            SharedPreferences.Editor editor = getSharedPreferences("uinfo", MODE_PRIVATE).edit();
                                            editor.putFloat("storedLat", storedLat);
                                            editor.putFloat("storedLon", storedLon);
                                            count++;
                                            editor.putInt("location_history", count);
                                            editor.apply();
                                        }
    

    distanceBetweenEarthCoordinates method

    public static float degreesToRadians(float degrees) {
       return (float) (degrees * Math.PI / 180);
    }
    
    public static float distanceBetweenEarthCoordinates(float lat1, float lon1, float lat2, float lon2) {
            float earthRadiusKm = 6371;
    
            float dLat = degreesToRadians(lat2 - lat1);
            float dLon = degreesToRadians(lon2 - lon1);
    
            lat1 = degreesToRadians(lat1);
            lat2 = degreesToRadians(lat2);
    
            float a = (float) (Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                    Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2));
            float c = (float) (2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)));
            return earthRadiusKm * c * 1000;
        }