2017-06-06 11 views
0

私は、同期化されたFusedLocationApi.getLastLocation呼び出しを同期化する必要があります。私はJavaの大きな専門家ではないし、私はそれを正しくしたかどうか分からない。Android FusedLocationApi.getLastLocation Synchronously

GoogleApiClientに接続し、ロケーション情報またはエラーが受信されるまでスレッドをブロックする必要があります。 10秒以上のタイムアウトはエラーとして処理する必要があります。

このように動作するか、onConnectedもメインスレッドで呼び出され、その時点でロックされますか?

私はまた、lock.wait(TimeUnit.SECONDS.toMillis(10));が通常の実行で瞬時に続くことに気付きましたが、ステップバイステップのデバッグでは意図したとおりに10秒間待機します。

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

基本的には、セマフォを使用して同様のiOSコードを書き直そうとしています。

var semaphore: DispatchSemaphore! 
var location: CLLocation! 

func lastLocation() -> 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() 
} 
+0

この回答をご覧ください:https://stackoverflow.com/questions/36740758/how-to-return-value-on-googleapiclient-onconnected – Entreco

答えて

1

あなたはFusedLocationApi.getLastLocation()を呼び出して、接続が確立されるまで待機するGoogleApiClient.blockingConnect()を使用することができます。

関連する問題