1

我想创建一个消息给GCM,每隔几秒发送一次。但一段时间后,我想再次删除locationupdates。为了将数据发送到gcm的intentservice,我使用了pendingintent。现在每次和它发生了很多我得到这个错误:Google API客户端错误,发送位置

产生的原因:

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 

    } 

} 

任何人都知道如何解决这个bug?或者如何解决它?我在网上搜索,但找不到任何东西。

+0

我现在在打电话,所以看不到行号。但是在代码的第83行,客户端没有连接。看看阻塞,直到有一个连接(不要阻止UI线程虽然) –

+0

你能更具体,我怎么才能检查,直到有一个连接?实现一个while循环?或者你能提出一个更好的解决方案吗? –

回答

1

问题是,在您的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(); 
    } 
} 

你也想设置标志为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设置为false意图:

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

它仍然给我一些错误...我不明白为什么,但有时它有时不起作用。当用户点击UI上的一个按钮时,我开始并停止它。 –

+0

当我第一次打电话时,会发送位置信息。然后我删除它们,之后当我想发回位置时,oncreate和onconnected不再被调用。 –

+0

@TimDirks我刚刚更新了答案,让我知道如果这对你有用! –

相关问题