15

How do I move marker on Google maps api V2 ? I am using below code but it does not move marker on the map. What am I doing wrong here ? This should work when location changes, so I have added onLocationChanged method and in that, am getting location details and trying to move marker on new details, but this doesn't work.

Here is my code:

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;

import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.gson.Gson;

public class MapViewActivity extends Activity implements LocationListener,
        SensorEventListener, OnClickListener {

    GoogleMap googleMap;

    private boolean started = false;
    private ArrayList<AccelLocData> sensorData;
    private SensorManager sensorManager;
    private Button btnStart, btnStop;
    private String provider;

    // File root, dir, sensorFile;
    FileOutputStream fOut;
    private Sensor mAccelerometer;
    private FileWriter writer;
    private DatabaseHelper databaseHelper;
    private BroadcastReceiver alarmReceiver;
    private PendingIntent pendingIntentSender, pendingIntentReceiver;

    private AlarmManager alarmManager;
    private Intent alarmIntent,alarmIntent2;

    // private Button btnUpload;

    @SuppressLint("NewApi")
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {

            databaseHelper = new DatabaseHelper(this);
            databaseHelper.removeAll();


            Log.v("datacount",
                    Integer.toString(databaseHelper.getLocDataCount()));

            sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
            mAccelerometer = sensorManager
                    .getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

            btnStart = (Button) findViewById(R.id.btnStart);
            btnStop = (Button) findViewById(R.id.btnStop);
            btnStart.setOnClickListener(this);
            btnStop.setOnClickListener(this);
            btnStart.setEnabled(true);
            btnStop.setEnabled(false);

            alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

            int status = GooglePlayServicesUtil
                    .isGooglePlayServicesAvailable(getBaseContext());
            if (status != ConnectionResult.SUCCESS) { // Google Play Services
                                                        // are
                                                        // not available

                int requestCode = 10;
                Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status,
                        this, requestCode);
                dialog.show();

            } else { // Google Play Services are available

                // Getting reference to the SupportMapFragment of
                // activity_main.xml
                // SupportMapFragment supportMapFragment = (MapFragment)
                // getFragmentManager().findFragmentById(R.id.map);

                // Getting GoogleMap object from the fragment
                googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();


                // can use for overlay on the map
                List<Double> latList = new ArrayList<Double>();
                latList.add(145.7309593);
                latList.add(146.34);
                latList.add(147.34);

                List<Double> lonList = new ArrayList<Double>();
                lonList.add(-122.6365384);
                lonList.add(-123.6365384);
                lonList.add(-124.6365384);

                for (int i = 0; i < 3; i++) {
                    // LatLng latLng = new LatLng(45.7309593, -122.6365384);
                    LatLng latLng = new LatLng(latList.get(i).doubleValue(),
                            lonList.get(i).doubleValue());
                    googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                    googleMap
                            .addMarker(new MarkerOptions()
                                    .position(latLng)
                                    .title("My Spot")
                                    .snippet("This is my spot!")
                                    .icon(BitmapDescriptorFactory
                                            .defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
                }

                // Enabling MyLocation Layer of Google Map
                googleMap.setMyLocationEnabled(true);

                LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

                Criteria criteria = new Criteria();
                provider = locationManager.getBestProvider(criteria, true);
                Location location = locationManager
                        .getLastKnownLocation(provider);

                if (location != null) {
                    onLocationChanged(location);
                }

                locationManager
                        .requestLocationUpdates(provider, 20000, 0, this);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void onSensorChanged(SensorEvent event) {

        if (started) {

            double x = event.values[0];
            double y = event.values[1];
            double z = event.values[2];

            long timestamp = System.currentTimeMillis();

            LocationManager locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
            Criteria criteria = new Criteria();
            criteria.setPowerRequirement(Criteria.POWER_MEDIUM);
            criteria.setAccuracy(Criteria.ACCURACY_FINE);

            provider = locManager.getBestProvider(criteria, true);
            Location location = locManager.getLastKnownLocation(provider);

            double latitude = 0;
            double longitude = 0;
            if (location != null) {
                latitude = location.getLatitude();
                longitude = location.getLongitude();
            }
            AccelLocData accelLocData = new AccelLocData(timestamp, x, y, z,
                    latitude, longitude);

            // Log.d("X data","data x:" + data.getX());

            try {
                // writer.write(data.toString());
                 if (databaseHelper != null)
                 databaseHelper.insertLocData(accelLocData);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }

    @Override
    public void onLocationChanged(Location location) {

        TextView tvLocation = (TextView) findViewById(R.id.tv_location);

        // Getting latitude of the current location
        double latitude = location.getLatitude();

        // Getting longitude of the current location
        double longitude = location.getLongitude();

        // Creating a LatLng object for the current location
        LatLng latLng = new LatLng(latitude, longitude);

        // Showing the current location in Google Map
        googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));

        // Zoom in the Google Map
        googleMap.animateCamera(CameraUpdateFactory.zoomTo(15));






    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.btnStart:

            Context context = getApplicationContext();
            alarmIntent = new Intent(context, AccelLocSender.class);

            AlarmManager alarmManager = (AlarmManager) context
                    .getSystemService(Context.ALARM_SERVICE);
            pendingIntentSender = PendingIntent.getBroadcast(context, 0,
                    alarmIntent, 0);

            alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
                    System.currentTimeMillis(), 60000, pendingIntentSender);

            alarmIntent2 = new Intent(context, AccelLocReceiver.class);
            pendingIntentReceiver = PendingIntent.getBroadcast(context, 0,
                    alarmIntent2, 0);
            alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
                    System.currentTimeMillis(), 30000, pendingIntentReceiver);

            btnStart.setEnabled(false);
            btnStop.setEnabled(true);
            Log.d("startbutton", "cam on click of start");
            started = true;

            // delete all files..
            // start thread to send data

            sensorManager.registerListener(this, mAccelerometer,
                    SensorManager.SENSOR_DELAY_FASTEST);
            break;
        case R.id.btnStop:
            try {
                btnStart.setEnabled(true);
                btnStop.setEnabled(false);
                // btnUpload.setEnabled(true);
                started = false;

                sensorManager.unregisterListener(this);

                Context context1 = getApplicationContext();
                AlarmManager alarmManager1 = (AlarmManager) context1
                        .getSystemService(Context.ALARM_SERVICE);
                alarmManager1.cancel(pendingIntentSender);
                alarmManager1.cancel(pendingIntentReceiver);

            //  System.exit(0);

                } catch (Exception e) {
                e.printStackTrace();
            }
            break;
        default:
            break;
        }

    }

    protected void onPause() {
        super.onPause();

        /*
         * if (writer != null) { try { writer.close(); } catch (IOException e) {
         * // TODO Auto-generated catch block e.printStackTrace(); } }
         */
    }

    protected void onResume() {
        super.onResume();
        /*
         * try { Log.d("onresume","called onresume"); writer = new
         * FileWriter(sensorFile, true); } catch (IOException e) { // TODO
         * Auto-generated catch block e.printStackTrace(); }
         */
    }

    @Override
    public void onProviderDisabled(String arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onAccuracyChanged(Sensor arg0, int arg1) {
        // TODO Auto-generated method stub

    }

}
Wall-E
  • 43
  • 7
tech_enthusiast
  • 683
  • 3
  • 12
  • 37

5 Answers5

29

Make variable

 Marker now;

in this part add Marker and remove marker, of course put in the rest of your marker attributes:

 @Override
public void onLocationChanged(Location location) {

    if(now != null){
                now.remove();

            }

    TextView tvLocation = (TextView) findViewById(R.id.tv_location);

    // Getting latitude of the current location
    double latitude = location.getLatitude();

    // Getting longitude of the current location
    double longitude = location.getLongitude();

    // Creating a LatLng object for the current location
    LatLng latLng = new LatLng(latitude, longitude);
    now = googleMap.addMarker(new MarkerOptions().position(latLng)));
    // Showing the current location in Google Map
    googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));

    // Zoom in the Google Map
    googleMap.animateCamera(CameraUpdateFactory.zoomTo(15));

}
Pratik Butani
  • 60,504
  • 58
  • 273
  • 437
