We are using FusedLocationProviderClient to fetch GPS location continuously in our app. We find that the location provided is slightly off (about 200mtrs) and delayed by about 15-20secs. This causes problems while driving.
The code snippet is below. Please let me know what we might be doing wrong, appreciate your help to fix this. If there is a better method to fetch location continuously, please suggest that as well.
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context);
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(500);
locationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
return;
}
Location location = locationResult.getLocations().get(locationResult.getLocations().size() - 1);
if (location != null) {
currLatFusedLoc = location.getLatitude();
currLngFusedLoc = location.getLongitude();
}
};
};
mFusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper());
Related
Iam trying to get current location updates for every 5 minutes and send to server but I am getting it in the foreground but I am not getting it on the background
I used Alarm Manager
I use this code :
mLocationRequest = LocationRequest.create();
mLocationRequest.setInterval(60*1000);
mLocationRequest.setFastestInterval(10*1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if (mLocationCallback == null)
mLocationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
return;
}
for (Location location : locationResult.getLocations()) {
if (location != null) {
if(BuildConfig.DEBUG)
mLastLocation = location;
}
}
}
};
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(MasterApplica tion.getInstance().getApplicationContext());
fusedLocationProviderClient.requestLocationUpdates(mLocationR equest, mLocationCallback, Looper.getMainLooper());
I started using FusedLocationClient and I'm not sure why would I need both an OnSuccessListener and a LocationCallback. Shouldn't just one of these suffice?
private void initLocationCallback(Context context) {
fusedLocationClient = LocationServices.getFusedLocationProviderClient(context);
fusedLocationClient.getLastLocation()
.addOnSuccessListener(new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
onLocationChanged(location);
}
});
locationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult != null) {
for (Location location : locationResult.getLocations()) {
if (location != null) {
onLocationChanged(location);
}
}
}
}
};
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setInterval(INTERVAL);
locationRequest.setFastestInterval(FASTEST_INTERVAL);
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, context.getMainLooper());
}
private void onLocationChanged(Location location) {
// use location...
}
According to documentation when getting lastKnownLocation(), OnSuccessListener should be enough also in rare cases Location might be null.
Personalty I am also using OnSuccessListener()
If you are not interested in the user's exact location at this precise moment, then lastKnownLocation() and OnSuccessListener would suffice and you don't need a LocationCallback.
But if you want precise location and want regular updates in case the user is on the move, then you need to implement the LocationCallback to keep getting location updates. In this case, you would typically want the last known location as getting a location update might take some time.
I am using FusedLocationProviderClient to trace location and I want to get the best location by using getAccuracy() method. I checked this method on some devices and it returns 1500 and sometimes 1700 while it has to be less than a few meters(less than 12). Why is this happening and what should I do?
Thanks in Advance.
My code:
mLocationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
Location location = locationResult.getLastLocation();
float acc = location.getAccuracy();
if (location != null && location.getAccuracy() < 10){
if(preLocation == null){
preLocation = location;
locationChanged(location);
sendLocation(location.getLatitude(), location.getLongitude());
}else if (preLocation.getLatitude() != location.getLatitude() && preLocation.getLongitude() != location.getLongitude()) {
// Logic to handle location object
locationChanged(location);
preLocation = location;
}
}
}
};
Try to set locationRequest priority to High Accuracy like this
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
//Location Permission already granted
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
}
} else {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
}
}
LocationCallback mLocationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
for (Location location : locationResult.getLocations()) {
//Do what you want with the location here
}
}
};
I am getting coordinates with FusedLocationProviderClient in my application on a button click to store into a database. The issue is that when I reboot the phone or the emulator the .getLastLocation() is null and I have to click another time the button i order for this to work. Is there a way to force to get a current position if the value of location from .lastKnownPosition() is null?
// Google fused location client for GPS position
private FusedLocationProviderClient flpc;
// Vars to store GPS info
public Double latitude, longitude;
public Float accuracy;
// Google Fused Client for location
public void getLocation() {
// FusedLocationProviderClient
flpc = LocationServices.getFusedLocationProviderClient(context);
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
......
return;
}
// Get the latest position from device
Task<Location> task = flpc.getLastLocation();
task.addOnSuccessListener(new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if(location!=null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
accuracy = location.getAccuracy();
}
}
});
}
In my button handler I call getLocation() and use latitude, longitude and accuracy to store to the database.
Any help appreciated!
When getLastLocation() is null, you need to make a LocationRequest
private LocationRequest locationRequest;
private LocationCallback locationCallback;
...
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(20 * 1000);
locationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
return;
}
for (Location location : locationResult.getLocations()) {
if (location != null) {
wayLatitude = location.getLatitude();
wayLongitude = location.getLongitude();
txtLocation.setText(String.format(Locale.US, "%s -- %s", wayLatitude, wayLongitude));
}
}
}
};
mFusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
If you don't need continuous updates, you can remove the request once you've received it.
mFusedLocationClient.removeLocationUpdates(locationCallback);
More info here: https://medium.com/#droidbyme/get-current-location-using-fusedlocationproviderclient-in-android-cb7ebf5ab88e
When the phone is rebooted the cached last location is lost so if you didnt open up an app that uses GPS like google maps or something then there will be no last location.
There never has to be a location returned to you, you should always assume it could be null.
If you want to get location, you just need to use LocationCallback as #tenprint said in this thread.
Refer this links
Android get location is null after phone reboot
I am using a simple code and keep getting
java.lang.NullPointerException: Listener must not be null
I am only using a very short and simple code to try and get my current location, yet I can't get it to work. It might has to do something with that "null" at the looper place in the requestLocationUpdates callback. But I am not sure.
I've been trying all day already.
Here is the short code:
public class MainActivity extends AppCompatActivity {
private FusedLocationProviderClient mFusedLocationClient;
private LocationCallback mLocationCallback;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
//
} else {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback,
null /* Looper */);
}
mLocationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
return;
}
for (Location location : locationResult.getLocations()) {
// Update UI with location data
TextView tv = (TextView) findViewById(R.id.tv);
Double latDouble = location.getLatitude();
String latString = latDouble.toString();
tv.setText(latString);
}
};
};
}
All I want is to simply get current location, why is it giving me such hard times? What causes this error?
thanks
You're trying to use mLocationCallback before you initialise it. Just move this code :
mLocationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
return;
}
for (Location location : locationResult.getLocations()) {
// Update UI with location data
TextView tv = (TextView) findViewById(R.id.tv);
Double latDouble = location.getLatitude();
String latString = latDouble.toString();
tv.setText(latString);
}
};
};
before this:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
//
} else {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback,
null /* Looper */);
}
The null in the Looper thread has nothing to do with it. By passing it as null you keep your callbacks on the calling thread.