Android AlarmManager.setExactAndAllowWhileIdle () y WakefulBroadcastReceiver No funciona en algunos dispositivos nuevos fabricados y de bajo precio

Creo que esta pregunta se hace muchas veces enstackoverflow pero aun así mucha gente lucha por resolverlo.

En mi aplicación de Android, tengo que activar el dispositivo cada media hora para obtener la ubicación actual y enviarlo al servidor. Para esto he usadoAlarmManager consetExactAndAllowWhileIdle() método yWakefulBroadcastReceiver. Funciona bien en casi todos los dispositivos estándar / populares como samsung, LG (Nexus), Sony, Panasonic, lenovo, Motorola, Micro max, etc. Pero algunos otros dispositivos, en su mayoría dispositivos de China, no son compatibles o no pueden permitirlo. despertarse del modo de reposo consetExactAndAllowWhileIdle(). Lo he probado enleeco letV (Android OS 6.1) dispositivo que no permite que el administrador de alarmas se active en intervalos específicos.

La parte de mi código que he mencionado a continuación:

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);
    }
}

Cada vez que el servicio anterior establezca la próxima alarma después de 30 minutos una vez que llamó.

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 he cambiado algunas configuraciones manualmente deleeco letV dispositivo como Configuración> Batería> Alinear activación> Desactivado ambas opciones. Si habilitó la batería, puede ignorar el despertar forzado de las aplicaciones.

Mis preguntas:

¿Qué pasó en este tipo de dispositivos? ¿Por qué no permiten que se active la alarma en un intervalo de tiempo específico?

En algunos dispositivos como Gionee s plus, la alarma se dispara 2-3 minutos tarde ... ¿por qué?

android.net.conn.CONNECTIVITY_CHANGE receptor de transmisión amplia para escuchar cuando la conectividad de red cambia ... ¿Qué hacer cuando no funciona en algunos dispositivos como Gionee s plus?

Hay muchas variaciones para la configuración de optimización de la batería para varios fabricantes ... ¿Puede dañar los servicios de fondo de nuestra aplicación si esa es la solución para esto?

Respuestas a la pregunta(4)

Su respuesta a la pregunta