Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  1. https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderApi
  2. https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderClient
like image 380
portfoliobuilder Avatar asked Oct 03 '17 19:10

portfoliobuilder


People also ask

How do I stop requestLocationUpdates?

Use the expiration on your request, after that expirated time, the location services should quit automatically.

How do I use requestLocationUpdates?

Before requesting location updates, your app must connect to location services and make a location request. The lesson on Changing Location Settings shows you how to do this. Once a location request is in place you can start the regular updates by calling requestLocationUpdates() .

What is FusedLocationProviderClient?

Requests location updates with the given request and results delivered to the given callback on the specified Executor . Task<Void> requestLocationUpdates(LocationRequest request, LocationCallback callback, Looper looper)

How do I request location data from fusedlocationproviderclient?

An example is provided below: Once the locationRequest object and the locationCallBack objects are initialized, request location data by calling the FusedLocationProviderClient’s requestLocationUpdates method. Pass the locationRequest and locationCallback objects as parameters.

How does a Fused Location Provider work?

The Fused Location Provider handles the above scenario by tracking the location outdoors via GPS and when the GPS signal drops within the building, it utilizes Wi-Fi. During the switching process from GPS to Wi-Fi, to provide a smoother transition, the device’s internal sensors are used to predict the movement.

What is the Google fused location provider API?

With businesses and corporations requiring location information and monitoring of their various assets, delivering comprehensive location solutions has been a tricky science for many developers. Identifying the growing demand for a convenient location providing service Google introduced the Fused Location Provider API.

What is the use of setmocklocation?

Sets the mock location to be used for the location provider. Sets whether or not the location provider is in mock mode. Key used for the Bundle extra in Location object holding a boolean indicating whether the location was set using setMockLocation (Location). If the value is false this extra is not set.


2 Answers

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);
    }
}
like image 198
Daniel Nugent Avatar answered Oct 09 '22 09:10

Daniel Nugent


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

like image 45
sushildlh Avatar answered Oct 09 '22 08:10

sushildlh