Here is the code that i have tried but when the user doesn't select anything and just return back the activity doesn't call the onActivityResult() method
I called the PlacePIcker as
googleMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng latLng) {
try {
googleMap.clear();
PlacePicker.IntentBuilder intentBuilder =
new PlacePicker.IntentBuilder();
Intent intent = intentBuilder.build(getApplicationContext());
startActivityForResult(intent, 5);
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
}
});
The onActivityResult() method
if (requestCode == 5 && resultCode == RESULT_OK) {
Toast.makeText(this,"here",Toast.LENGTH_SHORT).show();
if (data != null) {
Place place = PlacePicker.getPlace(data, this);
if (place != null) {
lat = place.getLatLng().latitude;
lng = place.getLatLng().longitude;
MarkerOptions marker = new MarkerOptions().position(
place.getLatLng()).title("Hello Maps"); marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_RED));
googleMap.addMarker(marker);
} else{
Toast.makeText(this,"place",Toast.LENGTH_SHORT).show();
MarkerOptions marker = new MarkerOptions().position(
new LatLng(latitude, longitude)).title("Hello Maps");
lat = latitude;
lng = longitude;
// Changing marker icon
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
// adding marker
googleMap.addMarker(marker);
}
} else{
Toast.makeText(this,"data",Toast.LENGTH_SHORT).show();
MarkerOptions marker = new MarkerOptions().position(
new LatLng(latitude, longitude)).title("Hello Maps");
lat = latitude;
lng = longitude;
// Changing marker icon
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
// adding marker
googleMap.addMarker(marker);
}
When I click the default back button whithin the placepicker activity i don't see any of the toast being called
As per the documentation, it should be returning the place.getplace() as null
When the user selects a place, you can retrieve the place by calling PlacePicker.getPlace(). If the user has not selected a place, the method will return null.
Which means it should go to onActivityResult(), but in my case on back and not selecting any places it's not coming to onActivityResult().
Can anyone please help me out with this??
I think you have missed an else statement
if (requestCode == 5 && resultCode == RESULT_OK) {
Toast.makeText(this,"here",Toast.LENGTH_SHORT).show();
if (data != null) {
Place place = PlacePicker.getPlace(data, this);
if (place != null) {
lat = place.getLatLng().latitude;
lng = place.getLatLng().longitude;
MarkerOptions marker = new MarkerOptions().position(
place.getLatLng()).title("Hello Maps"); marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_RED));
googleMap.addMarker(marker);
} else{
Toast.makeText(this,"place",Toast.LENGTH_SHORT).show();
MarkerOptions marker = new MarkerOptions().position(
new LatLng(latitude, longitude)).title("Hello Maps");
lat = latitude;
lng = longitude;
// Changing marker icon
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
// adding marker
googleMap.addMarker(marker);
}
} else{
Toast.makeText(this,"data",Toast.LENGTH_SHORT).show();
MarkerOptions marker = new MarkerOptions().position(
new LatLng(latitude, longitude)).title("Hello Maps");
lat = latitude;
lng = longitude;
// Changing marker icon
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
// adding marker
googleMap.addMarker(marker);
}
}else if(requestCode == 5 && resultCode == RESULT_CANCELED){
// handle no selection here
}
This is a major issue when your application is working over network that is working on the main thread and it wont render appropriate results on UI due to application's business with the main thread. For this please check the android's AsyncTask class that will get you do the job.
you can check youtube link:
Async Task implementation
Android documentation for Async Task
just to get you a quick walk through with the async task, it will implement three functions and on the button where you would want to call this operations to happen on side-thread, you would use AsyncTask.execute(), however:
1) doInBackground() -> your map's function will be called here.
2) onPreExecute() -> tasks or UI updates before the doInBackground is called.
3) onPostExecute() -> after the doInBackground has finished it's job.
Related
I am creating an Android application and have set up a standard Google Maps activity. The application so far just displays the location of the user. The camera is set to focus on the users location initally. I am running into a problem when I try to scroll or drag to a new position on the emulator. I drag and once i lift up the mouse the camera resets to its original position.
onMapReady Code
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
mMap.clear();
LatLng currentLocation = new LatLng(location.getLatitude(), location.getLongitude());
mMap.addMarker(new MarkerOptions().position(currentLocation).title("You Are Here"));
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(currentLocation)
.zoom(25)
.bearing(200)
.tilt(90)
.build();
mMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
try {
List<Address> listAddresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
if (listAddresses.get(0).getAdminArea() != null) {
String address += listAddresses.get(0).getAdminArea();
}
Toast.makeText(MapsActivity.this, address, Toast.LENGTH_SHORT).show();
Log.i("Address", address);
} catch (Exception e) {
e.printStackTrace();
}
}
if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},1);
} else {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
mMap.clear();
LatLng userLocation = new LatLng(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude());
mMap.addMarker(new MarkerOptions().position(userLocation).title("Your Location"));
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(userLocation)
.zoom(25)
.bearing(0)
.tilt(90)
.build();
mMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
}
This is the code I have to display a marker at current location. I also have code to get AdminArea of current location.
I believe the problem is that my code is runnning constantly so that when I attempt to drag the screen, it just resets to where the camera was originally set. The same occurs for the Toast displaying the current location. This does not update wth new information when i change new location
You are correct. You are setting the camera location in your onLocationChange method, which fires constantly (the user's location doesn't have to change much for this method to fire). So, by setting the camera location to the currentLocation, it will keep scrolling the map. Try commenting that out and see what happens.
public void onLocationChanged(Location location) {
mMap.clear();
LatLng currentLocation = new LatLng(location.getLatitude(), location.getLongitude());
mMap.addMarker(new MarkerOptions().position(currentLocation).title("You Are Here"));
//CameraPosition cameraPosition = new CameraPosition.Builder()
// .target(currentLocation)
// .zoom(25)
// .bearing(200)
// .tilt(90)
// .build();
//mMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
I have a KML layer which I form from an input Stream as so:
private KmlLayer layer;
inputStream = new URL("urlHERE").openStream();
layer = new KmlLayer(mMap, inputStream, getApplicationContext());
I want to iterate through each marker in this layer and check if it is within a certain distance to my current location and display it only if it is.
This is the code I am using to currently get the lat/long of the markers.
for (KmlPlacemark placemark: layer.getPlacemarks()) {
String s = placemark.getGeometry().getGeometryObject().toString();
Log.d("placemarks",s);
String start = "(";
String end = ")";
String latlngvalue = s.substring(s.indexOf(start)+1,s.lastIndexOf(end));
String[] strngs = latlngvalue.split(",");
double placemarkerLat = Double.parseDouble(strngs[0]);
double placemarkerLong = Double.parseDouble(strngs[2]);
markerLocation.setLatitude(placemarkerLat);
markerLocation.setLongitude(placemarkerLong);
What I want to do is add the information for each Marker in an ArrayList if they are within a certain distance of the user and then add the markers onto the map.
CHECK THIS LINE
currLocationMarker = mGoogleMap.addMarker(markerOptions); //YOUR ANSWER HERE
#Override
public void onLocationChanged(Location location) {
mGoogleMap.clear();
mHashMap.clear();
allMarkersLists.clear();
favouriteGpList.clear();
//place marker at current position
//mGoogleMap.clear();
if (currLocationMarker != null) {
currLocationMarker.remove();
}
latitude = location.getLatitude();
longitude = location.getLongitude();
latLng = new LatLng(location.getLatitude(), location.getLongitude());
markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)).draggable(true);
currLocationMarker = mGoogleMap.addMarker(markerOptions); //YOUR ANSWER HERE
mHashMap.put(currLocationMarker, 0);
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(11));
mGoogleMap.setMyLocationEnabled(true);
getMapPin();
//If you only need one location, unregister the listener
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
Im facing some problem with my application, specifically with route plot/draw on my google maps. Ive made test route around my house and found out, that GPS providers are not as accurate as similar applications like runtastic or endomondo.
Sometimes Location listener makes incomprehensible changes on my map and the polyline then draws any lines on the map near my location even with perfect GPS signal.
Some other time, it just doesnot work. It does not listen to location change.
Can anybody explain me (like Im five) how does other fitness application get their current position and the plot route onto the google map? Thanks!
//Map Fragment
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.fragment1)).getMap();
map.setMyLocationEnabled(true);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria, true);
//Permission gain
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION},
MY_PERMISSION_ACCESS_COURSE_LOCATION);
return;
}
isLocationEnabled(getApplicationContext());
Location myLocation = locationManager.getLastKnownLocation(provider);
if (myLocation != null) {
latitude = myLocation.getLatitude();
longitude = myLocation.getLongitude();
float zoom = (float) 17.0;
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), zoom));
Log.e("TAG", "GPS is on");
Toast.makeText(MainActivity.this, "latitude:" + latitude + " longitude:" + longitude, Toast.LENGTH_SHORT).show();
} else {
locationManager.requestLocationUpdates(provider, 5000, 0, this);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 10, this);
}
public void onLocationChanged(Location mylocation) {
if (lastLocationloc == null) {
lastLocationloc = mylocation;
}
LatLng lastLatLng = locationToLatLng(lastLocationloc);
LatLng thisLatLng = locationToLatLng(mylocation);
map.addPolyline(new PolylineOptions().add(lastLatLng).add(thisLatLng).width(6).color(Color.RED));
lastLocationloc = mylocation;
Toast.makeText(MainActivity.this, "!!!!Location CHANGE!!!!", Toast.LENGTH_SHORT).show();
}
public static LatLng locationToLatLng(Location loc) {
if (loc != null)
return new LatLng(loc.getLatitude(), loc.getLongitude());
return null;
}
For example, I want to plot it like this:
But my application works its own way..
First of all, you need to take into account the accuracy of the received location. You can get the accuracy using the Location.getAccuracy() method (documentation). The accuracy is measured in meters, so the lower the better:
if (location.getAccuracy() < MINIMUM_ACCURACY) {
// Add the new location to your polyline
}
You can set your MINIMUM_ACCURACY to be 10 meter for example.
On the other hand, you may want to add a new location to your polyline only if your new location is farther than a given distance to your last added location. As an example:
private static final float MINIMUM_ACCURACY = 10;
private static final float MINIMUM_DISTANCE_BETWEEN_POINTS = 20;
private Location lastLocationloc;
// ...
public void onLocationChanged(Location mylocation) {
if (mylocation.getAccuracy() < MINIMUM_ACCURACY) {
if (lastLocationloc == null || lastLocationloc.distanceTo(mylocation) > MINIMUM_DISTANCE_BETWEEN_POINTS) {
// Add the new location to your polyline
lastLocationloc = mylocation;
}
}
}
In my app I have a button to get the location programmatically. Everything went well until I realized that once I added the location marker, each time I was requesting for the location a new marker was added. Therefore I added an if statement that in my opinion is logical enough but does not work as I would like. When I get the location the first time everything is good and a marker is placed. When I push the location button a second time, the marker is deleted and no new marker is added. The app compiles on my phone with no problem. What am I doing wrong?
public void showCurrentLocation(MenuItem item) {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
Location currentLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
if (currentLocation == null){
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.toast_gps_view, null);
Toast toast = new Toast(getApplicationContext());
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
} else {
LatLng latLng = new LatLng(
currentLocation.getLatitude(),
currentLocation.getLongitude()
);
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(latLng, 16);
mMap.animateCamera(update);
if (myPosition != null){
myPosition.remove();
} else {
myPosition = mMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_location_icon))
.position(latLng)
.title("I'm here!"));
}
}
}
You are removing the Marker from the map when the Marker already exists but you are not adding it again.
Note that when you remove a marker from the map it is not null, it's state is undefined.
Change your if to update your Marker's position when the Marker exists:
if (myPosition != null){
myPosition.setPosition(latLng);
} else {
myPosition = mMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_location_icon))
.position(latLng)
.title("I'm here!"));
}
I have implemented the Google Maps API v2 in my Android app. I add a marker and zoom to level 14 when I open the activity containing the map fragment.
Here is how I add/update the marker:
private void updateMarker() {
if(marker != null){
marker.remove();
}
LatLng latlng = new LatLng(Double.parseDouble(latitude), Double.parseDouble(longitude));
marker = mMap.addMarker(new MarkerOptions().position(latlng).title(username));
marker.setIcon((BitmapDescriptorFactory.fromResource(R.drawable.marker)));
mMap.moveCamera(CameraUpdateFactory.newLatLng(latlng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(zoom), 2000, null);
}
It works correctly in debug via Android Studio, using a Nexus 5 with the latest Android installed. The problem is when I run a release build. The marker is added in the correct place, the zoom animation works correctly, zooming to the correct level. But it doesn't move to the marker I added.
Use this
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng, zoom));
Or
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latlng, zoom), 2000, null);
Don't call both method right after each other.
you should pass the result value of CameraUpdateFactory.newLatLngZoom(latlng, zoom) to animateCamera which returns a CameraUpdate that moves the center of the screen to a latitude and longitude specified by a LatLng object, and moves to the given zoom level. You can read more about it here
Implement GoogleApiClient.ConnectionCallbacks and override onConnected method as follows:
#Override
public void onConnected(Bundle bundle) {
Toast.makeText(this, "onConnected", Toast.LENGTH_SHORT).show();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
mGMLastKnownLocation = LocationServices.FusedLocationApi.getLastLocation(mGMGoogleApiClient);
try {
// Get LocationManager object from System Service LOCATION_SERVICE
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (isGPSEnabled)
{
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria, true);
//You can still do this if you like, you might get lucky
mGMLastKnownLocation = locationManager.getLastKnownLocation(provider);
if (mGMLastKnownLocation != null) {
//place marker at current position
mMap.clear();
// Get latitude of the current location
double latitude = mGMLastKnownLocation.getLatitude();
// Get longitude of the current location
double longitude = mGMLastKnownLocation.getLongitude();
// Create a LatLng object for the current location
latLng = new LatLng(latitude, longitude);
// Show the current location in Google Map
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
// Zoom in the Google Map
mMap.animateCamera(CameraUpdateFactory.zoomTo(7));
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(new LatLng(latitude, longitude)).title("You are here!").snippet("Consider yourself located").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE));
mCurrLocation = mMap.addMarker(markerOptions);
} else {
mGMLocationRequest = new LocationRequest();
mGMLocationRequest.setInterval(5000); //5 seconds
mGMLocationRequest.setFastestInterval(3000); //3 seconds
mGMLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
LocationServices.FusedLocationApi.requestLocationUpdates(mGMGoogleApiClient, mGMLocationRequest, this);
}
} else {
//prompt user to enable location
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(i);
}
}
} catch (Exception e) {
Log.e("Error : Location", "Impossible to connect to LocationManager", e);
}
}
Also, implement LocationListener and override the onLocationChanged method as follows:
#Override
public void onLocationChanged(Location location) {
//remove previous current location marker and add new one at current position
if (mCurrLocation != null) {
mCurrLocation.remove();
}
double latitude = location.getLatitude();
double longitude = location.getLongitude();
latLng = new LatLng(latitude, longitude);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(14));
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(new LatLng(latitude, longitude)).title("Position").snippet("I am here").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE));
mCurrLocation = mMap.addMarker(markerOptions);
Toast.makeText(this, "Location Changed", Toast.LENGTH_SHORT).show();
//If you only need one location, unregister the listener
LocationServices.FusedLocationApi.removeLocationUpdates(mGMGoogleApiClient, this);
}
I hope it helps!!