Android AlarmManager.setExactAndAllowWhileIdle () e WakefulBroadcastReceiver Não está funcionando em alguns dispositivos novos fabricados e de baixo preço

Eu acho que essa pergunta é feita muitas vezesstackoverflow mas ainda há muitas pessoas lutando para resolvê-lo.

No meu aplicativo Android, tenho que ativar o dispositivo a cada meia hora para obter a localização atual e enviá-lo ao servidor. Para isso eu useiAlarmManager comsetExactAndAllowWhileIdle() método eWakefulBroadcastReceiver. Está funcionando bem, quase todos os dispositivos padrão / populares como samsung, LG (Nexus), Sony, Panasonic, Lenovo, Motorola, Micro max e assim por diante ... Mas alguns outros dispositivos, na maioria, dispositivos chineses que não suportam ou não podem permitir dispositivos acorde do modo cochilo comsetExactAndAllowWhileIdle(). Eu testei emleeco letV (Android OS 6.1) dispositivo que não permita que o gerenciador de alarme seja ativado em um intervalo específico.

Minha parte do código que mencionei abaixo:

UserTrackingReceiverIntentService.java

public class UserTrackingReceiverIntentService extends IntentService {

    public static final String TAG = "UserTrackingReceiverIntentService";
    Context context;
    public UserTrackingReceiverIntentService() {
        super("UserTrackingReceiverIntentService");
    }

    @TargetApi(Build.VERSION_CODES.M)
    @Override
    protected void onHandleIntent(Intent intent) {
        this.context = this;

        if (!Util.isMyServiceRunning(LocationService.class, context)) {
            context.startService(new Intent(context, LocationService.class));
        }

        Calendar calendar = Calendar.getInstance();
        //********************************** SETTING NEXT ALARM *********************************************
            Intent intentWakeFullBroacastReceiver = new Intent(context, SimpleWakefulReceiver.class);
            PendingIntent sender = PendingIntent.getBroadcast(context, 1001, intentWakeFullBroacastReceiver, 0);
            AlarmManager alarmManager = (AlarmManager) context.getSystemService(context.ALARM_SERVICE);

        if (calendar.get(Calendar.MINUTE) >= 0 && calendar.get(Calendar.MINUTE) < 30) {
            calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY));
            calendar.set(Calendar.MINUTE, 30);
            calendar.set(Calendar.SECOND, 0);
        } else if (calendar.get(Calendar.MINUTE) >= 30) {
            if (calendar.get(Calendar.HOUR_OF_DAY) == 23) {
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.add(Calendar.DAY_OF_MONTH, 1);
            } else {
                calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + 1);
            }
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
        } else {
            calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY));
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
        }

        //MARSHMALLOW OR ABOVE
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
                    calendar.getTimeInMillis(), sender);
        }
        //LOLLIPOP 21 OR ABOVE
        else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(calendar.getTimeInMillis(), sender);
            alarmManager.setAlarmClock(alarmClockInfo, sender);
        }
        //KITKAT 19 OR ABOVE
        else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            alarmManager.setExact(AlarmManager.RTC_WAKEUP,
                    calendar.getTimeInMillis(), sender);
        }
        //FOR BELOW KITKAT ALL DEVICES
        else {
            alarmManager.set(AlarmManager.RTC_WAKEUP,
                    calendar.getTimeInMillis(), sender);
        }


        Util.registerHeartbeatReceiver(context);
        SimpleWakefulReceiver.completeWakefulIntent(intent);
    }
}

Todas as vezes acima do serviço, defina o próximo alarme após 30 minutos, depois que ele chamar.

public class SimpleWakefulReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // This is the Intent to deliver to our service.
        Calendar calendar = Calendar.getInstance();
        Intent service = new Intent(context, UserTrackingReceiverIntentService.class);
        Date date = new Date();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        String DateTime = sdf.format(date);
        DateTime = Util.locatToUTC(DateTime);
        service.putExtra("date", String.valueOf(DateTime));

        String latitude = Util.ReadSharePrefrence(context, "track_lat");
        String longitude = Util.ReadSharePrefrence(context, "track_lng");

        service.putExtra("lat", latitude);
        service.putExtra("lon", longitude);

        Log.i("SimpleWakefulReceiver", "Starting service @ " + calendar.get(Calendar.HOUR_OF_DAY) + " : " + calendar.get(Calendar.MINUTE) + " : " + calendar.get(Calendar.SECOND));

        // Start the service, keeping the device awake while it is launching.
        startWakefulService(context, service);
    }
}

Como alterei algumas configurações manualmente deleeco letV dispositivo como Configurações> Bateria> Alinhar ativação> Desativou as duas opções. Se habilitado, a bateria pode ignorar a ativação forçada dos aplicativos.

Minhas perguntas:

O que aconteceu com esse tipo de dispositivo? Por que eles não permitem que o alarme seja acionado em um intervalo de tempo específico?

Em alguns dispositivos como o Gionee s e o alarme disparando 2-3 minutos atrasado ... por quê?

android.net.conn.CONNECTIVITY_CHANGE receptor de transmissão ampla para ouvir quando a conectividade da rede muda ... O que fazer quando não está funcionando em alguns dispositivos como o Gionee s plus?

Há muitas variações na configuração de otimização da bateria para vários fabricantes ... Isso pode prejudicar os serviços em segundo plano do aplicativo, se é essa a solução para isso.

questionAnswers(4)

yourAnswerToTheQuestion