如何避免Android中使用地理围栏的多个回调级别

时间:2017-02-23 10:45:26

标签: android api asynchronous google-api geofencing

我正在尝试使用从外部API加载的地理位置位置创建一个Android应用程序。我使用改造来进行aysnc调用。问题是googleApiClient和外部API调用都是异步的。因此,我不知道哪一个首先完成以启动地理围栏。

如果我在onConnected()的{​​{1}}中启动地理围栏,我可能还没有来自API的LatLng。但是,如果我从API的回调中启动地理围栏,则googleApiClient可能尚未加载。

我可以做些什么来处理此问题,而不是仅在googleApiClient的{​​{1}}中执行异步API调用。我试图避免多个回调级别。这是我的代码,目前无效,因为我认为调用onConnected()时API的结果尚不存在:

googleApiClient

1 个答案:

答案 0 :(得分:1)

尝试这种方法

public class GeofenceHelper implements GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener, LocationListener, ResultCallback<Status> {
private List<Geofence> mGeofenceList = new ArrayList<>();
private GoogleApiClient googleApiClient;


private List<Point> pointsList = null;

public GeofenceHelper(Activity context) {
    this.context = context;
    permissionsHelper = new PermissionsHelper(context, REQ_PERMISSION);

    // let both work in parallel
    buildGoogleApiClient();
    geofencePointsRequest();
}

private void startGeofences() {
    Log.i(TAG, "startGeofences()");
    if (!googleApiClient.isConnected()) {
        Log.d(TAG, "Not connected");
        return;
    }
    if (permissionsHelper.checkPermission())
        LocationServices.GeofencingApi.addGeofences(
                googleApiClient,
                getGeofencingRequest(),
                getGeofencePendingIntent()
        ).setResultCallback(this);  // Result processed in onResult()
}

private void registerGeofences() {

    if (pointsList != null) {
        // populate data in list
        for (int i = 0; i < pointsList.size(); i++) {
            mGeofenceList.add(new Geofence.Builder()
                    .setRequestId(pointsList.get(i).getName())
                    .setCircularRegion(
                            pointsList.get(i).getLatitude(),
                            pointsList.get(i).getLongitude(),
                            pointsList.get(i).getRadius())
                    .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER
                            | Geofence.GEOFENCE_TRANSITION_EXIT)
                    .setExpirationDuration(Geofence.NEVER_EXPIRE)
                    .build());
        }

        // this will actually register geofences
        startGeofences();

    }
}

private void geofencePointsRequest() {
    GeofenceAreasRequest response = new GeofenceAreasRequest();
    response.getAllAreas(new GeofenceAreasResponse() {
        @Override
        public void onAreasLoaded(List<Point> points, int code) {
            Log.i(TAG, "Responsecode: " + String.valueOf(code));

            pointsList = points;

            registerGeofences();
        }
    });
}


private GeofencingRequest getGeofencingRequest() {
    Log.d(TAG, "getGeofencingRequest");
    GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
    builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
    builder.addGeofences(mGeofenceList);
    return builder.build();
}

public void start() {
    googleApiClient.connect();
}

public void stop() {
    googleApiClient.disconnect();
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    Log.i(TAG, "google api connected");
    getLastKnownLocation();
    registerGeofences();
}

}