2015-09-11 42 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时,问题已得到解决。 –