Clickable Google Maps marker in Fragment - android

What I am trying to accomplish here is be able to show a AlertDialog when I click on a marker that is dynamically added on load (call an API, get positions and show them on map). This is done in the fragments onCreateView.
The map loads here:
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
FragmentManager fm = getChildFragmentManager();
mapFragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
if (mapFragment == null) {
mapFragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.map_container, mapFragment).commit();
}
}
Later on, I switch from a SupportMapFragment to a GoogleMap:
#Override
public void onResume() {
super.onResume();
if (mMap == null && mapFragment != null) {
mapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = Tools.configBasicGoogleMap(googleMap);
mMap.setMapType(sharedPref.getMapType());
}
});
}
}
So, logically, my Map should be ready as mMap. Now, I want to show a AlertDialog, so I do implements GoogleMap.OnMarkerClickListener in the class definition for the fragment and implement it here:
#Override
public boolean onMarkerClick(final Marker marker) {
Toast.makeText(getContext(), "Hello world", Toast.LENGTH_SHORT).show();
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("Confirmation");
builder.setMessage("Pour confirmer le rapport, appuyez sur + 1.\nSi le rapport est faux, cliquez sur - 1.");
builder.setPositiveButton("+ 1", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id){
URL link = null;
try {
link = new URL(S.base_url + "report/increment/" + marker.getTag().toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(
link.openStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
});
AlertDialog ab = builder.create();
ab.show();
return false;
}
But not even the Toast doesn't show up... When I click on a marker I get the Directions and Open in Google Maps buttons, and the map centers itself on the marker, but my method doesn't start.
To conclude, logically when I click one of these markers that I load, the method onMarkerClick should trigger itself, but this never happens! Any idea why? Thanks.

I don't know why but Google Maps API can't used as implement to fragments. Following code may work it for you. You just need to assign markerClickListener for local, not implementing MarkerClickListener.
//Detect location and set on map
mMapView.getMapAsync(new OnMapReadyCallback() {
#SuppressLint("MissingPermission")
#Override
public void onMapReady(GoogleMap mMap) {
googleMap = mMap;
// Bla
// Bla
// Bla your codes about map
googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
// Triggered when user click any marker on the map
return false;
}
});
}
});

Related

Sygic not showing current position nor displaying markers

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;
}
});

Application closing while leaving edit text

