android - onLocationChanged never called - android

I am currently implementing a feature of getting user's current location with Google API.
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); // user location center in map (every update)
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
}
#Override
public void onConnected(#Nullable Bundle bundle) {
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) {
}
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setSmallestDisplacement(DISPLACEMENT)
.setInterval(UPDATE_INTERVAL)
.setFastestInterval(FASTEST_INTERVAL);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}else{
}
}
However, onLocationChanged callback function is never triggered when I requestLocationUpdates in onConnected. I have log several status out, showing that mLocationRequest is created and requestLocationUpdates is called.
Any ideas on this? Thank you all!

Related

mLastLocation: null, always is null, how can solve it?

mLastLocation: null, always is null, how can solve it?
this is my code
private void displayLocation() {
if(ActivityCompat.checkSelfPermission(TrackingOrder.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(TrackingOrder.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
Log.d("Check-1","ok");
requestRuntimePermission();
}
else
{
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
//mLastLocation = LocationServices.getFusedLocationProviderClient(this).getLastLocation().addOnSuccessListener(mGoogleApiClient);
Log.d("Check-2","ok");
Log.d("mLastLocation",String.valueOf(mLastLocation));
if(mLastLocation != null)
{
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
Log.d("Check - latitude",String.valueOf(latitude));
Log.d("Check - longitude",String.valueOf(longitude));
// Add Marker in your location and move the camera
LatLng yourLocation = new LatLng(latitude,longitude);
mMap.addMarker(new MarkerOptions().position(yourLocation).title("Your Location"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(yourLocation));
mMap.animateCamera(CameraUpdateFactory.zoomTo(17.0f));
//After add marker for your location, add marker for this order and draw route
drawRoute(yourLocation,Common.currentRequest.getAddress());
}
else
{
Log.d("Error","Cannot get location");
Toast.makeText(this,"Could'nt get your location", Toast.LENGTH_SHORT).show();
}
}
}
this is my mGoogleApiClient code
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addConnectionCallbacks(this)
.addApi(LocationServices.API).build();
mGoogleApiClient.connect();
}
But when I locad this displayLocation funcation, there is problem
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
Because the mLastLocation still get null.
So where I need to modify?
there has full code
https://luvtas.com/gmap.txt
There are some edge cases when getLastLocation returns null. Look at this question for more information:
LocationClient getLastLocation() return null
Are you testing on emulator or physical device? Do you have GPS turned on? Do you have permissions defined in Manifest.xml?
Also, in your code, you are listening for location updates in onLocationChanged(Location location). You are storing new received location in mLastLocation and then calling displayLocation(). And then you do mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); in displayLocation() and override value received from onLocationChanged. Maybe not intended?

Zoom Google Maps Android Firebase

I'm doing my car tracking application. The problem is that when I zoomed in or out, the zoom restarts its position. And when I look at another part of the map, it returns me to my location. How can I solve that?
public void onLocationChanged(Location location) {
if(getApplicationContext()!=null){
mLastLocation = location;
LatLng latLng = new LatLng(location.getLatitude(),location.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(15));
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
mLocationRequest = LocationRequest.create();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
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(CustomerMapActivity.this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE);
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
The issue is, with every new location update, your are moving and zooming the camera so you need remove
public void onLocationChanged(Location location) {
if(getApplicationContext()!=null){
mLastLocation = location;
LatLng latLng = new LatLng(location.getLatitude(),location.getLongitude());
// remove to stop frequent camera movement
//mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
//mMap.animateCamera(CameraUpdateFactory.zoomTo(15));
}
}
or alternatively, you can increase the location retrieval interval to give user some more time as
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);

Update googlemap Camera location every time location changes

I would like the camera to automatically update and move every time the location changes. Is this possible? I am using onMapReady() and onLocationChanged().
public class MainActivity extends AppCompatActivity implements LocationListener, OnMapReadyCallback {
OnCreate()
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationManager = (LocationManager) (getSystemService(Context.LOCATION_SERVICE));
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(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PICK_FINE_LOCATION_REQUEST);
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PICK_COARSE_LOCATION_REQUEST);
return;
}
locationCurrent = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
onLocationChanged(locationCurrent);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5, this);
mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
onMapReady()
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(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PICK_FINE_LOCATION_REQUEST);
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PICK_COARSE_LOCATION_REQUEST);
return;
}
LatLng latLng = new LatLng(locationCurrent.getLatitude(),locationCurrent.getLongitude());
CameraPosition cameraPosition= new CameraPosition(latLng,15,0,0);
CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition);
googleMap.animateCamera(cameraUpdate);
googleMap.setMyLocationEnabled(true);
googleMap.getUiSettings().setZoomControlsEnabled(true);
map = googleMap;
I have a global variable: Googlemap map;
onLocationChanged()
#Override
public void onLocationChanged(Location location) {
//Log.d("UPDATEMAP","onLocationChanged");
UpdateMap(map,location);}
I made a method called UpdateMap()
public void UpdateMap(GoogleMap map,Location location){
Log.d("UPDATEMAP","UpdateMap");
LatLng latLngUpdate = new LatLng(location.getLatitude(),location.getLongitude());
CameraPosition cameraPosition = new CameraPosition(latLngUpdate,15,0,0);
CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition);
map.animateCamera(cameraUpdate);
}
The error I am getting is that the global variable is equal to null even though I set it in onMapReady().
Any Help will be appreciated.
Thanks Ritvik.
Your map variable is null because onLocationChanged is being called before onMapReady.
To fix it request location updates in the method onMapReady after the variable is assigned.

Why I can't add markers or zoom in my google maps Android app?

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

GoogleMaps API v2 setMyLocationEnabled is different from LocationManager

I am having probably simple question, but i can't figure out, what is wrong.
When i set my location with button on the map, the location is almost 100 exact.
When i use Location manager to get my location, i am getting about 10-20 meters wrong location.
Here is the code:
#Override
public void onMapReady(final GoogleMap 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;
}
mGoogleMap = googleMap;
mGoogleMap.setMyLocationEnabled(true);
Button setLoc = (Button) findViewById(R.id.setLoc);
assert setLoc != null;
setLoc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mGoogleMap.clear();
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
Location location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, false));
latLng = new LatLng(location.getLatitude(), location.getLongitude());
Toast.makeText(MainActivity.this, String.valueOf(latLng), Toast.LENGTH_LONG).show();
//zoom to current position:
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(17));
mGoogleMap.addMarker(new MarkerOptions().position(latLng).title("Your location").anchor(0.0f, 1.0f));
}
});
}
What am i doing wrong? The blue point is not at the same place where my marker is, and the blue point have better precision as i said above.
Thanks!
small UPDATE
when i run the code on emulator, it is almost the same location...hmm, on real device it is different. What could be the problem?
I think it maybe device dependent. You need to change the priority to PRIORITY_HIGH_ACCURACY. Before requesting location updates, your app must connect to the location services and make a location request. Once a a location request is in place you can start the regular updates by calling requestLocationUpdates() do this in the onConnected() callback provided by Google API Client, which is called when the client is ready.
Update location using LocationListener callback. Call requestLocationUpdates(), passing it your instance of the GoogleApiClient, the LocationRequest object, and a LocationListener. Define a startLocationUpdates() method, called from the onConnected() callback.
#Override
public void onConnected(Bundle connectionHint) {
...
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}

Categories

Resources