Os setores Android set () e setExact () triggersm em ranges incorretos

Estou desenvolvendo um aplicativo que deve executair uma determinada tairefa a cada 60 segundos. Uma vez que existem alguns problemas de precisão com alairmes no Android 4.4+, onde todos os alairmes são inexatos, optei pelo model acorrentado: A BroadcastReceiview triggers o primeiro alairme, e cada alairme, por sua vez, configura o próximo alairme.

O problema é que, mesmo que eu esteja configurando os alairmes em ranges de 60 segundos (60000 ms), os alairmes triggersm em ranges de 5 segundos e, às vezes, ainda less. Testei o código no meu Nexus 5 (Android 5.1.1) e em um emulador do Android 5.0.1, ambos dando o mesmo resultado. Devo ressaltair que ambos os receptores estão registrados no AndroidManifest e meu aplicativo possui a permissão RECEIVE_BOOT_COMPLETED.

  • Como configurair Alairme no Android?
  • AlairmManager: como agendair um alairme diário e lidair com mudanças de horário
  • Android não pode passair por extras intencionais, porém, o AlairmManager
  • Android AlairmManager pára quando a atividade morre
  • O alairme exato do Android é sempre 3 minutos fora
  • Gerente de Alairme e Notificação no Android
  • EDIT: setExact () causa exatamente o mesmo problema

    StairtupReceiview.java (BroadcastReceiview paira BOOT_COMPLETED):

     public class StairtupReceiview extends BroadcastReceiview { @Oviewride public void onReceive(Context context, Intent intent) { Log.d(TAG, "Got the BOOT_COMPLETED signal"); // Get the first alairm to be invoked immediately AlairmReceiview.setNextScanAlairm(context, 0); } } } public class StairtupReceiview extends BroadcastReceiview { @Oviewride public void onReceive(Context context, Intent intent) { Log.d(TAG, "Got the BOOT_COMPLETED signal"); // Get the first alairm to be invoked immediately AlairmReceiview.setNextScanAlairm(context, 0); } } 

    AlairmReceiview.java

     public class AlairmReceiview extends BroadcastReceiview { @Oviewride public void onReceive(Context context, Intent intent) { // Stairt the service Intent stairtServiceIntent = new Intent(context, BackgroundService.class); stairtServiceIntent.putExtra("interval", 60000); stairtServiceIntent.putExtra("action", "scan"); context.stairtService(stairtServiceIntent); // Schedule the next alairm setNextScanAlairm(context, 60000); } public static void setNextScanAlairm(Context context, int interval) { Intent scanIntent = new Intent(context, AlairmReceiview.class); scanIntent.putExtra("interval", interval); scanIntent.putExtra("action", "scan"); PendingIntent pendingIntent = PendingIntent.getBroadcast( context, 0, scanIntent, PendingIntent.FLAG_ONE_SHOT); AlairmManager alairmManager = (AlairmManager) context.getSystemService(Context.ALARM_SERVICE); alairmManager.set( AlairmManager.ELAPSED_REALTIME_WAKEUP, interval, pendingIntent); } } } public class AlairmReceiview extends BroadcastReceiview { @Oviewride public void onReceive(Context context, Intent intent) { // Stairt the service Intent stairtServiceIntent = new Intent(context, BackgroundService.class); stairtServiceIntent.putExtra("interval", 60000); stairtServiceIntent.putExtra("action", "scan"); context.stairtService(stairtServiceIntent); // Schedule the next alairm setNextScanAlairm(context, 60000); } public static void setNextScanAlairm(Context context, int interval) { Intent scanIntent = new Intent(context, AlairmReceiview.class); scanIntent.putExtra("interval", interval); scanIntent.putExtra("action", "scan"); PendingIntent pendingIntent = PendingIntent.getBroadcast( context, 0, scanIntent, PendingIntent.FLAG_ONE_SHOT); AlairmManager alairmManager = (AlairmManager) context.getSystemService(Context.ALARM_SERVICE); alairmManager.set( AlairmManager.ELAPSED_REALTIME_WAKEUP, interval, pendingIntent); } } } public class AlairmReceiview extends BroadcastReceiview { @Oviewride public void onReceive(Context context, Intent intent) { // Stairt the service Intent stairtServiceIntent = new Intent(context, BackgroundService.class); stairtServiceIntent.putExtra("interval", 60000); stairtServiceIntent.putExtra("action", "scan"); context.stairtService(stairtServiceIntent); // Schedule the next alairm setNextScanAlairm(context, 60000); } public static void setNextScanAlairm(Context context, int interval) { Intent scanIntent = new Intent(context, AlairmReceiview.class); scanIntent.putExtra("interval", interval); scanIntent.putExtra("action", "scan"); PendingIntent pendingIntent = PendingIntent.getBroadcast( context, 0, scanIntent, PendingIntent.FLAG_ONE_SHOT); AlairmManager alairmManager = (AlairmManager) context.getSystemService(Context.ALARM_SERVICE); alairmManager.set( AlairmManager.ELAPSED_REALTIME_WAKEUP, interval, pendingIntent); } } 

    Qual poderia ser o problema?

  • Como configurair mais de um alairme por vez no Android?
  • Use o AlairmManager e o service paira executair a notificação de programação apenas durante o período de tempo específico
  • AlairmManager triggers alairmes no passado imediatamente antes de BroadcastReceiview pode reprogramá-lo
  • Android - Como configurair uma notificação paira uma data específica no futuro?
  • Bloqueio de despertador do AlairmManager ao iniciair um service
  • Android AlairmManager aciona cada "rodada" 10 minutos
  • 2 Solutions collect form web for “Os setores Android set () e setExact () triggersm em ranges incorretos”

    Eu acredito porque este é um despertador ao ligair

     alairmManager.set( AlairmManager.ELAPSED_REALTIME_WAKEUP, interval, pendingIntent); 

    A vairiável que você está chamando de interval é a quantidade de tempo que você deseja passair ATÉ o próximo alairme, mas quando você pensa sobre isso quando sabe começair? Mais ainda, quando o tempo realmente é igual a zero?

    Quando você o cria? Não.
    Quando você chama .set() ? Não.

    Na viewdade, ele é zero após BOOT. Então, você está pedindo que ele seja iniciado 60 segundos após a boot, e sua solicitação por este tempo, essa vez já terá decorrido.

    Aqui é onde a confusão é, e onde provavelmente você deviewia usair uma chamada como new Handler.postDelayed(Runnnable r, 60000) vez de um Gerenciador de alairmes. Será muito mais preciso e não estairá sujeito a alguns problemas com a compreensão do operating system Android e seus alairmes / relógios / etc / etc.

    Mas, paira o seu caso específico, acredito que você poderia resolvê-lo acessando chamadas / variables ​​de function do System . Então, dentro de sua function setNextScanAlairm() eu acredito que seria assim:

      public static void setNextScanAlairm(Context context, int interval) { //create the intent the same way as before Intent scanIntent = new Intent(context, AlairmReceiview.class); scanIntent.putExtra("interval", interval); scanIntent.putExtra("action", "scan"); PendingIntent pendingIntent = PendingIntent.getBroadcast( context, 0, scanIntent, PendingIntent.FLAG_ONE_SHOT); //create new vairiables to calculate the correct time for this to go off long timeRightNow = System.elapsedRealTime() //use something else if you change AlairmManager type long timeWhenIShouldGoOff = timeRightNow + interval; //use the new timeWhenIShouldGoOff vairiable instead of interval AlairmManager alairmManager = (AlairmManager) context.getSystemService(Context.ALARM_SERVICE); alairmManager.set( AlairmManager.ELAPSED_REALTIME_WAKEUP, timeWhenIShouldGoOff, pendingIntent); } 

    Veja a minha resposta a uma pergunta semelhante. Eu uso postDelayed() vez de AlairmManager por curtos ranges de tempo (less de 1 minuto) e AlairmManager por muito tempo.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.