J'ai un service exécutant pour suivre l'emplacement de l'utilisateur à un intervalle de temps spécifique. J'ai utilisé le service de premier plan pour les périphériques Oreo & Post-Oreo et le service pour les périphériques pré-Oreo. Le service fonctionne bien lorsque l'application est minimisée mais lorsque je supprimai l'application de la liste d'applications minimisée, le service est également tué. J'ai testé cela sur un périphérique Xiaomi avec Android 9. Comment conserver le service en marche lorsque l'utilisateur tue l'application.
manifeste: p>
public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{ public static final String TAG = LocationService.class.getSimpleName(); private static final long LOCATION_REQUEST_INTERVAL = 3000; private static final float LOCATION_REQUEST_DISPLACEMENT = 5.0f; private GoogleApiClient mGoogleApiClient; private FusedLocationProviderClient mFusedLocationProviderClient; private LocationRequest mLocationRequest; private LocationCallback mLocationCallback; @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); Log.d ("On Create-------> ","Inside on create"); buildGoogleApiClient(); showNotificationAndStartForegroundService(); mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(LocationService.this); mLocationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { super.onLocationResult(locationResult); List<Location> locationList = locationResult.getLocations (); for (Location loc : locationList) { if (loc.getLatitude () != 0 && loc.getLongitude () != 0) { Log.d (TAG,"Location -------------->>>>" + loc.getLatitude ()+ " " + loc.getLongitude ()); saveUserLocation (loc.getLatitude (),loc.getLongitude (),10990816+1); break; } } } }; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d ("On Start Command---> ","Inside on Start Command"); return START_STICKY; } private synchronized void buildGoogleApiClient() { mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); mGoogleApiClient.connect(); } private void createLocationRequest() { mLocationRequest = LocationRequest.create(); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mLocationRequest.setInterval(LOCATION_REQUEST_INTERVAL); /* mLocationRequest.setSmallestDisplacement(LOCATION_REQUEST_DISPLACEMENT);*/ mLocationRequest.setFastestInterval (LOCATION_REQUEST_INTERVAL/2); requestLocationUpdate(); } private void requestLocationUpdate() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return; } mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper()); } private void removeLocationUpdate() { mFusedLocationProviderClient.removeLocationUpdates(mLocationCallback); } /** * This Method shows notification for ForegroundService * Start Foreground Service and Show Notification to user for android all version */ private void showNotificationAndStartForegroundService() { final String CHANNEL_ID = BuildConfig.APPLICATION_ID.concat("_notification_id"); final String CHANNEL_NAME = BuildConfig.APPLICATION_ID.concat("_notification_name"); final int NOTIFICATION_ID = 100; NotificationCompat.Builder builder; NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { int importance = NotificationManager.IMPORTANCE_NONE; assert notificationManager != null; NotificationChannel mChannel = notificationManager.getNotificationChannel(CHANNEL_ID); if (mChannel == null) { mChannel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, importance); notificationManager.createNotificationChannel(mChannel); } builder = new NotificationCompat.Builder(this, CHANNEL_ID); builder.setSmallIcon(R.mipmap.ic_launcher) .setContentTitle(getString(R.string.app_name)); startForeground(NOTIFICATION_ID, builder.build()); } else { builder = new NotificationCompat.Builder(this, CHANNEL_ID); builder.setSmallIcon(R.mipmap.ic_launcher) .setContentTitle(getString(R.string.app_name)); startForeground(NOTIFICATION_ID, builder.build()); } } @Override public void onConnected(@Nullable Bundle bundle) { createLocationRequest(); } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { } @Override public void onTaskRemoved(Intent rootIntent) { Log.d ("On Task Removed------> ","inside on task removed"); super.onTaskRemoved (rootIntent); } @Override public void onDestroy() { Log.d ("On Destroy","On destroy called in location service"); if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) { mGoogleApiClient.disconnect(); } super.onDestroy(); } private void saveUserLocation(Double lat,Double lon,Integer time){ LocationSaveRequest locationSaveRequest = new LocationSaveRequest (); final List<com.vivacom.pi_sales_tracking.retrofit.locationsave.model.Location> locationList = new ArrayList<> (); com.vivacom.pi_sales_tracking.retrofit.locationsave.model.Location location = new com.vivacom.pi_sales_tracking.retrofit.locationsave.model.Location (); location.setUserId ("100"); location.setLat (lat); location.setLon (lon); location.setClientTimestampUtc (System.currentTimeMillis()/1000); locationList.add (location); locationSaveRequest.setLocations (locationList); CallLocationSave.save ("KAKBDURKBJSBSKHGYBKA==", locationSaveRequest, new CallLocationSave.LocationSaveCallBack () { @Override public void onSuccess() { locationList.clear (); } @Override public void onFailure(LocationHistoryResponse locationHistoryResponse) { locationList.clear (); } }); }
3 Réponses :
du niveau de l'API 26 ou du service ci-dessus ne fonctionne pas en arrière-plan pendant que l'application est tuée en raison de l'économie de la consommation de la batterie. Vous pouvez choisir un service de premier plan ou un gestionnaire de travail pour suivre l'emplacement. p>
ici Vous pouvez essayer de savoir comment Obtenez l'emplacement dans Work Manager. P>
Oui, Work Manager est une bonne option. Vous pouvez lire plus ici Stackoverflow.com/questions/50279364/.../ une> Notification de service au premier plan est un moyen plus simple en ce moment.
Les services de premier plan ne peuvent pas et ne seront pas exécutés si elles ne sont pas explicitement visibles à l'utilisateur. Vous devez utiliser une notification de premier plan. Ceci est une fonctionnalité de sécurité.
premier plan fort> p> Un service de premier plan effectue une opération qui est notable à l'utilisateur. Par exemple, une application audio utiliserait un Service de premier plan pour jouer une piste audio. Les services de premier plan doivent Afficher une notification. Les services de premier plan continuent à courir même lorsque L'utilisateur n'interaque pas avec l'application. P> blockQuote>
de: https://developer.android.com/guide/components / Services P>
Ma solution, affiche une notification de premier plan dans votre service: p>
xxx pré> p>
Merci de votre aide. J'ai déjà utilisé la notification de premier plan dans mon service et la méthode correspondante est appelée à l'intérieur de Create (). Dois-je le placer à l'intérieur de StationartCommand (intention d'intention, int Drapeaux, int StartID)?
Je l'ai utilisé à l'intérieur de StationartCommand (). Mais le résultat est le même. La notification de premier plan disparaît lorsque je supprimai l'application de la liste récente des applications.
En fait, je regarde la lat-Long dans un serveur. Après avoir supprimé l'application des applications récentes, aucune donnée n'a été enregistrée dans la base de données distante.
D'abord, assurez-vous que votre service fonctionne après la fermeture de l'application, l'envoi de données est une chose différente. Pouvez-vous voir la notification de premier plan après la fermeture de l'application?
Non, je ne peux pas voir la notification de premier plan après la fermeture de l'application.
Appelez-vous manifestationAndoificationAndSartForeService () à OnstartCommand () Non Oncreate ()
Oui, je l'ai appelé à l'intérieur de Sstartcommand (intention intention, int Drapeaux, int Startid).
Laissez-nous Continuez cette discussion en chat .
Vous devez utiliser testez de votre côté une fois le service arrêter redémarre automatiquement après parfois. p> p> start_sticky code> drapeau. Cela redémarrera le service une fois le service arrêté par système ou à partir de la liste des applications minimisées
Partagez le code où vous commencez le service et vous manifestez le fichier
Du fichier manifeste: À partir de Code: @onclick (r.id.btn_start_tracking) Public Void OnclickStart () {if (build.version.sdk_int> = build.version_codes.o ) {ceci.startforegroundservice (nouvelle intention (ceci, locationervice.class); } else {this.startservice (nouvelle intention (ceci, locationervice.class); }}
Ajoutez le code dans la question initiale pour une meilleure lisibilité
Partagez également votre code de service
J'ai partagé mon code.