2017-02-23 52 views
1

Я пытаюсь создать приложение Android с местоположениями geofence, которые загружаются из внешнего API. Я использую модификацию для вызова aysnc. Проблема заключается в том, что и googleApiClient, и внешний вызов API являются асинхронными. Поэтому я не знаю, какой из них заканчивается первым, чтобы начать геологию.Как избежать множественных уровней обратного вызова в Android с геообъектами

Если я запустил геообъекты в onConnected()googleApiClient, возможно, у меня еще нет LatLng из API. Но если я начну использовать геообъекты из обратного вызова API, то googleApiClient может еще не загрузиться.

Что я могу сделать, чтобы справиться с этой проблемой, а не просто выполнить вызов асинхронного API в onConnected() из googleApiClient. Я пытаюсь избежать нескольких уровней обратного вызова. Вот мой код, который в настоящее время не работает, потому что я думаю, что результаты API еще не там, когда startGeofences() называется:

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

public GeofenceHelper(Activity context){ 
     this.context = context; 
     permissionsHelper = new PermissionsHelper(context, REQ_PERMISSION); 
     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 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)); 
      for (int i = 0; i < points.size(); i++) { 
       mGeofenceList.add(new Geofence.Builder() 
         .setRequestId(points.get(i).getName()) 
         .setCircularRegion(
           points.get(i).getLatitude(), 
           points.get(i).getLongitude(), 
           points.get(i).getRadius()) 
         .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER 
           | Geofence.GEOFENCE_TRANSITION_EXIT) 
         .setExpirationDuration(Geofence.NEVER_EXPIRE) 
         .build()); 
      } 
     } 
    }); 
} 


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"); 
    startGeofences(); 
    getLastKnownLocation(); 
} 
} 
+0

Try чтобы сделать переоснащение aysnc-вызовов методомConnected(), и когда вы получили ответ на ваши вызовы, вызовите функцию startGeofences(). – Umar

+0

Вы могли бы разработать? Потому что это не то, чего я пытаюсь избежать, как объяснялось в моем оригинальном посте? – Tim

ответ

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

}

+0

Спасибо, сейчас работает – Tim

Смежные вопросы