OnMarkerClick() Method not working Android Studio - java

I have tried many of the solutions that abound here in the forum of the operation of onmarkerclick () but none have worked.
I am working with an app that uses the google maps api and we want to program a route tracer.
The operation that I am trying to achieve now is that by clicking on a marker you can trace the path to it, the problem is that the onmarkerclick method is not working or returning anything.
I will add the 2 parts of the code that I consider important to be able to find the solution to the problem:
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setOnMapClickListener(this);
mMap.setOnMarkerClickListener(this);
mMap.setOnInfoWindowClickListener(this);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
// Add layer
try {
layer = new KmlLayer(mMap, R.raw.kmltest, getApplicationContext());
layer.addLayerToMap();
// Set a listener for geometry clicked events.
layer.setOnFeatureClickListener(new KmlLayer.OnFeatureClickListener() {
#Override
public void onFeatureClick(Feature feature) {
Log.i("KML", "Feature clicked: " + feature.getProperty("CUA_DESCRI"));
}
});
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// end of layer add
}
public boolean onMarkerClick(Marker marker) {
Log.d("Comprobar markerclick", "onMarkerClick !!!!!!!!!!!!!!!!!! ");
btnTrazarRuta.hide();
//El destino que buscaremos al dar click
destinoRutaUnica = marker.getPosition().latitude + "," + marker.getPosition().longitude;
return false;
}
The onmarkerclick method should hide a button and get the position of the marker, but before that I put a logd to be able to see if it was at least entering the method, but no. It shows absolutely nothing.

Fron anyone who got the same problem.
in my case it was the line:
layer = new KmlLayer(mMap, R.raw.kmltest, getApplicationContext());
apparently, onmarkerclick() and at the same time oninfowindowsclick() stop working when working with a KML layer.
I don't know exactly why.

Once you add a KML layer, it will handle the clicks. You need to instruct the KML layer to delegate the clicks to e.g. your markers or polylines.
here's how to do it with markers (same principle for polylines etc):
MarkerManager markerManager = new MarkerManager(map);
MarkerManager.Collection markerCollection = markerManager.newCollection();
... where map is GoogleMap.
Now when adding a marker to the map
instead of doing:
map.addMarker(markerOptions);
map.setOnMarkerClickListener(listener);
do:
markerCollection.addMarker(markerOptions)
markerCollection.setOnMarkerClickListener(listener);
And now the final hint:
When adding a KML object to the map, pass in the markerManager (and polylineManager etc):
KmlLayer kmlLayer = new KmlLayer(map, R.raw.kmltest, ctxt, markerManager, polygonManager, polylineManager, groundOverlayManager, (cache));
In case you only use markers, it would simply be:
KmlLayer kmlLayer = new KmlLayer(map, R.raw.kmltest, ctxt, markerManager, null, null, null, null);
... and watch ALL your click listeners work

Related

How to lock focus on Camera2API app on a service without preview

