1

いつでも現在の場所が必要ですが、同期間の期間が何時間も離れている可能性があるため、生理が指数関数的に後退するonPerformSyncため、常にアクティブな位置を要求する別のサービスをセットアップしたくありません。SyncAdapter各同期の間に位置情報リクエストを実行するのは無駄です。

場所が見つかるまで、スレッドを使用してGoogleApiClientからスレッドを使用する予定です。LocationServices.FusedLocationApi.requestLocationUpdatesThread.sleep(###)onPerformSync

ただし、メインルーパーrequestLocationUpdatesで呼び出す必要があり、そのスレッドでコールバックを作成することを読みました。その場合、それを呼び出したスレッドでスリープしているため、場所の結果を返すことができないと予想されます。

自分のルーパー スレッドを開始する必要がありますか?

から現在の場所を取得する別の/より良い方法はありonPerformSyncますか?

4

1 に答える 1

1

Turns out my fears were not justified, my method does work without error. I have put together a handy example class below in case anyone else wants to do this:

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) 
    {
        //...
    }       


}

How to use it, in your onPerformSync method call it like this

cSyncLocation oSyncLocation = new cSyncLocation();
Location oLocation = oSyncLocation.GetLocationBlocking(getContext());

Obviously you will want to add some exception handling and deal with null location result.

于 2015-09-14T15:07:18.507 に答える