JRowan
  • 6,824
  • 8
  • 40
  • 59
  • 1
    Hi @JRowan , I don't know whether I put my question correctly. But I am talking about moving a marker on maps whenever I move my car on the road. One example could be like Google navigator app ( not talking about finding route) where marker would move whenever your car moves on the road. Are you talking about the same ? – tech_enthusiast May 01 '13 at 04:50
  • Hi Guys (@JRowan and @M.J , I just tested my application again. I am having problem after adding that also. So, I am doing some background processing (use alarm manager to do it) other than moving marker on map. So, if that background process is running then marker rarely moves on Maps. Can anybody help me what should I do for this problem ? – tech_enthusiast May 01 '13 at 05:23
  • maybe you should make a service for that, and then button could start and stop the service – JRowan May 01 '13 at 05:34
  • you have your updates set to 20000miliseconds thats pretty slow if thats what your talking about too – JRowan May 01 '13 at 06:13
  • then your not getting an update on location for at least every 20 seconds – JRowan May 01 '13 at 06:14
  • I am getting sensor values and location values at onSensorChanged() method. Can tht be the reason ? – tech_enthusiast May 01 '13 at 06:23
  • But I need to collect and store sensor data along with location data. How would i receive both individually ? – tech_enthusiast May 01 '13 at 06:35
  • make the variables your using inbetween the two global to the activity, and your locationManager .requestLocationUpdates(provider, 20000, 0, this); is set to update every 20 seconds, you can make that alot shorter too – JRowan May 01 '13 at 06:36
  • check if the variables are null, like i put the if(now != null) in your sensor too so you dont get a null pointer exception just incase the sensorchanged is trying to use information that the location update hasnt gotten yet – JRowan May 01 '13 at 06:38
  • no, i think your sensorchanged already is seperate from you locationlistener, the slowness was 20000 in you requestlocationupdates – JRowan May 01 '13 at 06:44
  • yea, I also thought the same. Now I am changing sensorManager.registerListener(this,mAccelerometer,SensorManager.SENSOR_DELAY_FASTEST); to sensorManager.registerListener(this,mAccelerometer,SensorManager.SENSOR_DELAY_UI); and Also updating the requestlocationupdates to 6000. I will test it now and will update status here. – tech_enthusiast May 01 '13 at 07:01
  • Hi @JRowan, the above changes I told at least made my application faster. I still have to check if my marker is moving or not, but can only go out in morning. It's 3 a.m. here, so can't go .. But other than this, I have a question that how would I update overlays on the map ? I mean for V1 api , there was ItemizedOverlay, for V2, what should I use ? – tech_enthusiast May 01 '13 at 10:17
  • im not really sure, i updated mine and made everything with markers, i never used lines or any of that for overlays, but there is a bunch of classes that you can use, i was out, im going back out, might be a while – JRowan May 01 '13 at 11:59
  • 5
    @JRowan instead of removing and readding the marker, you may use Marker.setPoisition(LatLng) – MaciejGórski May 01 '13 at 15:00
  • I have done exactly the same but still it doesn't move can you please see my [question](http://stackoverflow.com/q/42576534/6854117) ? – Moeez Mar 03 '17 at 13:16
6

Make the marker draggable using,

  MarkerOptions markerOptions = new MarkerOptions().position(myLaLn).title(
            "Current Location").draggable(true);
    map.addMarker(markerOptions);

& Get the dragged position & details as follows,

map.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() {

        @Override
        public void onMarkerDragStart(Marker marker) {
        }

        @Override
        public void onMarkerDragEnd(Marker marker) {
            Log.d(TAG, "latitude : "+ marker.getPosition().latitude);
            marker.setSnippet(marker.getPosition().latitude);
            map.animateCamera(CameraUpdateFactory.newLatLng(marker.getPosition()));

        }

        @Override
        public void onMarkerDrag(Marker marker) {
        }

    });
