Buscar..


Ejecutar una intención en un momento posterior

  1. Crea un receptor. Esta clase recibirá la intención y la manejará como desee.
public class AlarmReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        // Handle intent
        int reqCode = intent.getExtras().getInt("requestCode");
        ...
    }
}
  1. Dar un intento de AlarmManager. Este ejemplo activará la intención de ser enviado a AlarmReceiver después de 1 minuto.
final int requestCode = 1337;
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
am.set( AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 60000 , pendingIntent );

Cómo cancelar una alarma

Si desea cancelar una alarma y no tiene una referencia al PendingIntent original utilizado para configurar la alarma, debe volver a crear un PendingIntent exactamente como estaba cuando se creó originalmente.

El Administrador de alarmas considera que una intención es igual :

si su acción, datos, tipo, clase y categorías son iguales. Esto no compara ningún dato adicional incluido en los intentos.

Normalmente, el código de solicitud para cada alarma se define como una constante:

public static final int requestCode = 9999;

Entonces, para una alarma tan simple como esta:

Intent intent  = new Intent(this, AlarmReceiver.class);
intent.setAction("SomeAction");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, targetTimeInMillis, pendingIntent);

Aquí es cómo crearía una nueva referencia PendingIntent que puede usar para cancelar la alarma con una nueva referencia de AlarmManager:

Intent intent  = new Intent(this, AlarmReceiver.class);
intent.setAction("SomeAction");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, intent, PendingIntent.FLAG_NO_CREATE);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
if(pendingIntent != null) {
    alarmManager.cancel(pendingIntent);
}

Creando alarmas exactas en todas las versiones de Android.

A AlarmManager se AlarmManager cada vez más optimizaciones de la batería en el sistema Android, los métodos del AlarmManager también han cambiado significativamente (para permitir un tiempo más indulgente). Sin embargo, para algunas aplicaciones todavía se requiere que sea lo más exacto posible en todas las versiones de Android. El siguiente asistente utiliza el método más preciso disponible en todas las plataformas para programar un PendingIntent :

public static void setExactAndAllowWhileIdle(AlarmManager alarmManager, int type, long triggerAtMillis, PendingIntent operation) {
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){
        alarmManager.setExactAndAllowWhileIdle(type, triggerAtMillis, operation);
    } else if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
        alarmManager.setExact(type, triggerAtMillis, operation);
    } else {
        alarmManager.set(type, triggerAtMillis, operation);
    }
}

El modo API23 + Doze interfiere con AlarmManager

Android 6 (API23) introdujo el modo Doze que interfiere con AlarmManager. Utiliza ciertas ventanas de mantenimiento para manejar las alarmas, por lo que incluso si usó setExactAndAllowWhileIdle() no puede asegurarse de que su alarma se active en el momento deseado.

Puede desactivar este comportamiento para su aplicación usando la configuración de su teléfono ( Settings/General/Battery & power saving/Battery usage/Ignore optimizations o similares)

Dentro de tu aplicación puedes comprobar esta configuración ...

String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (pm.isIgnoringBatteryOptimizations(packageName)) {
   // your app is ignoring Doze battery optimization
}

... y, finalmente, mostrar el cuadro de diálogo de configuración respectiva:

Intent intent = new Intent();
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow