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我剛剛更新了答案,讓我知道如果這對你有用! –

相關問題