Search code examples
androidalarmmanagerandroid-alarms

Alarm is not stopping


I am working on alarm with android and broadcast receiver. Setting up and playing an alarm works but I cannot turn off the alarm. I have two button for set alarm and stop alarm .My codes is here;

public class MainActivity extends AppCompatActivity {
Button btn;

private Button startAlarmBtn;
private TimePickerDialog timePickerDialog;
final static int REQUEST_CODE = 1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
     Button cancel;



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


    cancel=(Button)findViewById(R.id.cancel);
    cancel.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            stopAlarm();
        }
    });
}
private void openPickerDialog(boolean is24hour) {

    Calendar calendar = Calendar.getInstance();

    timePickerDialog = new TimePickerDialog(
            MainActivity.this,
            onTimeSetListener,
            calendar.get(Calendar.HOUR_OF_DAY),
            calendar.get(Calendar.MINUTE),
            is24hour);
    timePickerDialog.setTitle("Alarm Ayarla");

    timePickerDialog.show();
}

TimePickerDialog.OnTimeSetListener onTimeSetListener
        = new TimePickerDialog.OnTimeSetListener(){

    @Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {

        Calendar calNow = Calendar.getInstance();
        Calendar calSet = (Calendar) calNow.clone();

        calSet.set(Calendar.HOUR_OF_DAY, hourOfDay);
        calSet.set(Calendar.MINUTE, minute);
        calSet.set(Calendar.SECOND, 0);
        calSet.set(Calendar.MILLISECOND, 0);

        if(calSet.compareTo(calNow) <= 0){

            calSet.add(Calendar.DATE, 1);
        }

        setAlarm(calSet);
    }};

private void setAlarm(Calendar alarmCalender){

    Toast.makeText(getApplicationContext(),"Alarm OK!",Toast.LENGTH_SHORT).show();
    Intent intent = new Intent(getBaseContext(), AlarmReceiver.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), REQUEST_CODE, intent, 0);
    AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
    alarmManager.set(AlarmManager.RTC_WAKEUP, alarmCalender.getTimeInMillis(), pendingIntent);

}
private void stopAlarm(){

    PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), REQUEST_CODE,
            new Intent(getApplicationContext(), AlarmReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);

    AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    pendingIntent.cancel();


}
}


public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

    Uri alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
    if (alarmUri == null)
    {
        alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    }
    Ringtone ringtone = RingtoneManager.getRingtone(context, alarmUri);
    ringtone.play();
}


}

How do I turn off the alarm?
My other question is, is it appropriate to have them in the main thread?
Should I use AsyncTask or multi-threading?

Thank you.


Solution

  • The alarm is not stopping because you don't have a handle to the ringtone instance you are playing. I suggest you add a timer to auto stop the ringtone, or you create a global instance of the ringtone, which on second thought might be a bad idea, because if you forget to clean up, it may leak and cause other problems.

    A simple approach to timing this is as shown below:

    public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
    
        Uri alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
        if (alarmUri == null)
        {
            alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        }
        Ringtone ringtone = RingtoneManager.getRingtone(context, alarmUri);
        ringtone.play();
    
    new CountDownTimer(30000, 1000) { // a timer for 30 seconds, that updates approximately every second
     public void onTick(long millisUntilFinished) {
      }
      public void onFinish() {
    // stop your ringtone here, or do other necessary stuff here
    // you might want to check if the ringtone was not stopped before this method
     }
    }.start();
    }
    }
    

    In response to your second question, you could as well use a thread with a handler or runnable to manage the ringtone accordingly. An AsyncTask may be too much work for something relatively simple.