35
votes

I am working on gps tracking apps in android. Here is my code architecture:

  1. BackgroundSyncService : A service class that is used for getting location update. Here GoogleApiClient is initialized and implements others Location related methods.
  2. AppRunCheckerReceiver : A BroadcastReceiver class that will check if my BackgroundSyncService is running or not in a time interval. If it stopped then it start.
  3. GpsEnableReceiver : A BroadcastReceiver it will fire if gps status changed. It will check if my BackgroundSyncService is running or not in a time interval. If it stopped then it start.
  4. InternetConnectionStateReceiver : A BroadcastReceiver it will fire when internet status changed. It will check if my BackgroundSyncService is running or not in a time interval. If it is stopped, then it start.

In my BackgroundSyncService service I initialize the GoogleApiClient using this way:

public void setLocationLocationRequest() {

        try {
            googleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this).addApi(com.google.android.gms.location.LocationServices.API).build();

            locationRequest = new LocationRequest();
            locationRequest.setInterval(3000);
            locationRequest.setFastestInterval(3000);
            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            googleApiClient.connect();
        } catch (Exception e) {

    }

Here accuricy is LocationRequest.PRIORITY_HIGH_ACCURACY and interval is

locationRequest.setInterval(3000)

here is the GoogleApiClient implementation code.

This application GPS info section contains Latitude longitude and Accuracy parameter

My Findings: in onLocationChanged(Location location) method I check the accuracy of Location object in this way : location.getAccuracy(). Here if accuracy is less than 50 meter, then I accept it.

In 85% of the cases it working like a charm. It sending me exact location from GPS. But in 15% cases, it sending me inaccurate location like more >300 meter.

The 15% device are low cost China brand mobile.

My Questions:

  1. How can i make accuracy level near 99%. Is there any problem on my code architecture?
  2. Does GPS accuracy depends on device configuration? if YES then what can I do for low configuration device?
  3. How Uber, Go-JEK etc. ride sharing apps works for all device? Is they have extra coding for GPS only?
  4. My application is for Bangladesh. Here internet is slow. Is it has negative impact on GPS accuracy?

Thanks in advance for this thread. And also sorry for bad english.

3
Have you tried with FusedLocationProviderAPI ?Piyush
thanks @Piyush , I used it but no improvements .Md. Sajedul Karim
When you say that it works OK for 85% of the cases - do you mean that 85% of the locations you get, or 85% of the devices? Regarding q. 4 - the internet speed has nothing to do with GPS. It's two different systems.TDG
Your question is good yet i doubt a developer will rewheel all the hard-work they did to achieve this thing to make your app then of course there is no competition .Yes gps accuracy has a relationship with device check the Networking section on a device spec, can get an idea what sat systems they use to get the GPS.Internet speed has nothing to do with GPS you can even turn off internet and work.This is the main thread read all and it will help you for sure stackoverflow.com/questions/3145089/…Charuක

3 Answers

23
votes

Location Updates can be done in following ways:

  1. Location you get from GPS is more accurate than the location you get from the network,so if you need accuracy use GPS

  2. Not sure about this but i think its about the context what type of location you want like you want the accuracy or the fastest one so according to that choose your provider

  3. FusedLocation provider is the most efficient and effective solution for getting the location on android now,it gathers the location data from different sources and according to the parameters passed like in how much time you want location to be updated,you want high accuracy or not etc.It provides you the best location.

  4. Yes you should use the FusedLocationProvider for getting the location on android,as google also recommends this and it the most effective and efficient way there to get location on android for now.

enter image description here

Why don't you try by creating Criteria.ACCURACY_HIGH

A constant indicating a high accuracy requirement - may be used for horizontal, altitude, speed or bearing accuracy. For horizontal and vertical position this corresponds roughly to an accuracy of less than 100 meters.

Android tries to mask the reality of the hardware from us, but in practice there are only two location providers: GPS and network. GPS location is slow and not all devices have it, but it is accurate. Network location is faster and is supported by almost all devices, but it is less accurate.

Google improved its map and location management with fused location provider.

The main entry point for interacting with the fused location provider.The methods must be used in conjunction with a GoogleApiClient.


Code:

 new GoogleApiClient.Builder(context)
         .addApi(LocationServices.API)
         .addConnectionCallbacks(this)
         .addOnConnectionFailedListener(this)
         .build()

gps –> (GPS, AGPS): Name of the GPS location provider. This provider determines location using satellites. Depending on conditions, this provider may take a while to return a location fix. Requires the permission android.permission.ACCESS_FINE_LOCATION.

