2016-08-20 91 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; 
}