45

Today, looking back at my old code, I've found out that OnCameraChangeListener() is now deprecated.

I'm finding difficult to understand how to fix this piece of code of mine:

mGoogleMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
    @Override
    public void onCameraChange(CameraPosition cameraPosition) {
        // Cleaning all the markers.
        if (mGoogleMap != null) {
            mGoogleMap.clear();
        }

        mPosition = cameraPosition.target;
        mZoom = cameraPosition.zoom;

        if (mTimerIsRunning) {
            mDragTimer.cancel();
        }

        mDragTimer.start();
        mTimerIsRunning = true;
    }
});

The new listener (aka OnCameraMoveListener()) method onCameraMove() doesn't have a CameraPosition cameraPosition input variable, so I'm pretty lost: is there a way to recycle my old code?

Here are some references.

Adinia
  • 3,722
  • 5
  • 40
  • 58
Davide3i
  • 1,035
  • 3
  • 15
  • 35

5 Answers5

74

In play-services-maps 9.4.0 version of the API, They replaced GoogleMap.OnCameraChangeListener() with three camera listeners :

  • GoogleMap.OnCameraMoveStartedListener
  • GoogleMap.OnCameraMoveListener
  • GoogleMap.OnCameraIdleListener

Based on your code, I think you need to use GoogleMap.OnCameraIdleListener and GoogleMap.OnCameraMoveStartedListener like this:

mGoogleMap.setOnCameraMoveStartedListener(new GoogleMap.OnCameraMoveStartedListener() {
            @Override
            public void onCameraMoveStarted(int i) {
                mDragTimer.start();
                mTimerIsRunning = true;
            }
        });

        mGoogleMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
            @Override
            public void onCameraIdle() {
                // Cleaning all the markers.
                if (mGoogleMap != null) {
                    mGoogleMap.clear();
                }

                mPosition = mGoogleMap.getCameraPosition().target;
                mZoom = mGoogleMap.getCameraPosition().zoom;

                if (mTimerIsRunning) {
                    mDragTimer.cancel();
                }

            }
        });
Bronx
  • 4,480
  • 4
  • 34
  • 44
Barrak90
  • 756
  • 5
  • 5
  • I'm calling an api on `setOnCameraIdleListener` and It plots markers in the map, but when I click on the `marker`, the `setOnCameraIdleListener` is again called, what to do? – Rohit Khatri Sep 04 '17 at 18:08
  • @RohitKhatri, you should call `googleMap.setOnCameraIdleListener(null)` at the end of that listener. – CoolMind Dec 19 '18 at 12:07
32

In the new model for camera change events, you are correct that the CameraPosition is not passed into the listener.

Instead, you should just use getCameraPosition() whenever you specifically need it (i.e., when the move starts, mid-move, canceled, or finished/returned to idle).

ianhanniballake
  • 191,609
  • 30
  • 470
  • 443
  • Which would be easy enough - if getCameraPosition would not allocate memory and cause my app to stutter when simply calling getCameraPosition on every callback due to gc runs. :/ – Matthias Schicker Sep 19 '16 at 15:47
  • 1
    @MatthiasSchicker - feel free to [file an issue against the Maps SDK](https://code.google.com/p/gmaps-api-issues/) – ianhanniballake Sep 19 '16 at 16:12
  • It actually was a known issue with the Google Maps SDK (https://code.google.com/p/gmaps-api-issues/issues/detail?id=6483) but it seems to be fixed now. Sorry, wasn't up-to-date. – Matthias Schicker Sep 20 '16 at 12:31
10

onnCameraChangeListener() is deprecated now, you can use

mMap.setOnCameraMoveStartedListener { reason: Int ->
            when (reason) {
                GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE -> {
                    Log.d("camera", "The user gestured on the map.")
                }
                GoogleMap.OnCameraMoveStartedListener
                        .REASON_API_ANIMATION -> {
                    Log.d("camera", "The user tapped something on the map.")
                }
                GoogleMap.OnCameraMoveStartedListener
                        .REASON_DEVELOPER_ANIMATION -> {
                    Log.d("camera", "The app moved the camera.")
                }
            }
        }

mMap.setOnCameraIdleListener {
    val midLatLng: LatLng = mMap.cameraPosition.target//map's center position latitude & longitude
        }

mMap.setOnCameraMoveStartedListener {

        }

Here mMap is GoogleMap object and I am calling it inside

override fun onMapReady(map: GoogleMap?) {
        mMap = map as GoogleMap
        //your stuff
    }
Kishan Solanki
  • 13,761
  • 4
  • 85
  • 82
5

It is advisable to use newly introduced four camera listeners (OnCameraIdleListener, OnCameraMoveListener, OnCameraMoveStartedListener,OnCameraMoveCanceledListener), but if you still want to go with setOnCameraChangeListener use specific version of android-maps-utils(Given below)

compile 'com.google.maps.android:android-maps-utils:0.4.3'

in your module level gradle file.

Pravin Divraniya
  • 4,223
  • 2
  • 32
  • 49
2

use mGoogleMap.setOnCameraIdleListener instead of mGoogleMap.setOnCameraChangeListener.

mGoogleMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
            @Override
            public void onCameraIdle() {
                 mPosition = mGoogleMap.getCameraPosition().target;
                 mZoom = mGoogleMap.getCameraPosition().zoom;

                double lat =  mGoogleMap.getCameraPosition().target.latitude;
                double lng =  mGoogleMap.getCameraPosition().target.longitude;


           }
        });
santhosh rb
  • 157
  • 2
  • 8