Randula
  • 1,537
  • 15
  • 11
6

Optimized way to move marker :

marker mMarker;

After adding marker to map. while change the location you just need to set position rather than remove marker and add again.

mMarker.setPosition(new LatLon(latLng));

this will reduce the code from remove and add marker to direct set position and also reduce complexity. :)

Enjoy.

PrinceMidha
  • 321
  • 3
  • 5
  • I have done exactly the same but still it doesn't move can you please see my [question](http://stackoverflow.com/q/42576534/6854117) ? – Moeez Mar 03 '17 at 13:15
5

You are just moving camera on location change where as you should add marker as well then it will draw marker on current location. and before adding marker clear all the previous markers by calling googlmap.clear();

M.J
  • 586
  • 6
  • 16
2

addMarker returns a reference to the marker which then later can be updated

mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                if(mMarker == null) {
                    mMarker = mMap.addMarker(new MarkerOptions().position(latLng));
                } else {
                    mMarker.setPosition(latLng);
                }
            }
        });
Fernando Gallego
  • 4,064
  • 31
  • 50
  • I have done almost the same but still it doesn't move can you please see my [question](http://stackoverflow.com/q/42576534/6854117) ? – Moeez Mar 03 '17 at 13:15
  • Thanks dude! @faisal1208 just put `mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(myCurrentLocation, 20));` on each verification! –  May 09 '17 at 04:57