1

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

我计划使用 aGoogleApiClient然后使用线程LocationServices.FusedLocationApi.requestLocationUpdates,直到找到位置。Thread.sleep(###)onPerformSync

但是,我已经读过requestLocationUpdates需要在主循环器上调用它,并且它会在该线程上进行回调,在这种情况下,我希望它无法返回位置结果,因为我正在调用它的线程上睡觉。

我需要开始自己的弯针线吗?

是否有另一种/更好的方法来获取当前位置onPerformSync

4

1 回答 1

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());

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

于 2015-09-14T15:07:18.507 回答