Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

interchangeable network and GPS location providers according to gps status android

Tags:

android

i would appreciate your help , if anyone can help me. i need to have an accurate location tracker in my app and i want it to act like this. it finds the first location of the person with network , meanwhile i start requesting GPS localisation. when gps gives me a location , i want to not listen anymore to network locations. After that i want to request a location from network only and only if Gps is not fixed(cant give me a location). When Gps is fixed again i want to stop listening to network,and this is the loop i want to implement since GPS is more acurate and i want to have network localisation as a backup. I Have seen this post , but i cant seem to understand how to adapt it to my needs,

How can I check the current status of the GPS receiver?

Ideas are needed, thank you in advance Stackoverflow Comunity.

like image 819
Rubin Basha Avatar asked Jul 15 '13 14:07

Rubin Basha


1 Answers

1. Stop Listening for Network Location Updates: It is very simple to do so. Simply call

your_loc_manager.removeUpdates(network_location_listener);

2. Getting Location from Network Provider if GPS Provider is not giving any fix You can try something like given below (instead of the timer you can try using GpsStatus Listener...)

inside the method for getting Network Provider updates

boolean network_enabled ;
try {
    network_enabled = locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch(Exception ex) {
    ex.printStackTrace();
}

if(!network_enabled)
    return;

locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 100, networkLocationListener);

return;

Inside the method for getting GPS Locations

boolean gps_enabled;
try {
    gps_enabled = locManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch(Exception ex) {
    ex.printStackTrace();
}

if(!gps_enabled) {
    // call your method for getting network location updates 
    return;
}

locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 50, locationListenerGps);
new Timer().schedule(new TimerTask() {

    @Override
    public void run() {
        // You should call your method of getting Network locations based on some 
        // condition which would tell whether you really need to ask for network location 

    }
}, 20000 /* Time Value after which you want to stop trying for GPS and switch to Network*/); 

EDIT 1:

Also "I don't need to know when to get updates from GPS , i need to know when to get updates from network (i mean i need to know when gps is searching , not when it is fixed). and how to control the interchangeability between network and GPS"

...If the fix has been lost then only you need to look for network updates so I had suggested to call

if (hasGPSFix) { 
    Log.i("GPS","Fix Lost (expired)"); 
    lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10, locationListener);
    lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 2000, 10, locationListener); //===> new line which I am suggesting  
} 
hasGPSFix = false;

This way, you will get the location update from Network while GPS will keep on trying for a fix. Once GPS fix is achieved hasGPSFix will change its value and the existing code in the said link will stop looking for network updates. At least this is what I could understand that you want to achieve. May be I have not understood you completely.

EDIT 2: Here is my class for handling both GPS and NETWORK providers

The mapActivity or wherever you need to get location updates, you need to create an instance of this MyLocation class. And also, to keep on getting the location updates you need to implement LocationResult in your calling activity. public abstract void gotLocation(Location location, boolean isGpsData); will tell you whether the update you have received just now is from network or GPS. Also, in case of data being returned from GPS, it automatically closes the netowrk listener. You will need to call getFineLocation() method if you want data from GPS and so on. You will need to enhance the given code for your purpose (like you need to enhance closeListeners() method to close only one provider when you just want to remove only the network updates, etc...), but it gives a basic implementation of what you want (along with the GpsStatus.Listener implementation, of course, so both combined should serve your purpose well).

public class MyLocation {
    LocationManager locManager;
    LocationResult locationResult;
    boolean gps_enabled = false;
    boolean network_enabled = false;

    public boolean getCoarseLocation(Context context, LocationResult result) {
    locationResult = result;
    if(locManager == null)
        locManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

    try {
        network_enabled = locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    } catch(Exception ex) {
        ex.printStackTrace();
    }

    if(!network_enabled)
        return false;

    locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 100, networkLocationListener);
    return true;
    }

    public boolean getFineLocation(Context context, LocationResult result) {
    locationResult = result;
    if(locManager == null)
        locManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

    try {
        gps_enabled = locManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    } catch(Exception ex) {

    }

    if(!gps_enabled)
        return false;//No way to get location data

    locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 100, locationListenerGps);
    return true;
    }

    LocationListener locationListenerGps = new LocationListener() {
    public void onLocationChanged(Location location) {
        locationResult.gotLocation(location,true);
        locManager.removeUpdates(networkLocationListener);
    }
    public void onProviderDisabled(String provider) {}
    public void onProviderEnabled(String provider) {}
    public void onStatusChanged(String provider, int status, Bundle extras) {}
    };

    LocationListener networkLocationListener = new LocationListener() {
    public void onLocationChanged(Location location) {
        locationResult.gotLocation(location,false);
    }
    public void onProviderDisabled(String provider) {}
    public void onProviderEnabled(String provider) {}
    public void onStatusChanged(String provider, int status, Bundle extras) {}
    };

    public void closeListeners() {
    if(locManager == null)
        return;

    if(locationListenerGps != null)
        locManager.removeUpdates(locationListenerGps);
    if(networkLocationListener != null)
        locManager.removeUpdates(networkLocationListener);
    }

    public static abstract class LocationResult {
    public abstract void gotLocation(Location location, boolean isGpsData);
    }

    public static boolean hasNetworkProvider(Context mContext) {
    List<String> myProvidersList = ((LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE)).getProviders(false);
    return myProvidersList.contains("network");
    }

    public static boolean hasGPSProvider(Context mContext) {
    List<String> myProvidersList = ((LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE)).getProviders(false);
    return myProvidersList.contains("gps");
    }
}
like image 63
Rajeev Avatar answered Oct 31 '22 11:10

Rajeev