I am building an app which uses Camera2API to take pictures. The thing is I need the Camera to take a picture without needing a preview. So far, I managed to do it by dumping (and adapting) the code from an activity into a service and it works like a charm, except for the fact that it is not focusing. On previous versions I had a state machine in charge of that focusing on the preview by means of a separate CaptureRequest.Builder, but I can't make it work without creating a new CaptureRequest.Builder on the service.
I followed this topic on the following stackoverflow discussion How to lock focus in camera2 api, android? but I did not manage to make it work.
My code does the following:
First I create a camera session once the camera has been opened.
public void createCameraSession() {
try {
// Here, we create a CameraCaptureSession for camera preview.
cameraDevice.createCaptureSession(Arrays.asList(imageReader.getSurface()),
new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
// The camera is already closed
if (null == cameraDevice) {
return;
}
// When the session is ready, we start displaying the preview.
mCaptureSession = cameraCaptureSession;
camera2TakePicture();
}
#Override
public void onConfigureFailed(
#NonNull CameraCaptureSession cameraCaptureSession) {
}
}, null
);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
Then on that camera session I call my method "camera2TakePicture()":
protected void camera2TakePicture() {
if (null == cameraDevice) {
return;
}
try {
Surface readerSurface = imageReader.getSurface();
List<Surface> outputSurfaces = new ArrayList<Surface>(2);
outputSurfaces.add(readerSurface);
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(readerSurface);
captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CameraMetadata.CONTROL_AF_MODE_AUTO);
captureBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
//MeteringRectangle meteringRectangle = getAFRegion();
//captureBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[] {meteringRectangle});
/**** TO BE USED ONCE SAMSUNG TABLETS HAVE BEEN REPLACED ****/
boolean samsungReplaced = false;
if(Boolean.parseBoolean(getPreferenceValue(this, "manualCamSettings"))) {
int exposureCompensation = Integer.parseInt(getPreferenceValue(this, "exposureCompensation"));
captureBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, exposureCompensation);
if(samsungReplaced) {
//Exposure
captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_OFF);
Float shutterSpeed = 1 / Float.parseFloat(getPreferenceValue(this, "camSSpeed"));
Long exposureTimeInNanoSec = new Long(Math.round(shutterSpeed * Math.pow(10, 9)));
captureBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, exposureTimeInNanoSec);
captureBuilder.set(CaptureRequest.SENSOR_FRAME_DURATION, 10 * exposureTimeInNanoSec);
//ISO
int ISO = Integer.parseInt(getPreferenceValue(this, "camISO"));
captureBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, ISO);
//Aperture
Float aperture = Float.parseFloat(getPreferenceValue(this, "camAperture"));
captureBuilder.set(CaptureRequest.LENS_APERTURE, aperture);
}
}
// Orientation
WindowManager window = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = window.getDefaultDisplay();
int rotation = display.getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
CameraCaptureSession.CaptureCallback CaptureCallback
= new CameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureCompleted(#NonNull CameraCaptureSession session,
#NonNull CaptureRequest request,
#NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
while(result.get(CaptureResult.CONTROL_AF_STATE) != CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED){
System.out.println("Not focused");
}
System.out.println("Focused");
}
};
mCaptureSession.stopRepeating();
mCaptureSession.abortCaptures();
mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);
captureBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_IDLE);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
As you can see, I set the CONTROL_AF_MODE to AUTO then start the AF_TRIGGER and launch the capture. I add a check on onCaptureCompleted() but the AF_STATE never seems to be on FOCUSED_LOCKED. It stays on ACTIVE_SCAN.
What am I doing wrong?
In your code snippet, you've stopped the repeating request, and issue one capture request for the still image, but just one.
Do you then go on to restart the repeating request? If you don't, there are no frames flowing through the camera, and AF cannot make progress.
So if you want to lock AF before you take a picture, you want to
Set AF_TRIGGER to START for a single capture only
Run preview until you get AE_STATE out of ACTIVE_SCAN
Issue single capture for still image.
Being in the background or foreground doesn't really change any of this.

Android: Here maps sdk's map is showing not accurate coordinates

