androidalarmmanagerrepeatingalarm

cancel repeating alarm at specific time


I'm looking to cancel 2 repeating alarms at a specific time but the app currently decides to call the cancel as soon as you create the alarms. For example if you set the the time to end repeation at 13:18 then the repeating alarm should repeat until it is that time.

Here is some of the code I have been toying with:

Toast.makeText(this, "Alarm Scheduled for " + midnight, Toast.LENGTH_LONG).show();


    AlarmManager Databackon = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

      Databackon.set(AlarmManager.RTC_WAKEUP,midnight, stoprepeat(V));
    // Databackon.set(AlarmManager.RTC_WAKEUP,midnight, PendingIntent.getBroadcast(this,4,  intent, PendingIntent.FLAG_UPDATE_CURRENT));



     Toast.makeText(this, "THIS " + midnight, Toast.LENGTH_LONG).show();


    /*  
      Button button1=(Button)findViewById(R.id.startupdates);
      button1.setVisibility(View.INVISIBLE);
      Button button2=(Button)findViewById(R.id.stopbutton);
      button2.setVisibility(View.VISIBLE);
    */
}

public PendingIntent stoprepeat(View V)
{
    Intent intent = new Intent(UpdatesActivity.this,AlarmReciever.class);
    PendingIntent pendingIntent =
            PendingIntent.getBroadcast(this,1,  intent, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
    am.cancel(pendingIntent);

    Intent intent2 = new Intent(UpdatesActivity.this,DataOff.class);
    PendingIntent pendingIntent2 =
            PendingIntent.getBroadcast(this,2, intent2,PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager am2 = (AlarmManager) getSystemService(ALARM_SERVICE);
    am2.cancel(pendingIntent2);

        Toast.makeText(this, "Repeating Alarm stopped", Toast.LENGTH_LONG).show();

          Button button1=(Button)findViewById(R.id.startupdates);
          button1.setVisibility(View.VISIBLE);
          Button button2=(Button)findViewById(R.id.stopbutton);
          button2.setVisibility(View.INVISIBLE);

        return pendingIntent;
}

Solution

  • Your code makes no sense. You have to keep in mind three basic things:

    1. All alarms are linked to the specific application.
    2. Alarms functionality is based on the pending intents.
    3. Cancellation can be done my matching to specific Intent.

    Considering that, you can implement the following solution.

    Create basic alarm as usual:

    Intent myIntent = new Intent(this, Target.class);
    PendingIntent pendingIntent = PendingIntent.getService(this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    am.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);
    

    Create another alarm, which will be responsible for cancellation and put pendingIntent from the 1st alarm to it:

    Intent cancellationIntent = new Intent(this, CancelAlarmBroadcastReceiver.class);
    cancellationIntent.putExtra("key", pendingIntent);
    PendingIntent cancellationPendingIntent = PendingIntent.getBroadcast(this, 0, cancellationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    am.set(AlarmManager.RTC_WAKEUP, time, cancellationPendingIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    

    Where CancelAlarmBroadcastReceiver is the following:

    public class CancelAlarmBroadcastReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            PendingIntent pendingIntent = intent.getParcelableExtra("key");
            AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            am.cancel(pendingIntent);
        }
    }
    

    I didn't check it, but I think it should work.