network –> (AGPS, CellID, WiFi MACID): Name of the network location provider. This provider determines location based on availability of cell tower and WiFi access points. Results are retrieved by means of a network lookup. Requires either of the permissions android.permission.ACCESS_COARSE_LOCATION or android.permission.ACCESS_FINE_LOCATION.


Other Options:

getLastKnownLocation()

The getLastKnownLocation() this returns the last known location...after you re-install the app it will not have any last known location...so it will result in NPE...instead use below code

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;
            //here is the if-else change so code avoids falling into both loops
         // 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", "GPS Enabled");
                    if (locationManager != null) {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                        }
                    }
                }
            } else if (isNetworkEnabled) {
                locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                Log.d("Network", "Network Enabled");
                if (locationManager != null) {
                    location = locationManager
                            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    if (location != null) {
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                    }
                }
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    }

    return location;
}

Check few Best examples I have found:

It worked for me...should work for you too...

7
votes
  1. How can i make accuracy level near 99%. Is there any problem on my code architecture?

This is real life scenario. You cannot ensure that all the location providers will work as expected. You should ask for best available position.

  1. a) Does GPS accuracy depends on device configuration?

YES. Some devices may have older GPS chipsets which can only track GPS signals (USA) since there are other positioning systems like Galileo (Europe), GLONASS (Russia), QZSS (Japan) and Beidou (China). The more the chipset support for these types the more chance you get to track more satellite hereby position fix. Also TTFF (time to first fix) depends on how many channels do the gps receiver has.

b) If YES then what can i do for low configuration device?

Since this is a hardware issue, you cannot do anything here. But other location sources can compensate the lack of GPS data such as AGPS (aided gps), wifi and cellular positioning. Also there are some paid options which provides a database to locate your device using wifi access points and cellids (they claim that they provide best solution on wifi but i m not sure as I dont use it. you can check it out http://combain.com). Wifi and cellid also depends on how many wifi access point and cell tower available around and how far they are (signal strength). If you need 50m accuracy, cellular positioning has nothing to do but wifi has a chance to get closer to this value.

Some study results from 2009 [3]

  • 3G iPhone w/ A-GPS ~ 8 meters
  • 3G iPhone w/ wifi ~ 74 meters
  • 3G iPhone w/ Cellular positioning ~ 600 meters
  1. How Uber, Go-JEK etc. ride sharing apps works for all device? Is they have extra coding for GPS only?

They may have specific Location strategies but it will based on using other sources during GPS outage.

  1. My application is for Bangladesh. Here internet is slow. Is it has negative impact on GPS accuracy?

Other answers claims that internet is not related to GPS. Yes it is true it is not related to GPS but location. AGPS uses internet to fetch 3 types of data (Satellite signals, almanac and ephemeris) which assist GPS to provide position fix faster. If ephemeris and almanac are outdated or the device moved several hundred km from the previous position fix then it is called cold start and takes around 12-15min without AGPS.

Fused location provider already knows how to provide best solution with these configurations, so you should bless it.

References:

3
votes

+1 for the description in question.
I hope we find the best answer for your question and better it over time, from what i know..there won't be just one correct answer here.

First,(and second)

  1. How can i make accuracy level near 99%. Is there any problem on my code architecture?

  2. Does GPS accuracy depends on device configuration? if YES then what can i do for low configuration device?

Both - device configuration and code architecture, are important here. If you are already at an 85% success rate, the code architecture is alright i think.
As far as GPS goes, line-of-sight is an important factor when it comes to device configurations and accuracy. Although a low cost mobile could return an accurate location with a clear line-of-sight. You can try running 2 cycles more/waiting to attain higher accuracy.

In a worst case scenario and for what its worth, you can also try retrieving location using the LocationManager and GPS provider technique which works as a fallback in the 15% just to compare and ensure you are using the most accurate location you can get. Location Strategies put it as

In most cases, you'll get better battery performance, as well as more appropriate accuracy, by using the Location Services API.

  1. How Uber, Go-JEK etc. ride sharing apps works for all device? Is they have extra coding for GPS only?
    They do work but not always with highest of accuracy for locations received within the app. If there are any location hacks for us developers, we need to find them, maybe a 5th page google search result :) or benefit from the open source environment. For me, best practices and android repo links suffice. You have already followed posts like Receive location updates

  2. My application is for Bangladesh. Here internet is slow. Is it has negative impact on GPS accuracy?
    No relation between internet and LocationManager + GPS_PROVIDER