Ошибка клиента API Google, отправка местоположений

Я хочу создать то, что я отправляю каждые несколько секунд сообщение в GCM. Но через некоторое время я хочу снова удалить локацию с обновлениями. Для отправки данных в сервисную службу gcm я использую pendingintent. Теперь каждый раз, и это часто случается, я получаю эту ошибку:

Вызванный:

java.lang.IllegalStateException: GoogleApiClient is not connected yet.
            at com.google.android.gms.common.internal.n.a(Unknown Source)
            at com.google.android.gms.common.api.b.b(Unknown Source)
            at com.google.android.gms.internal.lt.removeLocationUpdates(Unknown Source)
            at com.example.task_1.Location.LocationUpdate.stopLocationUpdates(LocationUpdate.java:83)
            at com.example.task_1.Location.LocationUpdate.onStartCommand(LocationUpdate.java:52)
            at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2704)
            at android.app.ActivityThread.access$1900(ActivityThread.java:141)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1353)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)

Это мой код:

public class LocationUpdate extends Service implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {
    private static final String TAG = "DRIVER";
    private SharedPreferences pref;
    private String driverId;
    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;
    private Intent mGcmIntentService;
    private PendingIntent mPendingIntent;

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand");
        super.onStartCommand(intent, flags, startId);
        boolean stopService = false;
        if (intent != null)
            stopService = intent.getBooleanExtra("stopservice", false);
        if (stopService)
            stopLocationUpdates();
        return START_STICKY;
    }

    @Override
    public void onCreate() {
        Log.e(TAG, "onCreate");
        pref = getSharedPreferences("driver_app", MODE_PRIVATE);
        driverId = pref.getString("driver_id", "");
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API).addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this).build();
        mGoogleApiClient.connect();
    }

    @Override
    public void onDestroy() {
        Log.e(TAG, "onDestroy");
        super.onDestroy();

    }

    public void stopLocationUpdates() {
        if(!mGoogleApiClient.isConnected()){
            mGoogleApiClient.connect();
        }
        mGcmIntentService = new Intent(this,SendDataIntentService.class);
        mGcmIntentService.putExtra("ID", "FusedLocation");
        mPendingIntent = PendingIntent.getService(this, 0, mGcmIntentService, PendingIntent.FLAG_CANCEL_CURRENT);
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mPendingIntent);
        if (mGoogleApiClient.isConnected())
            mGoogleApiClient.disconnect();
    }
    @Override
    public void onConnectionFailed(ConnectionResult arg0) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onConnected(Bundle arg0) {
        // TODO Auto-generated method stub
        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        mLocationRequest.setInterval(30000);
        startLocationUpdates();
    }
    private void startLocationUpdates() {
        mGcmIntentService = new Intent(this,SendDataIntentService.class);
        mGcmIntentService.putExtra("ID", "FusedLocation");
        mPendingIntent = PendingIntent.getService(this, 0, mGcmIntentService, PendingIntent.FLAG_CANCEL_CURRENT);
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mPendingIntent);
    }

    @Override
    public void onConnectionSuspended(int arg0) {
        // TODO Auto-generated method stub

    }

}

Кто-нибудь знает, как решить эту ошибку? Или как это исправить? Я искал в Интернете, но ничего не могу найти.

1 ответ

Решение

Проблема в том, что в вашем stopLocationUpdates() метод, вы не ожидаете подключения API, прежде чем вызывать removeLocationUpdates(),

Один простой способ исправить это - установить логический флаг, когда вам нужно удалить обратные вызовы местоположения, но API не подключен.

Добавьте переменную-член:

private boolean isRemoving = false;

Затем измените логику, чтобы он ожидал подключения API, прежде чем отменить регистрацию обратных вызовов местоположения.

в stopLocationUpdates() метод:

public void stopLocationUpdates() {
    if(!mGoogleApiClient.isConnected()){
        isRemoving = true; //added
        mGoogleApiClient.connect();
    }
    else {
        mGcmIntentService = new Intent(this, SendDataIntentService.class);
        mGcmIntentService.putExtra("ID", "FusedLocation");
        mPendingIntent = PendingIntent.getService(this, 0, mGcmIntentService, PendingIntent.FLAG_CANCEL_CURRENT);
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mPendingIntent);
        if (mGoogleApiClient.isConnected())
            mGoogleApiClient.disconnect();
    }
}

в onConnected() Перезвоните:

@Override
public void onConnected(Bundle arg0) {

    if (isRemoving){
        stopLocationUpdates();
    }
    else {
        // TODO Auto-generated method stub
        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        mLocationRequest.setInterval(30000);
        startLocationUpdates();
    }
}

Вы также хотели бы установить флаг обратно в false в startLocationUpdates():

private void startLocationUpdates() {
    isRemoving = false; //added
    mGcmIntentService = new Intent(this,SendDataIntentService.class);
    mGcmIntentService.putExtra("ID", "FusedLocation");
    mPendingIntent = PendingIntent.getService(this, 0, mGcmIntentService, PendingIntent.FLAG_CANCEL_CURRENT);
    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mPendingIntent);
}

Также в onCreate():

@Override
public void onCreate() {
    Log.e(TAG, "onCreate");
    isRemoving = false; //added
    pref = getSharedPreferences("driver_app", MODE_PRIVATE);
    driverId = pref.getString("driver_id", "");
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API).addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this).build();
    mGoogleApiClient.connect();
}

Изменить: Чтобы перезапустить обратные вызовы местоположения после того, как они были ранее отменены, вы можете использовать onStartCommand() метод.

изменять onStartCommand() так что он может как остановить, так и запустить обновление местоположения:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.e(TAG, "onStartCommand");
    super.onStartCommand(intent, flags, startId);
    boolean stopService = false;
    if (intent != null) {
        stopService = intent.getBooleanExtra("stopservice", false);
    }

    if (stopService) {
        stopLocationUpdates();
    }
    else{
        isRemoving = false;
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API).addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this).build();
        mGoogleApiClient.connect();
    }
    return START_STICKY;
}

Затем, чтобы перезапустить обновления местоположения, вы должны позвонить startService() с намерением, которое имеет stopservice установить в ложь:

    Intent i = new Intent(this, LocationUpdate.class);
    i.putExtra("stopservice", false);
    startService(i);
Другие вопросы по тегам