0

I want to get user's location every 5 minutes, so I created a Service with the following codes:

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

public class Tracker extends Service {

    private SharedPreferences prefs;
    private LocationManager locationManager;
    private long minTime = 300000; // miliseconds
    private float minDistance = 10; // meters
    private boolean gpsStatus;
    private boolean networkStatus;

    @Override
    public void onCreate() {
        Log.i("Location2", "Location: Created");
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("Location2", "Location: Started");

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        gpsStatus = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        networkStatus = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        locationManager.requestLocationUpdates(getProviderName(), minTime, minDistance, locationListener);

        return Service.START_STICKY;
    }

    private void resetLocationProvider() {
        Log.e("Location2", "Provider Reset");
        deleteLocationListener();
        locationManager.requestLocationUpdates(getProviderName(), minTime, minDistance, locationListener);
    }

    private void deleteLocationListener() {
        locationManager.removeUpdates(locationListener);
    }

    private LocationListener locationListener = new LocationListener() {

        @Override
        public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
        }

        @Override
        public void onProviderEnabled(String provider) {
            resetLocationProvider();
            Log.e("Location2", "Provider Enabled: " + provider);
        }

        @Override
        public void onProviderDisabled(String provider) {
            resetLocationProvider();
            Log.e("Location2", "Provider Disabled: " + provider);
        }

        @Override
        public void onLocationChanged(Location location) {
            Log.i("Location2", "Location Time: " + TimeToDate.getDate(location.getTime(), "yyyy-MM-dd HH:mm:ss"));
            Log.i("Location2", "Location Provider: " + location.getProvider());
            Log.i("Location2", "Location Accuracy: " + location.getAccuracy());
            Log.i("Location2", "Location Latitude: " + location.getLatitude());
            Log.i("Location2", "Location Longitude: " + location.getLongitude());

            if (gpsStatus != locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                gpsStatus = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
                resetLocationProvider();
                return;
            }

            if (networkStatus != locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
                networkStatus = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
                resetLocationProvider();
            }
        }
    };

    private String getProviderName() {
        LocationManager locationManager = (LocationManager) this
                .getSystemService(Context.LOCATION_SERVICE);

        Criteria criteria = new Criteria();
        criteria.setPowerRequirement(Criteria.POWER_MEDIUM); // Chose your desired power consumption level.
        criteria.setAccuracy(Criteria.ACCURACY_FINE); // Choose your accuracy requirement.
        criteria.setSpeedRequired(false); // Chose if speed for first location fix is required.
        criteria.setAltitudeRequired(false); // Choose if you use altitude.
        criteria.setBearingRequired(false); // Choose if you use bearing.
        criteria.setCostAllowed(false); // Choose if this provider can waste money :-)

        // Provide your criteria and flag enabledOnly that tells
        // LocationManager only to return active providers.
        return locationManager.getBestProvider(criteria, true);
    }

    @Override
    public void onDestroy() {
        deleteLocationListener();
        super.onDestroy();
    };

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

}

As is seen, I've used a minTime of 300,000 ms, But I got a location every about 20 seconds rather than every 5 minutes. As documentation says:

The elapsed time between location updates will never be less than minTime, although it can be more depending on the Location Provider implementation and the update interval requested by other applications

And also I know, an active provider is not a good choice for a background process. However, what is wrong with my code?

1 Answers1

0

Based on this answer, I changed my codes to:

        @Override
        public void onLocationChanged(Location location) {
            if (location != null) {
                if (location.getProvider().equals(LocationManager.GPS_PROVIDER) && android.os.Build.VERSION.SDK_INT < 16) {
                    Log.i("TEST", "DATE: " + TimeToDate.getDate(location.getTime(), "yyyy-MM-dd HH:mm:ss"));
                    Log.i("TEST", "LAT: " + location.getLatitude());
                    Log.i("TEST", "LONG: " + location.getLongitude());
                    locationManager.removeUpdates(locationListener);
                    new Handler().postDelayed(new Runnable() {

                        @Override
                        public void run() {
                            locationManager.requestLocationUpdates(getProviderName(), minTime, minDistance, locationListener);
                        }
                    }, minTime);
                }
                ...

And now it works.

Community
  • 1
  • 1