Comment redémarrer le service après l'application est tué de tâches récentes
J'ai créé un service pour chercher de l'emplacement actuel de l'appareil à intervalles réguliers. Je veux que le service s'exécute en arrière-plan, même si l'application est désactivée à partir d'applications récemment ouvertes. Actuellement, le service s'exécute en arrière-plan uniquement jusqu'à ce que l'app est présent dans les applications récemment ouvertes, mais arrêter immédiatement lorsque l'application est glissée hors (ou tués d'une autre façon).
J'ai essayé toute sorte d'aide disponibles dans le débordement de la pile et pourtant je ne suis pas en mesure de résoudre ce problème. S'il vous plaît aider. Voici mon code pour le service.
package com.packr.services;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ServiceInfo;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import java.text.DateFormat;
import java.util.Date;
/**
* Created by Arindam on 11-Dec-15.
*/
public class LocationService extends Service implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
protected static final String TAG = "packrMATE";
/**
* The desired interval for location updates. Inexact. Updates may be more or less frequent.
*/
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
/**
* The fastest rate for active location updates. Exact. Updates will never be more frequent
* than this value.
*/
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
UPDATE_INTERVAL_IN_MILLISECONDS / 2;
//Keys for storing activity state in the Bundle.
protected final static String REQUESTING_LOCATION_UPDATES_KEY = "requesting-location-updates-key";
protected final static String LOCATION_KEY = "location-key";
protected final static String LAST_UPDATED_TIME_STRING_KEY = "last-updated-time-string-key";
/**
* Provides the entry point to Google Play services.
*/
protected GoogleApiClient mGoogleApiClient;
/**
* Stores parameters for requests to the FusedLocationProviderApi.
*/
protected LocationRequest mLocationRequest;
/**
* Represents a geographical location.
*/
protected Location mCurrentLocation;
/**
* Tracks the status of the location updates request. Value changes when the user presses the
* Start Updates and Stop Updates buttons.
*/
protected Boolean mRequestingLocationUpdates;
/**
* Time when the location was updated represented as a String.
*/
protected String mLastUpdateTime;
@Override
public void onCreate() {
Log.d(TAG,"Service started");
super.onCreate();
mRequestingLocationUpdates = false;
mLastUpdateTime = "";
//Kick off the process of building a GoogleApiClient and requesting the LocationServices
//API.
buildGoogleApiClient();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG,"Service fucking started");
mGoogleApiClient.connect();
if (mGoogleApiClient.isConnected()) {
startLocationUpdates();
}
return Service.START_STICKY;
}
@Override
public void onDestroy() {
mGoogleApiClient.disconnect();
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Connected to GoogleApiClient");
//If the initial location was never previously requested, we use
//FusedLocationApi.getLastLocation() to get it. If it was previously requested, we store
//its value in the Bundle and check for it in onCreate(). We
//do not request it again unless the user specifically requests location updates by pressing
//the Start Updates button.
//
//Because we cache the value of the initial location in the Bundle, it means that if the
//user launches the activity,
//moves to a new location, and then changes the device orientation, the original location
//is displayed as the activity is re-created.
if (mCurrentLocation == null) {
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
Toast.makeText(getApplicationContext(),"Hello Babe",Toast.LENGTH_SHORT).show();
}
//If the user presses the Start Updates button before GoogleApiClient connects, we set
//mRequestingLocationUpdates to true (see startUpdatesButtonHandler()). Here, we check
//the value of mRequestingLocationUpdates and if it is true, we start location updates.
startLocationUpdates();
}
@Override
public void onConnectionSuspended(int i) {
//The connection to Google Play services was lost for some reason. We call connect() to
//attempt to re-establish the connection.
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
@Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
Toast.makeText(this, String.valueOf(location.getLatitude() + " "+ String.valueOf(location.getLongitude())),
Toast.LENGTH_SHORT).show();
Log.e(TAG,"fuck man location found");
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
//Refer to the javadoc for ConnectionResult to see what error codes might be returned in
//onConnectionFailed.
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());
}
protected synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
createLocationRequest();
}
/**
* Sets up the location request. Android has two location request settings:
* {@code ACCESS_COARSE_LOCATION} and {@code ACCESS_FINE_LOCATION}. These settings control
* the accuracy of the current location. This sample uses ACCESS_FINE_LOCATION, as defined in
* the AndroidManifest.xml.
* <p/>
* When the ACCESS_FINE_LOCATION setting is specified, combined with a fast update
* interval (5 seconds), the Fused Location Provider API returns location updates that are
* accurate to within a few feet.
* <p/>
* These settings are appropriate for mapping applications that show real-time location
* updates.
*/
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
//Sets the desired interval for active location updates. This interval is
//inexact. You may not receive updates at all if no location sources are available, or
//you may receive them slower than requested. You may also receive updates faster than
//requested if other applications are requesting location at a faster interval.
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
//Sets the fastest rate for active location updates. This interval is exact, and your
//application will never receive updates faster than this value.
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
/**
* Requests location updates from the FusedLocationApi.
*/
protected void startLocationUpdates() {
//The final argument to {@code requestLocationUpdates()} is a LocationListener
//(http://developer.android.com/reference/com/google/android/gms/location/LocationListener.html).
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
/**
* Removes location updates from the FusedLocationApi.
*/
protected void stopLocationUpdates() {
//It is a good practice to remove location requests when the activity is in a paused or
//stopped state. Doing so helps battery performance and is especially
//recommended in applications that request frequent location updates.
//The final argument to {@code requestLocationUpdates()} is a LocationListener
//(http://developer.android.com/reference/com/google/android/gms/location/LocationListener.html).
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
@Override
public void onTaskRemoved(Intent rootIntent) {
Log.e("FLAGX : ", ServiceInfo.FLAG_STOP_WITH_TASK + "");
Intent restartServiceIntent = new Intent(getApplicationContext(),
this.getClass());
restartServiceIntent.setPackage(getPackageName());
PendingIntent restartServicePendingIntent = PendingIntent.getService(
getApplicationContext(), 1, restartServiceIntent,
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext()
.getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 1000,
restartServicePendingIntent);
super.onTaskRemoved(rootIntent);
}
}
OriginalL'auteur Arindam Dawn | 2015-12-11
Vous devez vous connecter pour publier un commentaire.
Remplacer onTaskRemoved() dans votre service et de l'utilisation de l'alarme manager pour démarrer à nouveau le service. Voici le code de notre application qui fait la même chose et fonctionne très bien:
Que vous pouvez envoyer l'emplacement périodiquement, même dans le cas où le service se fait tuer sur le bas de la mémoire (ou pour toute autre raison), je vous propose de gérer la uncaughtException redémarrer après N secondes. C'est de cette manière que nous avons fait dans notre application qui fonctionne parfaitement:
Remarque: je PENSE, et je me souviens que j'ai vérifié sur Kitkat qui START_STICKY ne fonctionne pas sur Kitkat et en plus de l'API niveaux. Veuillez vérifier cela par vous-même.
PLUS:
Comme vous le faites loc envoyant régulièrement, vous pourriez avoir à envisager la mode de veille profonde. Pour obtenir les choses fonctionnent dans le sommeil profond, l'utilisation WakefulBroadcastReceiver combiné avec AlarmManager. Jetez un oeil à mes autres post Comment utiliser http en mode de veille prolongée.
Mise à JOUR:
Cette solution ne fonctionne pas (en fait, n'ont pas besoin de travailler) si l'utilisateur "FORCER l'ARRÊT", l'application de Paramètres. C'est bon en fait en redémarrant le service n'est pas un bon moyen si l'utilisateur lui-même veut arrêter l'application. Donc, il est très bien.
Grâce à l'Aube, ont un beau codage 😉
J'ai ajouté PLUS de la réponse qui traite sur le mode de veille prolongée. Voir si vous devez prendre soin de cela.
Supposons que l'utilisateur veut réellement l'application pour arrêter l'exécution. Peuvent-ils faire cela? Il peut être agréable pour vous que votre service / processus fonctionne tout le temps, mais c'est vraiment de l'utilisateur prérogative s'il doit ou non faire.
Bon point. Le code ci-dessus de ne pas redémarrer le service si l'utilisateur de Forcer l'Arrêt " l'application de Paramètres. Si c'est la nature de l'application, puis je suis sûr que c'est très bien et on peut repartir si il enlève de l'application de tâches récentes. Dire, mon application est lié à la sécurité. Il permet de suivre l'emplacement de l'utilisateur derrière (moins souvent) donc sa famille sait où il est. Je ne peux pas éviter de redémarrer le service, quand il tue de tâches récentes. La plupart du temps, l'utilisateur intention est de ne pas arrêter l'application elle-même par la suppression de l'app à partir de tâches récentes. Mais forcer l'arrêt de l'app est ce qu'il fait. Du sens ?
OriginalL'auteur cgr
remplacer
return Service.START_NOT_STICKY;
avecreturn START_STICKY;
OriginalL'auteur Hojjat Imani
Si vous SEULEMENT voulez redémarrer le service après il tuer de groupe, simple d'utilisation
Si vous utilisez
START_STICKY
, lorsque vous tuez application de récentes tâche, votre service sera tué (onTaskRemoved
tiré,onDestroy
PAS tiré) PUIS il sera automatiquement commencer à nouveau (onCreate
tiré,onStartComand
tiré)OriginalL'auteur Phan Van Linh