tutorial pendingintent getbroadcast ejemplo android alarmmanager wear-os

pendingintent - La alarma exacta de Android siempre tiene 3 minutos de descanso.



alarmmanager android tutorial (1)

El problema parece ocurrir solo en dispositivos Samsung (por ejemplo, Galaxy Grand, S4, S5, S6, Nota 3, Nota 4) con Lollipop (5.0, 5.1, 5.1.1). Parece que las alarmas no están programadas cuando el dispositivo está en la batería con la pantalla apagada. Si el dispositivo se está cargando o tiene una pantalla encendida durante la programación de la alarma, el problema no se producirá.

Puedes verificar si la próxima alarma será inexacta con:

adb shell dumpsys alarm

No encontré la solución perfecta para este problema, solo soluciones donde cada una tiene algunos inconvenientes:

  1. Use setAlarmClock lugar de setExact (vea esta respuesta ). Esto funciona muy bien (no en todos los dispositivos), pero el problema con esta solución es que la alarma afectará al sistema al mostrar el ícono de alarma en la barra de estado (si alguien ya no tiene configurado el reloj de alarma) y mostrar la próxima hora programada de alarma en widgets de alarma, etc. Desafortunadamente, mientras esto funciona en Galaxy Grand con 5.1.1, no en Galaxy S4 con 5.0.1.
  2. Habilitar la pantalla antes de programar la alarma (hago esto medio segundo antes de programar la próxima alarma para evitar la condición de carrera). Por supuesto, no es una buena solución para cada aplicación habilitar la pantalla solo para programar la próxima alarma.
  3. ¡Un informe de error que describe un problema similar lo conecta con la longitud del nombre del paquete de la aplicación! No verifiqué si realmente soluciona el problema, porque cambiar el nombre del paquete no es una opción para una aplicación ya publicada.
  4. Hay otro informe en el que alguien afirma que esto se puede arreglar utilizando WakefulBroadcastReceiver , pero no funciona en mi caso.

BTW Este tema me vuelve loco :)

Edición: Parece que este problema no ocurre cuando hay una palabra clave "alarma" o "alerta" en el nombre del paquete de la aplicación (como lo señaló Mathieu H. en los comentarios a continuación).

También pude solucionar el problema manualmente al deshabilitar la optimización de la aplicación en la configuración de la batería (o en la aplicación Smart Manager). Parece que no se puede hacer mediante programación, por lo que puede intentar preguntar a sus usuarios ...

Tengo una aplicación que utiliza el AlarmManager para AlarmManager regularmente el teléfono a toda hora y enviar un mensaje a un reloj con Android Wear que produce una breve vibración. Tengo dos usuarios con un Samsung Galaxy S6 con Android 5.1.1 y el Sony SW 3 con 5.1.1 que experimentan un error extraño. En la primera hora completa, la vibración está en el momento exacto, pero todas las demás vibraciones se retrasan 3 minutos. A veces, incluso la primera hora completa de vibración se retrasa.

Aquí hay un código:

final Calendar time = Calendar.getInstance(); time.set(Calendar.SECOND, 0); time.set(Calendar.MILLISECOND, 0); time.set(Calendar.MINUTE, 0); time.set(Calendar.HOUR_OF_DAY, time.get(Calendar.HOUR_OF_DAY) + 1); final Intent hourlyChimeIntent = new Intent(context, HourlyChimeReceiver.class); hourlyChimeIntent.setAction(key); final AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); final PendingIntent pi = PendingIntent.getBroadcast(context, 0, hourlyChimeIntent, PendingIntent.FLAG_CANCEL_CURRENT); am.setExact(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pi);

WakeLock un WakeLock en el receptor y luego envié un mensaje al reloj Wear en un hilo. No se pierde ninguna vibración, solo llegan 3 minutos tarde.

No tengo otros informes sobre este problema y todos mis dispositivos de prueba funcionan bien. Aunque no tengo un dispositivo Samsung.

¿Alguna idea de qué podría causar el retraso de 3 minutos? ¿Samsung ignora setExact y hace que mi alarma sea inexacta? ¿Cómo forzar las alarmas exactas en Samsung?

EDITAR:

Aquí está el código específico de Android Wear. En el método onReceive del receptor hago esto:

final PowerManager mgr = (PowerManager)context.getSystemService(Context.POWER_SERVICE); final PowerManager.WakeLock lock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID); lock.acquire(7L * 1000L); final GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context).addApi(Wearable.API).build(); new Thread(new Runnable() { @Override public void run() { googleApiClient.blockingConnect(); long pattern[]; pattern = new long[] {0L, 500L}; final NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await(2000L, TimeUnit.MILLISECONDS); if (nodes != null) { for (final Node node : nodes.getNodes()) { // just send and forget Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), "/hourly_chime", Utils.Vibrator.serializeVibratePattern(pattern).getBytes()).await(); } } } }).start();