Search code examples
androidandroid-pendingintentandroid-alarms

cancel alarm from another activity with the same pendingintent


I have a problem and searched about it all the day but can't do it correctly

how to cancel the alarm from another activity (alarm_Time activity ) ? I think the problem with me in the intent that I used to cancel the the same pendingintent that set the alarm

here is the code in alarm_Time activity to cancel the alarm :

    final Intent intent = getIntent();
    int alarm_No = intent.getIntExtra("alarm_No",0);
    pending_intent = PendingIntent.getBroadcast(alarm_Time.this,alarm_No, intent, PendingIntent.FLAG_UPDATE_CURRENT);


    //intialize alarm_off button
    Button alarm_off = (Button) findViewById(R.id.alarm_off);
    // create on click listner to end alarm
    //final Intent finalIntent = intent;
    alarm_off.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //method that change update_txt txtbox
                              // set_alarm_text("Alarm off!");
            //cancel the alarm
            alarmManager.cancel(pending_intent);
            // put extra string into my_intent
            // tells the clock that you pressed the "alarm off" button
            intent.putExtra("extra", "alarm off");
            // stop the ringtone
            sendBroadcast(intent);
        }
    });

code of the activity where i set the alarm (MainActivity2) :

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar); ///
    this.context = this ;

    update_txt = (TextView) findViewById(R.id.update_txt);
    info_txt = (TextView) findViewById(R.id.info_txt);

    final int[] h = {21, 21};
    final int[] m = {15, 16};
    final int length = h.length;

    final Intent[] intent = new Intent[length];
    final Calendar[] cal = new Calendar[length];
    final AlarmManager[] alarmManager = new AlarmManager[length];
    final PendingIntent[] pending_intent = new PendingIntent[length]; ;

    for(int i =0; i<length; i++) {
        cal[i] = Calendar.getInstance();
        cal[i].set(Calendar.HOUR_OF_DAY, h[i]);
        cal[i].set(Calendar.MINUTE, m[i]);
        if (cal[i].getTimeInMillis() < System.currentTimeMillis())
        {    cal[i].add(Calendar.DAY_OF_MONTH, 1);  }

        intent[i] = new Intent(this.context, AlarmReceiver.class);
        alarmManager[i] = (AlarmManager) getSystemService(ALARM_SERVICE);

    }



    Button alarm_on = (Button) findViewById(R.id.alarm_on);
    alarm_on.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            String h1_string = String.valueOf(h[0]);
            String m1_string = String.valueOf(m[0]);


  for(int i =0; i<length; i++) {


      set_alarm_text("Alarm on!" + h1_string + ":" + m1_string);
      intent[i].putExtra("extra", "alarm on");
      intent[i].putExtra("Alarm_no", i);
      pending_intent[i] = PendingIntent.getBroadcast(MainActivity2.this, i, intent[i], PendingIntent.FLAG_UPDATE_CURRENT );
      alarmManager[i].set(AlarmManager.RTC_WAKEUP, cal[i].getTimeInMillis(), pending_intent[i]);

  }


        }
    });

    //intialize alarm_off button
    Button alarm_off = (Button) findViewById(R.id.alarm_off);
    // create on click listner to end alarm
    alarm_off.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Bundle extras = getIntent().getExtras();
            int alarm_No = -1;
            if (extras != null) {
                alarm_No = extras.getInt("alarm_No2");
            }

            Log.v("help", String.valueOf(alarm_No));

            set_alarm_text("Alarm off!");
            alarmManager[0].cancel(pending_intent[0]);
            intent[0].putExtra("extra", "alarm off");
            sendBroadcast(intent[0]);
        }
    });
}

private void set_alarm_text(String output) {
    update_txt.setText(output);
}

private void set_info_text(String output) {
    info_txt.setText(output);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

}

AlarmReceiver.java

public class AlarmReceiver extends BroadcastReceiver{


@Override
public void onReceive(Context context, Intent intent) {
    Log.e("We are in the receiver", "Yay");

     //fetch extra strings from the intent   >>>  get_ur_string =extra //   alarm on - alarm off
    String get_ur_string = intent.getExtras().getString("extra");
    int No = intent.getExtras().getInt("Alarm_no");


  //  Log.e("What is the key? ", get_ur_string);


    //create an intent to the ringtone service
    Intent service_intent = new Intent(context, RingtonePlayingService.class);

    // pass the extra from Main Activity to Ringtone Playing Service
    service_intent.putExtra("extra", get_ur_string);
    service_intent.putExtra("Alarm_no", No);

    //start the ringtone services
    context.startService(service_intent);



}

}

