我想收集特定时间段的位置更新,并在最后对位置进行一些操作。我目前记录方法onLocationChanged
的时间。如何收集位置更新以便在onLocationChanged之外进行后续处理
public class LocationProvider implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private static final String TAG = LocationProvider.class.getSimpleName();
private Context mContext;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private long mStartTime;
private long mDuration;
List<Location> locations;
public LocationProvider(Context context) {
mContext = context;
GoogleApiAvailability api = GoogleApiAvailability.getInstance();
if (api.isGooglePlayServicesAvailable(mContext) == ConnectionResult.SUCCESS) {
mGoogleApiClient = new GoogleApiClient.Builder(mContext)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
} else {
Log.e(TAG, "Could not connect to Google Play services");
}
}
@Override
public void onConnected(Bundle bundle) {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG, "onConnectionFailed: " + connectionResult.toString());
}
@Override
public void onConnectionSuspended(int i) {
Log.e(TAG, "GoogleApiClient connection has been suspended: " + String.valueOf(i));
}
@Override
public void onLocationChanged(Location location) {
locations.add(location);
if (System.currentTimeMillis() - mStartTime > mDuration) {
stopTracking();
// do stuff
}
}
public void startTracking(long interval, long fastInterval, long duration) {
mDuration = duration;
locations = new ArrayList<>();
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(interval)
.setFastestInterval(fastInterval);
if (!mGoogleApiClient.isConnected() || !mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
mStartTime = System.currentTimeMillis();
}
private void stopTracking() {
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
}
}
但是,我想离婚这个逻辑,因为我想根据我的需要做不同的事情。我推断,如果我创建了一个用于注册我的位置侦听器的新线程,则可以等待主线程,直到完成位置集合以使用locations
列表。
public class LocationUpdates {
private LocationProvider mLocationProvider;
private Looper mLooper;
public List<Location> gatherUpdates(final Context context,
final long interval,
final long fastInterval,
final long duration)
throws InterruptedException {
long startTime = System.currentTimeMillis();
new Thread() {
@Override
public void run() {
Looper.prepare();
mLooper = Looper.myLooper();
mLocationProvider = new LocationProvider(context);
mLocationProvider.startTracking(interval, fastInterval, duration);
Looper.loop();
}
}.start();
while (System.currentTimeMillis() - startTime < duration) {
}
mLooper.quit();
mLooper.getThread().join();
return mLocationProvider.locations;
}
}
相反,我观察到的是(间隔3秒,持续时间10秒):
- 线达到
gatherUpdates
返回后然而长onLocationChanged
mLocationProvider.startTracking(interval, fastInterval, duration);
被称为用于第一次只有现在
因此,e虽然位置监听器已经注册,但是明显地阻止它接收更新。我无法弄清楚为什么我的逻辑不能达到我期望的目标。
即使没有线程,是否有方法在收集完成后收集一堆位置更新并在onLocationChanged
之外使用它们?
如果downvoter可能好心指出什么是缺乏在这个问题上,我可能会解决这个问题。这个问题的答案仍然是我感兴趣的。 – Reti43