Mon application utilise AlarmManager et fonctionne depuis 4 ans. Mais j'ai remarqué que cela a commencé à échouer sur certains appareils.
Je suis presque sûr que le code est correct (j'utilise WakefulBroadcastReceiver et setExactAndAllowWhileIdle pour les appareils avec Doze) car il fonctionne parfaitement sur les appareils Nexus, mais il échoue dans les appareils de certains fabricants (Huawei, Xiaomi ...).
Les appareils Huawei, par exemple, ont une sorte de gestionnaire de batterie qui détruit les applications, et lorsqu'une application est tuée, les alarmes programmées sont annulées. Ainsi, définir une application comme «protégée» dans le gestionnaire de batterie Huawei résout le problème.
Mais récemment, j'ai remarqué que cela ne fonctionnait pas avec plus d'appareils: Xiaomi, Samsung (peut-être est-ce lié au nouveau "Smart Manager"?) ... Il semble que ce comportement devienne un standard: tuer les applications d'arrière-plan.
Quelqu'un connait-il quelque chose à propos de ça? Un moyen de s'assurer que l'alarme est déclenchée?
EDIT: Ce problème est causé par des "économiseurs de batterie" ajoutés par différents fabricants. Plus d'informations ici: https://dontkillmyapp.com/
la source
Réponses:
J'essaye de le résoudre depuis plusieurs semaines déjà. Je n'ai rien trouvé. Huawei tue toutes les alarmes après un certain temps. Si je mets l'application sur l'application protégée dans leur économiseur de batterie, cela n'aide pas. Mais si je change le nom du package de mon application pour contenir des mots tels que réveil, horloge ou calendrier, cela fonctionne tout à fait normalement comme sur tout autre appareil. Je ne comprends pas comment Google peut donner une certification pour cette merde. Je pense que l'OEM ne devrait pas modifier la plate-forme principale de cette manière. Je comprends qu'ils ont leur propre économiseur de pâte qui tue l'application après un certain temps, lorsque l'utilisateur ne l'utilise pas. Mais cette tuerie alerte également des applications protégées.
SetAlarmClock () pour les alarmes de synchronisation exactes aide également. Mais il n'est pas possible de l'utiliser pour penser comme la mise à jour du widget.
Mise à jour: la protection par mots-clés de nom de package ne fonctionne déjà pas sur les appareils Huawei actuels, c'était vrai en 2017.
la source
Le problème est Smart Manager. Samsung dispose d'un gestionnaire de batterie qui empêche parfois certaines applications de s'exécuter en arrière-plan. Il a essayé de «reprendre» en revenant à l'application mais désactive complètement l'application ou peut reprendre toutes les 5 minutes environ (selon la façon dont Samsung l'a).
Cela fonctionnerait sur les versions stock d'Android car il n'y a pas de gestionnaire Samsung. Vous pouvez également installer une version personnalisée d'Android qui dispose de certaines fonctionnalités pour activer SM (en fonction de la rom).
la source
La plupart des appareils Android modernes sont livrés avec une application ou un mécanisme qui essaie automatiquement de déterminer comment économiser la batterie et, par conséquent, peut tuer certaines applications tierces. Cela peut entraîner la suppression des tâches et travaux planifiés (par exemple, les alarmes ne se déclenchent pas, la notification push ne fonctionne pas, etc.). Dans de nombreux cas, cela se produit complètement indépendamment des mécanismes d'économie de batterie d'Android.Dans mon cas, je ne pourrais pas optimiser davantage la batterie lorsque je détecte un modèle d'appareil, je redirige l'utilisateur vers le gestionnaire de démarrage pour mettre mon application sur liste blanche.
Vous avez trouvé dans ce lien pour chaque modèle l'intention que vous devez appeler https://android-arsenal.com/details/1/6771
la source
Utilisez AlarmManager pour les appareils <5.0 et JobScheduler pour les appareils 5.0+. Je ne peux pas dire avec certitude que JobScheduler ne sera pas affecté par les manigances des fabricants, mais cela me semblerait beaucoup moins probable, étant donné qu'Android tente d'éloigner les gens d'AlarmManager et de JobScheduler.
EDIT: Google a sorti une solution de première partie à ce problème appelée WorkManager . Il fait abstraction de plusieurs cadres de planification et utilise le plus approprié pour l'appareil.
la source
J'ai aussi une application qui définit des alarmes. La solution est d'utiliser AlarmManager.setAlarmClock () sur api> = 21. Ceci n'est pas affecté par somnoler afaik et a l'avantage supplémentaire de mettre une icône de réveil dans la barre d'état système.
la source
la plupart des nouveaux téléphones de nos jours sont livrés avec une sorte de gestionnaire de batterie / économie d'énergie qui fait la même chose que vous avez décrite. sans compter les duboosters et les clean masters.
Je pense que vous devez mettre une clause de non-responsabilité ou une FAQ dans la liste de votre application / Play Store indiquant que cette application doit être mise en exception de votre application de gestionnaire de batterie pour fonctionner correctement.
la source
J'ai arrêté d'utiliser AlarmManager il y a quelque temps ... une alternative meilleure et plus stable
oui ... c'est pénible ... mais le travail est fait PEU IMPORTE QUOI
la source
Écoutez-vous BOOT_COMPLETED? Vous devez à nouveau définir des alarmes lorsqu'un périphérique est redémarré.
la source
Quelle version d'Android ces appareils fonctionnent-ils?
À partir de l'API 23, le système d'exploitation lui-même passera en mode veille à faible consommation lorsqu'il n'a pas été utilisé pendant un certain temps, et dans ce mode, les alarmes ne seront pas délivrées. Il existe cependant un moyen pour les applications de dire explicitement «J'ai besoin que cette alarme se déclenche à ce moment, quelle que soit l'utilisation de la batterie». les nouvelles méthodes AlarmManager appelées
setAndAllowWhileIdle()
etsetExactAndAllowWhileIdle()
.D'après votre description, il semble que cela ne soit peut-être pas la cause particulière de vos problèmes sur les appareils de certains OEM, mais c'est quelque chose dont tous les développeurs utilisant le gestionnaire d'alarmes devraient être conscients.
Enfin, de nombreuses utilisations du gestionnaire d'alarmes sont mieux traitées en utilisant les mécanismes du Job Scheduler. Pour des raisons de compatibilité ascendante, le Play Services "GCM Network Manager" est en fait très proche du Job Scheduler en termes de fonctionnalités - il utilise le Job Scheduler en interne sur les nouvelles versions d'Android - et ne concerne pas nécessairement la mise en réseau, malgré le nom de la classe.
la source
Je ne pense pas que la suppression de l'application empêchera le gestionnaire d'alarmes de réveiller votre application.
Ce n'est que lorsque vous "forcez l'arrêt" ou désactivez l'application que vous ne recevez pas de rappel du gestionnaire d'alarme.
La cause première pourrait être autre chose.
Aussi sur M ... setExactAndAllowWhileIdle fait la limitation ... c'est-à-dire que si vous programmez une alarme toutes les 2 minutes, elle ne sera pas déclenchée. ..Il doit y avoir une fenêtre de 15 minutes. .
la source
Pour Xiaomi, vous devrez peut-être activer AutoStart pour votre application. J'essaie de faire une liste de modifications Android (généralement du fabricant du téléphone) qui peuvent affecter un processus d'arrière-plan. Si vous avez quelque chose de nouveau, veuillez ajouter une réponse ici Liste des tueurs de tâches Android
la source
Nous devons activer notre application dans le gestionnaire de démarrage automatique du gestionnaire d'applications, certains combinés comme vivo v5,
In vivo v5, nous pouvons trouver ce menu dans iManager -> Gestionnaire d'applications -> Gestionnaire de démarrage automatique. Activez notre application ici.
Ensuite, votre alarm / alarmmanager déclenchera une alarme si l'application est tuée ou fermée.
la source
Je cherchais une réponse et après plusieurs heures j'ai trouvé ceci:
https://stackoverflow.com/a/35220476/3174791
En résumé, c'est un moyen de savoir si votre application a été tuée par des `` applications protégées '' et cela ne fonctionne que sur les appareils Huawei. faites-moi savoir s'il existe une solution pour d'autres appareils (Samsung, Sony, Xiaomi, etc.).
la source
C'est peut-être tard mais j'espère que cela aide quelqu'un.
J'ai été coincé sur le même problème pendant si longtemps. Mais maintenant je sais comment résoudre ce problème. C'est pour toute personne qui pourrait avoir le même problème. Les gens ne cessent de dire que vous devez activer AutoStart mais j'ai réussi à le faire sans utiliser le démarrage automatique.
Tout d'abord, WakeFullBroadcastaReceiver est désormais obsolète et vous devez utiliser BroadcastReceiver. Deuxièmement, vous devez utiliser ForegroudService au lieu de BackgroundService.
Je vais vous donner l'exemple ci-dessous:
IntentService.class
public class NotificationService extends IntentService { //In order to send notification when the app is close //we use a foreground service, background service doesn't do the work. public NotificationService() { super("NotificationService"); } @Override public void onCreate() { super.onCreate(); } @Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) { super.onStartCommand(intent, flags, startId); //There is no difference in the result between start_sticky or start_not_sticky at the moment return START_NOT_STICKY; } @Override protected void onHandleIntent(@Nullable Intent intent) { //TODO check if the app is in foreground or not, we can use activity lifecyclecallbacks for this startForegroundServiceT(); sendNotification(intent); stopSelf(); } /*** * you have to show the notification to the user when running foreground service * otherwise it will throw an exception */ private void startForegroundServiceT(){ if (Build.VERSION.SDK_INT >= 26) { String CHANNEL_ID = "my_channel_01"; NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "Channel human readable title", NotificationManager.IMPORTANCE_DEFAULT); ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel); Notification notification = new Notification.Builder(this, CHANNEL_ID) .setContentTitle("") .setContentText("").build(); startForeground(1, notification); } } private void sendNotification(Intent intent){ //Send notification //Use notification channle for android O+ } }
démarrer le service de premier plan dans BroadcastReceiver.class
public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Intent service = new Intent(context, NotificationService.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { context.startForegroundService(service); } else { context.startService(service); } } }
Et le setAlarms comme ceci:
public static void setAlarm(Context context, int requestCode, int hour, int minute){ AlarmManager alarmManager =( AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context//same activity should be used when canceling the alarm , AlarmReceiver.class); intent.setAction("android.intent.action.NOTIFY"); //setting FLAG_CANCEL_CURRENT makes some problems. and doest allow the cancelAlarm to work properly PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1001, intent, 0); Calendar time = getTime(hour, minute); //set Alarm for different API levels if (Build.VERSION.SDK_INT >= 23){ alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,time.getTimeInMillis(),pendingIntent); } else{ alarmManager.set(AlarmManager.RTC_WAKEUP,time.getTimeInMillis(),pendingIntent); }
Ensuite, vous devez déclarer le récepteur et le service de premier plan dans le manifeste.
<receiver android:name=".AlarmReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.NOTIFY"> </action> </intent-filter> </receiver> <service android:name=".NotificationService" android:enabled="true" android:exported="true"></service>
J'espère que ça aidera quelqu'un.
la source