当onPerformSync
出现时,我需要当前位置,但我不想设置一个始终有效请求位置的单独服务,因为我的SyncAdapter
期间会以指数方式退出,以便同步之间的时间段可以相隔很多小时。在每次同步之间运行位置请求会很浪费。
我计划使用GoogleApiClient
和LocationServices.FusedLocationApi.requestLocationUpdates
然后Thread.sleep(###)
onPerformSync
线程,直到找到位置。
但是我已经读过需要在main looper and that it makes callbacks on that thread上调用requestLocationUpdates
,在这种情况下,我预计它将无法返回位置结果,因为我正在调用它的线程上休眠。
我需要开始自己的looper线程吗?
是否有其他/更好的方式从onPerformSync
获取当前位置?
答案 0 :(得分: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());
显然,您需要添加一些异常处理并处理null位置结果。