I am using the HERE Maps Lite SDK for Android as a library in my project.
I want to show MapView, and add overlays of all shelters I have in my database, in their specific coordinates.
The map works well, but the shown coordinates are not accurate. I tried to geocode the coordinates in lat-long website, and they are correct, but in the map they are shown right to their real location.
My code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shelters_map);
mapView = findViewById(R.id.mapview);
mapView.onCreate(savedInstanceState);
ActivityCompat.requestPermissions(SheltersMapActivity.this, new String[] {
Manifest.permission.ACCESS_FINE_LOCATION}, 123);
if (ContextCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
Toast.makeText(getApplicationContext(), "אנא אפשר גישה לשירותי מיקום", Toast.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(this,
new String[]{ACCESS_FINE_LOCATION},
1);
} else // premission is granted
{
GPStracker g = new GPStracker(getApplicationContext());
userLocation = g.getLocation();
}
loadMapScene();
addSheltersOverlay();
// loadMapScene();
}
private void loadMapScene() {
// Load a scene from the SDK to render the map with a map style.
mapView.getMapScene().loadScene(MapStyle.NORMAL_DAY, new MapScene.LoadSceneCallback() {
#Override
public void onLoadScene(#Nullable MapScene.ErrorCode errorCode) {
if (errorCode == null) {
mapView.getCamera().setTarget(new GeoCoordinates(userLocation.getLatitude(),
userLocation.getLongitude()));
mapView.getCamera().setZoomLevel(15);
} else {
Log.d("data1", "onLoadScene failed: " + errorCode.toString());
}
}
});
}
private void addSheltersOverlay() {
db = new DatabaseHandler(this);
ArrayList<Shelter> places = this.db.getAllPlaces();
Shelter userLocationPlace = new Shelter("המיקום שלך", "", userLocation, null, 0, "");
places.add(userLocationPlace);
int size = places.size();
for(int i = 0; i < size; i++) {
TextView textView = new TextView(this);
textView.setTextColor(Color.parseColor("#FFFFFF"));
textView.setText(places.get(i).getName());
LinearLayout linearLayout = new LinearLayout(this);
if (places.get(i) instanceof Basement)
linearLayout.setBackgroundColor(Color.BLACK);
else if (places.get(i) instanceof Stairs)
linearLayout.setBackgroundColor(Color.GREEN);
else
linearLayout.setBackgroundColor(Color.BLUE);
linearLayout.setPadding(10, 10, 10, 10);
linearLayout.addView(textView);
GeoCoordinates geoCoordinates = new GeoCoordinates(places.get(i).getLocation().getLatitude(),
places.get(i).getLocation().getLongitude());
MapOverlay<LinearLayout> mapOverlay = new MapOverlay<>(linearLayout, geoCoordinates);
mapView.addMapOverlay(mapOverlay);
}
}
The shown map:
.
I can see the streets names in the shown map itself, and I see that it is not the accurate point.
Anybody help?
From the code it looks correct, but I cannot see the location vs. the expected location. By default, MapOverlays are drawn centered on the coordinates. You can set an anchor point to move the overlay in relation to the coordinates. This could help if there is always an offset between the coordinates in your database and the location on the map.
Maybe, can you try to render a small MapCircle item onto the map at the expected location? Then you can more easily see where that location lies on the map. You can compare the results with https://www.latlong.net/.

Creating Marker (Google Map Markers) object without Google Map reference