I have an application that contains several fragments in one activity.
And one of the fragment is implemented map with edit text for user address auto fill based on camera change listener, while i back press from that map fragment i manage to back to previous fragment, but once i clicked edit text in that map fragment pressing back button closing the full application without force close.
I don't know the exact problem.
Sorry for my bad English.
public class Maps extends Fragment implements OnMapReadyCallback {
Unbinder unbinder;
#BindView(R.id.address_submit)
Button addressSubmit;
private GoogleMap mMap;
IDU idu;
User user;
EditText addressDoor, addressAddressline, addressStreet, addressCity, addressPincode, addressState;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_maps, container, false);
unbinder = ButterKnife.bind(this, rootView);
Activity_Dashboard.navigation.hideBottomNavigation();
idu = new IDU_Presenter(this, getActivity());
user = SharedPreferenceManager.getInstance(getActivity()).getUser();
addressDoor = (EditText)rootView.findViewById(R.id.address_door);
addressAddressline = (EditText)rootView.findViewById(R.id.address_addressline);
addressStreet = (EditText)rootView.findViewById(R.id.address_street);
addressCity = (EditText)rootView.findViewById(R.id.address_city);
addressState = (EditText)rootView.findViewById(R.id.address_state);
addressPincode = (EditText)rootView.findViewById(R.id.address_pincode);
final RippleBackground rippleBackground = (RippleBackground) rootView.findViewById(R.id.content);
ImageView b = (ImageView) rootView.findViewById(R.id.confirm_address_map_custom_marker);
rippleBackground.startRippleAnimation();
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
if (mMap == null) {
SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
rootView.setFocusableInTouchMode(true);
rootView.requestFocus();
rootView.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// Log.i(tag, "keyCode: " + keyCode);
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
Fragment_Address_list fragment = new Fragment_Address_list();
FragmentActivity activitys = (FragmentActivity) getActivity();
FragmentManager fm = activitys.getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.frame_layout, fragment);
ft.commit();
return true;
}
return false;
}
});
return rootView;
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
final Geocoder geocoder = new Geocoder(getActivity(), Locale.getDefault());
mMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
#Override
public void onCameraIdle() {
double lat = mMap.getCameraPosition().target.latitude;
double lng = mMap.getCameraPosition().target.longitude;
Location startPoint = new Location("locationA");
startPoint.setLatitude(11.010519);
startPoint.setLongitude(76.986481);
Location startPoint1 = new Location("locationb");
startPoint1.setLatitude(lat);
startPoint1.setLongitude(lng);
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(lat, lng, 1);
if (addresses.size() == 0) {
Toast.makeText(getActivity(), "Invalid location", Toast.LENGTH_SHORT).show();
} else {
if (addresses.get(0).getThoroughfare() == null) {
addressAddressline.setText(addresses.get(0).getSubLocality());
} else {
addressAddressline.setText(addresses.get(0).getThoroughfare());
}
addressStreet.setText(addresses.get(0).getSubLocality());
addressCity.setText(addresses.get(0).getLocality());
addressPincode.setText(addresses.get(0).getPostalCode());
addressState.setText(addresses.get(0).getAdminArea());
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
LatLng TutorialsPoint = new LatLng(11.010519, 76.986481);
MarkerOptions markerOptions = new MarkerOptions().position(TutorialsPoint).title("Your location");
Marker mMarker = mMap.addMarker(markerOptions);
mMarker.showInfoWindow();
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(TutorialsPoint, 18f));
}
You can override the onBackPressed() method which is triggered when the user clicks on the back button.
#Override
public void onBackPressed() {
//DO YOUR STUFF LIKE SHOWING DIALOG
new AlertDialog.Builder(this)
.setMessage("Are you sure you want to exit?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
MyActivity.super.onBackPressed();
}
})
.setNegativeButton("No", null)
.show();
}
You can here change the fragment to go back to the previous one (which is the default behavior of your code as you are using fragmentManager), you can display a Toast or whatever.
Hope it helps.

GoogleMap null when trying to access it from another fragment

