SyncAdapter onPerformSync 获取当前位置
SyncAdapter onPerformSync get current location
当 onPerformSync
发生时,我需要当前位置,但我不想设置一个单独的服务,该服务一直处于活动状态,请求位置,因为我的 SyncAdapter
周期呈指数倒退,因此之间的周期同步可能相隔数小时。在每次同步之间进行位置请求 运行 会很浪费。
我计划使用 GoogleApiClient
和 LocationServices.FusedLocationApi.requestLocationUpdates
然后 Thread.sleep(###)
onPerformSync
线程直到找到位置。
但是我读到 requestLocationUpdates
需要在 main looper and that it makes callbacks on that thread 上调用,在这种情况下,我预计它会无法获得 return 定位结果,因为我正在睡在线程上叫它。
我需要开始自己的循环线程吗?
是否有 another/better 方法从 onPerformSync
获取当前位置?
原来我的担心是没有道理的,我的方法确实没有错误。我在下面整理了一个方便的示例 class,以防其他人想要这样做:
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());
显然您会想要添加一些异常处理并处理空位置结果。
当 onPerformSync
发生时,我需要当前位置,但我不想设置一个单独的服务,该服务一直处于活动状态,请求位置,因为我的 SyncAdapter
周期呈指数倒退,因此之间的周期同步可能相隔数小时。在每次同步之间进行位置请求 运行 会很浪费。
我计划使用 GoogleApiClient
和 LocationServices.FusedLocationApi.requestLocationUpdates
然后 Thread.sleep(###)
onPerformSync
线程直到找到位置。
但是我读到 requestLocationUpdates
需要在 main looper and that it makes callbacks on that thread 上调用,在这种情况下,我预计它会无法获得 return 定位结果,因为我正在睡在线程上叫它。
我需要开始自己的循环线程吗?
是否有 another/better 方法从 onPerformSync
获取当前位置?
原来我的担心是没有道理的,我的方法确实没有错误。我在下面整理了一个方便的示例 class,以防其他人想要这样做:
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());
显然您会想要添加一些异常处理并处理空位置结果。