I know there are similar questions around, but I was not able to find a solid answer, here is my question: Is there any way I can make Markers without a Google Map reference to be stored in an ArrayList (or any other storage), and then just simply add them to my map?
Background:
I have an app, that at the moment has around 3,500 markers. Each marker also has a data associated with it (boolean array storing data for each marker which is used to make them visible/invisible based on users interactions). At the moment, I get these marker's location and data using a class that extends AsyncTask. After the loading is finished, then I create my markers using this data on the main Thread. However, this takes some time, and it freezes the UI while the markers are being created and added to the map. I want to do this somehow in the background.
What I have tried so far:
I created another class that extends AsyncTask passing in my LocationData and my Google Map object. But I get an error when I try to make the markers in my Async class. I get a Runtime error saying I need to do this on the UI thread.
java.lang.RuntimeException: An error occurred while executing
doInBackground()
Caused by: com.google.maps.api.android.lib6.common.apiexception.c: Not
on the main thread
I have also thought about just making MarkerOptions object in the background and then use that to create markers in the main thread; however, I cannot add a tag to the MarkerOption, it needs to be added to the marker. In that case, I need to go through all of them again in the main thread just to add the tag, which I feel like is not saving me too much time/resources.
Any suggestion/help would be appreciated on how to create these markers and attach their tags without blocking the UI?
Thanks in advance.
Here are some of my code:
LocationLoader class
(BinLocation is my Location class, each object has boolean variables (marker tags) and LatLng)
public class LocationLoader extends AsyncTaskLoader> {
private String TAG = LocationLoader.class.getName();
String[] fileNameArray;
//ArrayLists
private ArrayList<BinLocation> mBinLocationArrayList = new ArrayList<>();
public LocationLoader(Context context, String... fileNames){
super(context);
//get the file names that was passed in
fileNameArray = fileNames;
}//LocationLoader
#Override
protected void onStartLoading() {
Log.v(TAG, "onStartLoading called");
forceLoad();
}//onStartLoading
#Override
public ArrayList<BinLocation> loadInBackground() {
Log.v(TAG, "loadInBackground called");
String path = "/storage/emulated/0/";
File file;
String output = "";
//Read data from file
for (int i = 0; i < fileNameArray.length; i++) {
file = new File(path + fileNameArray[i]);
try (Scanner scanner = new Scanner(file)) {
//first line of the text, containing the location and version
output = scanner.nextLine();
String prefix = (output.split(":"))[0];
String line;
while (scanner.hasNextLine()) {
line = scanner.nextLine();
String inputArray[] = line.split(",");
BinLocation binLocation = new BinLocation(
prefix + "-" + inputArray[0],
Double.parseDouble(inputArray[1]),
Double.parseDouble(inputArray[2]),
Integer.parseInt(inputArray[3].trim()),
Integer.parseInt(inputArray[4].trim()),
Integer.parseInt(inputArray[5].trim()),
Integer.parseInt(inputArray[6].trim()));
mBinLocationArrayList.add(binLocation);
}//while
} catch (Exception e) {
Log.e(TAG, "File read error: ", e);
}
}//for
Log.v(TAG, "readLocation finished");
Log.v(TAG, "ArrayList size: " + mBinLocationArrayList.size());
return mBinLocationArrayList;
}//loadInBackground
}//LocationLoader class
Here is my MarkerLoader class (I have tried this and got the doInBackground() error). Also there is no code right now here for adding the data to the marker but it foes in the loop right after it has been added to the map.
public class MarkerLoader extends AsyncTaskLoader<ArrayList<Marker>> {
private GoogleMap map;
private ArrayList<Marker> mMarkerArrayList = new ArrayList<>();
private ArrayList<MyLocation> mBinLocationArrayList = new ArrayList<>();
public MarkerLoader (Context context, GoogleMap map, ArrayList<BinLocation> binLocationArrayList) {
super(context);
this.map = map;
this.mBinLocationArrayList = binLocationArrayList;
}//MarkerLoader
#Override
protected void onStartLoading() {
Log.v(TAG, "onStartLoading called");
forceLoad();
}//onStartLoading
#Override
public ArrayList<Marker> loadInBackground() {
Log.v(TAG, "loadInBackground called");
Marker marker;
for (BinLocation binLocation : mMyLocationArrayList) {
marker = map.addMarker(new MarkerOptions()
.position(binLocation.getPosition()));
mMarkerArrayList.add(marker);
}
Log.v(TAG, "loadInBackground finished, with: " + mMarkerArrayList.size());
return mMarkerArrayList;
}
}
This is the helper function(populateMap()) in the main Activity that makes the markers and save them in an ArrayList
private void populateMap() {
if (!checkMapReady() || !mMapIsEmpty) {
return;
}//if Map Not ready
//Initialize ArrayList
mMarkerArrayList = new ArrayList<>();
/**
* This part uses the loop to go through each MyLocation object in the ArrayList, extract
* all the data, and set the markers
*/
//Check to make sure the BinLocation ArrayList is not empty otherwise we will crash
if (mBinLocationArrayList.isEmpty()) {
Log.w(TAG, "populateMap() terminated, mBinLocationArrayList empty");
return;
}//if BinLocation empty
//Safety check to clear the map before populating it
mMap.clear();
//create a markerMyLocation object
Marker mMaker;
//This goes through the ArrayList for every MyLocation object and sets up the markerMyLocation
for (BinLocation binLocation : mBinLocationArrayList) {
//get boolean values
boolean[] booleanValues = {binLocation.getGarbage(), binLocation.getContainer(),
binLocation.getPaper(), binLocation.getCompost()};
//Set different icon
switch (markerIconPreference) {
case "customIcon":
//custom icon
//Decide what icon to use
if (booleanValues[0] && !booleanValues[1] && !booleanValues[2] && !booleanValues[3]) {
//Make a new MarkerOptions object to add the data
//garbage markers
mMaker = mMap.addMarker(new MarkerOptions()
.title(binLocation.getId())
.position(binLocation.getPosition())
.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_garbage))
.visible(garbageVisible));
} else {
//Make a new MarkerOptions object to add the data
//recycling markers
mMaker = mMap.addMarker(new MarkerOptions()
.title(binLocation.getId())
.position(binLocation.getPosition())
.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_recycling))
.visible(recyclingVisible));
}
//Add our boolean array as an object to our markerMyLocation
mMaker.setTag(booleanValues);
//Add the markerMyLocation to the ArrayList
mMarkerArrayList.add(mMaker);
break;
case "coloredTeardrop":
//teardrop icon
//Decide what icon to use
if (booleanValues[0] && !booleanValues[1] && !booleanValues[2] && !booleanValues[3]) {
//Make a new MarkerOptions object to add the data
//garbage markers
mMaker = mMap.addMarker(new MarkerOptions()
.title(binLocation.getId())
.position(binLocation.getPosition())
.visible(garbageVisible));
} else {
//Make a new MarkerOptions object to add the data
//recycling markers
mMaker = mMap.addMarker(new MarkerOptions()
.title(binLocation.getId())
.position(binLocation.getPosition())
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN))
.visible(recyclingVisible));
}
//Add our boolean array as an object to our markerMyLocation
mMaker.setTag(booleanValues);
//Add the markerMyLocation to the ArrayList
mMarkerArrayList.add(mMaker);
break;
}//switch
}//for
//disable the progress bar
mProgressBar.setVisibility(View.GONE);
//De-activate the CountDown timer since the map is ready
mCountDownTimer.cancel();
//set the boolean to false
mMapIsEmpty = false;
Log.v(TAG, "populateMap finished. Markers: " + mMarkerArrayList.size());
}//populateMap
Here is the onMapReady function
public void onMapReady(GoogleMap map) {
Log.v(TAG, "onMapReady called");
mMap = map;
//Setup on map loaded
mMap.setOnMapLoadedCallback(this);
//Check to see if the map is empty and the location array list is not empty and then call populateMap
if (mMapIsEmpty && !mBinLocationArrayList.isEmpty()) {
populateMap();
}//if map empty
//set bounds
mMap.setLatLngBoundsForCameraTarget(GREATER_VANCOUVER_BOUND);
//Set min zoom level to match the bound
mMap.setMinZoomPreference(10.0f);
//disable map toolbar
UiSettings mUiSettings = mMap.getUiSettings();
mUiSettings.setMapToolbarEnabled(false);
//Set listeners
mMap.setOnMarkerClickListener(this);
mMap.setOnInfoWindowCloseListener(this);
mMap.setOnInfoWindowClickListener(this);
// Setting our custom info window, passing out helper method
mMap.setInfoWindowAdapter(new CustomInfoWindowAdapter());
//Here we check for permission and setup the map accordingly
if (!checkLocationPermission()) {
//Permission is not granted, log, and use the default location
Log.v(TAG, "No location permission");
//setup default map
defaultMapSetup();
} else {
Log.v(TAG, "Location permission granted");
//Enable my location and initialize the map there
mMap.setMyLocationEnabled(true);
//Setup the map
locationMapSetup();
}//if -permission
}//onMapReady
try to Create your markers in another thread like this
YourActivity.this.runOnUiThread(new Runnable(){
public void run(){
//paste your code here.
});

How can I make this request

What I had: An application that when you opened, it showed you a map with 3 buttons that said, "Restaurant", "Hospitals","Bars", and once clicked one of them they showed you this places nearby
What I have: For aesthetic questions an app that when you open, it shows you a RecyclerView with images, and when you click one of these images takes you to a map with your current position.
What I want: That when I click on one of the images of the RecyclerView for example Restaurants, it show a map with the restaurants near me, but making this request from the OnClickListener that I have in my RecyclerView's Adapter on the OnBindViewHolder() method
My Question: How do I make this request if the elements such as Latitude and Longitude are in another Activity and also within a Method called OnMapReady () in which I used to make the request with the buttons I had initially. Please I would appreciate the answers with code examples, I am still not very good at programming and there are millions of terms that I do not understand, thanks in advance
My RecyclerView and where I want to make the request
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, final int position) {
holder.etiNombre.setText(listalugares.get(position).getNombre());
holder.foto.setImageResource(listalugares.get(position).getFoto());
holder.foto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (position == 0){
Intent myIntent = new Intent(context, MapsActivity.class);
context.startActivity(myIntent);
}
}
});
}
Where I used to make my request
#Override
public void onMapReady(GoogleMap googleMap) {//esta funcion es llamada cuando el mapa esta listo para usarse(1- locacion)
mMap = googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);//esto es lo que que dice de que forma queremos que se vea el mapa
//Initialize Google Play Services
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
Button btnRestaurant = (Button) findViewById(R.id.btnRestaurant);
btnRestaurant.setOnClickListener(new View.OnClickListener() {
String Restaurant = "restaurant";
#Override
public void onClick(View v) {
Log.d("onClick", "Button is Clicked");
mMap.clear();
String url = getUrl(latitude, longitude, Restaurant);
Object[] DataTransfer = new Object[2];
DataTransfer[0] = mMap;
DataTransfer[1] = url;
Log.d("onClick", url);
GetNearbyPlacesData getNearbyPlacesData = new GetNearbyPlacesData();
getNearbyPlacesData.execute(DataTransfer);
Toast.makeText(MapsActivity.this,"Nearby Restaurants", Toast.LENGTH_LONG).show();
}
});
To pass data from an activity to another, you'll have to use Intent's extras field. It's a Bundle (a key/value data-structure) where you can store everything you want (with size constraints, so it's usually a good idea to pass only IDs or stuff like that, not the actual data).
What you can do here is: in your adapter's onClick method, add an extra field to the Intent, containing the information type you want to display (either restaurant, bar or hospital). Then, in your second activity (the one containing the map), in the onCreate method, read the field from the Intent. Then you can still place your Nearby Places request in the onMapReady method, using the field to determine which type you're requesting, instead of depending on a specific button click event.

