I have implemented Google maps v2 for Android app. My location, marker everything is showing fine, but when I am on move OnMylocationChange is called and marker is updated, but I have to scroll up or down as the view of my location goes off the map.
How do I update my map to scroll with my current location? Like Google Maps App.
#Override
public void onMyLocationChange(Location location)
{
if (markermylocation != null)
{
markermylocation.remove();
}
curlat = location.getLatitude();
curlong = location.getLongitude();
myLocation(curlat, curlong, username, imageURL, ZOOMVALUE);
}
private void myLocation(double lat, double lng, String name, String url, float zoom)
{
if(firsttime == 1)
{
LatLng ll = new LatLng(lat,lng);
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(ll, zoom);
googleMap.animateCamera(update);
firsttime = 0;
}
final String uname = name;
curlat = lat;
curlong = lng;
Picasso.with(getActivity()).load(url).resize(120, 120).transform(transformation).into(new Target()
{
#Override
public void onBitmapFailed(Drawable arg0)
{
markerOptionsmylocaiton = new MarkerOptions().position(new LatLng(curlat, curlong)).icon(BitmapDescriptorFactory.fromResource(R.drawable.profilepic)).title(uname).anchor(0.5f, 1f);
markermylocation = googleMap.addMarker(markerOptionsmylocaiton);
}
#Override
public void onBitmapLoaded(Bitmap b, LoadedFrom arg1)
{
bitmapMarkermylocation = BitmapDescriptorFactory.fromBitmap(b);
if(b != null)
{
markerOptionsmylocaiton = new MarkerOptions().position(new LatLng(curlat, curlong)).icon(bitmapMarkermylocation).title(uname).anchor(0.5f, 1f);
}
else
{
markerOptionsmylocaiton = new MarkerOptions().position(new LatLng(curlat, curlong)).icon(BitmapDescriptorFactory.fromResource(R.drawable.profilepic)).title(uname).anchor(0.5f, 1f);
}
markermylocation = googleMap.addMarker(markerOptionsmylocaiton);
}
#Override
public void onPrepareLoad(Drawable arg0)
{
}
});
}
Thanks!
I think you just have to remove the if (firsttime == 1) conditional, then the map should recenter whenever your location is updated.
LatLng ll = new LatLng(lat,lng);
CameraUpdate update = null;
if(firsttime == 1) {
update = CameraUpdateFactory.newLatLngZoom(ll, zoom);
firsttime = 0;
} else {
update = CameraUpdateFactory.newLatLng(ll);
}
googleMap.animateCamera(update);
is there a reason you have that in there?
as mentioned in spec:
CameraUpdateFactory is a class containing methods for creating CameraUpdate objects that change a map's camera. To modify the map's camera, call animateCamera(CameraUpdate), animateCamera(CameraUpdate, GoogleMap.CancelableCallback) or moveCamera(CameraUpdate), using a CameraUpdate object created with this class.
read more
so when you are implementing this :
markermylocation = googleMap.addMarker(markerOptionsmylocaiton);
take care of camera move with this methods:
// Showing the current location in Google Map
googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
// Zoom in the Google Map
googleMap.animateCamera(CameraUpdateFactory.zoomTo(15));
Related
i am trying to run a geoquery everytime someone select a place from PlaceAutoComplete fragment and show the markers on the map. It is working fine for the first.When i start the app the icons are are all fine the geoquery is running fine, but when i enter a location second time the app crashes showing an error llegalArgumentException: Unmanaged descriptor below is what i am trying to do.
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
SupportPlaceAutocompleteFragment autocompleteFragment =
(SupportPlaceAutocompleteFragment)
getChildFragmentManager().findFragmentById
(R.id.place_autocomplete_fragment);
autocompleteFragment.setOnPlaceSelectedListener(new
PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
Toast.makeText(getContext(),place.getAddress(),Toast.LENGTH_LONG).show();
Log.i(TAG, "Place: " + place.getName());
Double latitude1 = place.getLatLng().latitude;
Double longitude1 =place.getLatLng().longitude;
LatLng latLng = new LatLng(latitude1,longitude1);
getPeople(latLng); // method to call geofire query
}
#Override
public void onError(Status status) {
// TODO: Handle the error.
Log.i(TAG, "An error occurred: " + status);
}
});
return mMainView;
}
public void getPeople(LatLng latLng1){
mMap.clear();
mMap.addCircle(new CircleOptions()
.center(latLng1)
.radius(2000)
.strokeColor(Color.BLACK)
.fillColor(0x220000FF)
.strokeWidth(1)
);
DatabaseReference ref =
FirebaseDatabase.getInstance().getReference().child("Location");
GeoFire geoFire = new GeoFire(ref);
GeoQuery geoQuery = geoFire.queryAtLocation(new
GeoLocation(latLng1.latitude, latLng1.longitude), 2);
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
#Override
public void onKeyEntered(final String key, GeoLocation location) {
UIDLocation.put(key,location);
marker.setIcon(BitmapDescriptorFactory.fromResource
(R.drawable.ic_mapmarker2));
markers.put(key, marker);
for (Map.Entry<String,GeoLocation> entry : UIDLocation.entrySet())
{
final Marker marker = markers.get(entry.getKey());
if (marker != null) {
DatabaseReference mUser =
FirebaseDatabase.getInstance().getReference().child("People")
.child(string);
mUser.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
String display_name =
dataSnapshot.child("name").getValue().toString();
String status =
dataSnapshot.child("status").getValue().toString();
String image =
dataSnapshot.child("image").getValue().toString();
PeopleInfo info = new PeopleInfo();
info.setName(display_name);
info.setStatus(status);
info.setImage(image);
marker.setTag(info);
String iconName = dataSnapshot.child("iconName")
.getValue().toString();
Context context = getContext();
int id = context.getResources().getIdentifier(iconName, "drawable",
context.getPackageName());
String s = String.valueOf(id);
Bitmap icon = BitmapFactory.decodeResource(context.getResources(),id);
marker.setIcon(BitmapDescriptorFactory.fromResource(id));
}
#Override
public void onCancelled(DatabaseError
databaseError) {
}
});
}
}
#Override
public void onMapReady(final GoogleMap googleMap) {
mMap = googleMap;
mUiSettings = mMap.getUiSettings();
mUiSettings.setZoomControlsEnabled(true);
mFusedLocationClient =
LocationServices.getFusedLocationProviderClient(getContext());
Task task= mFusedLocationClient.getLastLocation()
.addOnSuccessListener(getActivity(), new
OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if (location != null) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
LatLng latLng = new LatLng(latitude, longitude);
myPosition = new LatLng(latitude, longitude);
markeroptn = new MarkerOptions();
markeroptn.position(myPosition);
markeroptn.title("You are Here");
mMap.moveCamera(CameraUpdateFactory.newLatLng(myPosition));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(myPosition,10));
getWorkMen(myPosition);
}
}
});
So far what i have learned from the posts on SO that its because the program is trying to set the icon on marker which is already there. I tried clear() map in the begining of getPeople() but still it is showing the same error.It works fine first time. i also tried remove() also but its also not working.
The problem may come from the way you manage the Marker variables. In the code, you store a marker variable as global outside of the method scope. When calling map.clear(), it makes the marker variable invalid and if somehow you still use this variable to set something, it may cause the exception. The same thing happens with the markers Map you use to map key and Marker, it's not being cleared when map.clear().
Try to manage your map elements more carefully, clear each map element dependently and avoid using map.clear().
Suggestion approach:
Create new marker
private void addMarker(String key, LatLng latLng) {
// Clear the current marker before add the new one
if (marker != null) {
marker.remove();
marker = null;
}
// Store new marker to the variable
marker = mMap.addCircle(new CircleOptions()
.center(latLng)
.radius(2000)
.strokeColor(Color.BLACK)
.fillColor(0x220000FF)
.strokeWidth(1)
);
// Add to markers map if needed
markers.put(key, marker);
}
Clear all markers (clear manually every marker variable available, don't use map.clear:
public synchronized void clear() {
// markers is the marker map
for (Marker marker : markers.values()) {
try {
marker.remove();
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
}
}
// Clear all the marker map
markers.clear();
// Marker is the your global marker variable
marker.remove();
}
I am trying to replace mMpap.SetMyPosition(true); function with my own. I had some success on it and when my custom image for "My Position Icon" is tapped, it moves camera to current location with my custom marker.
Everything works fine on it except whenever "My Position Icon" is tapped, it leaves a copy of marker to that position and moves to current location with a new marker.
I am fairly new to Android Development and looking for some help.
My code inside onCreate(Bundle savedInstanceState) is:
ImageView img = (ImageView) findViewById(R.id.myPostionButton);
img.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
getTheLocation();
}
});
And getTheLocation() is:
if (location != null) {
final double latitude = location.getLatitude();
final double longitude = location.getLongitude();
LatLng latLng = new LatLng(latitude, longitude);
final Marker marker = mMap.addMarker(
new MarkerOptions()
.position(new LatLng(latitude, longitude))
.draggable(true)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_marker)));
mMap.setTrafficEnabled(true);
mMap.setMinZoomPreference(10.0f);
mMap.setMaxZoomPreference(20.0f);
//mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 16.0f),4000 , null);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 16.0f));
mMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
#Override
public void onCameraMove() {
LatLng centerOfMap = mMap.getCameraPosition().target;
marker.setPosition(centerOfMap);
}
});
mMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
#Override
public void onCameraIdle() {
LatLng centerOfMap = mMap.getCameraPosition().target;
marker.setPosition(centerOfMap);
double latitude = centerOfMap.latitude;
double longitude = centerOfMap.longitude;
Geocoder geocoder = new Geocoder(getApplicationContext());
try {
List<Address> addressList = geocoder.getFromLocation(latitude, longitude, 1);
String str = addressList.get(0).getAddressLine(0) + ", ";
str += addressList.get(0).getSubLocality() + ", ";
str += addressList.get(0).getLocality() + ", ";
str += addressList.get(0).getCountryCode();
mFromAddress.setText(str);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
And onMapReady(GoogleMap googleMap) is:
mMap = googleMap;
getTheLocation();
Please Help.
You can try any one of the following based on your situation:
1. If you have only one marker in map, before adding the new marker, clear the map using mMap.clear();
2. If you have multiple markers then you have to keep your current marker object as member variable mMarker. Then just before adding the new marker you can use mMarker.remove();.
I am trying to use Geofire to store and display the users that are logged in on a map I am new in android studio as I am able to store location on firebase using geofire
but I am not able to retrieve the stored location from the firebase
Here is my code
public class tracking extends FragmentActivity implements
GeoQueryEventListener,OnMapReadyCallback,
GoogleMap.OnCameraChangeListener{
private static final GeoLocation INITIAL_CENTER = new GeoLocation(30.7333148, 76.7794179);
private static final int INITIAL_ZOOM_LEVEL = 14;
private static final String GEO_FIRE_DB = "https://trace-
5fa8c.firebaseio.com";
private static final String GEO_FIRE_REF = GEO_FIRE_DB + "/_geofire";
private GoogleMap mMap;
private GoogleMap map;
private Circle searchCircle;
private GeoFire geoFire;
private GeoQuery geoQuery;
private Map<String,Marker> markers;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tracking);
// Obtain the SupportMapFragment and get notified when the map is ready
to be used.
SupportMapFragment mapFragment = (SupportMapFragment)
getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync((OnMapReadyCallback) this);
// setup GeoFire
this.geoFire = new GeoFire(FirebaseDatabase.getInstance().getReferenceFromUrl(GEO_FIRE_REF));
// radius in km
this.geoQuery = this.geoFire.queryAtLocation(INITIAL_CENTER, 1);
// setup markers
this.markers = new HashMap<String, Marker>();
}
#Override
protected void onStop() {
super.onStop();
// remove all event listeners to stop updating in the background
this.geoQuery.removeAllListeners();
for (Marker marker: this.markers.values()) {
marker.remove();
}
this.markers.clear();
}
#Override
protected void onStart() {
super.onStart();
// add an event listener to start updating locations again
this.geoQuery.addGeoQueryEventListener(this);
}
#Override
public void onKeyEntered(String key, GeoLocation location) {
// Add a new marker to the map
Marker marker = this.map.addMarker(new MarkerOptions().position(new
LatLng(location.latitude, location.longitude)));
this.markers.put(key, marker);
}
#Override
public void onKeyExited(String key) {
// Remove any old marker
Marker marker = this.markers.get(key);
if (marker != null) {
marker.remove();
this.markers.remove(key);
}
}
#Override
public void onKeyMoved(String key, GeoLocation location) {
// Move the marker
Marker marker = this.markers.get(key);
if (marker != null) {
this.animateMarkerTo(marker, location.latitude, location.longitude);
}
}
#Override
public void onGeoQueryReady() {
}
#Override
public void onGeoQueryError(DatabaseError error) {
new AlertDialog.Builder(this)
.setTitle("Error")
.setMessage("There was an unexpected error querying GeoFire: " +
error.getMessage())
.setPositiveButton(android.R.string.ok, null)
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
}
// Animation handler for old APIs without animation support
private void animateMarkerTo(final Marker marker, final double lat, final
double lng) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final long DURATION_MS = 3000;
final Interpolator interpolator = new
AccelerateDecelerateInterpolator();
final LatLng startPosition = marker.getPosition();
handler.post(new Runnable() {
#Override
public void run() {
float elapsed = SystemClock.uptimeMillis() - start;
float t = elapsed/DURATION_MS;
float v = interpolator.getInterpolation(t);
double currentLat = (lat - startPosition.latitude) * v +
startPosition.latitude;
double currentLng = (lng - startPosition.longitude) * v +
startPosition.longitude;
marker.setPosition(new LatLng(currentLat, currentLng));
// if animation is not finished yet, repeat
if (t < 1) {
handler.postDelayed(this, 16);
}
}
});
}
private double zoomLevelToRadius(double zoomLevel) {
// Approximation to fit circle into view
return 16384000/Math.pow(2, zoomLevel);
}
#Override
public void onCameraChange(CameraPosition cameraPosition) {
LatLng center = cameraPosition.target;
double radius = zoomLevelToRadius(cameraPosition.zoom);
this.searchCircle.setCenter(center);
this.searchCircle.setRadius(radius);
this.geoQuery.setCenter(new GeoLocation(center.latitude,
center.longitude));
// radius in km
this.geoQuery.setRadius(radius/1000);
}
#Override
public void onMapReady(GoogleMap googleMap) {
LatLng latLngCenter = new LatLng(INITIAL_CENTER.latitude,
INITIAL_CENTER.longitude);
this.searchCircle = this.map.addCircle(new
CircleOptions().center(latLngCenter).radius(1000));
this.searchCircle.setFillColor(Color.argb(66, 255, 0, 255));
this.searchCircle.setStrokeColor(Color.argb(66, 0, 0, 0));
this.map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLngCenter,
INITIAL_ZOOM_LEVEL));
this.map.setOnCameraChangeListener(this);
}
}
I am not able to retrieve any location coordinates (log and lat)
please help
thanks in advance
I have an an activity where the main view is Google maps. And I set up a marker when the map is initially loaded, but when I click on it I am not able to get the locality or anything. The maps appears, but I can't click on the marker, or tap or tap on the screen and hold to create a new marker. basically it cannot do anything...And i can't figure out why! Hope you guys can see something that I am not seeing.
Here is my main activity.
public class MapsActivity extends FragmentActivity {
//Maps
private GoogleMap mMap;
//Marker
private Marker marker;
//Location
private LocationListener locationListener = null;
private LocationManager locationManager = null;
private static final float DEFAULTZOOM = 15;
private double longitude_mapsActivity;
private double latitude_from_mapsActivity;
private String cityName_mapsActivity;
private String countryName_mapsActivity;
//ProgressBar
private ProgressBar myPB_MAPS;
//Buttons
private ImageButton fab_doneButton;
//SearchEditText
private EditText editText_Search;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
mMap.animateCamera(CameraUpdateFactory.zoomTo(15), 2000, null);
}
});
//Get user current location.
//myPB_MAPS = (ProgressBar) findViewById(R.id.myPB_MAPS);
//initialize your map
initMap();
//FAB button
fab_doneButton = (ImageButton) findViewById(R.id.activity_maps_FAB_done);
fab_doneButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (countryName_mapsActivity == null) {
Toast.makeText(MapsActivity.this, "Location is null", Toast.LENGTH_SHORT).show();
} else {
Global_Class.getInstance().getValue().countryName_GLOBAL = countryName_mapsActivity;
Global_Class.getInstance().getValue().cityName_GLOBAL = cityName_mapsActivity;
Global_Class.getInstance().getValue().longitude_user_GLOBAL = longitude_mapsActivity;
Global_Class.getInstance().getValue().latitude_user_GLOBAL = latitude_from_mapsActivity;
//Go to make sure we're sending all the GPS info, so we set geoLocationFromMapsIsPresent to true.
FinishCard.geoLocationFromMapsIsPresent();
FinishCard.setComingBackFromMaps();
Intent FinishCardIntent = new Intent(MapsActivity.this, FinishCard.class);
startActivity(FinishCardIntent);
}
}
});
//EditText
editText_Search = (EditText) findViewById(R.id.maps_EditText);
editText_Search.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
performSearch();
return true;
}
return false;
}
});
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
}
private void performSearch()
{
String location = editText_Search.getText().toString();
if(location.length() == 0)
{
Toast.makeText(this,"Please enter a location",Toast.LENGTH_SHORT).show();
return;
}
//1-first step
Geocoder gc = new Geocoder(this);
List<Address> list = null;//For this function I only want a single address.
try
{
//3-Third step
list = gc.getFromLocationName(location,10);
}
catch (IOException e)
{
e.printStackTrace();
}
//4-Fourth step
Address add = list.get(0);//Give me the first and only item of the list.
//5-fifth step
String locality = add.getLocality();//So if you enter Taj mahal you get Agra, the place where its at, thats what Address locality does.
double lat = add.getLatitude();
double lng = add.getLongitude();
//GoToLocation() method
gotoLocation(lat, lng, DEFAULTZOOM);
//For Removing existing markers.
if(marker != null)
{
marker.remove();
}
MarkerOptions options = new MarkerOptions()
.title(locality)
.position(new LatLng(lat, lng))
.draggable(true);
marker = mMap.addMarker(options);
}
private void gotoLocation(double lat, double lng, float zoom)
{
LatLng ll = new LatLng(lat,lng);
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(ll, zoom);
mMap.moveCamera(update);
}
private void setMarker(String locality, String country, double lat, double lng)
{
if(marker != null)
{
marker.remove();
}
MarkerOptions options = new MarkerOptions()
.title(locality)
.position(new LatLng(lat, lng))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE))
.draggable(true);
if(country.length() > 0)
{
options.snippet(country);//Background highlight TEXT SUPER IMPORTANT
}
//.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE));
marker = mMap.addMarker(options);//So here we connect our marker to our map, which is used in initMap.
}
private void initMap()
{
if(mMap == null)
{
if(mMap != null)
{
mMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener()
{
#Override
public void onMapLongClick(LatLng ll) {
Geocoder gc = new Geocoder(MapsActivity.this);
List<Address> list = null;
try {
list = gc.getFromLocation(ll.latitude, ll.longitude, 1);
} catch (IOException e) {
e.printStackTrace();
}
Address add = list.get(0);
MapsActivity.this.setMarker(add.getLocality(), add.getCountryName(), ll.latitude, ll.longitude);//this is where we set the orange marker.
latitude_from_mapsActivity= ll.latitude;
longitude_mapsActivity= ll.longitude;
countryName_mapsActivity = add.getCountryName();
cityName_mapsActivity = add.getLocality();
}
});
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker)
{
LatLng ll = marker.getPosition();
latitude_from_mapsActivity= ll.latitude;
longitude_mapsActivity = ll.longitude;
Geocoder gc = new Geocoder(MapsActivity.this);
//Global_Class.getInstance().getValue().cardLocality = "Paris";
List<Address> list = null;
try
{
list = gc.getFromLocation(ll.latitude, ll.longitude,1);
}
catch (IOException e)
{
e.printStackTrace();
}
try
{
Address add = list.get(0);
countryName_mapsActivity = add.getCountryName();
cityName_mapsActivity = add.getLocality();
return false;
}
catch (IndexOutOfBoundsException e)
{
return false;
}
}
});
mMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() //If you want to drag the original google maps marker you use this method, if you comment this out it will use the orange one.
{
#Override
public void onMarkerDragStart(Marker marker) {
}
#Override
public void onMarkerDrag(Marker marker) {
}
#Override
public void onMarkerDragEnd(Marker marker) {
Geocoder gc = new Geocoder(MapsActivity.this);
List<Address> list = null;
LatLng ll = marker.getPosition();
try {
list = gc.getFromLocation(ll.latitude, ll.longitude, 1);
} catch (IOException e) {
e.printStackTrace();
}
Address add = list.get(0);
marker.setTitle(add.getLocality());
marker.setSnippet(add.getCountryName());
//marker.showInfoWindow();
}
});
}
}
}
}
Here is my xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.daprlabs.swipedeck.GeoLocation.MapsActivity">
<RelativeLayout
android:layout_width="340dp"
android:layout_height="50dp"
android:background="#FFFFFF"
android:elevation="10sp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp">
<EditText
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/maps_EditText"
android:imeOptions="actionSearch"
android:inputType="text"/>
</RelativeLayout>
<ProgressBar
android:layout_width="50dp"
android:layout_height="50dp"
android:id="#+id/myPB_MAPS"
android:layout_marginLeft="150dp"
android:layout_marginTop="55dp"/>
<ImageButton
android:layout_width="70dp"
android:layout_height="70dp"
android:background="#drawable/circle_fab"
android:id="#+id/activity_maps_FAB_done"
android:layout_gravity="right|bottom"
android:src="#drawable/white_plus" />
</fragment>
You are contradicting yourself in your initMap().
Remove the following if statement:
if (mMap == null)
Also only call initMap() after mapFragment.getMapAsync returns. At this point, you know your map is ready to go.
mapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
mMap.animateCamera(CameraUpdateFactory.zoomTo(15), 2000, null);
initMap();
}
});
You are supposed to implement
OnMapReadyCallback
And in turn override
onMapReady
Now you can manipulate the Map within onMapReady. Before that, it is not certain that your Map has actually set properly.
Anything that manipulates the Map like loading markers over it and setting marker click listeners has to happen in onMapReady.
As an example of Map's manipulation at appropriate time, you can take hint from the following code where Map's camera is only set when it has properly set.
public class YourMapFragment extends Fragment implements OnMapReadyCallback {
...
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentPosition,16));
mMap.addMarker(new MarkerOptions()
.position(currentPosition)
.snippet("Lat:" + lat + "Lng:" + log));
}
...
}
I am having trouble using the loactionListener in eclipse for android. I have been googling for a while now an I can't seem to see why this shouldn't work. The only thing I can think of is that maybe it is because my testing device has no sim. (the internet is provided via wifi).
I have used this as a reference and still, nothing.
Could anyone help me with this problem.
here is the relevant parts of my activity:
public class MainMenu extends Activity implements LocationListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_menu);
theMap = ((MapFragment)getFragmentManager().findFragmentById(R.id.the_map)).getMap();
theMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
locMan = (LocationManager)getSystemService(LOCATION_SERVICE);
}
#Override
public void onLocationChanged(Location location) {
final Double lat = location.getLatitude();
final Double lng = location.getLongitude();
LatLng lastLatLng = new LatLng(lat, lng);
String title = getString(new StringLang().textSet(userLang,"marker_title"));
String snippit = getString(new StringLang().textSet(userLang,"marker_snip"));
if(userMarker!=null) userMarker.remove();
userMarker = theMap.addMarker(new MarkerOptions()
.position(lastLatLng)
.title(title)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher))
.snippet(snippit));
reverseGeoCode(lat, lng);
}
}
I was using a different method to display my location on the map, which worked well but it never updated. It always showed my location at the last place I used the GPS, which turns out was 60mile accross the country. I can see this is working but is there a better way of doing this.
Old method:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_menu);
if(findViewById(R.id.the_map) != null){
//map has loaded continue
theMap = ((MapFragment)getFragmentManager().findFragmentById(R.id.the_map)).getMap();
theMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
locMan = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
android.location.Location lastLoc = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
LatLng lastLatLng ;
if(lastLoc == null){
/* Use the LocationManager class to obtain GPS locations */
double latitude = 0;
double longitude = 0;
lastLatLng = new LatLng(latitude, longitude);
lat = latitude;
lng = longitude;
String title = getString(new StringLang().textSet(userLang,"marker_title"));
String snippit = getString(new StringLang().textSet(userLang,"marker_snip"));
if(userMarker!=null) userMarker.remove();
userMarker = theMap.addMarker(new MarkerOptions()
.position(lastLatLng)
.title(title)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.your_loc_icon))
.snippet(snippit));
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(lastLatLng) // Sets the center of the map to user position
.zoom(0) // Sets the zoom
.bearing(90) // Sets the orientation of the camera to east
.tilt(20) // Sets the tilt of the camera to 30 degrees
.build(); // Creates a CameraPosition from the builder
currentLoc = lastLatLng;
theMap.animateCamera (CameraUpdateFactory.newCameraPosition(cameraPosition), 3000, null);
final TextView geoTagText = (TextView)findViewById(R.id.text_geoTag);
geoTagText.setText("We cannot find your current location, please check your settings.");
}else{
double latitude = lastLoc.getLatitude();
double longitude = lastLoc.getLongitude();
lastLatLng = new LatLng(latitude, longitude);
lat = latitude;
lng = longitude;
animateMap(lastLatLng);
}
}else{
theMap = ((MapFragment)getFragmentManager().findFragmentById(R.id.the_map)).getMap();
theMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
locMan = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
android.location.Location lastLoc = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
LatLng lastLatLng;
double latitude = lastLoc.getLatitude();
double longitude = lastLoc.getLongitude();
lastLatLng = new LatLng(latitude, longitude);
lat = latitude;
lng = longitude;
animateMap(lastLatLng);
//no map to load
}
}
#Override
public void onLocationChanged(Location location) {
final Double lat = location.getLatitude();
final Double lng = location.getLongitude();
LatLng lastLatLng = new LatLng(lat, lng);
String title = getString(new StringLang().textSet(userLang,"marker_title"));
String snippit = getString(new StringLang().textSet(userLang,"marker_snip"));
if(userMarker!=null) userMarker.remove();
userMarker = theMap.addMarker(new MarkerOptions()
.position(lastLatLng)
.title(title)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher))
.snippet(snippit));
}
it would also be useful to add that there is button to relocate the user manually if they want.
reLocBtn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
if(menuActive == true){
playSound();
LocationManager loc = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
android.location.Location gpsLoc = (Location) loc.getLastKnownLocation(LocationManager.GPS_PROVIDER);
double lat = gpsLoc.getLatitude();
double lng = gpsLoc.getLongitude();
LatLng lastLatLng = new LatLng(lat, lng);
animateMap(lastLatLng);
}
}
});
I'm not to sure why either method doesn't update, but the second method seams to work better on first load.
You don't appear to be using requestLocationUpdates() anywhere. In that method you pass a LocationListener object that it then calls for location updates.
i.e. in your case:
locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
locMan.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
If you are using Google Maps API v2, you can do it using that, for example:
private GoogleMap.OnMyLocationChangeListener myLocationChangeListener = new GoogleMap.OnMyLocationChangeListener() {
#Override
public void onMyLocationChange(Location location) {
LatLng loc = new LatLng(location.getLatitude(), location.getLongitude());
mMarker = mMap.addMarker(new MarkerOptions().position(loc));
if(mMap != null){
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(loc, 16.0f));
}
}
};
and then set the listener for the map:
mMap.setOnMyLocationChangeListener(myLocationChangeListener);
This will get called when the map first finds the location.
No need for LocationService or LocationManager at all.