2

I have a problem with google maps api. What I want to do is to move the camera along with the Location so the blue indicator always is in center.

Thought that a good place to put code is in the OnLocationChanged method but that was not the case.

I tried to run this code there:

LatLng latlng = new LatLng(mLastLocation.getLatitude(),mLastLocation.getLongitude());
    CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latlng,17);
    mMap.animateCamera(cameraUpdate);

UPDATE

So i can not do this then?

@Override
public void onLocationChanged(Location location) {
mLocationRequest = LocationRequest.create()
        .setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)
        .setInterval(10 * 1000)
        .setFastestInterval(1 * 1000);

    LatLng latLng = new LatLng(location.getLatitude(),location.getLongitude());
    CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(latLng)
            .zoom(ZOOM)
            .bearing(0)
            .tilt(0)
            .build();
    mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
codemoonger
  • 613
  • 3
  • 11
  • 22
  • Here is the solution from another thread: http://stackoverflow.com/questions/13742551/how-to-get-my-location-changed-event-with-google-maps-android-api-v2 – Pablo Baxter Apr 26 '16 at 21:41
  • Why cant I just add the following to OnLocationChanged event.:: @Override public void onLocationChanged(Location location) { mLocationRequest = LocationRequest.create() .setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY) .setInterval(10 * 1000) .setFastestInterval(1 * 1000); mMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(location.getLatitude(), location.getLongitude()))); } – codemoonger Apr 27 '16 at 16:17
  • The blue indicator location request is implemented by the map, which can give out different points at different time intervals than your location request. AFAIK, there is no way to listen to the default location provider used by the map, which you'll need to smoothly update the map camera position. – Pablo Baxter Apr 27 '16 at 16:28
  • Ok so I cant do as shown in my code under the my update @PabloBaxter – codemoonger Apr 27 '16 at 16:59

1 Answers1

2

The code will work to update your camera position, but will not center the Google Map blue indicator precisely. This is because the blue dot is listening to a different locationRequest than the one you are creating in the code snippet (which doesn't seem to be doing anything). The following code snippet is from here

/* Our custom LocationSource. 
 * We register this class to receive location updates from the Location Manager
 * and for that reason we need to also implement the LocationListener interface. */
private class FollowMeLocationSource implements LocationSource, LocationListener {

    private OnLocationChangedListener mListener;
    private LocationManager locationManager;
    private final Criteria criteria = new Criteria();
    private String bestAvailableProvider;
    /* Updates are restricted to one every 10 seconds, and only when
     * movement of more than 10 meters has been detected.*/
    private final int minTime = 10000;     // minimum time interval between location updates, in milliseconds
    private final int minDistance = 10;    // minimum distance between location updates, in meters

    private FollowMeLocationSource() {
        // Get reference to Location Manager
        locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);

        // Specify Location Provider criteria
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        criteria.setPowerRequirement(Criteria.POWER_LOW);
        criteria.setAltitudeRequired(true);
        criteria.setBearingRequired(true);
        criteria.setSpeedRequired(true);
        criteria.setCostAllowed(true);
    }

    private void getBestAvailableProvider() {
        /* The preferred way of specifying the location provider (e.g. GPS, NETWORK) to use 
         * is to ask the Location Manager for the one that best satisfies our criteria.
         * By passing the 'true' boolean we ask for the best available (enabled) provider. */
        bestAvailableProvider = locationManager.getBestProvider(criteria, true);
    }

    /* Activates this provider. This provider will notify the supplied listener
     * periodically, until you call deactivate().
     * This method is automatically invoked by enabling my-location layer. */
    @Override
    public void activate(OnLocationChangedListener listener) {
        // We need to keep a reference to my-location layer's listener so we can push forward
        // location updates to it when we receive them from Location Manager.
        mListener = listener;

        // Request location updates from Location Manager
        if (bestAvailableProvider != null) {
            locationManager.requestLocationUpdates(bestAvailableProvider, minTime, minDistance, this);
        } else {
            // (Display a message/dialog) No Location Providers currently available.
        }
    }

    /* Deactivates this provider.
     * This method is automatically invoked by disabling my-location layer. */
    @Override
    public void deactivate() {
        // Remove location updates from Location Manager
        locationManager.removeUpdates(this);

        mListener = null;
    }

    @Override
    public void onLocationChanged(Location location) {
        /* Push location updates to the registered listener..
         * (this ensures that my-location layer will set the blue dot at the new/received location) */
        if (mListener != null) {
            mListener.onLocationChanged(location);
        }

        /* ..and Animate camera to center on that location !
         * (the reason for we created this custom Location Source !) */
        mMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(location.getLatitude(), location.getLongitude())));
    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {

    }

    @Override
    public void onProviderEnabled(String s) {

    }

    @Override
    public void onProviderDisabled(String s) {

    }
}

Now, in your onMapReady(GoogleMap) callback, put this in:

public void onMapReady(GoogleMap map){
    mMap = map;
    FollowMeLocationSource locationSource = new FollowMeLocationSource();
    locationSource.getBestAvailableProvider();
    mMap.setLocationSource(locationSource);
    mMap.setMyLocationEnabled(true);
}

Modify this example as you need, but this should get you the functionality you are looking for.

Community
  • 1
  • 1
Pablo Baxter
  • 2,144
  • 1
  • 17
  • 36
  • I will try this. Because as for now my code does not do anything as you say. Camera is not moving at all. – codemoonger Apr 27 '16 at 18:11
  • I have tested the code and I am getting error "java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference" at this row "locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);" @PabloBaxter – codemoonger Apr 27 '16 at 18:50
  • Are you assigning mContext to whatever context holds your map? – Pablo Baxter Apr 27 '16 at 19:01
  • mContext is there. But now when I tested if the OnLocationChanged was called it is never called. – codemoonger Apr 27 '16 at 19:04
  • Put a log statement, and check if "activate()" gets called. Also, check if you have Location enabled on the phone too. – Pablo Baxter Apr 27 '16 at 19:26
  • First i added the code in my MainActivity.class. But now I have rewritten it and added it to my MainActivity.class. Here you can checkout my code at: [pastebin.com](http://pastebin.com/9y5SYPnG) Now i getting error: ".MainActivity() is not accessible from class android.app.Instrumentation" – codemoonger Apr 27 '16 at 20:39
  • Change this code MainActivity locationSource = new MainActivity(); locationSource.getBestAvailableProvider(); mMap.setLocationSource(locationSource); to this getBestAvailableProvider(); mMap.setLocationSource(this); However you may want to abstract a lot of these interfaces to their own class. – Pablo Baxter Apr 27 '16 at 21:18