Setting the visible region in Google Maps [duplicate]

Firstly I am sorry about my English.
I try to set exact visibile bounds in google maps android api. For example map will only show America's region and user can't scroll map to Canada. When you look to link you can understand what I try to do.I think I can do it with CameraChangeListener and getting visible regions but I couldn't implement algorithm. Can you help me ?
http://sehirharitasi.ibb.gov.tr/
It is not that easy and good as your link but it's something that can work:
//When you setup the map:
map.setOnCameraChangeListener(new OnCameraChangeListener() {
#Override
public void onCameraChange(CameraPosition cameraPosition) {
checkBounds();
}
});
And the CheckBounds function can either check if the visible area is inside the allowed one:
public void checkBounds() {
//non ricostruire allowedbounds ogni volta, sono sempre gli stessi, fatti il build nell'onCreate
LatLngBounds actualVisibleBounds = map.getProjection().getVisibleRegion().latLngBounds;
if (allowedBounds.contains(actualVisibleBounds)){
return
}else{
map.animateCamera(CameraUpdateFactory.newLatLngBounds(allowedBounds));
}
}
Or you can use the center of the viewport and check if is inside the allowed area (to allow bounding zooms)
public void checkBounds() {
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(northeast);
builder.include(southwest);
final LatLngBounds allowedBounds = builder.build();
LatLngBounds centro = map.getProjection().getVisibleRegion().latLngBounds;
if (allowedBounds.contains(centro.getCenter()))
return;
else {
map.animateCamera(CameraUpdateFactory.newLatLngZoom(defaultLatLng, zoomLevel));
}
}

Categories