Google API 客户端错误,发送位置

Google API client bug, sending locations

我想创建每隔几秒向 GCM 发送一条消息。但过了一段时间我想再次删除位置更新。为了将数据发送到 gcm 的 intentservice,我使用了 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.access00(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

    }

}

有人知道如何解决这个错误吗?或者如何解决?我在互联网上搜索但找不到任何东西。

问题是在您的 stopLocationUpdates() 方法中,您在调用 removeLocationUpdates().

之前没有等待 API 连接

解决此问题的一个简单方法是在需要删除位置回调但未连接 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();
    }
}

您还想在 startLocationUpdates() 中将标志设置回 false:

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;
}

然后,为了重新开始位置更新,您可以使用 stopservice 设置为 false 的 Intent 调用 startService()

    Intent i = new Intent(this, LocationUpdate.class);
    i.putExtra("stopservice", false);
    startService(i);