Como lidar com as atualizações do Local Listener dentro de um Serviço no Android?

Estou trabalhando em um aplicativo que deve obter a localização precisa do usuário continuamente se o usuário estiver dentro de uma zona específica. As atualizações de localização devem ser salvas em um servidor (Parse.com) para que outros usuários possam obter a localização atual do usuário.

O fluxo é:

Aplicativo onCreate ->inicie o serviço com LocationListener ->onLocationChanged ->salvar novo local no Parse.com ->O método after.com Save da Nuvem Parse.com envia notificação por push aos usuários ->outros usuários recebem notificações via receptor de transmissão ->atualizar marcador de usuário no mapa <-

Questões:

Não tenho certeza sobre como implementar a etapa 4, devo salvar o novo local em análise dentro do método onLocationChanged? devo passá-lo para um BroadcastReciever e salvá-lo em análise lá? ou devo passá-lo para um método estático na minha classe CurrentUser que executará o salvamento no servidor?

Percebi que a documentação requestLocationUpdates diz:

"Este método é indicado para os casos de uso em primeiro plano, mais especificamente para solicitar locais enquanto estiver conectado ao LocationClient. Para casos de uso em segundo plano, recomenda-se a versão PendingIntent do método."

No meu caso, qual método devo usar?

Quais valores devo usar para obter uma localização quase em tempo real sem consumir mais de 5% da energia da bateria por hora?

Minha classe de serviço:

public class UserTracker extends Service implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener, LocationListener{

static int GEOFENCE_STATUS; 
final static int INSIDE_GEOFENCE = 9001, OUTSIDE_GEOFENCE = 9002;

static final int MINIMUM_ACCURACY = 26;

final static int GEOFENCE_RADIUS = 2000;

static final int NULL_LOCATION_ERROR = 7001;

static final int INSIDE_INTERVAL = 10000, INSIDE_FASTEST_INTERVAL = 1000, INSIDE_SMALLEST_DISPLACEMENT = 10;
static final int OUTSIDE_INTERVAL = 300000, OUTSIDE_FASTEST_INTERVAL = 60000, OUTSIDE_SMALLEST_DISPLACEMENT = 100;

static Location eventLocation;

LocationClient lc;

@Override
public void onCreate() {
    super.onCreate();
    eventLocation = new Location("Test");
    lc = new LocationClient(getApplicationContext(), this, this);
}

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

    double eventLat = intent.getDoubleExtra("Latitude", -1);
    double eventLon = intent.getDoubleExtra("Longitude", -1);
    if (eventLat == -1 || eventLon == -1) {
        stopSelf();
        return START_REDELIVER_INTENT;
    }

    eventLocation.setLatitude(eventLat);
    eventLocation.setLongitude(eventLon);

    lc.connect();

    return START_STICKY;
}

public int getGeofenceStatus(Location currentLocation) {
    if (currentLocation == null) {          
        return NULL_LOCATION_ERROR;         
    } 
    if (currentLocation.distanceTo(eventLocation) > GEOFENCE_RADIUS) {
        Log.d(TAG, "User is outside geofence");
        return OUTSIDE_GEOFENCE;
    } else {
        Log.d(TAG, "User is inside geofence");
        return INSIDE_GEOFENCE;
    }
}

public void requestLocationUpdates(int status) {

    GEOFENCE_STATUS = status;

    LocationRequest request = LocationRequest.create();

    switch (status) {
    case NULL_LOCATION_ERROR:
        stopSelf();
        break;
    case INSIDE_GEOFENCE:           
        request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        request.setInterval(INSIDE_INTERVAL);
        request.setFastestInterval(INSIDE_FASTEST_INTERVAL);
        request.setSmallestDisplacement(INSIDE_SMALLEST_DISPLACEMENT);
        break;
    case OUTSIDE_GEOFENCE:
        request.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        request.setInterval(OUTSIDE_INTERVAL);
        request.setFastestInterval(OUTSIDE_FASTEST_INTERVAL);
        request.setSmallestDisplacement(OUTSIDE_SMALLEST_DISPLACEMENT);         
        break;
    }
    lc.requestLocationUpdates(request, this);
}

@Override
public void onLocationChanged(Location location) {
    int newStatus = getGeofenceStatus(location);
    int accuracy = (int) location.getAccuracy(); 

    String message = "Geofence status: " + newStatus + 
            "\nAccuracy: " + accuracy + 
            "\nDistance to event: " + location.distanceTo(eventLocation);
    Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();

    if (newStatus == INSIDE_GEOFENCE && accuracy < MINIMUM_ACCURACY) {
        Log.d(TAG, "Accuracy is good");
                    // do the save on server procees
    }
    if (GEOFENCE_STATUS != newStatus) {
        requestLocationUpdates(newStatus);
    }       
}

@Override
public void onConnectionFailed(ConnectionResult result) {
    Log.d(TAG, "LocationClient connection failed: " + result.getErrorCode());
}

@Override
public void onConnected(Bundle arg0) {
    Location currentLocation = lc.getLastLocation();
    requestLocationUpdates(getGeofenceStatus(currentLocation));
}

@Override
public void onDisconnected() {
    Log.d(TAG, "LocationClient disconnected");
}

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

questionAnswers(0)

yourAnswerToTheQuestion