RingtonePlayingService.java

public class RingtonePlayingService extends Service {

MediaPlayer media_song;
int startId;
boolean isRunning;

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

public int onStartCommand(Intent intent, int flags, int startId)
{
    Log.i("LocalService", "Received start id " + startId +": " + intent);

    // fetch the extra string values
    String state = intent.getExtras().getString("extra");
    int alarm_No = intent.getExtras().getInt("Alarm_no");

    // Log.e("Ringtone state:extra", state);


    // notification
    // set up the notification service
    NotificationManager notify_manager = (NotificationManager)
            getSystemService(NOTIFICATION_SERVICE);
    // set up an intent that goes to the Main Activity
    Intent intent_main_activity = new Intent(this.getApplicationContext(), MainActivity2.class);
    intent.putExtra("extra", "alarm on");
    intent.putExtra("Alarm_no2", alarm_No);
    // set up a pending intent
    PendingIntent pending_intent_main_activity = PendingIntent.getActivity(this, alarm_No,
            intent_main_activity, 0);

    // make the notification parameters
    Notification notification_popup = new Notification.Builder(this)
            .setContentTitle("An alarm is going off!")
            .setContentText("Click me!")
            .setSmallIcon(R.drawable.image)

            .setContentIntent(pending_intent_main_activity)
            .setAutoCancel(true)
            .build();

    // set up notification atart command
    notify_manager.notify(0, notification_popup);




    // this converts the extra strings from the intent to start IDs, values 0 or 1
    assert state != null;
    switch (state) {
        case "alarm on":
            startId = 1;
            int alarm_num = intent.getExtras().getInt("No");
            break;
        case "alarm off":
            startId = 0;
            Log.e("Start ID is", state);
            break;
        default:
            startId = 0;
            break;
    }

    // if else statments

    // if there is no music playing, and the user pressing "alarm on"
    // music should start playing
    if( !this.isRunning && startId == 1  ){
        Log.e("there is no music","and u want start");
        // create an instant of the media player
        media_song = MediaPlayer.create(this, R.raw.tone);
        // start the ringtone
        media_song.start();

        this.isRunning = true;
        this.startId = 0;

    }
    // if there is music playing, and the user pressing "alarm off"
    // music should stop playing
    else  if( this.isRunning && startId == 0 ){
        Log.e("there is  music", "and u want stop");

        // stop the ringtone
        media_song.stop();
        media_song.reset();

        this.isRunning = false;
        this.startId = 0;

    }





    return START_NOT_STICKY;
}

@Override
public void onDestroy() {
    //tell the user we stopped
    Log.e("on Destroy called", "ta da");

    super.onDestroy();
    this.isRunning = false;

}

}


Solution

  • You are trying to cancel the alarm from an Activity this way:

    final Intent intent = getIntent();
    int alarm_No = intent.getIntExtra("alarm_No",0);
    pending_intent = PendingIntent.getBroadcast(alarm_Time.this,alarm_No, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    ...
    //cancel the alarm
    alarmManager.cancel(pending_intent);
    

    but you set the alarm like this:

    intent[i] = new Intent(this.context, AlarmReceiver.class);
    intent[i].putExtra("Alarm_no", i);
    pending_intent[i] = PendingIntent.getBroadcast(MainActivity2.this, i, intent[i], PendingIntent.FLAG_UPDATE_CURRENT );
    alarmManager[i].set(AlarmManager.RTC_WAKEUP, cal[i].getTimeInMillis(), pending_intent[i]);
    

    You are using the wrong Intent. In your Activity when you call getIntent(), it will return the Intent that was used to start the Activity. You use that in your call to PendingIntent.getBroadcast(). This will not return you the correct PendingIntent. You need to pass the same Intent that you used when you set the alarm to the call to PendingIntent.getBroadcast(). This should look something like this:

    final Intent intent = new Intent(this, AlarmReceiver.class);
    int alarm_No = intent.getIntExtra("alarm_No",0);
    pending_intent = PendingIntent.getBroadcast(alarm_Time.this,alarm_No, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    ...
    //cancel the alarm
    alarmManager.cancel(pending_intent);
    

    Also, I notice that you pass the alarm number in the extra like this:

    intent[i].putExtra("Alarm_no", i);
    

    using the key "Alarm_no", but you try to get the alarm number in the alarmtime_Activity using

    int alarm_No = intent.getIntExtra("alarm_No",0);
    

    using the key "alarm_No". These keys are just Strings, so they are case-sensitive. Is it possible that you aren't using the exact same key? I can't tell because you haven't posted the code you used to launch alarmtime_Activity.