Salman Khan
Salman Khan

Reputation: 2832

Drag and Drop pin on google map manually and get Longitude & Latitude accordingly

In Google Maps, I'm dropping a pin on user's current location but now I want to give another functionality to user that he can drag that pin manually and drop anywhere on the map, also by the time he drops the pin manually I can receive a callback which gives me the Longitude and Latitude of that position where user drops that pin.

If you can give me some examples it will be greatly appreciable.

Upvotes: 4

Views: 5704

Answers (3)

Marialena
Marialena

Reputation: 817

In the last few days I finally found how to implement those functions you described and because there was no answer in this question, I decided to post what I found even though there has been a long time since you asked and you may found another answer by yourself.

So, I used the code of this git. I managed to do all that you want except the callback that I didn't try it in that way. I am getting the position of the pin after pressing a button.


There is no need to post my AndroidManifest because I read that you had no problem with displaying your location, so the permissions needed were fine.


The only thing that was required to do, was to create an activity named MapsActivity. This is the whole content of it:

import com.google.android.gms.maps.*;
import com.google.android.gms.maps.model.*;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;

import common.logger.Log;

public class MapsActivity extends Activity implements
        OnMapReadyCallback, GoogleMap.OnInfoWindowClickListener,
        GoogleMap.OnMarkerDragListener {

    LatLng position = new LatLng(34.6767, 33.04455);
    final Marker marker_final = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);

        MapFragment mapFragment = (MapFragment) getFragmentManager()
                .findFragmentById(R.id.
                        map);
        mapFragment.getMapAsync(this);

        ImageButton returnback = (ImageButton)findViewById(R.id.returnback);
        returnback.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                    Toast.makeText(MapsActivity.this.getApplicationContext(), position.latitude + ":"  + position.longitude, Toast.LENGTH_LONG).show();
            }
        });


    }

    @Override
    public void onMapReady(GoogleMap map) {


        map.setMyLocationEnabled(true);
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(position, 13));
        CameraUpdate zoom = CameraUpdateFactory.zoomTo(15);
        map.animateCamera(zoom);

        map.addMarker(new MarkerOptions()
                .title("Shop")
                .snippet("Is this the right location?")
                .position(position))
                .setDraggable(true);

       // map.setInfoWindowAdapter(new PopupAdapter(getLayoutInflater()));
        map.setOnInfoWindowClickListener(this);
        map.setOnMarkerDragListener(this);
    }

    @Override
    public void onInfoWindowClick(Marker marker) {
        Toast.makeText(this, marker.getTitle(), Toast.LENGTH_LONG).show();
    }

    @Override
    public void onMarkerDragStart(Marker marker) {
        LatLng position0 = marker.getPosition();

        Log.d(getClass().getSimpleName(), String.format("Drag from %f:%f",
                position0.latitude,
                position0.longitude));
    }

    @Override
    public void onMarkerDrag(Marker marker) {
        LatLng position0 = marker.getPosition();

        Log.d(getClass().getSimpleName(),
                String.format("Dragging to %f:%f", position0.latitude,
                        position0.longitude));

    }

    @Override
    public void onMarkerDragEnd(Marker marker) {
        position = marker.getPosition();

        Log.d(getClass().getSimpleName(), String.format("Dragged to %f:%f",
                position.latitude,
                position.longitude));
    }
}

