问题
I have 2 buttons save and set alarm
and cancel alarm
which are meant to do exactly what they suggest.
Inside onCreate declared variables
final Intent alarmintent = new Intent(AlarmActivity.this, AlarmReceiver.class);
final AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
final PendingIntent sender1 = PendingIntent.getBroadcast(getApplicationContext(), 2, alarmintent, PendingIntent.FLAG_UPDATE_CURRENT | Intent.FILL_IN_DATA);
Code inside Cancel Button onClickListener
boolean alarmUp = (PendingIntent.getBroadcast(AlarmActivity.this, 2,alarmintent,PendingIntent.FLAG_NO_CREATE) == null);
if (alarmUp)
{
new AlertDialog.Builder(AlarmActivity.this)
.setTitle("Alert")
.setMessage("This alarm will be deleted.")
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
alarmManager.cancel(sender1);
sender1.cancel();
Toast.makeText(getApplicationContext(), "Alarm Cancelled.", Toast.LENGTH_LONG).show();
}
})
.create().show();
}
else
{
new AlertDialog.Builder(AlarmActivity.this)
.setTitle("Alert")
.setMessage("Alarm for this is not set yet.")
.setPositiveButton("Ok",null)
.create().show();
}
Code for save button
boolean alarmUp = (PendingIntent.getBroadcast(AlarmActivity.this, 2,
alarmintent,
PendingIntent.FLAG_NO_CREATE) == null);
if (alarmUp)
{
//Log.d("myTag", "Alarm is already active");
new AlertDialog.Builder(AlarmActivity.this)
.setTitle("Alert")
.setMessage("Already an alarm is set for this particular time and day.")
.setPositiveButton("OK",null
)
.create().show();
}
Calendar c = Calendar.getInstance();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,c.getTimeInMillis()+5000,24 * 60 * 60 * 1000, sender1);
When i click save
for the first time it shows
a http://www.4shared.com/download/puMWZEvRba/alert1.png
However as i have cancel
too i can click that to cancel the alarm.So i click cancel
button and it shows
a http://www.4shared.com/download/1UOTyVK0ce/alert2.png
which seems right.But when i again click save
button it shows
a http://www.4shared.com/download/puMWZEvRba/alert1.png
which means the cancel
button is not doing what it should do although it executes the toast
for this alarm will be deleted.
.Which again means there must be some problem with alarmManager.cancel(sender1)
.
Question
What to modify in the code to get the cancel
button work correctly?
P.S
I referred many posts like this but can't get what's the exact problem in my case.
Updated Code
For cancel button
final Intent alarmintent = new Intent(AlarmActivity.this, AlarmReceiver.class);
final AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
final PendingIntent sender1 = PendingIntent.getBroadcast(getApplicationContext(), 2, alarmintent, PendingIntent.FLAG_UPDATE_CURRENT);
boolean alarmUp = (PendingIntent.getBroadcast(AlarmActivity.this, 2,alarmintent,PendingIntent.FLAG_NO_CREATE) == null);
if (alarmUp)
{
new AlertDialog.Builder(AlarmActivity.this)
.setTitle("Alert")
.setMessage("This alarm will be deleted.")
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
alarmManager.cancel(sender1);
sender1.cancel();
Toast.makeText(getApplicationContext(), "Alarm Cancelled.", Toast.LENGTH_LONG).show();
}
})
.create().show();
}
else
{
new AlertDialog.Builder(AlarmActivity.this)
.setTitle("Alert")
.setMessage("Alarm for this is not set yet.")
.setPositiveButton("Ok",null)
.create().show();
}
For Save Button
final Intent alarmintent = new Intent(AlarmActivity.this, AlarmReceiver.class);
final AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
final PendingIntent sender1 = PendingIntent.getBroadcast(getApplicationContext(), 2, alarmintent, PendingIntent.FLAG_UPDATE_CURRENT);
boolean alarmUp = (PendingIntent.getBroadcast(AlarmActivity.this, 2,
alarmintent,
PendingIntent.FLAG_NO_CREATE) == null);
if (alarmUp)
{
//Log.d("myTag", "Alarm is already active");
new AlertDialog.Builder(AlarmActivity.this)
.setTitle("Alert")
.setMessage("Already an alarm is set for this particular time and day.")
.setPositiveButton("OK",null
)
.create().show();
}
Calendar c = Calendar.getInstance();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,c.getTimeInMillis()+5000,24 * 60 * 60 * 1000, sender1);
This results in same as previous.Cancel
button doesn't seem to work.
Solution
Thanks to @David Wasser i got it working now.Please see his answer.I also had to change
boolean alarmUp = (PendingIntent.getBroadcast(AlarmActivity.this, 2,
alarmintent,PendingIntent.FLAG_NO_CREATE) == null)
to
boolean alarmUp = (PendingIntent.getBroadcast(AlarmActivity.this, 2,
alarmintent,PendingIntent.FLAG_NO_CREATE) != null)
in both the blocks.
But as developer.android.com says FLAG_NO_CREATE Flag indicating that if the described PendingIntent already exists, then simply return null instead of creating it.
I don't know about this issue!
回答1:
Several things are wrong here:
1 Don't use Intent.FILL_IN_DATA
in the call to PendingIntent.getBroadcast()
. This is an Intent
flag and not a PendingIntent
flag. It doesn't belong here.
2 When you use the PendingIntent.FLAG_NO_CREATE
this will return null
if the PendingIntent
doesn't already exist. In your code to set alarmUp
you've got the comparison against null
backwards. NOTE: See my comments at the end of this answer about the fact that the documentation for this is wrong
3 In your onCreate()
you are doing this:
PendingIntent sender1 = PendingIntent.getBroadcast(getApplicationContext(), 2,
alarmintent, PendingIntent.FLAG_UPDATE_CURRENT | Intent.FILL_IN_DATA);
This line will create the PendingIntent
even if you don't set an alarm with it. Later, when you check if the PendingIntent
exists with this code:
boolean alarmUp = (PendingIntent.getBroadcast(AlarmActivity.this, 2,
alarmintent, PendingIntent.FLAG_NO_CREATE) == null);
alarmUp
will always be false
, because you have already created the PendingIntent
in onCreate()
.
NOTE: The PendingIntent
is created when you call PendingIntent.getBroadcast()
, not when you set the alarm.
EDIT: Add more code examples
As I said earlier, you can't create the PendingIntent
if you want to use it to determine whether the alarm is set or not. You must first check if the PendingIntent
exists and then you can create it to set/cancel it. To fix, do this:
In cancel button:
final Intent alarmintent = new Intent(AlarmActivity.this, AlarmReceiver.class);
final AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
// Determine if the alarm has already been set
boolean alarmUp = (PendingIntent.getBroadcast(AlarmActivity.this, 2,alarmintent,PendingIntent.FLAG_NO_CREATE) != null);
if (alarmUp) {
final PendingIntent sender1 = PendingIntent.getBroadcast(getApplicationContext(), 2, alarmintent, PendingIntent.FLAG_UPDATE_CURRENT);
...
In save button:
final Intent alarmintent = new Intent(AlarmActivity.this, AlarmReceiver.class);
final AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
// Determine if the alarm has already been set
boolean alarmUp = (PendingIntent.getBroadcast(AlarmActivity.this, 2, alarmintent, PendingIntent.FLAG_NO_CREATE) != null);
if (alarmUp) {
final PendingIntent sender1 = PendingIntent.getBroadcast(getApplicationContext(), 2, alarmintent, PendingIntent.FLAG_UPDATE_CURRENT);
...
EDITED again to fix documentation discrepancy with PendingIntent.FLAG_NO_CREATE
:
Note: It seems the Android documentation about PendingIntent.FLAG_NO_CREATE
is wrong! It says:
Flag indicating that if the described PendingIntent already exists, then simply return null instead of creating it.
but this is backwards. This method will return the PendingIntent
if it already exists. It will return null
if it doesn't already exist.
I've edited my answer to reflect the correct operation of this flag.
来源:https://stackoverflow.com/questions/21508611/alarm-cancel-button-not-working-correctly