Au lancement de l'application, l'application démarre le service qui doit effectuer une tâche réseau. Après avoir ciblé le niveau 26 de l'API, mon application ne parvient pas à démarrer le service sur Android 8.0 en arrière-plan.
Causé par: java.lang.IllegalStateException: non autorisé à démarrer le service Intention {cmp = my.app.tt / com.my.service}: l'application est en arrière-plan uid UidRecord {90372b1 u0a136 Procès inactif CEM: 1 seq (0,0 , 0)}
si je comprends bien: limites d'exécution en arrière - plan
La méthode startService () lève désormais une exception IllegalStateException si une application ciblant Android 8.0 essaie d'utiliser cette méthode dans une situation où elle n'est pas autorisée à créer des services d'arrière-plan.
" dans une situation où ce n'est pas permis " - qu'est-ce que cela signifie réellement ?? Et comment y remédier. Je ne veux pas définir mon service comme "premier plan"
startForegroundService()
au lieu destartService()
.Réponses:
Les situations autorisées sont une liste blanche temporaire dans laquelle le service d'arrière-plan se comporte comme avant Android O.
Source: https://developer.android.com/about/versions/oreo/background.html
En d'autres termes, si votre service d'arrière-plan ne répond pas aux exigences de la liste blanche, vous devez utiliser le nouveau JobScheduler . C'est fondamentalement la même chose qu'un service en arrière-plan, mais il est appelé périodiquement au lieu de s'exécuter en arrière-plan en continu.
Si vous utilisez un IntentService, vous pouvez passer à un JobIntentService. Voir la réponse de @ kosev ci-dessous .
la source
FirebaseInstanceIdService
et saonTokenRefresh
méthode sont-ils un message FCM de haute priorité?J'ai une solution. Pour les appareils antérieurs à 8.0, vous devez simplement utiliser
startService()
, mais pour les appareils postérieurs à 7.0, vous devez utiliserstartForgroundService()
. Voici un exemple de code pour démarrer le service.Et dans la classe de service, veuillez ajouter le code ci-dessous pour la notification:
Où O est la version Android 26.
la source
ContextCompat.startForegroundService(...)
bibliothèque de support qui peut être utilisée à la place.La meilleure façon est d'utiliser JobIntentService qui utilise le nouveau JobScheduler pour Oreo ou les anciens services s'ils ne sont pas disponibles.
Déclarez dans votre manifeste:
Et dans votre service, vous devez remplacer onHandleIntent par onHandleWork:
Ensuite, vous démarrez votre service avec:
la source
enqueueWork(...)
est également une méthode statique.Si le service s'exécute dans un thread d'arrière-plan en s'étendant
IntentService
, vous pouvez le remplacerIntentService
parJobIntentService
celui fourni dans le cadre de la bibliothèque de support AndroidL'avantage d'utiliser
JobIntentService
est qu'il se comporte comme unIntentService
sur des périphériques pré-O et sur O et supérieur, il le distribue comme un travailJobScheduler
peut également être utilisé pour des travaux périodiques / à la demande. Mais, assurez-vous de gérer la compatibilité descendante car l'JobScheduler
API n'est disponible qu'à partir de l'API 21la source
Dans Oreo, Android a défini des limites aux services d'arrière-plan .
Si vous avez toujours besoin d'un service en cours d'exécution, vous pouvez utiliser le service de premier plan.
Vous pouvez donc faire un service de premier plan . Vous devrez montrer une notification à l'utilisateur lorsque votre service est en cours d'exécution. Voir cette réponse (il y en a beaucoup d'autres)
Une solution si -
vous ne voulez pas de notification pour votre service?
Vous pouvez utiliser des tâches périodiques avec Alarm Manager , Job Scheduler , Evernote-Jobs ou Work Manager .
J'ai testé le service pour toujours avec Work-Manager.
la source
Oui, c'est parce que vous ne pouvez plus démarrer les services en arrière-plan sur l'API 26. Vous pouvez donc démarrer ForegroundService au-dessus de l'API 26.
Vous devrez utiliser
et publier une notification lors du traitement de la fuite.
la source
Comme @kosev l'a dit dans sa réponse, vous pouvez utiliser JobIntentService. Mais j'utilise une solution alternative - j'attrape IllegalStateException et démarre le service en premier plan. Par exemple, cette fonction démarre mon service:
et quand je traite l'intention, je fais une telle chose:
la source
context.startService
fonctionne en arrière - plan - parfois - cela ressemble à la seule meilleure façon sinon vous devez mettre en œuvre plus de code dans votre classe principaleextending Application
etimplementing ActivityLifecycleCallbacks
et de garder trace si l'application est au premier plan ou arrière - plan et commencer à votre intention en conséquence.D'après les notes de version de Firebase , ils indiquent que la prise en charge d'Android O a été publiée pour la première fois dans 10.2.1 (bien que je recommande d'utiliser la version la plus récente).
veuillez ajouter de nouvelles dépendances de messagerie firebase pour android O
mettez à niveau les services google play et les référentiels google si nécessaire.
la source
Si une intention fonctionnait bien auparavant lorsque l'application est en arrière-plan, ce ne sera plus le cas d'Android 8 et supérieur. Se référant uniquement à l'intention qui doit effectuer un traitement lorsque l'application est en arrière-plan.
Les étapes ci-dessous doivent être suivies:
JobIntentService
place deIntentService
.La classe qui s'étend
JobIntentService
devrait implémenter laonHandleWork(@NonNull Intent intent)
méthode - et devrait avoir en dessous de la méthode, qui invoquera laonHandleWork
méthode:Appelez
enqueueWork(Context, intent)
de la classe où votre intention est définie.Exemple de code:
com.android.support:support-compat
est nécessaire pourJobIntentService
- j'utilise26.1.0 V
.Le plus important est de s'assurer que la version des bibliothèques Firebase est au moins activée
10.2.1
, j'ai eu des problèmes avec10.2.0
- si vous en avez!Votre manifeste doit avoir l'autorisation ci-dessous pour la classe Service:
J'espère que cela t'aides.
la source
Je vois beaucoup de réponses qui recommandent d'utiliser simplement un ForegroundService. Pour utiliser un ForegroundService, une notification doit lui être associée. Les utilisateurs verront cette notification. Selon la situation, ils peuvent être ennuyés par votre application et la désinstaller.
La solution la plus simple consiste à utiliser le nouveau composant d'architecture appelé WorkManager. Vous pouvez consulter la documentation ici: https://developer.android.com/topic/libraries/architecture/workmanager/
Vous venez de définir votre classe de travail qui étend Worker.
Ensuite, vous planifiez quand vous voulez l'exécuter.
Facile! Il existe de nombreuses façons de configurer les travailleurs. Il prend en charge les travaux récurrents et vous pouvez même faire des choses complexes comme le chaînage si vous en avez besoin. J'espère que cela t'aides.
la source
WorkManager is intended for tasks that are deferrable—that is, not required to run immediately
... cela pourrait être plus simple, cependant, mon application a besoin d'un service d'arrière-plan qui exécute immédiatement les demandes des utilisateurs!Solution alternative en utilisant JobScheduler, il peut démarrer le service en arrière-plan dans un intervalle de temps régulier.
Faites d'abord une classe nommée Util.java
Ensuite, créez la classe JobService nommée TestJobService.java
Après cette classe BroadCast Receiver nommée ServiceReceiver.java
Mettre à jour le fichier manifeste avec le code de classe de service et de récepteur
Lanceur main_intent gauche vers le fichier mainActivity.java qui est créé par défaut, et les modifications dans le fichier MainActivity.java sont
WOOAAH !! Le service en arrière-plan démarre sans le service de premier plan
la source
Si vous exécutez votre code sur 8.0, l'application se bloquera. Commencez donc le service au premier plan. Si en dessous de 8.0 utilisez ceci:
Si au-dessus ou 8.0 alors utilisez ceci:
la source
java.lang.SecurityException: Permission Denial: startForeground from pid=13708, uid=10087 requires android.permission.FOREGROUND_SERVICE
. Correction sur stackoverflow.com/a/52382711/550471si vous avez intégré la notification push de messagerie Firebase,
Ajoutez des dépendances de messagerie Firebase nouvelles / mises à jour pour Android O (Android 8.0), en raison des limites d'exécution en arrière-plan .
mettez à niveau les services google play et les référentiels google si nécessaire.
Mise à jour:
la source
Utilisez
startForegroundService()
au lieu destartService()
et n'oubliez pas de créerstartForeground(1,new Notification());
votre service dans les 5 secondes suivant le démarrage du service.la source
En raison de votes controversés sur cette réponse (+ 4 / -4 à compter de cette modification), VEUILLEZ REGARDER D'ABORD LES AUTRES RÉPONSES ET UTILISER CELLE-CI UNIQUEMENT COMME DERNIÈRE STATION . Je ne l'ai utilisé qu'une seule fois pour une application de mise en réseau qui s'exécute en tant que root et je suis d'accord avec l'opinion générale que cette solution ne doit pas être utilisée dans des circonstances normales.
Réponse originale ci-dessous:
Les autres réponses sont toutes correctes, mais je voudrais souligner qu'une autre façon de contourner ce problème consiste à demander à l'utilisateur de désactiver les optimisations de batterie pour votre application (ce n'est généralement pas une bonne idée, sauf si votre application est liée au système). Voir cette réponse pour savoir comment demander à désactiver l'optimisation de la batterie sans interdire votre application dans Google Play.
Vous devez également vérifier si les optimisations de batterie sont désactivées dans votre récepteur pour éviter les plantages via:
la source
JobScheduler
et autres. Certaines applications doivent fonctionner à un niveau inférieur à celui des applications de synchronisation classiques. Il s'agit d'une solution alternative lorsque cela ne fonctionne pas.ne pas utiliser dans onStartCommand:
il suffit de le changer en:
et ça va marcher
la source