如何解决涉及PlacePicker的竞争条件?

时间:2015-09-07 18:39:57

标签: android google-places-api

我在PlacePicker活动和我自己的活动之间存在竞争条件,我希望在PlacePicker结束后立即启动。

以下是我的应用的工作原理: 它始于PlaceActivity。在PlaceActivity的onStart中,我连接到GoogleAPI。在onConnected中,我使用Places来确定用户的位置。如果该位置的概率小于.8,则调用PlacePicker(这是它自己的活动)。 Placepicker是使用startActivityForResult创建的。在相应的onActivityResult中,RatingsActivity已启动并从PlacePicker传递到该位置。问题是,在PlacePicker停止后PlaceActivity重新启动和RatingsActivity的开始之间存在竞争。我该如何解决?我知道我可以要求用户按下另一个按钮来查找他们的位置,但我更倾向于在onStart中自动发生。

@Override
public void onStart() {
    super.onStart();
    mGoogleApiClient.connect();
}

@Override
public void onConnected(Bundle bundle) {
    detectCurrentPlace();
}

public void detectCurrentPlace() {
    PendingResult<PlaceLikelihoodBuffer> result = Places.PlaceDetectionApi.getCurrentPlace(mGoogleApiClient, null);

    //Find the most probable place
    //If prob is greater than threshold, assume this is the correct place.
    //Otherwise, open placepicker
    final double thresh = .8;

    //intent.putExtra("com.parse.starter.name", mostProbPlace.getName());
    //intent.putExtra("com.parse.starter.address", mostProbPlace.getAddress());

    result.setResultCallback(new ResultCallback<PlaceLikelihoodBuffer>() {
        @Override
        public void onResult(PlaceLikelihoodBuffer placeLikelihoods) {
            double highestProb = 0;
            PlaceLikelihood mostProbPlace = null;
            for(PlaceLikelihood p : placeLikelihoods) {
                if(p.getLikelihood() > highestProb) {
                    highestProb = p.getLikelihood();
                    mostProbPlace = p;
                }
                StringBuffer types = new StringBuffer();
                for (int type : p.getPlace().getPlaceTypes()) {
                    types.append(", " + type);
                }
                Log.i(TAG, String.format("Place '%s' has liklihood: %g", p.getPlace().getName(), p.getLikelihood()));
                Log.i(TAG, String.format("Website: '%s; Types: %s", p.getPlace().getWebsiteUri(), types));
            }
            placeLikelihoods.release();

            //Log.i(TAG, "Probability of place: " + mostProbPlace.getLikelihood());
            if(highestProb > thresh) {
                //I'm not sure if this line is right
                Intent intent = new Intent(getApplicationContext(), RatingActivity.class);
                intent.putExtra("com.parse.starter.name", mostProbPlace.getPlace().getName());
                intent.putExtra("com.parse.starter.address", mostProbPlace.getPlace().getAddress());
                startActivity(intent);
            }

            else {
               createPlacePicker();
            }

            placeLikelihoods.release();
        }


    });
}

public void createPlacePicker() {
    PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();

    Context context = getApplicationContext();
    try {
        startActivityForResult(builder.build(context), PLACE_PICKER_REQUEST);

    } catch(GooglePlayServicesRepairableException e) {
        e.printStackTrace();
        Log.d(TAG, "REPAIRABLE_SERVICES");
    } catch(GooglePlayServicesNotAvailableException e) {
        e.printStackTrace();
        Log.d(TAG, "NOTAVAILABLE_SERVICES");
    }
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode == PLACE_PICKER_REQUEST) {
        if(resultCode == RESULT_OK) {
            Place place = PlacePicker.getPlace(data, this);
            String toastMsg = String.format("Place: %s", place.getName());
            Toast.makeText(this, toastMsg, Toast.LENGTH_LONG).show();
            Intent intent = new Intent(this, RatingActivity.class);
            intent.putExtra("com.parse.starter.name", place.getName());
            intent.putExtra("com.parse.starter.address", place.getAddress());
            startActivity(intent);
        }
    }
}

1 个答案:

答案 0 :(得分:1)

据我所知,竞争条件是由每次调用detectCurrentPlace时运行onStart的事实引起的。

我认为您只需要在活动开始时存储PlaceActivity的状态,这样您就可以修改onStart的行为,具体取决于它是从发布中调用,还是作为从PlacePicker返回的结果。

class PlaceActivity {
   boolean mRunningPlacePicker;

  @Override
  public void onStart() {
      super.onStart();
      if (mRunningPlacePicker) {
        // we've returned from placepicker - don't run the detectCurrentPlace again 
        // because RatingsActivity has already launched from onActivityResult 
         ...
       } else {
         mGoogleApiClient.connect();
      }
  }

  @Override
  protected void onSaveInstanceState(Bundle outState) {
      super.onSaveInstanceState(outState);
      // save the state in case Android destroys our activity
      outState.putBoolean("mRunningPlacePicker", mRunningPlacePicker);
  }

  @Override
  protected void onRestoreInstanceState(Bundle savedInstanceState) {
      super.onRestoreInstanceState(savedInstanceState);
      // restore the state
      if (savedInstanceState != null) {
          mRunningPlacePicker = savedInstanceState.getBoolean("mRunningPlacePicker");
      }
  }
  @Override
  public void onConnected(Bundle bundle) {
      detectCurrentPlace();
  }

  public void detectCurrentPlace() {
     // do your deciding...
     result.setResultCallback(new ResultCallback<PlaceLikelihoodBuffer>() {
        @Override
        public void onResult(PlaceLikelihoodBuffer placeLikelihoods) {
          ...
          if (highestProb > thresh) {
            ...
          } else {
             // save the fact we are running the place picker
             mRunningPlacePicker = true;
             createPlacePicker();
          }
  }

}