Search code examples
javaandroidservicealarm

cancelAlarm method not actually canceling my AlarmManager


I have used this cancelAlarm method from another reputable answer on stack, and it isn't getting the job done, and I am out of ideas of why this isn't working.

I have an activity where one button will start an alarm that will go off every given interval. I then have another button that will cancel that alarm. Here are the buttons first:

    start.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            setupAlarm(10);
        }
    });

    stop.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try{
                cancelAlarm(ALARM_ID);
            } catch(Exception e){
                Toast.makeText(getApplicationContext(), "ERROR", Toast.LENGTH_SHORT).show();
            }
        }
    });

And here are my setupAlarm and cancelAlarm methods:

private void setupAlarm(int seconds) {
    AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
    Intent i = new Intent(getBaseContext(), AlarmReceiver.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(
            MainActivity.this, ALARM_ID, i, PendingIntent.FLAG_UPDATE_CURRENT);
    Calendar t = Calendar.getInstance();
    t.setTimeInMillis(System.currentTimeMillis());

    int interval = seconds*1000;
    am.setRepeating(AlarmManager.RTC_WAKEUP, t.getTimeInMillis(), interval, pendingIntent);
    MainActivity.this.finish();
}

private void cancelAlarm(int alarmId){
    Intent i = new Intent(getBaseContext(), AlarmManager.class);
    PendingIntent sender = PendingIntent.getBroadcast(MainActivity.this, alarmId, i, 0);
    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    alarmManager.cancel(sender);
    sender.cancel();
}

I remembered to make another alarm manager with the same ID, and call alarmManager.cancel(sender); on the PendingIntent but it doesn't seem to do anything, because my service will start back up anyway.

AlarmReciever class:

public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent)
{
    Context oAppContext = context.getApplicationContext();

    if (oAppContext == null) {
        oAppContext = context;
    }

    Intent serviceIntent = new Intent(oAppContext, MyService.class);
    oAppContext.startService(serviceIntent);
}
}

MyService class:

public class MyService extends Service implements SensorEventListener{

private PowerManager.WakeLock wakeLock;

Sensor mSensor;
SensorManager mSensorManager;
String toastString = "";

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

@Override
public void onCreate(){
    mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
    mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);

    PowerManager mgr = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
    wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
    wakeLock.acquire();


    Toast.makeText(this, "onCreate Successful", Toast.LENGTH_SHORT).show();
}

@Override
public int onStartCommand(Intent intent, int flags, int startid) {
    Toast.makeText(this, "onStart Successful", Toast.LENGTH_SHORT).show();
    return Service.START_STICKY;
}

@Override
public void onSensorChanged(SensorEvent event) {
    //record some data from the accelerometer
    quit();
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

private void quit(){
    mSensorManager.unregisterListener(MyService.this);
    wakeLock.release();
    this.stopSelf();
}
}

And I keep on getting the toasts from my MyService class telling me that my onCreate and onStart were successfully instantiated, even after calling my cancelAlarm method.


Solution

  • Use same PendingIntent that you used while creating Alarm. Use AlarmReceiver.class instead of AlarmManager.class in your Intent:

    Intent i = new Intent(getBaseContext(), AlarmReceiver.class);
    

    Update cancelAlarm() method as below:

    private void cancelAlarm(int alarmId){
        Intent i = new Intent(getBaseContext(), AlarmReceiver.class);
        PendingIntent sender = PendingIntent.getBroadcast(MainActivity.this, alarmId, i, PendingIntent.FLAG_UPDATE_CURRENT);
    
        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        alarmManager.cancel(sender);
        sender.cancel();
    }
    

    Hope this will help~