2

I want to enable location in Google Maps Android API v2. What I want is:

  1. load the map centered on a fix latitude/longitude,.
  2. Start listening to location changes, and once a provider (network/GPS) gets the location, center the map on this location and animate it (animation shall only run once). Meanwhile, location listener updates user's location after specified amount of time,
  3. Store this location data and use it to fetch nearby places of interest via my API.

I'm kind of confused with how to get periodic updates, the amount of time interval to choose. Right now, I have set up the project to show a map and used

googleMap.setMyLocationEnabled(true);
googleMap.setOnMyLocationChangeListener(myLocationChangeListener);

private GoogleMap.OnMyLocationChangeListener myLocationChangeListener = new GoogleMap.OnMyLocationChangeListener() {
    @Override
    public void onMyLocationChange(Location location) {
        LatLng loc = new LatLng(location.getLatitude(), location.getLongitude());
        if(googleMap != null){
            if(!firstTime){
                CameraPosition cameraPosition = new CameraPosition.Builder()
                .target(loc).zoom(zoom).build();
                googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); 
                firstTime = true;
            }

            lat = location.getLatitude();
            lng = location.getLongitude();
            Toast.makeText(context, "Location is: " + String.valueOf(lat) + ", " 
                    + String.valueOf(lng), Toast.LENGTH_LONG).show();
        }
    }
};

to set lat/lng in variables. My questions are:

  1. Is this a correct approach? Or can it be made better?
  2. The location change listener updates itself quite often. I'm seeing toasts being made in a few seconds interval. How to regulate that?
  3. How to stop the listener from fetching location when the activity's gone (paused/stopped)? Thank you!
Basit
  • 1,830
  • 2
  • 31
  • 50

3 Answers3

5

For question 2 :

Use requestLocationUpdates(long minTime, float minDistance, Criteria criteria, PendingIntent intent)

First two parameters are :

Parameters minTime : minimum time interval between location updates, in milliseconds minDistance : minimum distance between location updates, in meters

           private static final long POLLING_FREQ = 1000 * 10;
           private static final float MIN_DISTANCE = 10.0f;

           // Reference to the LocationManager and LocationListener
           private LocationManager mLocationManager;
           private LocationListener mLocationListener;

           // Register for network location updates
            if (null != mLocationManager
                    .getProvider(LocationManager.NETWORK_PROVIDER)) {
                mLocationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER, POLLING_FREQ,
                        MIN_DISTANCE, mLocationListener);
            }

            // Register for GPS location updates
            if (null != mLocationManager
                    .getProvider(LocationManager.GPS_PROVIDER)) {
                mLocationManager.requestLocationUpdates(
                        LocationManager.GPS_PROVIDER, POLLING_FREQ,
                        MIN_DISTANCE, mLocationListener);
            }

You can adjust them to your own needs.

For question 3 :

Use : removeUpdates(PendingIntent intent) Removes all location updates for the specified pending intent.

As of question 1.

Your approach seems reasonable. If you need constant location updates if not then I can suggest other things to reduce battery consumption.

     mLocationListener = new LocationListener() {

    // Called back when location changes

    public void onLocationChanged(Location location) {


        // Get your location here
        // estimate

    }

    public void onStatusChanged(String provider, int status,
            Bundle extras) {
        // NA
    }

    public void onProviderEnabled(String provider) {
        // NA
    }

    public void onProviderDisabled(String provider) {
        // NA
    }
};
android_Muncher
  • 1,057
  • 7
  • 14
  • How to implement `requestLocationUpdates` in this scenario? Could you provide some code with it, please? Moreover, when do I stop listening to updates? For the scope of my application, I guess it'd be in `onPause()` and `onStop()` activity cycle events, yes? – Basit Oct 29 '14 at 17:54
  • 1
    i would do that in onPause() like you know there is no guarantee that onStop() will be called. inYour onResume() add the line that I added in my edit. – android_Muncher Oct 29 '14 at 17:56
  • Actually I was thinking about regulating the hits on my API by storing the entire Location object and compare the distance between its and current location. Could you please suggest those other things that could reduce battery consumption? (I'm fine with using network provider just so long as GPS provider isn't enabled. I'd prefer network, actually). – Basit Oct 29 '14 at 17:58
  • If you are getting frequent updates then i cant help i am sure you are aware of cached location. I am making an edit from my code example. let me know if that makes sense. – android_Muncher Oct 29 '14 at 18:02
  • Where do I get location? Is there another function I need to implement? – Basit Oct 30 '14 at 08:25
  • You dont get your location from the code you posted ? I used onlocationchanged() from locationListener interface. – android_Muncher Oct 30 '14 at 13:39
  • No, I meant how do I listen to location changes via the code you provided in the answer? – Basit Oct 30 '14 at 15:55
  • It actually did. Thank you for the help :) – Basit Oct 31 '14 at 17:14
