6

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.

Community
  • 1
  • 1
Rubin Basha
  • 292
  • 2
  • 10

1 Answers1

1

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");
    }
}
Rajeev
  • 1,374
  • 1
  • 11
  • 18
  • // 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. My Comment: this is my problem, i cant seem to find a way to form that condition ,the condition is if gps is fixed or not. the mater of GPS being enabled or not is not a problem,the problem is understanding if gps is able to respond or is it searching for satellites(that is what i mean by fixed or searching) – Rubin Basha Jul 15 '13 at 14:49
  • Then I think you should look at this [answer](http://stackoverflow.com/a/6782146/430480). It is pretty much doing what you want to do. The part where he is doing this `if (hasGPSFix) { Log.i("GPS","Fix Lost (expired)"); lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10, locationListener); } hasGPSFix = false;` here you should request for both GPS & network updates. That should do it as relevant handling already seems to be there when GPS Fix has been acquired again – Rajeev Jul 15 '13 at 15:14
  • this answer was not valid from what i tried because he uses a method Global.getInstance().currentGPSLocation which is an invalid method,doesn't exist in the Global class from what I saw. An other thing is that 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. – Rubin Basha Jul 15 '13 at 19:25
  • Had difficulties in removing updates from network because the location listener is related to the class in which the location manager is implemented,not the location manager itself.I'm thinking of a solution but i will try it tomorrow at work, i'll create separate classes for each location provider and if i get locations from the gps class than with a reflection method i will call the remove updates of the network class. than after that i will call the request updates from network if gps is not giving me locations anymore. Still I dont have a clear idea how to estimate gps status as not fixed. – Rubin Basha Jul 15 '13 at 19:26
  • I don't think you need separate classes for each provider. What you need to do is to maintain separate instances of each provider and the listener of those providers. Currently I do not have access to my code, I can show you my implementation when I am with my work PC. Look for the new edit in my answer as it is big so not giving as comment. – Rajeev Jul 16 '13 at 06:34
  • Ok i understand your answer , but maybe i have deficits in some part of java and i don't know how to initialise 2 location listeners in the same class,because location listener is just implemented in the class definition and than only the methods are available,i dont know how to set a specific listener to a specific locationManager. – Rubin Basha Jul 16 '13 at 07:32
  • my biggest problem now is probably that i cant find a way how to ignore network locations when gps on , and restart listening to them when gps is not fixed. i tried creating 2 location managers , one for network and one for gps, but when i used the remove updates method , than it removed the listener itself , not the updates of a specific locationManager, nonetheless i have yet to try many things. i thank u very much for your effort,it is very pleasant to know there are many people who like to help just for the pleasure of helping someone. – Rubin Basha Jul 16 '13 at 07:37
  • Hi Rubin, sorry for late reply but I guess we are in different time zones so it can't be avoided at times. I have update my answer with **EDIT 2** where I have given my implementation of using both the location providers at the same time. You will need to enhance this to better suit your purpose. And yes, you will need to try many things, but hey, that is the fun part...isn't it? :-) – Rajeev Jul 16 '13 at 18:11
  • Yes that is the fun part :) , because when the problem is solved than i feel joy and i know that i have grown up in the professional point of view. i tried some things yesterday and it worked for me. I used 2 location listeners and it worked very good. so basically we had the same idea , it just needed some tweaks for it to fulfill my needs. thank u very much for the help. It is nice to share experience with different people all over the world. :) – Rubin Basha Jul 17 '13 at 09:00