Search code examples
javaandroidgpsandroid-gps

How to have inbuilt GPS locker like "GPS Connected" in app?


I would like to have highest precision on my app when I acquire GPS position with

Location.getLatitude()
Location.getLongitude()

and I have found out the GPS has to be running in the background to have highest precision.

If anyone knows them, the function of the app GPS Connected, and similar apps like GPS Fix, GPS Locker, does exactly what i want.

I would like to reproduce that in my app so I dont have to install and run that extra app.

I cant find any opensource code for this.

Can anyone help?


Solution

  • After a long search and tips from several sources, we have found someone doing something that could be what we are looking for:

    Getting the user's location in Android when the phone is locked

    This person is looking for a solution to update his GPS location even when his screen is locked, but has in the meantime implemented what I think is the solution for my problem: launching a service where the location is extracted through a function getLocation(). This function is periodically called in the service by a runnable+handler with an arbitrary time interval of UPDATE_CYCLE_PERIOD.

    In the function getLocation() the updates are done only if Network is connected or GPS is active, but also accordingly to 2 other conditions: MIN_TIME_BW_UPDATES and MIN_DISTANCE_CHANGE_FOR_UPDATES, called by a method named locationManager.requestLocationUpdates(). We re still not sure what this is doing, exactly, but the guess is it is simply defining the update conditions for the locationManager.

    The code for that particular Method, called inside getLocation() is:

    locationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER, //Or .GPS_PROVIDER
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
    

    The code for the periodic runnable+handler:

        handler = new Handler();
        runnable = new Runnable() {
            public void run() {
               location = getLocation();
               handler.postDelayed(runnable, UPDATE_CYCLE_PERIOD);
            }
        };
    

    The code for that function is

    public Location getLocation() {
        try {
            locationManager = (LocationManager) mContext
                    .getSystemService(LOCATION_SERVICE);
    
            // getting GPS status
            isGPSEnabled = locationManager
                    .isProviderEnabled(LocationManager.GPS_PROVIDER);
    
            // getting network status
            isNetworkEnabled = locationManager
                    .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    
            if (!isGPSEnabled && !isNetworkEnabled) {
                // no network provider is enabled
            } else {
                this.canGetLocation = true;
                // First get location from Network Provider
                if (isNetworkEnabled) {
                    locationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("Network", "Network");
                    if (locationManager != null) {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                        }
                    }
                }
                // if GPS Enabled get lat/long using GPS Services
                if (isGPSEnabled) {
                    if (location == null) {
                        locationManager.requestLocationUpdates(
                                LocationManager.GPS_PROVIDER,
                                MIN_TIME_BW_UPDATES,
                                MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                        Log.d("GPS Enabled", "GPS Enabled");
                        if (locationManager != null) {
                            location = locationManager
                                    .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                            if (location != null) {
                                latitude = location.getLatitude();
                                longitude = location.getLongitude();
                            }
                        }
                    }
                }
            }
    
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        return location;
    }
    

    The numeric values we are defining for those 3 variables are:

    UPDATE_CYCLE_PERIOD = 5 sec (10 sec originally)
    
    MIN_DISTANCE_CHANGE_FOR_UPDATES = 1 meter (10 meters originally)
    
    MIN_TIME_BW_UPDATES = 1 sec  (1 min originally)
    

    This is us guessing we can mimic the effect of the app "GPS Connected" Lock GPS function, by having super-frequent and super-precise updates - if, at all, that app is doing a similar thing. We will probably have to test and optimize for battery consumption, since these values seem extremely consuming. Any comments are welcome here.