title: Android FusedLocationApi.getLastLocation Synchronously
body: <p>I need to convert async FusedLocationApi.getLastLocation call to the sync one. I'm not a big expert in Java and I'm not sure I've did it right. </p>
  
  <p>I want to connect to <code>GoogleApiClient</code> and then block calling thread until location information or error is received. Timeout more than 10 seconds should be treated as an error. </p>
  
  <p>Will it work this way or <code>onConnected</code> will be called on main thread as well and it will be locked at that moment?</p>
  
  <p>I also noticed that <code>lock.wait(TimeUnit.SECONDS.toMillis(10));</code> continues instantly in regular runs, but in step-by-step debugging it does wait 10 seconds as intended.</p>
  
  <pre><code>public class SyncLocationService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
  
      public GoogleApiClient mGoogleApiClient;
  
      public SyncLocationService(Context context) {
          mGoogleApiClient = new GoogleApiClient.Builder(context)
                  .addConnectionCallbacks(this)
                  .addOnConnectionFailedListener(this)
                  .addApi(LocationServices.API)
                  .build();
      }
  
      private final Object lock = new Object();
      public android.location.Location mLocation;
  
      @Override
      public android.location.Location lastLocation() {
          mGoogleApiClient.connect();
          synchronized (lock) {
              try {
                  lock.wait(TimeUnit.SECONDS.toMillis(10));
              } catch (InterruptedException e) {
                  Log.i("NativeLocationService", "InterruptedException");
              }
          }
          return mLocation;
      }
  
      @Override
      public void onConnected(@Nullable Bundle bundle) {
          try {
              mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
              mGoogleApiClient.disconnect();
          } catch (SecurityException e) {
              Log.i("NativeLocationService", "SecurityException");
          } finally {
              synchronized (lock) {
                  lock.notify();
              }
          }
      }
  
      @Override
      public void onConnectionSuspended(int i) {
  
      }
  
      @Override
      public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
          synchronized (lock) {
              lock.notify();
          }
      }
  }
  </code></pre>
  
  <p>Basically I'm trying to rewrite similar iOS code which does it's job using semaphore.</p>
  
  <pre><code>var semaphore: DispatchSemaphore!
  var location: CLLocation!
  
  func lastLocation() -&gt; location? {
      self.semaphore = DispatchSemaphore(value: 0)
      self.locationManager.startUpdatingLocation()
      _ = self.semaphore!.wait(timeout: .now() + 10)  // seconds
      self.semaphore = nil
      return self.location
  }
  
  // MARK: - CLLocationManagerDelegate
  func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
      guard let semaphore = self.semaphore else {
          return
      }
      guard let first = locations.first else {
          return
      }
      self.location = first
      self.locationManager.stopUpdatingLocation()
      semaphore.signal()
  }
  </code></pre>