2016-08-20 168 views
1

我有一個Service跟蹤用戶的位置,在我得到用戶的位置時,雖然GoogleApiClient如何防止服務被破壞

它發生了一些時間Service停止,取決於互聯網或模型電話Service停止發送位置到webservice。它好像被摧毀了。

我該如何預防?

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

    private static final String TAG = "LocationService"; 
    public long UPDATE_MILLISECONDS_DEFAULT = 180000; 

    private boolean currentlyProcessingLocation = false; 
    private LocationRequest locationRequest; 
    private GoogleApiClient googleApiClient; 

    @Override 
    public void onCreate() { 
     Log.d(TAG,"Location service create"); 
     super.onCreate(); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     // if we are currently trying to get a location and the alarm manager has called this again, 
     // no need to start processing a new location. 
     if (!currentlyProcessingLocation) { 
      currentlyProcessingLocation = true; 
      startTracking(); 
     } 

     return START_NOT_STICKY; 
    } 

    private void startTracking() { 
     Log.d(TAG, "startTracking"); 

     if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) { 
      googleApiClient = new GoogleApiClient.Builder(this) 
        .addApi(LocationServices.API) 
        .addConnectionCallbacks(this) 
        .addOnConnectionFailedListener(this) 
        .build(); 

      if (!googleApiClient.isConnected() || !googleApiClient.isConnecting()) { 
       googleApiClient.connect(); 
      } 
     } else { 
      Log.e(TAG, "unable to connect to google play services."); 
     } 
    } 

    protected void sendLocationToServer(Location location) { 
      // here I call my webservice and send location 
      Log.d(TAG, "Update to Server location"); 
    } 

    @Override 
    public void onDestroy() { 
     Log.d(TAG,"Destroy service"); 
     stopLocationUpdates(); 
     super.onDestroy(); 

    } 


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

    @Override 
    public void onLocationChanged(Location location) { 
     sendLocationToServer(location); 
    } 

    public void stopLocationUpdates() { 
     if (googleApiClient != null && googleApiClient.isConnected()) { 
      googleApiClient.disconnect(); 
     } 
    } 

    /** 
    * Called by Location Services when the request to connect the 
    * client finishes successfully. At this point, you can 
    * request the current location or start periodic updates 
    */ 
    @Override 
    public void onConnected(Bundle bundle) { 
     Log.d(TAG, "onConnected"); 

     locationRequest = LocationRequest.create(); 
      locationRequest.setInterval(UPDATE_MILLISECONDS_DEFAULT); // milliseconds for default 
      locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); 


     //locationRequest.setFastestInterval(1000); // the fastest rate in milliseconds at which your app can handle location updates 

     LocationServices.FusedLocationApi.requestLocationUpdates(
       googleApiClient, locationRequest, this); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Log.e(TAG, "onConnectionFailed"); 

     stopLocationUpdates(); 
     stopSelf(); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     Log.e(TAG, "GoogleApiClient connection has been suspend"); 
    } 


} 

回答

5

你返回從onStartCommand()START_NOT_STICKY。因此,無論何時操作系統殺死您的Service(例如回收內存),它都不會被重新創建。

更改以下行:

return START_NOT_STICKY; 

要這樣:

return START_STICKY; 

START_STICKYdocumentation

不斷從onStartCommand(Intent, int, int)返回:如果此 服務的過程在開始時被殺(從012返回後)onStartCommand(Intent, int, int)),然後將其保持在開始狀態 ,但不保留此傳遞的意圖。稍後系統會嘗試 重新創建服務。由於它處於啓動狀態,因此 保證在創建 新服務實例後調用onStartCommand(Intent, int, int);如果沒有任何掛起的啓動命令將 傳送到服務中,則將以空對象 對象調用它,因此您必須小心檢查此操作。

注:START_STICKY不會阻止Service被殺死。它只是告訴操作系統儘快重啓(取決於可用資源)。爲了使您的Service不太可能被殺死,您可以撥打startForeground()使其在前臺運行,以便 運行。

0

你只需要改變這行代碼

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    // if we are currently trying to get a location and the alarm manager has called this again, 
    // no need to start processing a new location. 
    if (!currentlyProcessingLocation) { 
     currentlyProcessingLocation = true; 
     startTracking(); 
    } 

    return START_STICKY; 
}