2015-09-11 47 views
1

onPerformSync發生時,我需要當前位置,但我不想設置一個獨立的服務,它始終處於活動狀態,請求位置,因爲我的SyncAdapter時期會以指數方式退避,以致同步之間的時間段可能會多個小時分開。在每次同步之間運行位置請求是浪費的。SyncAdapter onPerformSync獲取當前位置

我打算使用GoogleApiClientLocationServices.FusedLocationApi.requestLocationUpdates,然後Thread.sleep(###)線程onPerformSync直到找到一個位置。

但是我讀了requestLocationUpdates需要在main looper and that it makes callbacks on that thread上調用,在這種情況下,我期望它會返回位置結果失敗,因爲我睡在調用它的線程上。

我需要啓動自己的循環線程嗎?

onPerformSync有沒有另一種/更好的方式獲得當前位置?

回答

1

原來我的擔心沒有道理,我的方法沒有錯誤地工作。我已經把下面一個簡便的事例類的情況下,任何人想這樣做:

public class cSyncLocation implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener 
{ 

    // ======================================================= 
    // private vars 
    // ======================================================= 
    private GoogleApiClient moGoogleApiClient; 
    private LocationRequest moLocationRequest; 
    private Location moCurrentLocation; 
    private static final int kTIMEOUT_MILLISECONDS = 2500; 

    // ======================================================= 
    // public static vars 
    // ======================================================= 

    // ======================================================= 
    // public methods 
    // ======================================================= 

    public void Start(Context oContext) 
    { 
     if (moGoogleApiClient == null) 
     { 
      moGoogleApiClient = new GoogleApiClient.Builder(oContext) 
           .addApi(LocationServices.API) 
           .addConnectionCallbacks(this) 
           .addOnConnectionFailedListener(this) 
           .build(); 
     } 
     if (moLocationRequest == null) 
     { 
      moLocationRequest = new LocationRequest(); 

      moLocationRequest.setInterval(1); 
      moLocationRequest.setFastestInterval(1); 
      moLocationRequest.setInterval(1); 
      moLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     } 
     // Start the connection 
     if (moGoogleApiClient != null) 
     { 
      if (!moGoogleApiClient.isConnecting() && !moGoogleApiClient.isConnected()) 
       moGoogleApiClient.connect(); 
      else if (moCurrentLocation == null) 
       LocationServices.FusedLocationApi.requestLocationUpdates(moGoogleApiClient, moLocationRequest, this); 

     } 
    } 

    public void Stop() 
    { 
     if (moGoogleApiClient != null && moGoogleApiClient.isConnected()) 
      LocationServices.FusedLocationApi.removeLocationUpdates(moGoogleApiClient, this); 
     if (moGoogleApiClient != null) 
      moGoogleApiClient.disconnect();  
    } 

    public Location GetLocationBlocking(Context oContext) 
    { 
     if (moCurrentLocation == null) 
     { 
      intTimeout = kTIMEOUT_MILLISECONDS; 
      Start(oContext); 
      while(intTimeout > 0 && aFrmLocationActivity.IsLastLocationExpired(oContext)) 
      { 
       Thread.sleep(100); 
       intTimeout -= 100; 
      } 
      Stop(); 
     } 
     return moCurrentLocation; 
    } 

    // ======================================================= 
    // Location API Events 
    // ======================================================= 

    @Override 
    public void onLocationChanged(Location oLocation) 
    { 
     if (oLocation != null) 
     { 
      moCurrentLocation = oLocation; 
     } 
    } 

    // ======================================================= 
    // Google API Connection Events 
    // ======================================================= 


    @Override 
    public void onConnected(Bundle connectionHint) 
    { 
     // Connected to Google Play services! The good stuff goes here. 
     if (moGoogleApiClient != null) 
     { 
      Location oLocation = LocationServices.FusedLocationApi.getLastLocation(moGoogleApiClient); 
      if (oLocation != null) 
       moCurrentLocation = oLocation; 
      else 
       LocationServices.FusedLocationApi.requestLocationUpdates(moGoogleApiClient, moLocationRequest, this); 
     } 
    } 

    @Override 
    public void onConnectionSuspended(int cause) 
    { 
     //... 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult result) 
    { 
     //... 
    }  


} 

如何使用它,在你onPerformSync方法調用它

cSyncLocation oSyncLocation = new cSyncLocation(); 
Location oLocation = oSyncLocation.GetLocationBlocking(getContext()); 

顯然,你會想添加一些異常處理並處理空位置結果。

+0

它不適用於我,'onLocationChanged'從未被調用過。 –

+0

檢查您在清單中使用權限ACCESS_FINE_LOCATION。如果您的目標是在Android 6.0(API級別23)或更高版本上運行,那麼您將需要向用戶請求訪問您的應用的UI部分中的位置的權限,一旦授權它也可以在同步適配器上工作。但也許它只是在找到位置之前超時。 –

+0

我嘗試使用ACCESS_COARSE_LOCATION權限接收位置。當我將其更改爲ACCESS_FINE_LOCATION時,問題已得到解決。 –