I have two fragments in my application. Ons is a map fragment and the other is a list fragment. Both of these are added to a single activity. The idea is that when a user is selected from the list, the app switches to the map fragment and displays the user. The problem is that I am getting a nullPointer exception on the GoogleMap object.
I know that the map works, because on a button press in the map fragment, I can see my current location, and I do not get 'n NullPointer.
This is the onClickListener in my ListFragment:
listEmployees.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ChildUser childUser = children.get(position);
Tracker.showMapFragment(childUser);
}
});
This is the function that is called from my ListFragment in my parent Activity:
public static void showMapFragment(ChildUser childUser) {
mViewPager.setCurrentItem(0, true);
MapFragment.showSelectedUser(childUser);
trackingEmployee = true;
}
This is the applicable code in my MapFragment:
Initialisation:
mMapFragment = new SupportMapFragment() {
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d("MAP", "on activity created");
googleMap = mMapFragment.getMap();
googleMap.getUiSettings().setZoomControlsEnabled(false);
}
};
getChildFragmentManager().beginTransaction().add(R.id.map, mMapFragment).commit();
The showSelectedUser function:
public static void showSelectedUser(ChildUser childUser) {
try {
googleMap.clear();
LatLng point = new LatLng(childUser.getChildLatitude(), childUser.getChildLongetude());
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(point, 15);
MarkerOptions marker = new MarkerOptions();
marker.position(point);
googleMap.addMarker(marker);
googleMap.animateCamera(cameraUpdate);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
I get a NullPointerException at googleMap.clear();. Please advise me as to what I can possibly be doing wrong as it works fine when I show my current location from within the MapFragment. Please let me know if you need additional information. Thank you in advance!
UPDATE
When the MapFragment is visible and I press a button, I can view the users current location in the MapFragment with the following code:
public static void showUserLocation() {
googleMap.clear();
if (Tracker.clockedInShift) {
CacheUploads cacheUpload = new CacheUploads(context);
LatLng point = cacheUpload.getMostRecentLocation();
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(point, 15);
MarkerOptions marker = new MarkerOptions();
marker.position(point);
googleMap.addMarker(marker);
googleMap.animateCamera(cameraUpdate);
}
}
The map is linked up correctly because this code gets executed successfully. Why is the googleMap object null when accessed from the ListFragment? Please let me know if you require more information! Thanks
Looks like the answer to this question was fairly obvious. Using an inner class solved the problem. The following code solved everything:
private static GoogleMap googleMap;
public static class MyMapFragment extends SupportMapFragment {
public MyMapFragment() {
super();
}
public static MyMapFragment newInstance() {
MyMapFragment frag = new MyMapFragment();
return frag;
}
#Override
public View onCreateView(LayoutInflater arg0, ViewGroup arg1, Bundle arg2) {
View v = super.onCreateView(arg0, arg1, arg2);
googleMap = getMap();
return v;
}
}
Then just use googleMap to do whatever you want. The above code should be in your Activity/Fragment.

Image Button is not working in InfoWindowAdapter in google map v2

I am trying to add some image button in my marker info.
Though the buttons are added in the view but i cat not click on them.
When I try to click it clicks on the whole view.
My code us given below.
MainActivity.java
private GoogleMap googleMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final RelativeLayout base;
base = (RelativeLayout) findViewById(R.id.base);
googleMap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap();
try {
initilizeMap(); // Loading map
} catch (Exception e) {
Log.d("asdfadfadf", "asdfasdf");
}
googleMap.setMyLocationEnabled(true);
//googleMap.clear();
IconGenerator i = new IconGenerator(getBaseContext());
i.setStyle(IconGenerator.STYLE_BLUE);
Bitmap tt = i.makeIcon("asdf");
LatLng myLocation = new LatLng(22.899171, 89.500186);
Marker myLocMarker = googleMap.addMarker(new MarkerOptions()
.position(myLocation)
.icon(BitmapDescriptorFactory.fromBitmap(tt))
.title("sssss"));
googleMap.setInfoWindowAdapter(new InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker mk) {
// TODO Auto-generated method stub
return null;
}
#Override
public View getInfoContents(Marker arg0) {
// TODO Auto-generated method stub
ImageButton set,from,favor;
View view = getLayoutInflater().inflate(R.layout.marker_info,null);
set = (ImageButton) view.findViewById(R.id.imageButtonDestination);
from = (ImageButton) view.findViewById(R.id.imageButtonFrom);
favor = (ImageButton) view.findViewById(R.id.imageButtonFavourite);
set.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.d("sssssssssssssssss", "sssssssssssssssss");
}
});
return view;
}
});
}
/**
* function to load map. If map is not created it will create it for you
* */
private void initilizeMap() {
if (googleMap == null) {
Toast.makeText(getApplicationContext(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
if (googleMap == null) {
googleMap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap(); // check if map is created successfully or not
}
}
#Override
protected void onResume() {
super.onResume();
initilizeMap();
}
}
don't know what to do.
Thanks in advance.
You can't add click listeners to the Marker's InfoWindow as it's not a real view. But a Bitmap that gets rendered from you layout.
From Google Docs: https://developers.google.com/maps/documentation/android/marker#info_windows
Note: The info window that is drawn is not a live view. The view is
rendered as an image (using View.draw(Canvas)) at the time it is
returned. This means that any subsequent changes to the view will not
be reflected by the info window on the map. To update the info window
later (e.g., after an image has loaded), call showInfoWindow().
Furthermore, the info window will not respect any of the interactivity
typical for a normal view such as touch or gesture events. However you
can listen to a generic click event on the whole info window as
described in the section below.
Set GoogleMap.OnInfoWindowClickListener() to your map, implement the interface. You get the marker passed to you, call you action form there:
googleMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
#Override public void onInfoWindowClick(Marker marker) {
//do your thing here
}
});
I don't understand very well what you require, but according understanding is something of a click on an image to add to the map (a marker). if so may try this:
googleMap.setOnMarkerClickListener(new OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker arg0) {
//Your code when you do click
return false;
}
});
I hope help you, and Sorry for my english :(

Google Maps Android API v2 detect long press on map and add marker not working

I want to add a marker on map with long press.
Toast in onMapClick() was display with normal tap. But long press is not working. Toast in onMapLongClick() is not displayed with long press. Also marker is not displayed on map.
I'm using SupportMapFragment because I want to use my application on Android 2.x devices. I have tested my app on Nexus One which has Android version 2.3.7.
This is my code.
public class MainActivity extends FragmentActivity implements
OnMapClickListener, OnMapLongClickListener {
final int RQS_GooglePlayServices = 1;
private GoogleMap myMap;
Location myLocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager myFragmentManager = getSupportFragmentManager();
SupportMapFragment mySupportMapFragment = (SupportMapFragment) myFragmentManager
.findFragmentById(R.id.map);
myMap = mySupportMapFragment.getMap();
myMap.setMyLocationEnabled(true);
myMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
// myMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// myMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
// myMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
myMap.setOnMapClickListener(this);
myMap.setOnMapLongClickListener(this);
}
#Override
protected void onResume() {
super.onResume();
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(getApplicationContext());
if (resultCode == ConnectionResult.SUCCESS) {
Toast.makeText(getApplicationContext(),
"isGooglePlayServicesAvailable SUCCESS", Toast.LENGTH_LONG)
.show();
} else {
GooglePlayServicesUtil.getErrorDialog(resultCode, this,
RQS_GooglePlayServices);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onMapClick(LatLng point) {
myMap.animateCamera(CameraUpdateFactory.newLatLng(point));
Toast.makeText(getApplicationContext(), point.toString(),
Toast.LENGTH_LONG).show();
}
#Override
public void onMapLongClick(LatLng point) {
myMap.addMarker(new MarkerOptions().position(point).title(
point.toString()));
Toast.makeText(getApplicationContext(),
"New marker added#" + point.toString(), Toast.LENGTH_LONG)
.show();
}
}
How can I solve this ?
I used this. It worked.
GoogleMap gm;
gm.setOnMapLongClickListener(this);
#Override
public void onMapLongClick(LatLng point) {
gm.addMarker(new MarkerOptions()
.position(point)
.title("You are here")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
}
You have no icon setted.
Try:
#Override
public void onMapLongClick(LatLng point) {
myMap.addMarker(new MarkerOptions()
.position(point)
.title(point.toString())
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
Toast.makeText(getApplicationContext(),
"New marker added#" + point.toString(), Toast.LENGTH_LONG)
.show();
}
googleMap = supportMapFragment.getMap();
// Setting a click event handler for the map
googleMap.setOnMapClickListener(new OnMapClickListener() {
#Override
public void onMapClick(LatLng latLng) {
// Creating a marker
MarkerOptions markerOptions = new MarkerOptions();
// Setting the position for the marker
markerOptions.position(latLng);
// Setting the title for the marker.
// This will be displayed on taping the marker
markerOptions.title(latLng.latitude + " : " + latLng.longitude);
// Clears the previously touched position
googleMap.clear();
// Animating to the touched position
googleMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));
// Placing a marker on the touched position
googleMap.addMarker(markerOptions);
}
});
OR
mMap.setOnMapLongClickListener(new
GoogleMap.OnMapLongClickListener() {
#Override
public void onMapLongClick (LatLng latLng){
Geocoder geocoder =
new Geocoder(MapMarkerActivity.this);
List<Address> list;
try {
list = geocoder.getFromLocation(latLng.latitude,
latLng.longitude, 1);
} catch (IOException e) {
return;
}
Address address = list.get(0);
if (marker != null) {
marker.remove();
}
MarkerOptions options = new MarkerOptions()
.title(address.getLocality())
.position(new LatLng(latLng.latitude,
latLng.longitude));
marker = mMap.addMarker(options);
}
});

Categories

Resources