简体   繁体   中英

Cancelling Alarm Manager in Android

I am having some problem when trying to cancel AlarmManager in Android. I am calling this retrieveBudget() onCreate:

public void retrieveBudget() {
    txtDisplayMonthlyExpenses = (TextView) findViewById(R.id.txtDisplayMonthlyExpense);
    txtDisplayBudget = (TextView) findViewById(R.id.txtDisplayBudget);
    cbDisplayReminderNotify = (CheckBox) findViewById(R.id.cbDisplayReminderNotify);
    cbDisplayReminderNotify.setEnabled(false);

    DatabaseAdapter mDbHelper = new DatabaseAdapter(this);
    mDbHelper.createDatabase();
    mDbHelper.open();
    TransactionRecController trc = new TransactionRecController(
            mDbHelper.open());
    currentMonthExpense = trc.getThisMonthDebit();
    txtDisplayMonthlyExpenses.setText("$ "
            + formatter.format(currentMonthExpense));

    BudgetController bc = new BudgetController(mDbHelper.open());

    BudgetModel bm = bc.getBudget();
    if (bm.getBudgetAmount() != 0 && bm.getReminderNotify() != null) {
        budget = bm.getBudgetAmount();
        txtDisplayBudget.setText("$ " + formatter.format(budget));
        if (bm.getReminderNotify().equals("Y")) {
            cbDisplayReminderNotify.setChecked(true);
        } else {
            cbDisplayReminderNotify.setChecked(false);
        }
        AlarmManager mgr = (AlarmManager) context
                .getSystemService(Context.ALARM_SERVICE);
        PendingIntent pi = null;
        if (bm.getReminderNotify().equals("Y")
                && currentMonthExpense > budget) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(System.currentTimeMillis());
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 1);
            notificationCount = notificationCount + 1;

            Intent notificationIntent = new Intent(context,
                    BudgetAlarm.class);
            notificationIntent.putExtra("NotifyCount", notificationCount);
            pi = PendingIntent.getBroadcast(context, notificationCount,
                    notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
                    calendar.getTimeInMillis(), 60000, pi);
        } else {
            mgr.cancel(pi);
        }
    } else {
        txtDisplayBudget.setText("No budget record yet");
    }

    mDbHelper.close();
}

And inside my budgetAlarm class, it just simply setting the notification. So my problem is it did execute the notification every minute. But after I changed my reminderNotify to "N" instead of "Y", it does not cancel the alarm manager. I wonder why is it so because after my update SQL statement, I am calling this retrieveBudget() again.

Thanks in advance.

EDIT

These are the codes where I update the budget part. I am calling the the retrieveBudget() once again when the Okay from dialogue box was clicked.

public void onEditBudgetClicked(View view) {
    AlertDialog.Builder EditDialog = new AlertDialog.Builder(this);
    EditDialog.setTitle("Edit Budget");

    // Get the components from XML file
    LayoutInflater li = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View dialogView = li.inflate(R.layout.edit_budget, null);
    txtEditBudgetAmount = (EditText) dialogView
            .findViewById(R.id.txtEditBudgetAmount);
    cbEditReminderNotify = (CheckBox) dialogView
            .findViewById(R.id.cbEditReminderNotify);

    // Retrieve budget record
    DatabaseAdapter mDbHelper = new DatabaseAdapter(this);
    mDbHelper.createDatabase();
    mDbHelper.open();
    BudgetController bc = new BudgetController(mDbHelper.open());
    BudgetModel bm = bc.getBudget();
    if (bm.getBudgetAmount() != 0 && bm.getReminderNotify() != null) {
        txtEditBudgetAmount.setText(Float.toString(bm.getBudgetAmount()));
        if (bm.getReminderNotify().equals("Y")) {
            cbEditReminderNotify.setChecked(true);
            editReminderNotify = "Y";
        } else {
            cbEditReminderNotify.setChecked(false);
        }
    }
    mDbHelper.close();

    cbEditReminderNotify.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (cbEditReminderNotify.isChecked()) {
                editReminderNotify = "Y";
            } else {
                editReminderNotify = "N";
            }
        }
    });

    EditDialog.setView(dialogView);
    EditDialog.setPositiveButton("Ok",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    onEditBudgetSubmitClicked();
                    dialog.dismiss();
                    retrieveBudget();
                }
            });

    EditDialog.setNegativeButton("Cancel",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    dialog.dismiss();
                }
            });
    EditDialog.show();
}

The value of notification count used while initializing the pending intent at the time creation and cancellation of the alarm manager should be same.

Use same value of requestFalg in the pending intent.

Replace this part:

AlarmManager mgr = (AlarmManager) context
            .getSystemService(Context.ALARM_SERVICE);
PendingIntent pi = null;
if (bm.getReminderNotify().equals("Y")
           && currentMonthExpense > budget) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 1);
    notificationCount = notificationCount + 1;
    Intent notificationIntent = new Intent(context,
                BudgetAlarm.class);
    notificationIntent.putExtra("NotifyCount", notificationCount);
    pi = PendingIntent.getBroadcast(context, notificationCount,
                notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
                calendar.getTimeInMillis(), 60000, pi);
    } else {
        mgr.cancel(pi);
    }

with

AlarmManager mgr = (AlarmManager) context
            .getSystemService(Context.ALARM_SERVICE);
Intent notificationIntent = new Intent(context,
                BudgetAlarm.class);
PendingIntent pi = null;
if (bm.getReminderNotify().equals("Y")
            && currentMonthExpense > budget) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 1);
    notificationCount = notificationCount + 1;
    notificationIntent.putExtra("NotifyCount", notificationCount);
    pi= PendingIntent.getBroadcast(context, 1,
                notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
                calendar.getTimeInMillis(), 60000, pi);
    } else {
        pi= PendingIntent.getBroadcast(context, 1,
                notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        mgr.cancel(pi);
    }

if you changed the value of requestFlag (in your case notificationcount)while initializing the pending intent after launching the alarm, you won't be able to cancel it.

Use same value of requestFlag in the pending intent while creating and cancelling the alarm. Here, I am using 1.

Since you are changing the value of notificationFlag after launching the alarm manager, don't use notificationFlag as a requestFlag. Use a constant integer value as a requestFlag while initializing pi inside both if and else part.

pi= PendingIntent.getBroadcast(context, CONSTANT_INTEGER,notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

check the link below:

PendingIntent getBroadcast (Context context, int requestCode, Intent intent, int flags)

http://developer.android.com/reference/android/app/PendingIntent.html#getBroadcast%28android.content.Context,%20int,%20android.content.Intent,%20int%29

    AlarmManager mgr = (AlarmManager) context
            .getSystemService(Context.ALARM_SERVICE);
    PendingIntent pi = null;
    if (bm.getReminderNotify().equals("Y")
            && currentMonthExpense > budget) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 1);
        notificationCount = notificationCount + 1;

        Intent notificationIntent = new Intent(context,
                BudgetAlarm.class);
        notificationIntent.putExtra("NotifyCount", notificationCount);
        pi = PendingIntent.getBroadcast(context, notificationCount,
                notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
                calendar.getTimeInMillis(), 60000, pi);
    } else {
       notificationCount = notificationCount + 1;

        Intent notificationIntent = new Intent(context,
                BudgetAlarm.class);
        notificationIntent.putExtra("NotifyCount", notificationCount);
        pi = PendingIntent.getBroadcast(context, notificationCount,
                notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        mgr.cancel(pi);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM