2015-06-24 38 views
1

這是有點轉發,我很抱歉,但我最後一次發佈它我認爲我明白了,但顯然不是。當我試圖撥打我使用的服務來獲取此錯誤由於:java.lang.IllegalStateException: GoogleApiClient is not connected yet. 因爲我試圖在GoogleApiClient連接之前調用LocationServices。所以在改變代碼後,我再也沒有收到錯誤信息,實際上我沒有在logcat中得到任何東西。 這是我開始從我的SearchActivity.class服務:服務從Activity中調用,但沒有得到任何logcat?

SearchActivity.class

button = (Button)findViewById(R.id.buttonPressed); 
    button.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      startService(new Intent(getBaseContext(), LocationService.class)); 

     } 
    }); 

這是服務:

LocationService.class

public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks, 
     GoogleApiClient.OnConnectionFailedListener, LocationListener { 

    // LogCat tag 
    private static final String TAG = LocationService.class.getSimpleName(); 

    private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000; 

    private Location mLastLocation; 

    // Google client to interact with Google API 
    private GoogleApiClient mGoogleApiClient; 

    // boolean flag to toggle periodic location updates 
    private boolean mRequestingLocationUpdates = false; 

    private LocationRequest mLocationRequest; 

    // Location updates intervals in sec 
    private static int UPDATE_INTERVAL = 10000; // 10 sec 
    private static int FATEST_INTERVAL = 5000; // 5 sec 
    private static int DISPLACEMENT = 10; // 10 meters 


    @Override 
    public void onCreate() { 
     super.onCreate(); 

     mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(LocationServices.API).build(); 


    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 

     if (mGoogleApiClient != null) { 
      if(mGoogleApiClient.isConnected()) { 
       if (mLocationRequest != null) { 
        togglePeriodicLocationUpdates(); 
       } 
      } 
     } 



     return START_NOT_STICKY; 
    } 

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

    protected void createLocationRequest() { 
     mLocationRequest = new LocationRequest(); 
     mLocationRequest.setInterval(UPDATE_INTERVAL); 
     mLocationRequest.setFastestInterval(FATEST_INTERVAL); 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     mLocationRequest.setSmallestDisplacement(DISPLACEMENT); 
    } 

    private void togglePeriodicLocationUpdates() { 
     mGoogleApiClient.connect(); 
     if(mGoogleApiClient.isConnected()) { 
      if (!mRequestingLocationUpdates) { 

       mRequestingLocationUpdates = true; 

       startLocationUpdates(); 

       Log.d(TAG, "Periodic location updates started!"); 

      } else { 

       mRequestingLocationUpdates = false; 

       // Stopping the location updates 
       stopLocationUpdates(); 

       Log.d(TAG, "Periodic location updates stopped!"); 
      } 
     } 
    } 

    protected void stopLocationUpdates() { 
     LocationServices.FusedLocationApi.removeLocationUpdates(
       mGoogleApiClient, this); 
    } 

    protected void startLocationUpdates() { 
     mGoogleApiClient.connect(); 
     if(mGoogleApiClient.isConnected()) { 
      LocationServices.FusedLocationApi.requestLocationUpdates(
        mGoogleApiClient, mLocationRequest, this); 
     } 
    } 

    @Override 
    public void onConnected(Bundle arg0) { 
     createLocationRequest(); 
    } 

    @Override 
    public void onConnectionSuspended(int arg0) { 
     mGoogleApiClient.connect(); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult result) { 
     Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " 
       + result.getErrorCode()); 
    } 

@Override 
public void onLocationChanged(Location location) { 
    // Assign the new location 
    mLastLocation = location; 

    Toast.makeText(getApplicationContext(), "Location changed!", 
      Toast.LENGTH_SHORT).show(); 
} 

@Override 
public boolean stopService(Intent name) { 
    return super.stopService(name); 
} 

AndroidManifest.xml中

</activity> 
    <service android:name=".LocationService"> 
    </service> 

編輯:

嗯,我想出如何得到它的工作。 但現在我面臨的問題是必須點擊按鈕2次才能正常啓動。只需要改變onStartCommand()一點。

@Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 

     if (mGoogleApiClient != null) { 
      mGoogleApiClient.connect(); 
      if(mGoogleApiClient.isConnected()) { 

       if (mLocationRequest != null) { 

        togglePeriodicLocationUpdates(); 
       } 
      } 
     } 



     return START_NOT_STICKY; 
    } 
+0

你期望的日誌中的logcat看?爲什麼不嘗試調試以查看它是如何運行的? – helleye

+0

對於初學者來說,這個'Log.d(標籤,「定期位置更新開始!」); '和'Log.i(TAG, 「連接失敗:ConnectionResult.getErrorCode()=」 + result.getErrorCode());' – Ivan

+0

當代碼調用connect()來連接到GoogleApi LocationServices,發生連接處理* * **異步。當執行線程從您的調用返回connect()時,您還沒有可用的連接。如果連接成功建立,則調用onConnected()回調。只有在那時你纔有一個可用的mGoogleApiClient。您應該查看一些[可用文檔](https://developers.google.com/android/guides/api-client#HandlingFailures)以更好地理解此處理。這有點複雜。 –

回答

0

你應該閱讀GoogleApiClient的文件,特別是(對於眼下的問題)的connect() method。我突出了相關部分:

將客戶端連接到Google Play服務。 立即返回 ,並在後臺連接到服務。如果 連接成功,則調用onConnected(Bundle)並將 入隊。在失敗時,調用onConnectionFailed(ConnectionResult) 。

如果客戶端已經連接或連接,此方法沒有任何內容 。

所以,這是目前與您的代碼發生:

  1. 單擊該按鈕來啓動服務。
  2. 您在onCreate()中創建GoogleApiClient。
  3. 您在onStartCommand中調用connect(),onStartCommand會在後臺連接時立即返回。
  4. 但是,您檢查isConnected(),因爲連接仍在繼續,您什麼都不做,並從onStartCommand返回。
  5. 稍後,您再次點擊按鈕啓動服務。
  6. 因爲它已經被創建,它直接進入onStartCommand。
  7. 至此,該GoogleApiClient已連接的,所以一切按預期工作。

你應該做的是落實onConnected()。從那裏,調用togglePeriodicLocationUpdates()而不是在onStartCommand()中做。這將完成你想要的:

  1. 點擊按鈕啓動服務。
  2. 服務在onCreate()中創建GoogleApiClient。
  3. 服務在onStartCommand()中啓動連接。
  4. 在將來某個時候,建立連接和服務調用togglePeriodicLocationUpdates()從onConnected()。
相關問題