I am google map apis for my current location. I am working on map application in which it first load current position then user can be able to point to any where on the map. My problem is that if i am moving, then my location is again and again moving towards my current position and user is not able to point the desired location on map as it again routes towards its current location. My code is given below, in which i am using code to initialize the map. Your help will be appreciated.
private static final LocationRequest REQUEST = LocationRequest.create()
.setInterval(8000) // 5 seconds
.setFastestInterval(16) // 16ms = 60fps
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
private void setUpMapIfNeeded() {
if (mMap == null) {
mMap = ((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map)).getMap();
mMap.clear();
mMap.setOnMapClickListener(MyLocationActivity.this);
if (mMap != null) {
mMap.setOnMapClickListener(MyLocationActivity.this);
mMap.setMyLocationEnabled(true);
mMap.setBuildingsEnabled(true);
mMap.getUiSettings().setCompassEnabled(false);
mMap.setIndoorEnabled(true);
mMap.setMapType(mMap.MAP_TYPE_NORMAL);
mMap.setTrafficEnabled(true);
}
}
}
private void setUpLocationClientIfNeeded() {
if (mLocationClient == null) {
mLocationClient = new LocationClient(getApplicationContext(),
connectionCallbacks, onConnectionFailedListener);
}
}
ConnectionCallbacks connectionCallbacks = new ConnectionCallbacks() {
#Override
public void onDisconnected() {
}
#Override
public void onConnected(Bundle connectionHint) {
showLoadingDialog();
mLocationClient.requestLocationUpdates(REQUEST, locationListener);
}
};
OnConnectionFailedListener onConnectionFailedListener = new OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult result) {
}
};
OnMyLocationChangeListener onMyLocationChangeListener = new OnMyLocationChangeListener() {
#Override
public void onMyLocationChange(Location location) {
}
};
LocationListener locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
dismissLoadingDialog();
float diff = 0;
if (lastLocation != null) {
diff = location.distanceTo(lastLocation);
}
if ((lastLocation == null) || (diff > 5)) {
LatLng latLng = new LatLng(location.getLatitude(),
location.getLongitude());
CameraPosition cameraPosition = new CameraPosition(latLng, 14,
45, 0);
CameraUpdate cameraUpdate = CameraUpdateFactory
.newCameraPosition(cameraPosition);
mMap.animateCamera(cameraUpdate, 25, null);
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.flag));
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.getUiSettings().setZoomGesturesEnabled(true);
lastLocation = location;
}
}
};
#using_coding there may be many ways to do it, i didn't check this code, but may be it will help you in your scenario.
1: Make a boolean checking in the creation of your activity like:
boolean isFirstTime = true;
In your location listener for the first time make:
mMap.setMyLocationEnabled(true);
And in this column make your isFirstTime to be false and in that block make MyLocationEnabled to be false. In this way if users location is changed then it will check boolean and if it is false then it will not update your current location.
2: Second way is not the solution but you can also do it, like you can set the location request time to be relatively more.
Related
I am currently working on an app with Android studio. This app uses the google maps API.
Recently I managed to initialize the map with my location but for some reason, this does not let me add a marker in my location or make it start with a certain zoom. (You only see a blue dot)
Do you know why? What am I doing wrong?
My map activity code is like this:
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener {
private GoogleMap mMap;
LocationManager locationManager;
String provider;
LatLng myPosition;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
provider = locationManager.getBestProvider(new Criteria(), false);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
locationManager.requestLocationUpdates(provider, 400, 1, this);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap.setMyLocationEnabled(true);
Location location = locationManager.getLastKnownLocation(provider);
if(location != null){
// Getting latitude of the current location
double latitude = location.getLatitude();
// Getting longitude of the current location
double longitude = location.getLongitude();
// Creating a LatLng object for the current location
myPosition = new LatLng(latitude, longitude);
//mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(myPosition,14));
//mMap.addMarker((new MarkerOptions().position(myPosition)));
}
}
#Override
public void onLocationChanged(Location location) {
//mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(myPosition,14));
// mMap.addMarker((new MarkerOptions().position(myPosition)));
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
#Override
protected void onResume() {
super.onResume();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
locationManager.requestLocationUpdates(provider, 400, 1, this);
}
#Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
}
EDIT:
First of all, thanks to everyone who tried to help me.
Second of all, I couldnt make my app work using all the tools you provided me so right now I still want to use location manager. The other reason for me using this is that I hate Android Studio emulator and my LG G3 only accepts API 21 (I think so)
This is the current code. I think it works fine but whenever it starts it starts in the last known location and not in the actual location. I do not know what to put instead of this --> Location locationActual = locationManager.getLastKnownLocation(provider);;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener {
private GoogleMap mMap;
LocationManager locationManager;
String provider;
LatLng myPosition;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
provider = locationManager.getBestProvider(new Criteria(), false);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
locationManager.requestLocationUpdates(provider, 400, 1, this);
/* locationRequest = new LocationRequest();
//locationRequest.setInterval(7500);
//locationRequest.setFastestInterval(5000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);*/
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap.setMyLocationEnabled(true);
Location locationActual = locationManager.getLastKnownLocation(provider);;
if(locationActual != null) {
// Getting latitude of the current location
double latitude = locationActual.getLatitude();
// Getting longitude of the current location
double longitude = locationActual.getLongitude();
// Creating a LatLng object for the current location
myPosition = new LatLng(latitude, longitude);
mMap.moveCamera(CameraUpdateFactory.newLatLng(myPosition));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(myPosition, 16));
}
}
#Override
public void onLocationChanged(Location location) {
Log.i("TESTTAG", "onLocationChanged called");
LatLng currentPosition = new LatLng(location.getLatitude(),location.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLng(currentPosition));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentPosition, 16));
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
#Override
protected void onResume() {
super.onResume();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
locationManager.requestLocationUpdates(provider, 400, 1, this);
}
#Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
}
Add marker in on LocationChanged.
#Override
public void onLocationChanged(Location location) {
if(mMap != null){
Latlng currentPosition = new Latlng(location.latitude, location.longitude);
mMap.addMarker(new MarkerOptions().position(currentPosition));
googleMap.moveCamera(CameraUpdateFactory.newLatLng(currentPosition));
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentPosition, 16));
}
}
Instead of LodcationManger Use FusedLocationProviderApi. The advantage of FusedLocationProviderApi is here.
Complete tutorial here.
Okay let's try to do this the new and better way with FusedLocationApi.
You will need these implements.
implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener
private GoogleMap mMap;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
locationRequest = new LocationRequest();
locationRequest.setInterval(7500);
locationRequest.setFastestInterval(5000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap.setMyLocationEnabled(true);
}
#Override
public void onConnected(#Nullable Bundle bundle) {
requestLocationUpdates();
}
private void requestLocationUpdates() {
Log.i("TESTTAG", "requestLocationUpdates");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{
Manifest.permission.ACCESS_FINE_LOCATION
}, 10);
}
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
Log.i("TESTTAG", "Is connected? requestlocationupdates " + String.valueOf(googleApiClient.isConnected()));
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onLocationChanged(Location location) {
Log.i("TESTTAG", "onLocationChanged called");
Double myLocationLat = location.getLatitude();
Double myLocationLong = location.getLongitude();
LatLng myLocation = new LatLng(myLocationLat, myLocationLong);
mMap.addMarker(new MarkerOptions().position(myLocation));
mMap.moveCamera(CameraUpdateFactory.newLatLng(myLocation));
mMap.animateCamera(CameraUpdateFactory.zoomTo(15.0f));
}
This will 100% work for you. It will crash on first run because of permissions (You need to find a good place to actually ask for your permissions)
LocationRequest.setInterval(7500) means that it will ask for your device position ever 7,5 seconds.
If you try to use this in your project i am certain it will work for you
I developed an application for Android in Eclipse with Google maps. The problem is that the blue dot indicating my current location appears always parallel to the road where I am driving, on roads outside cities. But if you are within the city the point already on top of the road.
I'm using this to get my location on the start of the app:
locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
Location myLocation = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, false));
then I add the blue dot to the map:
googleMap.setMyLocationEnabled(true);
and then I start listening for location changes:
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, time, 1, this);
My location change function:
#Override
public void onLocationChanged(Location location) {
if (location != null) {
Lat1 = location.getLatitude();
Long1 = location.getLongitude();
if (Lat1 != Lat || Long1 != Long) {
Lat = location.getLatitude();
Long = location.getLongitude();
if (startNav == true) {
googleMap.animateCamera(CameraUpdateFactory
.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 17));
b = new LatLng(Lat, Long);
if (a != null) {
String urlTopass = makeURL(b.latitude, b.longitude, a.latitude, a.longitude);
new connectAsyncTask(urlTopass).execute();
}
}
}
}
}
My question is why does the blue dot appear parallel to the street instead of on top of it?
Use the FusedLocationProviderAPI. It is recommended over using the older open source Location APIs, especially since you're already using a Google Map so you are already using Google Play Services.
Simply set up a Location Listener, and update your current location Marker in each onLocationChanged() callback. If you only want one location update, just un-register for callbacks after the first callback returns.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume() {
super.onResume();
if (mGoogleApiClient == null || !mGoogleApiClient.isConnected()){
buildGoogleApiClient();
mGoogleApiClient.connect();
}
if (map == null) {
MapFragment mapFragment = (MapFragment) getFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
}
#Override
public void onMapReady(GoogleMap retMap) {
map = retMap;
setUpMap();
}
public void setUpMap(){
map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
map.setMyLocationEnabled(true);
}
#Override
protected void onPause(){
super.onPause();
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
protected synchronized void buildGoogleApiClient() {
Toast.makeText(this, "buildGoogleApiClient", Toast.LENGTH_SHORT).show();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
public void onConnected(Bundle bundle) {
Toast.makeText(this,"onConnected", Toast.LENGTH_SHORT).show();
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
//mLocationRequest.setSmallestDisplacement(0.1F);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
//remove previous current location Marker
if (marker != null){
marker.remove();
}
double dLatitude = mLastLocation.getLatitude();
double dLongitude = mLastLocation.getLongitude();
marker = map.addMarker(new MarkerOptions().position(new LatLng(dLatitude, dLongitude))
.title("My Location").icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(dLatitude, dLongitude), 8));
}
}
My app uses Google Maps Api, to display user's current location and seems to be working fine except for two issues:
1 User's location is not being updated in realtime unless app is relaunched.
2 I don't know how to resume LocationServices.FusedLocationApi in onResume method, hence once user leaves the app, GPS does not restart.
I tried following most of the suggestions found in tutorials and similar questions on this site (like this Where should I request location updates in A service?) but nothing has worked for my case so far.
Here's my code:
public class MainActivity extends AppCompatActivity
implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener
{
private static final int ERROR_DIALOG_REQUEST = 9001;
GoogleMap mMap;
private GoogleApiClient mLocationClient;
private LocationListener mListener;
private View view;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (servicesOK()) { // If map is available, load it.
setContentView(R.layout.activity_map);
if (initMap()){
mLocationClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
mLocationClient.connect();
} else {
Toast.makeText(this, "Map not connected!", Toast.LENGTH_SHORT).show();
}
} else {
setContentView(R.layout.activity_main);
}
}
public boolean servicesOK (){
// Checks if GooglePlayServices (Google Map) connection is established
int isAvailable = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (isAvailable == ConnectionResult.SUCCESS) {
return true;
} else if (GooglePlayServicesUtil.isUserRecoverableError(isAvailable)) {
Dialog dialog =
GooglePlayServicesUtil.getErrorDialog(isAvailable, this, ERROR_DIALOG_REQUEST);
dialog.show();
} else {
Toast.makeText(this, "Mapping unsuccessful!", Toast.LENGTH_SHORT).show();
}
return false;
}
private boolean initMap() {
if (mMap == null) {
SupportMapFragment mapFragment =
(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mMap = mapFragment.getMap();
}
return (mMap != null);
}
private void gotoLocation(double lat, double lng) {
LatLng latLng = new LatLng(lat, lng);
}
public void showCurrentLocation(MenuItem item) {
Location currentLocation = LocationServices.FusedLocationApi
.getLastLocation(mLocationClient);
if (currentLocation == null) {
Toast.makeText(this, "Couldn't connect to map!", Toast.LENGTH_SHORT).show();
Log.d("Hello", "Couldn't connect to map" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!********************************");
} else {
LatLng latLng = new LatLng(
currentLocation.getLatitude(),
currentLocation.getLongitude()
);
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(
latLng, 15
);
mMap.animateCamera(update);
}
}
#Override
public void onConnected(Bundle connectionHint) {
// Executed when connection is successful
Toast.makeText(this, "Map ready!", Toast.LENGTH_SHORT).show();
Location currentLocation = LocationServices.FusedLocationApi
.getLastLocation(mLocationClient);
LatLng latLng1 = new LatLng(
currentLocation.getLatitude(),
currentLocation.getLongitude()
);
//Adds Marker when map is connected!
MarkerOptions options = new MarkerOptions().position(latLng1).visible(true).title("Me!") .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_VIOLET));
mMap.addMarker(options);
mListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
Toast.makeText(MainActivity.this,
"Location changed!", Toast.LENGTH_SHORT).show();
gotoLocation(location.getLatitude(), location.getLongitude());
}
};
// Requests user's current location
LocationRequest request = LocationRequest.create();
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
request.setInterval(10000); // TODO: 11/12/15 Change this to 90000 (90 secs)!!!!!!!!!!!!!
request.setFastestInterval(3000); // TODO: 11/12/15 Change this to 60000 (60 secs)!!!!!!!!!
LocationServices.FusedLocationApi.requestLocationUpdates(
mLocationClient, request, mListener
);
}
#Override
protected void onPause() { // Stops location updates
super.onPause();
LocationServices.FusedLocationApi.removeLocationUpdates(
mLocationClient, mListener
);
Log.d("Hello", "The map has been paused!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!********************************");
}
#Override
protected void onResume() { // Resumes location updates
super.onResume();
Log.d("Hello", "The map has been resumed!!!!!!!!!!!!!!!!!********************************");
//Moves camera to user's current location!
LocationRequest request = LocationRequest.create();
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
Location currentLocation = LocationServices.FusedLocationApi
.getLastLocation(mLocationClient);
if (currentLocation == null) {
Toast.makeText(this, "Couldn't connect to map!", Toast.LENGTH_SHORT).show();
} else {
LatLng latLng = new LatLng(
currentLocation.getLatitude(),
currentLocation.getLongitude()
);
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(
latLng, 15
);
mMap.animateCamera(update);
}
}
#Override
public void onConnectionSuspended(int i) {
// Executed when connection is stopped
Log.d("Hello", "The connection was suspended!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!********************************");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// Executed when connection is unsuccessful
Log.d("Hello", "The connection failed!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!********************************");
}
}
I think you should call again the
LocationServices.FusedLocationApi.requestLocationUpdates(
mLocationClient, request, mListener);
in the onResume() method and make the LocationRequest request global
You are not starting LocationUpdates in your activity at all. Start it in onConnected(). Refer here.
Once you start location updates, in onResume() you just need to check that GoogleApiClient is connected as well as requestingLocationUpdates has initialized and you start locationUpdates. See this.
PS: your code has other inconsistencies too though, you should probably read the whole guide once and understand the methods accurately.
I finally solved the problem by using this answer.
Rather than onResume() (which didn't work for me after weeks of trying), I used onRestart()
#Override
protected void onRestart(){
super.onRestart();
onConnected(Bundle.EMPTY);
}
And it worked perfectly!
I am using below code to show current location on google maps. But the problem is that if i am moving my location is updating again and again. For the first time loading i want to fix my current location on the map, after that if i am moving then i don't want to update it. I am selecting a point on the map, and if i am moving or after few seconds it again moves to my current location and don't allow user to select desired point. My code is given below, please help me out here.
MarkerOptions markerOptions = new MarkerOptions();
private GoogleMap mMap;
private Location lastLocation = null;
private LocationClient mLocationClient;
LocationListener locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
float diff = 0;
if (lastLocation != null) {
diff = location.distanceTo(lastLocation);
}
if ((lastLocation == null) || (diff > 5)) {
LatLng latLng = new LatLng(location.getLatitude(),
location.getLongitude());
CameraPosition cameraPosition = new CameraPosition(latLng, 20,
45, 0);
CameraUpdate cameraUpdate = CameraUpdateFactory
.newCameraPosition(cameraPosition);
mMap.animateCamera(cameraUpdate, 2000, null);
lastLocation = location;
}
}
};
private void setUpMapIfNeeded() {
if (mMap == null) {
mMap = ((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.mapVirard)).getMap();
mMap.setOnMapClickListener(Virtuvity.this);
if (mMap != null) {
mMap.setOnMapClickListener(Virtuvity.this);
mMap.setMyLocationEnabled(true);
mMap.setBuildingsEnabled(true);
mMap.setIndoorEnabled(true);
mMap.getUiSettings().setCompassEnabled(false);
mMap.setMapType(mMap.MAP_TYPE_NORMAL);
mMap.setTrafficEnabled(true);
mMap.setOnCameraChangeListener(new OnCameraChangeListener() {
#Override
public void onCameraChange(CameraPosition arg0) {
LatLng latLng = arg0.target;
latitude = latLng.latitude;
longitude = latLng.longitude;
}
});
}
}
}
ConnectionCallbacks connectionCallbacks = new ConnectionCallbacks() {
#Override
public void onDisconnected() {
}
#Override
public void onConnected(Bundle connectionHint) {
mLocationClient.requestLocationUpdates(REQUEST, locationListener);
}
};
private void setUpLocationClientIfNeeded() {
if (mLocationClient == null) {
mLocationClient = new LocationClient(getApplicationContext(),
connectionCallbacks, onConnectionFailedListener);
}
}
OnConnectionFailedListener onConnectionFailedListener = new OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult result) {
}
};
#Override
public void onMapClick(LatLng arg0) {
// TODO Auto-generated method stub
}
Inside onLocationChanged if location != null
call mLocationClient.removeUpdates(this);
Using
mMap.setMyLocationEnabled(true)
can set the myLocation layer enable.
But the problem is how to get the myLocation when the user clicks on the button?
I want to get the longitude and latitude.
The Google Maps API location now works, even has listeners, 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.
OnMyLocationChangeListener interface is deprecated.
use com.google.android.gms.location.FusedLocationProviderApi instead. FusedLocationProviderApi provides improved location finding and power usage and is used by the "My Location" blue dot. See the MyLocationDemoActivity in the sample applications folder for example example code, or the Location Developer Guide.
At the moment GoogleMap.getMyLocation() always returns null under every circumstance.
There are currently two bug reports towards Google, that I know of, Issue 40932 and Issue 4644.
Implementing a LocationListener as brought up earlier would be incorrect because the LocationListener would be out of sync with the LocationOverlay within the new API that you are trying to use.
Following the tutorial on Vogella's Site, linked earlier by Pramod J George, would give you directions for the Older Google Maps API.
So I apologize for not giving you a method to retrieve your location by that means. For now the locationListener may be the only means to do it, but I'm sure Google is working on fixing the issue within the new API.
Also sorry for not posting more links, StackOverlow thinks I'm spam because I have no rep.
---- Update on February 4th, 2013 ----
Google has stated that the issue will be fixed in the next update to the Google Maps API via Issue 4644. I am not sure when the update will occur, but once it does I will edit this post again.
---- Update on April 10th, 2013 ----
Google has stated the issue has been fixed via Issue 4644. It should work now.
try this
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = service.getBestProvider(criteria, false);
Location location = service.getLastKnownLocation(provider);
LatLng userLocation = new LatLng(location.getLatitude(),location.getLongitude());
Ensure that you have turned ON the location services on the device.
Else you won't get any location related info.
This works for me,
map = ((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();
map.setMyLocationEnabled(true);
GoogleMap.OnMyLocationChangeListener myLocationChangeListener = new GoogleMap.OnMyLocationChangeListener() {
#Override
public void onMyLocationChange (Location location) {
LatLng loc = new LatLng (location.getLatitude(), location.getLongitude());
map.animateCamera(CameraUpdateFactory.newLatLngZoom(loc, 16.0f));
}
};
map.setOnMyLocationChangeListener(myLocationChangeListener);
}
To get the location when the user clicks on a button call this method in the onClick-
void getCurrentLocation() {
Location myLocation = mMap.getMyLocation();
if(myLocation!=null)
{
double dLatitude = myLocation.getLatitude();
double dLongitude = myLocation.getLongitude();
Log.i("APPLICATION"," : "+dLatitude);
Log.i("APPLICATION"," : "+dLongitude);
mMap.addMarker(new MarkerOptions().position(
new LatLng(dLatitude, dLongitude)).title("My Location").icon(BitmapDescriptorFactory.fromBitmap(Utils.getBitmap("pointer_icon.png"))));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(dLatitude, dLongitude), 8));
}
else
{
Toast.makeText(this, "Unable to fetch the current location", Toast.LENGTH_SHORT).show();
}
}
Also make sure that the
setMyLocationEnabled
is set to true.
Try and see if this works...
Have you tried GoogleMap.getMyLocation()?
I just found this code snippet simple and functional,
try :
public class MainActivity extends ActionBarActivity implements
ConnectionCallbacks, OnConnectionFailedListener {
...
#Override
public void onConnected(Bundle connectionHint) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
}
}}
here's the link of the tutorial : Getting the Last Known Location
try this
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
} else {
// Show rationale and request permission.
}
Try This
public class MyLocationListener implements LocationListener
{
#Override
public void onLocationChanged(Location loc)
{
loc.getLatitude();
loc.getLongitude();
String Text = “My current location is: ” +
“Latitud = ” + loc.getLatitude() +
“Longitud = ” + loc.getLongitude();
Toast.makeText( getApplicationContext(),Text, Toast.LENGTH_SHORT).show();
tvlat.setText(“”+loc.getLatitude());
tvlong.setText(“”+loc.getLongitude());
this.gpsCurrentLocation();
}
It will give the current location.
mMap.setMyLocationEnabled(true);
Location userLocation = mMap.getMyLocation();
LatLng myLocation = null;
if (userLocation != null) {
myLocation = new LatLng(userLocation.getLatitude(),
userLocation.getLongitude());
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(myLocation,
mMap.getMaxZoomLevel()-5));
Only one condition, I tested that it wasn't null was, if you allow enough time to user to touch the "get my location" layer button, then it will not get null value.
the accepted answer works but some of the used methods are now deprecated so I think it is best if I answer this question with updated methods.
this is answer is completely from this guide on google developers
so here is step by step guide:
implement all this in your map activity
MapActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks
in your onCreate:
private GoogleMap mMap;
private Context context;
private TextView txtStartPoint,txtEndPoint;
private GoogleApiClient mGoogleApiClient;
private Location mLastKnownLocation;
private LatLng mDefaultLocation;
private CameraPosition mCameraPosition;
private boolean mLocationPermissionGranted;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
context = this;
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */,
this /* OnConnectionFailedListener */)
.addConnectionCallbacks(this)
.addApi(LocationServices.API)
.addApi(Places.GEO_DATA_API)
.addApi(Places.PLACE_DETECTION_API)
.build();
mGoogleApiClient.connect();
}
in your onConnected :
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(map);
mapFragment.getMapAsync(this);
in your onMapReady :
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Do other setup activities here too, as described elsewhere in this tutorial.
// Turn on the My Location layer and the related control on the map.
updateLocationUI();
// Get the current location of the device and set the position of the map.
getDeviceLocation();
}
and these two are methods in onMapReady :
private void updateLocationUI() {
if (mMap == null) {
return;
}
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
}
if (mLocationPermissionGranted) {
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
} else {
mMap.setMyLocationEnabled(false);
mMap.getUiSettings().setMyLocationButtonEnabled(false);
mLastKnownLocation = null;
}
}
private void getDeviceLocation() {
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
}
if (mLocationPermissionGranted) {
mLastKnownLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
}
// Set the map's camera position to the current location of the device.
float DEFAULT_ZOOM = 15;
if (mCameraPosition != null) {
mMap.moveCamera(CameraUpdateFactory.newCameraPosition(mCameraPosition));
} else if (mLastKnownLocation != null) {
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(mLastKnownLocation.getLatitude(),
mLastKnownLocation.getLongitude()), DEFAULT_ZOOM));
} else {
Log.d("pouya", "Current location is null. Using defaults.");
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mDefaultLocation, DEFAULT_ZOOM));
mMap.getUiSettings().setMyLocationButtonEnabled(false);
}
}
this is very fast , smooth and effective. hope this helps
I would rather use FusedLocationApi since OnMyLocationChangeListener is deprecated.
First declare these 3 variables:
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
private LocationListener mLocationListener;
Define methods:
private void initGoogleApiClient(Context context)
{
mGoogleApiClient = new GoogleApiClient.Builder(context).addApi(LocationServices.API).addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks()
{
#Override
public void onConnected(Bundle bundle)
{
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(1000);
setLocationListener();
}
#Override
public void onConnectionSuspended(int i)
{
Log.i("LOG_TAG", "onConnectionSuspended");
}
}).build();
if (mGoogleApiClient != null)
mGoogleApiClient.connect();
}
private void setLocationListener()
{
mLocationListener = new LocationListener()
{
#Override
public void onLocationChanged(Location location)
{
String lat = String.valueOf(location.getLatitude());
String lon = String.valueOf(location.getLongitude());
Log.i("LOG_TAG", "Latitude = " + lat + " Longitude = " + lon);
}
};
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mLocationListener);
}
private void removeLocationListener()
{
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mLocationListener);
}
initGoogleApiClient() is used to initialize GoogleApiClient object
setLocationListener() is used to setup location change listener
removeLocationListener() is used to remove the listener
Call initGoogleApiClient method to start the code working :) Don't forget to remove the listener (mLocationListener) at the end to avoid memory leak issues.