Stop location updates with FusedLocation - android

How do I stop the FusedLocation listener for updates?
This is how I set it up:
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(getActivity());
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
return;
}
for (Location location : locationResult.getLocations()) {
// Update UI with location data
// Write a message to the database
};
};
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
//
} else {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback,
null /* Looper */);
}
How to stop listening for location updates in the onStop method for example?

The official documentation recommends stop locations in onPause method and restart updates in onResume method.
The code will be something like this:
#Override
protected void onPause() {
super.onPause();
stopLocationUpdates();
}
private void stopLocationUpdates() {
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
}
#Override
protected void onResume() {
super.onResume();
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}
private void startLocationUpdates() {
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback,
null /* Looper */);
}
Check this link for more info: https://developer.android.com/training/location/receive-location-updates

Related

Android background Service to check location services is on or off

I am looking for a background service that checks when the location services is on or off.
You can listen location updates using FusedLocationClient:
#Override
protected void onResume() {
super.onResume();
if (requestingLocationUpdates) {
startLocationUpdates();
}
}
private void startLocationUpdates() {
fusedLocationClient.requestLocationUpdates(locationRequest,
locationCallback,
Looper.getMainLooper());
}
locationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
return;
}
for (Location location : locationResult.getLocations()) {
// Update UI with location data
// ...
}
};
};

FusedLocationProviderClient accuracy returns 1500 on some device

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
}
}
};

Problems with Google Location API

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.

FusedLocationProviderClient when and how to stop Looper?

I used to use FusedLocationApi until I learned that it is deprecated (see references below). It was simple to implement. As the documentation says you need to use it in conjunction with GoogleApiClient
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient,
locationRequest, this);
I recently changed to FusedLocationProviderClient (see reference below) Following a tutorial I was able to successfully get FusedLocationProviderClient working
Tutorial: https://github.com/codepath/android_guides/wiki/Retrieving-Location-with-LocationServices-API
// new Google API SDK v11 uses getFusedLocationProviderClient(this)
getFusedLocationProviderClient(this).requestLocationUpdates(mLocationRequest, new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
// do work here
onLocationChanged(locationResult.getLastLocation();
}
},
Looper.myLooper());
The issue I am running into is the Looper thread. Even with the application in the background, the Looper thread continues to run. I would like to pause location updates when the application is in the background and then resume location updates when the application is in the foreground. How can I achieve this?
References:
https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderApi
https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderClient
You just need to call mFusedLocationClient.removeLocationUpdates(mLocationCallback) in onPause() of your Activity. However, there is a bit more to it than just that.
Use member variables for the FusedLocationProviderClient and LocationRequest in your main activity:
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
public class MainActivity extends AppCompatActivity
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
FusedLocationProviderClient mFusedLocationClient;
LocationRequest mLocationRequest;
//..........
Use a member variable for the LocationCallback as well:
LocationCallback mLocationCallback = new LocationCallback(){
#Override
public void onLocationResult(LocationResult locationResult) {
for (Location location : locationResult.getLocations()) {
Log.i("MainActivity", "Location: " + location.getLatitude() + " " + location.getLongitude());
}
};
};
Then, assign mFusedLocationClient in onCreate() :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
requestLocationUpdates();
//...............
}
Then in onResume(), if theFusedLocationProviderClient is set up, then use it.
#Override
public void onResume() {
if (mFusedLocationClient != null) {
requestLocationUpdates();
}
}
public void requestLocationUpdates() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(120000); // two minute interval
mLocationRequest.setFastestInterval(120000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
}
}
And finally, in onPause(), call removeLocationUpdates():
#Override
public void onPause() {
super.onPause();
if (mFusedLocationClient != null) {
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
}
}
After getting location just remove mFusedLocationClient.removeLocationUpdates as he mentioned in above answers.
if (mFusedLocationClient != null)
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
Looper will be called requestLocationUpdates until you remove it.
In my problem, I did as I mention above. Below is my code.
mFusedLocationClient.getLastLocation()
.addOnSuccessListener(new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
// GPS location can be null if GPS is switched off
if (location != null) {
mLocation = location;
if (mFusedLocationClient != null) {
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
}
} else {
startLocationUpdates();
}
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(HomeActivity.this, "Error trying to get last GPS location", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
});
and below is my requestLocationUpdates so I will get a request until the location is available.
private void startLocationUpdates() {
mSettingsClient.checkLocationSettings(mLocationSettingsRequest)
.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
#Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
Log.i(TAG, "All location settings are satisfied.");
getPackageManager().checkPermission(Manifest.permission.ACCESS_FINE_LOCATION, getPackageName());
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback, Looper.myLooper());
getLastLocationNewMethod();
}
})
.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
int statusCode = ((ApiException) e).getStatusCode();
switch (statusCode) {
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Log.i(TAG, "Location settings are not satisfied. Attempting to upgrade " +
"location settings ");
try {
ResolvableApiException rae = (ResolvableApiException) e;
rae.startResolutionForResult(HomeActivity.this, 0x1);
} catch (IntentSender.SendIntentException sie) {
Log.i(TAG, "PendingIntent unable to execute request.");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
String errorMessage = "Location settings are inadequate, and cannot be " +
"fixed here. Fix in Settings.";
Log.e(TAG, errorMessage);
Toast.makeText(HomeActivity.this, errorMessage, Toast.LENGTH_LONG).show();
// mRequestingLocationUpdates = false;
}
getLastLocationNewMethod(); // this method is where I can get location. It is calling above method.
}
});
}
Note: For more information here is GitHub Repo LINK

Getting User location lat lng with API 22

Trying something as simple as the following code, does not seem to work:
I always get in the logs "No Location :("
Am I missing something?
public class MainActivity extends AppCompatActivity implements LocationListener {
LocationManager locationManager;
String provider;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
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;
}
Location location = locationManager.getLastKnownLocation(provider);
if(location != null){
Log.i("Location","Location achieved");
}else{
Log.i("Location","No location :(");
}
}
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
in onCreate():
new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build()
Total code in Activity:
public class MainActivity extends ActionBarActivity implements
ConnectionCallbacks, OnConnectionFailedListener, LocationListener {
#Override
public void onConnected(Bundle connectionHint) {
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
#Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateUI();
}
private void updateUI() {
mLatitudeTextView.setText(String.valueOf(mCurrentLocation.getLatitude()));
mLongitudeTextView.setText(String.valueOf(mCurrentLocation.getLongitude()));
mLastUpdateTimeTextView.setText(mLastUpdateTime);
}
#Override
public void onResume() {
super.onResume();
if (mGoogleApiClient.isConnected() && !mRequestingLocationUpdates) {
startLocationUpdates();
}
}
}
To Stop receiving updates:
#Override
protected void onPause() {
super.onPause();
stopLocationUpdates();
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
If you are running an emulator, make sure to send an location event from the emulator settings. Nevertheless, getLastKnownLocation can always return null. You could use LocationManager#requestLocationUpdates to listen to any location changes instead.

Categories

Resources