SyncAdapter onPerformSync 获取当前位置

SyncAdapter onPerformSync get current location

onPerformSync 发生时,我需要当前位置,但我不想设置一个单独的服务,该服务一直处于活动状态,请求位置,因为我的 SyncAdapter 周期呈指数倒退,因此之间的周期同步可能相隔数小时。在每次同步之间进行位置请求 运行 会很浪费。

我计划使用 GoogleApiClientLocationServices.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());

显然您会想要添加一些异常处理并处理空位置结果。