Currently doing a simple app that contain google map. and i would like to link to next activity when the user click on a designed coordinate but it is not working and there is no error, please help me
double latitude = 1.34503109;
double longitude = 103.94008398;
LatLng latLng = new LatLng(latitude, longitude);
gMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng latLng) {
Intent i = new Intent(Activity_Selecting_Bus.this,
Activity_Bus_Selected.class);
startActivity(i);
}
});
If I understand correctly you have markers set up in your map and when user clicks on a marker you start another activity. The following code should work (in SupportMapFragment):
getMap().setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
// do the thing!
return true;
}
});
If you don't have markers and want to listen for a certain location click use this instead:
getMap().setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng latLng) {
// do the thing!
}
});
In this case you probably want to start the activity when the user clicks "close enough" to a certain location. I use this library http://googlemaps.github.io/android-maps-utils/ which contains method
SphericalUtil.computeDistanceBetween(LatLng from, LatLng to)
which returns distance between two LatLngs in meters.
EDIT Example:
First you define where the user has to click and which activity does that particular click launch:
private static final HashMap<LatLng, Class<? extends Activity>> sTargets = new HashMap();
static {
sTargets.put(new LatLng(34.0204989,-118.4117325), LosAngelesActivity.class);
sTargets.put(new LatLng(42.755942,-75.8092041), NewYorkActivity.class);
sTargets.put(new LatLng(42.352711,-83.099205), DetroitActivity.class);
}
private static final int RANGE_METERS = 200 * 1000; // 200 km range
Then when the user clicks on the map, you compute distance to each point. If it fits, you launch the activity.
getMap().setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng input) {
for(Map.Entry<LatLng,<? extends Activity>> entry : sTargets.entrySet()) {
LatLng ll = entry.getKey();
boolean inRange = SphericalUtil.computeDistanceBetween(input, ll) < RANGE_METERS;
if (inRange) {
Class<? extends Activity> cls = entry.getValue();
Intent i = new Intent(getActivity(), cls);
getActivity().startActivity(i);
break; // stop calculating after first result
}
}
}
});
Related
I would like to implement multiple polygons with an editable using a drag listener. I am able to draw the multiple polygons but I don't know how to make editable.
I am able to move marker for current polygon but when I try to move previous polygon’s marker app is crash. I tried with saving polygon list but I can not able to drag the marker.
please see my code HERE.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (readyToGo()) {
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
if (savedInstanceState == null) {
mapFragment.getMapAsync(this);
}
mapFragment.getMapAsync(this);
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
CameraUpdate center =
CameraUpdateFactory.newLatLng(new LatLng(40.76793169992044,
-73.98180484771729));
CameraUpdate zoom = CameraUpdateFactory.zoomTo(15);
mMap.moveCamera(center);
mMap.animateCamera(zoom);
mMap.setIndoorEnabled(false);
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng latLng) {
Marker marker = mMap.addMarker(new MarkerOptions().position(latLng).draggable(true));
marker.setTag(latLng);
markerList.add(marker);
points.add(latLng);
drawPolygon(points);
}
});
mMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() {
#Override
public void onMarkerDragStart(Marker marker) {
}
#Override
public void onMarkerDrag(Marker marker) {
updateMarkerLocation(marker, false);
}
#Override
public void onMarkerDragEnd(Marker marker) {
updateMarkerLocation(marker, true);
}
});
}
public void closePolygon(View view) {
}
public void newPolygon(View view) {
//
points.clear();
markerList.clear();
polygon = null;
// mMap.clear();
}
private void updateMarkerLocation(Marker marker, boolean calculate) {
LatLng latLng = (LatLng) marker.getTag();
int position = points.indexOf(latLng);
points.set(position, marker.getPosition());
marker.setTag(marker.getPosition());
drawPolygon(points);
}
private void drawPolygon(List<LatLng> latLngList) {
if (polygon != null) {
polygon.remove();
}
polygonOptions = new PolygonOptions();
polygonOptions.addAll(latLngList);
polygon = mMap.addPolygon(polygonOptions);
}
}
Basically this approach keeps the markers and points as collections associated with each polygon. It simplifies things by assuming after 5 markers a new polygon is created (equivalent to an add polygon).
UPDATED: To use the "new polygon" button as defined in the layout in github. Button listener just sets a flag and instead of using a size=5 check replace the check with the flag.
A map from any marker to its corresponding list is maintained for use in the updateMarkerLocation method.
All of this is predicated on the fact that any marker has a unique id provided by the map API getId() which in practice is a string like "m7".
I've listed the parts updated:
// Map a marker id to its corresponding list (represented by the root marker id)
HashMap<String,String> markerToList = new HashMap<>();
// A list of markers for each polygon (designated by the marker root).
HashMap<String,List<Marker>> polygonMarkers = new HashMap<>();
// A list of polygon points for each polygon (designed by the marker root).
HashMap<String,List<LatLng>> polygonPoints = new HashMap<>();
// List of polygons (designated by marker root).
HashMap<String,Polygon> polygons = new HashMap<>();
// The active polygon (designated by marker root) - polygon added to.
String markerListKey;
// Flag used to record when the 'New Polygon' button is pressed. Next map
// click starts a new polygon.
boolean newPolygon = false;
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
CameraUpdate center =
CameraUpdateFactory.newLatLng(new LatLng(40.76793169992044,
-73.98180484771729));
CameraUpdate zoom = CameraUpdateFactory.zoomTo(15);
mMap.moveCamera(center);
mMap.animateCamera(zoom);
mMap.setIndoorEnabled(false);
Button b = findViewById(R.id.bt_new_polygon);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
newPolygon = true;
}
});
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng latLng) {
Marker marker = mMap.addMarker(new MarkerOptions().position(latLng).draggable(true));
marker.setTag(latLng);
// Special case for very first marker.
if (polygonMarkers.size() == 0) {
polygonMarkers.put(marker.getId(),new ArrayList<Marker>());
// only 0 or 1 polygons so just add it to new one or existing one.
markerList = new ArrayList<>();
points = new ArrayList<>();
polygonMarkers.put(marker.getId(),markerList);
polygonPoints.put(marker.getId(),points);
markerListKey = marker.getId();
}
if (newPolygon) {
newPolygon = false;
markerList = new ArrayList<>();
points = new ArrayList<>();
polygonMarkers.put(marker.getId(),markerList);
polygonPoints.put(marker.getId(),points);
markerListKey = marker.getId();
}
markerList.add(marker);
points.add(latLng);
markerToList.put(marker.getId(),markerListKey);
drawPolygon(markerListKey, points);
}
});
private void updateMarkerLocation(Marker marker, boolean calculate) {
// Use the marker to figure out which polygon list to use...
List<LatLng> pts = polygonPoints.get(markerToList.get(marker.getId()));
// This is much the same except use the retrieved point list.
LatLng latLng = (LatLng) marker.getTag();
int position = pts.indexOf(latLng);
pts.set(position, marker.getPosition());
marker.setTag(marker.getPosition());
drawPolygon(markerToList.get(marker.getId()),pts);
}
private void drawPolygon(String mKey, List<LatLng> latLngList) {
// Use the existing polygon (if any) for the root marker.
Polygon polygon = polygons.get(mKey);
if (polygon != null) {
polygon.remove();
}
polygonOptions = new PolygonOptions();
polygonOptions.addAll(latLngList);
polygon = mMap.addPolygon(polygonOptions);
// And update the list for the root marker.
polygons.put(mKey,polygon);
}
Initial
Initial collection of 3 polygons added by clicking on map...
Modified
Then an image showing a point in each polygon stretched...
i want to show the location indicator when the map is loaded and add a marker whenever the map is clicked but none of these seem to work !
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MapFragment mapFragment = (MapFragment) getSupportFragmentManager().findFragmentById(R.id.mapFragment);
assert mapFragment != null;
mapFragment.getMapAsync(new OnMapInitListener() {
#Override
public void onMapReady(MapView mapView) {
OnlineManager.getInstance().enableOnlineMapStreaming(true);
PositionManager.getInstance().startPositionUpdating();
PositionManager.getInstance().enableRemotePositioningService();
mpView=mapView;
mpView.addMapGestureListener(new MapGestureAdapter() {
#Override
public boolean onMapClicked(final MotionEvent e, final boolean isTwoFingers) {
MapMarker marker = new MapMarker(new GeoCoordinates(PositionManager.getInstance().getLastKnownPosition().getLongitudeAccuracy(),PositionManager.getInstance().getLastKnownPosition().getLatitudeAccuracy()));
mpView.addMapObject(marker);
return true;
}
});
}
#Override
public void onMapError(int error, String info) {}
});
}
You’re trying to create new Marker with getLongitudeAccuracy() and getLatitudeAccuracy(). You need to use geo coordinates!
If you want to add the marker to the position of last known gps signal you can use this code:
MapMarker marker = new MapMarker(PositionManager.getInstance().getLastKnownPosition().getCoordinates())
But as there can be no known position at that time it can result in no marker added. So be sure you have location turned on and strong signal. Based on your example it would make more sense to add marker to the position you clicked on. For that purpose use this code:
mpView.addMapGestureListener(new MapGestureAdapter() {
#Override
public boolean onMapClicked(final MotionEvent e, final boolean isTwoFingers) {
MapMarker marker = new MapMarker(mpView.geoCoordinatesFromPoint(e.getX(), e.getY()));
mpView.addMapObject(marker);
return true;
}
});
In my google maps fragment,
I used this to add my item as clusters
mClusterManager = new ClusterManager<ContactInfo>(getActivity(), googleMap);
mClusterManager.setOnClusterClickListener(this);
mClusterManager.addItem(myItem);
Now, I can manage to set onClusterClickListener by
mClusterManager.setOnClusterClickListener(this);
By using the above code, I can detect when I click those clusters,
However, when I click those seperate markers, this does not work.
How to detect those seperate markers I added to clusterManager?
setOnClusterClickListener is invoked when a Cluster is tapped.
You also need to set setOnClusterItemClickListener which is
Sets a callback that's invoked when an individual ClusterItem is
tapped. Note: For this listener to function, the ClusterManager must
be added as a click listener to the map.
And be sure to implement ClusterManager.OnClusterItemClickListener<T extends ClusterItem>
Try This custom Class.
private class PersonRenderer extends DefaultClusterRenderer<Person> {
public PersonRenderer() {
super(MainActivity.this, mMap, mClusterManager1);
}
#Override
protected void onBeforeClusterItemRendered(Person person, MarkerOptions markerOptions) {
Debug.e("call", "onBeforeClusterItemRendered");
// Draw a single person.
// Set the info window to show their name.
}
#Override
protected boolean shouldRenderAsCluster(Cluster<Person> cluster) {
Debug.e("call", "shouldRenderAsCluster");
return cluster.getSize() > 1;
}
#Override
protected void onClusterItemRendered(Person clusterItem, Marker marker) {
super.onClusterItemRendered(clusterItem, marker);
Debug.e("call", "onClusterItemRendered");
}
}
onClusterClick
#Override
public boolean onClusterClick(Cluster<Person> cluster) {
Debug.e("call", "onClusterClick");
// Show a toast with some info when the cluster is clicked.
String firstName = cluster.getItems().iterator().next().name;
// Toast.makeText(this, cluster.getSize() + " (including " + firstName + ")", Toast.LENGTH_SHORT).show();
// Zoom in the cluster. Need to create LatLngBounds and including all the cluster items
// inside of bounds, then animate to center of the bounds.
// Create the builder to collect all essential cluster items for the bounds.
LatLngBounds.Builder builder = LatLngBounds.builder();
for (ClusterItem item : cluster.getItems()) {
builder.include(item.getPosition());
}
// Get the LatLngBounds
final LatLngBounds bounds = builder.build();
// Animate camera to the bounds
try {
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 100));
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
onClusterInfoWindowClick
#Override
public void onClusterInfoWindowClick(Cluster<Person> cluster) {
Debug.e("call", "onClusterInfoWindowClick");
// Does nothing, but you could go to a list of the users.
// clickedCluster = cluster;
}
onClusterItemClick
#Override
public boolean onClusterItemClick(Person item) {
// Does nothing, but you could go into the user's profile page, for example.
Debug.e("call", "onClusterItemClick");
clickedClusterItem = item;
return false;
}
onClusterItemInfoWindowClick
#Override
public void onClusterItemInfoWindowClick(Person item) {
// Does nothing, but you could go into the user's profile page, for example.
Debug.e("call", "onClusterItemInfoWindowClick");
}
I am trying to display a list of venues on Google Maps in Android, which can be clustered on zoom out and on zoom in unclustered.
WHEN UNCLUSTERED, an individual item info window can be opened to look at that venue details, and clicked to open a separate activity.
I am using this https://developers.google.com/maps/documentation/android-api/utility/marker-clustering?hl=en
I am doing this :
Getting Map Fragment in onResume()
#Override
public void onResume() {
super.onResume();
// Getting map for the map fragment
mapFragment = new SupportMapFragment();
mapFragment.getMapAsync(new VenuesInLocationOnMapReadyCallback(getContext()));
// Adding map fragment to the view using fragment transaction
FragmentManager fragmentManager = getChildFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.venues_in_location_support_map_fragment_container, mapFragment);
fragmentTransaction.commit();
}
MapReadyCallback :
private class VenuesInLocationOnMapReadyCallback implements OnMapReadyCallback {
private static final float ZOOM_LEVEL = 10;
private final Context context;
public VenuesInLocationOnMapReadyCallback(Context context) {
this.context = context;
}
#Override
public void onMapReady(final GoogleMap map) {
// Setting up marker clusters
setUpClusterManager(getContext(), map);
// Allowing user to select My Location
map.setMyLocationEnabled(true);
// My location button handler to check the location setting enable
map.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener() {
#Override
public boolean onMyLocationButtonClick() {
promptForLocationSetting(getContext(), map);
// Returning false ensures camera try to move to user location
return false;
}
});
map.getUiSettings().setMyLocationButtonEnabled(true);
// Disabling map toolbar
map.getUiSettings().setMapToolbarEnabled(false);
}
}
Setting up Cluster Manager
private void setUpClusterManager(final Context context, GoogleMap map) {
// Declare a variable for the cluster manager.
ClusterManager<LocationMarker> mClusterManager;
// Position the map.
LatLng wocLatLng = new LatLng(28.467948, 77.080685);
map.moveCamera(CameraUpdateFactory.newLatLngZoom(wocLatLng, VenuesInLocationOnMapReadyCallback.ZOOM_LEVEL));
// Initialize the manager with the context and the map.
mClusterManager = new ClusterManager<LocationMarker>(context, map);
// Point the map's listeners at the listeners implemented by the cluster
// manager.
map.setOnCameraChangeListener(mClusterManager);
map.setOnMarkerClickListener(mClusterManager);
// Add cluster items (markers) to the cluster manager.
addLocations(mClusterManager);
// Setting custom cluster marker manager for info window adapter
map.setInfoWindowAdapter(mClusterManager.getMarkerManager());
mClusterManager.getMarkerCollection().setOnInfoWindowAdapter(new MyLocationInfoWindowAdapter());
map.setOnInfoWindowClickListener(new MyMarkerInfoWindowClickListener());
}
Adding Cluster items (markers)
private void addLocations(ClusterManager<LocationMarker> mClusterManager) {
for (int i = 0; i < venuesDetailsJsonArray.length(); i++) {
try {
JSONObject thisVenueJson = (JSONObject) venuesDetailsJsonArray.get(i);
JSONObject thisVenueLocationJson = thisVenueJson.getJSONObject("location");
LocationMarker thisVenueMarker = new LocationMarker(thisVenueLocationJson.getDouble("latitude"),
thisVenueLocationJson.getDouble("longitude"), thisVenueJson.getInt("id"));
mClusterManager.addItem(thisVenueMarker);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
MyLocationInfoWIndowAdapter
private class MyLocationInfoWindowAdapter implements GoogleMap.InfoWindowAdapter {
#Override
public View getInfoWindow(Marker marker) {
return null;
}
#Override
public View getInfoContents(Marker marker) {
Log.e("getInfoContent", marker.toString());
View venueInfoWindow = ((LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.venues_map_item, null);
return venueInfoWindow;
}
}
MarkerInfoWindowClickListener
private class MyMarkerInfoWindowClickListener implements GoogleMap.OnInfoWindowClickListener {
#Override
public void onInfoWindowClick(Marker marker) {
// TODO: This is the click listener, that means all the info must be added as Tag to Marker
Intent venueDetailsDisplayIntent = new Intent(getActivity(), VenueDetailsDisplayActivity.class);
startActivity(venueDetailsDisplayIntent);
}
}
Location Marker class
public class LocationMarker implements ClusterItem{
private final LatLng mPosition;
private final int id;
public LocationMarker(double lat, double lng, int id) {
mPosition = new LatLng(lat, lng);
this.id = id;
}
#Override
public LatLng getPosition() {
return mPosition;
}
public int getId() {
return this.id;
}
}
The way that I am understanding the flow is this :
onResume --> fragmentTransaction --> VenuesInLocationOnMapReadyCallback --> setUpClusterManager --> addLocations (This adds Custom markers)
Marker Click --> MyLocationInfoWindowAdapter --> getInfoContents(Marker marker)
Marker Info Window click --> MyMarkerInfoWindowClickListener
According to my Understanding of process (I could be wrong):
I am adding an id to my custom LocationMarker when Adding markers in addLocations function.
I need to display different info in infoWindow for different markers.
InfoWindow is displayed using MyLocationInfoWindowAdapter-->getInfoContents(Marker marker)
But here is the rub, I can't find a way to figure out which marker has been clicked upon so that I can set appropriate info in InfoWindow.
On Click on opened InfoWindow I need to open a separate Activity. A/C to me InfoWindow click is handled using MyMarkerInfoWindowClickListener-->onInfoWindowClick(Marker marker) Here too I am having the same problem (I can't figure out which marker's info window has been clicked).
Hi I have this code which adds a marker when I click on the map but if i rerun the app the marker disappears. Is there any way that I can store the marker somehow and then display it ? I have read about shared preferences but I can't provide the code for it. How can I save the onmapclick action in shared preferences and then display it ?Anyone can help me out ?
gMap.setOnMapClickListener(new GoogleMap.OnMapClickListener(){
#Override
public void onMapClick(LatLng point) {
gMap.addMarker(new MarkerOptions().position(point));
}
});
Check this link if you still need any help.
Marker m = null;
SharedPreferences prefs = null;//Place it before onCreate you can access its values any where in this class
// onCreate method started
prefs = this.getSharedPreferences("LatLng",MODE_PRIVATE);
//Check whether your preferences contains any values then we get those values
if((prefs.contains("Lat")) && (prefs.contains("Lng"))
{
String lat = prefs.getString("Lat","");
String lng = prefs.getString("Lng","");
LatLng l =new LatLng(Double.parseDouble(lat),Double.parseDouble(lng));
gMap.addMarker(new MarkerOptions().position(l));
}
Inside your onMapClick
gMap.setOnMapClickListener(new GoogleMap.OnMapClickListener(){
#Override
public void onMapClick(LatLng point) {
marker = gMap.addMarker(new MarkerOptions().position(point));
/* This code will save your location coordinates in SharedPrefrence when you click on the map and later you use it */
prefs.edit().putString("Lat",String.valueOf(point.latitude)).commit();
prefs.edit().putString("Lng",String.valueOf(point.longitude)).commit();
}
});
To remove marker
gMap.setOnMarkerClickListener(new OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker arg0) {
//Your marker removed
marker.remove();
return true;
}
});
How to create custom marker with your own image
// create marker
MarkerOptions marker = new MarkerOptions().position(new LatLng(lat, lng);
// Changing marker icon
marker.icon(BitmapDescriptorFactory.fromResource(R.drawable.your_own_image)));
// adding marker
gMap.addMarker(marker);