This is my activity_maps.xml layout (I've also added an edit text, but there is no need to use it):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:descendantFocusability="beforeDescendants"
    android:focusableInTouchMode="true"
    android:background="#ecf0f1">

    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/scrollView3" >

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent">

            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="fill_parent"
                android:weightSum="1"
                android:layout_height="wrap_content">

                <EditText
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="0.9"
                    android:id="@+id/locationsearch" />

                <ImageButton
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:id="@+id/search"
                    android:layout_weight="0.1"
                    android:background="@drawable/search" />

            </LinearLayout>

            <fragment xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/map"
            android:layout_width="match_parent"
            android:layout_height="405dp"
            android:name="com.google.android.gms.maps.MapFragment"/>

            <ImageButton
                android:layout_width="60dp"
                android:layout_height="60dp"
                android:id="@+id/returnback"
                android:background="@drawable/less" />
        </LinearLayout>
    </ScrollView>

</LinearLayout>

Upvotes: 3

itsrajesh4uguys
itsrajesh4uguys

Reputation: 4638

Hi Use the below code.

you will get the dropped pin position.

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;



import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.OverlayItem;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;

import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;

import android.os.AsyncTask;
import android.os.Bundle;

import android.view.MotionEvent;
import android.view.View;

import android.widget.ImageView;

import android.widget.RelativeLayout;

import android.widget.Toast;


public class rescue extends MapActivity {


    private LocationManager myLocationManager;
    private LocationListener myLocationListener;

    private MapView myMapView;
    private MapController myMapController;
    private String provider;
    private MyLocationOverlay me=null;


    private int defaultLat =(int)(51.51216124955517); 
    private int defaultLong =(int)(-0.1373291015625);

    private GeoPoint defaultGeoPint = new GeoPoint(defaultLat,defaultLong);






    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.rescue);

        setCurrentLocation();

    }


    @Override
    protected boolean isRouteDisplayed() {
        // TODO Auto-generated method stub
        return false;
    }











    private void setCurrentLocation()
    {
      myMapView = (MapView)findViewById(R.id.rescueMapView);
      myMapView.setTraffic(true);
      ///myMapView.setBuiltInZoomControls(true);

      myMapController = myMapView.getController();
      myMapController.setZoom(16); //Fixed Zoom Level


      myLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
      myLocationListener = new MyLocationListener();

      try
      {
      Criteria criteria = new Criteria();
      provider = myLocationManager.getBestProvider(criteria, false);

      Location location = myLocationManager.getLastKnownLocation(provider);

      myLocationManager.requestLocationUpdates(
              provider,
        0,
        0,
        myLocationListener);

      Location lastLocation = myLocationManager.getLastKnownLocation(provider); 

          if(lastLocation != null)
          {
              int lastLocLat =(int)(lastLocation.getLatitude()*1000000); 
              int lastLocLong =(int)(lastLocation.getLongitude()*1000000);
              //Get the current location in start-up
              GeoPoint initGeoPoint = new GeoPoint(lastLocLat,lastLocLong);
              CenterLocatio(initGeoPoint);
          }
          else
          {
              AlertDialog.Builder builder = new AlertDialog.Builder(this);
              builder.setTitle("Location Services Disabled")
                     .setMessage("The location service on the device are disabled, your location is not able to be found, please call AXA uding the button below to be rescued")
                     .setCancelable(false)
                     .setPositiveButton("Drop pin", new DialogInterface.OnClickListener() {
                         public void onClick(DialogInterface dialog, int id) {
                              //do things
                             CenterLocatio(defaultGeoPint);
                         }
                     });
              builder.create().show();


          }
      }
      catch (Exception e) 
      {
        // TODO: handle exception


            Context context = getApplicationContext();
            String toasttext = e.getMessage();
            int duration = Toast.LENGTH_SHORT;

            Toast toast = Toast.makeText(context, toasttext, duration);
            toast.show();


      }






    }

    private void CenterLocatio(GeoPoint centerGeoPoint)
     {
        myMapView.getOverlays().clear();
      myMapController.animateTo(centerGeoPoint);



      Drawable marker=getResources().getDrawable(R.drawable.marker);

        marker.setBounds(0, 0, marker.getIntrinsicWidth(),
                                marker.getIntrinsicHeight());

        int lat = centerGeoPoint.getLatitudeE6();
        int lon = centerGeoPoint.getLongitudeE6();

        double lat1 = centerGeoPoint.getLatitudeE6()/1E6;

        double lon1 = centerGeoPoint.getLongitudeE6()/1E6;

        ArrayList<Double> passing = new ArrayList<Double>();
        passing.add(lat1);
        passing.add(lon1);

        Context context = getApplicationContext(); 
        ReverseGeocodeLookupTask task = new ReverseGeocodeLookupTask();
        task.applicationContext = context;
        task.activityContext = rescue.this; 
        task.execute(passing);

        myMapView.getOverlays().add(new SitesOverlay(marker,lat, lon ));

        me=new MyLocationOverlay(this, myMapView);
        myMapView.getOverlays().add(me);

     };

     private class MyLocationListener implements LocationListener{

         @Override
          public void onLocationChanged(Location argLocation) {
           // TODO Auto-generated method stub
           GeoPoint myGeoPoint = new GeoPoint(
            (int)(argLocation.getLatitude()*1000000),
            (int)(argLocation.getLongitude()*1000000));

           //CenterLocatio(myGeoPoint);
          }

          public void onProviderDisabled(String provider) {
           // TODO Auto-generated method stub
          }

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

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



         }


     private GeoPoint getPoint(int lat, int lon) {

         return(new GeoPoint(lat, lon));

         /*
            return(new GeoPoint((int)(lat*1000000.0),
                                  (int)(lon*1000000.0)));
                               */
          }


      private class SitesOverlay extends ItemizedOverlay<OverlayItem> {
            private List<OverlayItem> items=new ArrayList<OverlayItem>();
            private Drawable marker=null;
            private OverlayItem inDrag=null;
            private ImageView dragImage=null;
            private int xDragImageOffset=0;
            private int yDragImageOffset=0;
            private int xDragTouchOffset=0;
            private int yDragTouchOffset=0;

            public SitesOverlay(Drawable marker, int lat, int longitude) {
              super(marker);
              this.marker=marker;

              dragImage=(ImageView)findViewById(R.id.drag);
              xDragImageOffset=dragImage.getDrawable().getIntrinsicWidth()/2;
              yDragImageOffset=dragImage.getDrawable().getIntrinsicHeight();

              items.add(new OverlayItem(getPoint(lat,
                                                  longitude),
                                        "UN", "United Nations"));

              /*
              items.add(new OverlayItem(getPoint(40.76866299974387,
                                                  -73.98268461227417),
                                        "Lincoln Center",
                                        "Home of Jazz at Lincoln Center"));
               */
              populate();
            }

            @Override
            protected OverlayItem createItem(int i) {
              return(items.get(i));
            }

            @Override
            public void draw(Canvas canvas, MapView mapView,
                              boolean shadow) {
              super.draw(canvas, mapView, shadow);

              boundCenterBottom(marker);
            }

            @Override
            public int size() {
              return(items.size());
            }

            @Override
            public boolean onTouchEvent(MotionEvent event, MapView mapView) {
              final int action=event.getAction();
              final int x=(int)event.getX();
              final int y=(int)event.getY();
              boolean result=false;

              if (action==MotionEvent.ACTION_DOWN) {
                for (OverlayItem item : items) {
                  Point p=new Point(0,0);

                  myMapView.getProjection().toPixels(item.getPoint(), p);

                  if (hitTest(item, marker, x-p.x, y-p.y)) {
                    result=true;
                    inDrag=item;
                    items.remove(inDrag);
                    populate();

                    xDragTouchOffset=0;
                    yDragTouchOffset=0;

                    setDragImagePosition(p.x, p.y);
                    dragImage.setVisibility(View.VISIBLE);

                    xDragTouchOffset=x-p.x;
                    yDragTouchOffset=y-p.y;

                    break;
                  }
                }
              }
              else if (action==MotionEvent.ACTION_MOVE && inDrag!=null) {
                setDragImagePosition(x, y);
                result=true;
              }
              else if (action==MotionEvent.ACTION_UP && inDrag!=null) {
                dragImage.setVisibility(View.GONE);

                GeoPoint pt=myMapView.getProjection().fromPixels(x-xDragTouchOffset,
                                                           y-yDragTouchOffset);


                String title = inDrag.getTitle();
                OverlayItem toDrop=new OverlayItem(pt, title,
                                                   inDrag.getSnippet());



                items.add(toDrop);
                populate();










                double lat = pt.getLatitudeE6()/1E6;

                double lon = pt.getLongitudeE6()/1E6;

                ArrayList<Double> passing = new ArrayList<Double>();
                passing.add(lat);
                passing.add(lon);

                Context context = getApplicationContext(); 
                ReverseGeocodeLookupTask task = new ReverseGeocodeLookupTask();
                task.applicationContext = context;
                task.activityContext = rescue.this; 
                task.execute(passing);

                //CenterLocatio(pt);



                inDrag=null;
                result=true;
              }

              return(result || super.onTouchEvent(event, mapView));
            }

            private void setDragImagePosition(int x, int y) {
              RelativeLayout.LayoutParams lp=
                (RelativeLayout.LayoutParams)dragImage.getLayoutParams();

              lp.setMargins(x-xDragImageOffset-xDragTouchOffset,
                              y-yDragImageOffset-yDragTouchOffset, 0, 0);
              dragImage.setLayoutParams(lp);
            }
          }

      public class ReverseGeocodeLookupTask extends AsyncTask <ArrayList<Double>, Void, String>
        {
            private ProgressDialog dialog;
            protected Context applicationContext;
            protected Context activityContext;

            @Override
            protected void onPreExecute()
            {
                this.dialog = ProgressDialog.show(activityContext, "Please wait", 
                        "Requesting location", true);
            }


            protected String doInBackground(ArrayList<Double>... params) 
            {


                String foundAddress = "";
                String localityName = "";
                ArrayList<Double> passed = params[0];
                double lat = passed.get(0);
                double lon = passed.get(1);
                try
                {

                List<Address> addresses = new Geocoder(applicationContext,Locale.getDefault()).getFromLocation(lat,lon, 1);
                if (addresses.size() > 0)
                {
                    String addressLine = "";

                    for(Integer i = 0; i < addresses.get(0).getMaxAddressLineIndex(); i++)
                    {
                        if(!addressLine.equals(""))
                        {
                            addressLine+= ", ";
                        }

                        addressLine+=  addresses.get(0).getAddressLine(i);
                    }

                    if(addressLine!="")
                    {
                        foundAddress+= addressLine;
                    }


                }


                }
                catch (Exception e) {
                    // TODO: handle exception

                }
                finally
                {

                }



                return foundAddress;
            }

            @Override
            protected void onPostExecute(String result)
            {
                this.dialog.cancel();
                showToast(result);

            }
        }



      public void showToast(String message)
        {
            Context context = getApplicationContext();
            String toasttext = message;
            int duration = Toast.LENGTH_SHORT;

            Toast toast = Toast.makeText(context, toasttext, duration);
            toast.show();
        }

}

Use below permission in manifest file

 <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
         <uses-library android:name="com.google.android.maps" />
        <activity
            android:label="@string/app_name"
            android:name=".DragAndDropPinActivity" >

        </activity>


            <activity
            android:label="@string/app_name"
            android:name=".rescue" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

Upvotes: 0

Abhi
Abhi

Reputation: 9005

Refer Below links where you can find samples from Commons guy

Sample

SO question

Upvotes: 0

Related Questions