0

To relegate how often updates are made, you pass a parameter into requestLocationUpdates. You are likely passing 0 in for the second argument, which updates as fast as possible. Pass in something more appropriate for your application (it's in milliseconds).

Overall, your approach seems fine. However it may take a bit before a location fix is found. To accommodate for that, I usually get the last known location (which might be very old and useless, but is "usually" close enough). This way the user gets an instant update:

String locationProvider = LocationManager.GPS_PROVIDER;
Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);

To stop listening for updates, in your onPause() method:

locationManager.removeUpdates(locationListener);
Greg Miller
  • 469
  • 4
  • 11
  • How can I request current location from a provider rather than using `getLastKnownLocation()`? – Basit Oct 29 '14 at 18:24
  • Why would you need to? AFAIK, that's the only method that will give you that data. – Greg Miller Oct 29 '14 at 18:26
  • Because `getLastKnownLocation` can be grossly incorrect many times. How about this: `locationManager.requestLocationUpdates(provider, 400, 1, this);` and then getting the location by overriding `onLocationChanged`? – Basit Oct 29 '14 at 18:39
  • I don't follow. getLastKnownLocation() returns the last known location, just as it says. Of course the last fix could have been a different location that where the user actually is. Are you claiming getLastKnownLocation() returns something other than the last known location at times? – Greg Miller Oct 29 '14 at 18:52
  • I'm not claiming anything. There's a fundamental difference even between the terms 'last known location' and 'current location'. What I want is the current location of user not the location Android has cached when a specific provider was enabled. – Basit Oct 29 '14 at 18:55
  • I think what you meant to say is: It does exactly what it says, exactly the way I explained it, with the exact caveat I explained. Thanks. – Greg Miller Oct 29 '14 at 18:56
  • If you'd seen the code in the original question, you'd know that I wasn't even using `requestLocationUpdates` in the first place. Secondly, maybe you should learn the difference between lastknownlocation and current location (user's location at this very moment). Thank you. – Basit Oct 29 '14 at 19:00
0

I already answered to the similar question here.How to get the current location in Google Maps Android API v2?

The point is to use GoogleApiClient due to deprecation of OnMyLocationChangeListener.

private LocationRequest  mLocationRequest;
private GoogleApiClient  mGoogleApiClient;
private LocationListener mLocationListener;

private void initGoogleApiClient(Context context)
{
    mGoogleApiClient = new GoogleApiClient.Builder(context).addApi(LocationServices.API).addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks()
    {
        @Override
        public void onConnected(Bundle bundle)
        {
            mLocationRequest = LocationRequest.create();
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            mLocationRequest.setInterval(1000);

            setLocationListener();
        }

        @Override
        public void onConnectionSuspended(int i)
        {
            Log.i("LOG_TAG", "onConnectionSuspended");
        }
    }).build();

    if (mGoogleApiClient != null)
        mGoogleApiClient.connect();

}

private void setLocationListener()
{
    mLocationListener = new LocationListener()
    {
        @Override
        public void onLocationChanged(Location location)
        {
            String lat = String.valueOf(location.getLatitude());
            String lon = String.valueOf(location.getLongitude());
            Log.i("LOG_TAG", "Latitude = " + lat + " Longitude = " + lon);
        }
    };

    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mLocationListener);
}

private void removeLocationListener()
{
    LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mLocationListener);
}

Don't forget to call mGoogleApiClient.connect(); and removeLocationListener(); methods when you finish working with Google Maps.

Ayaz Alifov
  • 8,334
  • 4
  • 61
  • 56