Solução para usar o AlarmManager fora do prazo

        Recentemente, os produtos de nossa empresa foram reclamados por clientes de que o desligamento programado não é pontual e ocasionalmente não funciona. A operação de recorrência específica é desligar automaticamente após um período de tempo relativamente longo, e esse problema de probabilidade é fácil de ocorrer.

        Como essa função de desligamento programado foi implementada por um ex-colega, tive que verificar o código, verificar o código de rastreamento e descobri que o método de temporização usava o método set() no AlarmManager:

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, setTime, pendingIntent);

        Eu mesmo depurei e descobri que o tempo de curto prazo pode realizar a função normalmente e, em seguida, ajustei um temporizador de dez horas para desligar e descobri que realmente havia um erro, e o desligamento foi atrasado por três minutos. 

Consulte documentos e outras informações:

        Documentos oficiais sugerem que o API19 (android4.4) seja iniciado, a fim de economizar energia (reduzir o despertar do sistema e o uso da bateria). Usar Alarm.set() e Alarm.setRepeating() não garante precisão. API19 e superior devem usar dois outros métodos de alarme precisos, setWindow() e setExact().

No entanto, depois de usar o método setExact() no Android 8.0, ainda achei que o tempo não seria pontual por muito tempo. Continuei verificando as informações e descobri que o oficial adicionou uma nova interface de aplicativo após a API23 (android 6.0) :

 Em seguida, altere pacientemente o método de interface para setExactAndAllowWhileIdle().

        Mas uma coisa estranha ainda aconteceu. Depois de usar esta interface no Android 8.0 e definir um timer de longo prazo para dez horas e, em seguida, desligar a tela, descobriu-se que ainda havia um problema de não chegar no horário e atrasou por dois minutos completos.

        Neste momento, não tenho paciência, então decidi mudar para outro método de implementação, em vez de usar o AlarmManager para o tempo, a estabilidade é realmente preocupante.

Solução

Por fim, o polling é usado para comparar o tempo de desligamento definido com o horário atual.

        Aqui eu me inscrevo para ouvir  a transmissão do sistema ACTION_TIME_TICK, e o sistema enviará uma transmissão ACTION_TIME_TICK a cada minuto:

 

        Uma comparação é feita toda vez que uma transmissão é recebida e o timestamp de desligamento definido é comparado com o horário atual.Se o valor absoluto do tempo comparado for menor que 60, a operação correspondente será executada.

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            final String action = intent.getAction();
           
            if (action.equals(ACTION_TIME_TICK)) {

             //setMillionSeconds为设定的定时时间戳
            if (Math.abs(setMillionSeconds - System.currentTimeMillis()) <= 60000) {

                //to do what you whant to do 

            }             
          }
        }
    };


        Usar este método é muito mais estável do que usar o AlarmManager! Se o tempo definido pelo AlarmManager pode ser chamado de volta é uma metafísica!

No entanto, deve-se observar que a transmissão ACTION_TIME_TICK requer registro dinâmico

Acho que você gosta

Origin blog.csdn.net/weixin_42433094/article/details/123103829
Recomendado
Clasificación