FusedLocationProviderClient何时以及如何停止Looper?

时间:2017-10-03 19:34:21

标签: android multithreading geolocation android-looper

我曾经使用过FusedLocationApi,直到我得知它已被弃用(参见下面的参考资料)。实施起来很简单。正如文档所说,您需要将其与GoogleApiClient一起使用

LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient,
                        locationRequest, this);

我最近更改为FusedLocationProviderClient(参见下面的参考资料)根据教程,我能够成功地使FusedLocationProviderClient正常工作

教程: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());

我遇到的问题是Looper线程。即使应用程序在后台运行,Looper线程也会继续运行。我想在应用程序在后台时暂停位置更新,然后在应用程序位于前台时恢复位置更新。我怎样才能做到这一点?

参考文献:

  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

2 个答案:

答案 0 :(得分:17)

您只需在活动的mFusedLocationClient.removeLocationUpdates(mLocationCallback)中致电onPause()即可。但是,除此之外还有更多内容。

在主要活动中使用FusedLocationProviderClient,GoogleApiClient和LocationRequest的成员变量:

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;
    GoogleApiClient mGoogleApiClient;
    LocationRequest mLocationRequest;

    //..........

也为LocationCallback使用成员变量:

LocationCallback mLocationCallback = new LocationCallback(){
    @Override
    public void onLocationResult(LocationResult locationResult) {
        for (Location location : locationResult.getLocations()) {
            Log.i("MainActivity", "Location: " + location.getLatitude() + " " + location.getLongitude());

        }
    };

};

然后,在mFusedLocationClient中分配onCreate()

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);

    //...............
}

然后在onResume()中,如果设置了GoogleApiClient和FusedLocationProviderClient,则使用它们。否则,这是第一次启动Activity,所以连接GoogleApiClient:

@Override
public void onResume() {
    if (mGoogleApiClient != null && mFusedLocationClient != null) {
        requestLocationUpdates();
    } else {
        buildGoogleApiClient();
    }
}

protected synchronized void buildGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    mGoogleApiClient.connect();
}

@Override
public void onConnected(Bundle bundle) {
    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());
    }
}

最后,在onPause()中,请致电removeLocationUpdates()

@Override
public void onPause() {
    super.onPause();
    if (mFusedLocationClient != null) {
        mFusedLocationClient.removeLocationUpdates(mLocationCallback);
    }
}

答案 1 :(得分:0)

获取位置信息后,请按照他在上述答案中提到的去掉mFusedLocationClient.removeLocationUpdates

if (mFusedLocationClient != null) 
        mFusedLocationClient.removeLocationUpdates(mLocationCallback);

Looper将被称为requestLocationUpdates,直到您将其删除。

在我的问题中,我确实如上所述。下面是我的代码。

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

下面是我的requestLocationUpdates,所以我会收到请求,直到该位置可用为止。

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

注意:有关更多信息,请访问GitHub Repo LINK