I've managed to understand this code. This code is used in an reminder app. What this code do is to set and cancel alarm. However, i don't know how the newly created reference could cancel existing PendingIntent. Please explain me this code (the execute method).
Here's the code:
public class AlarmService extends IntentService {
private static final String TAG = "AlarmService";
public static final String POPULATE = "POPULATE";
public static final String CREATE = "CREATE";
public static final String CANCEL = "CANCEL";
private IntentFilter matcher;
public AlarmService() {
super(TAG);
matcher = new IntentFilter();
matcher.addAction(POPULATE);
matcher.addAction(CREATE);
matcher.addAction(CANCEL);
}
@Override
protected void onHandleIntent(Intent intent) {
String action = intent.getAction();
String alarmId = intent.getStringExtra(AlarmMsg.COL_ALARMID);
String alarmMsgId = intent.getStringExtra(AlarmMsg.COL_ID);
String startTime = intent.getStringExtra(Alarm.COL_FROMDATE);
String endTime = intent.getStringExtra(Alarm.COL_TODATE);
if (matcher.matchAction(action)) {
if (POPULATE.equals(action)) {
RemindMe.dbHelper.populate(Long.parseLong(alarmId), RemindMe.db);
execute(CREATE, alarmId);
}
if (CREATE.equals(action)) {
execute(CREATE, alarmId, alarmMsgId, startTime, endTime);
}
if (CANCEL.equals(action)) {
execute(CANCEL, alarmId, alarmMsgId, startTime, endTime);
RemindMe.dbHelper.shred(RemindMe.db);
}
}
}
/**
* @param action
* @param args {alarmId, alarmMsgId, startTime, endTime}
*/
private void execute(String action, String... args) {
Intent i;
PendingIntent pi;
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Cursor c;
String alarmId = (args!=null && args.length>0) ? args[0] : null;
String alarmMsgId = (args!=null && args.length>1) ? args[1] : null;
String startTime = (args!=null && args.length>2) ? args[2] : null;
String endTime = (args!=null && args.length>3) ? args[3] : null;
String status = CANCEL.equals(action) ? AlarmMsg.CANCELLED : AlarmMsg.ACTIVE;
if (alarmMsgId != null) {
c = RemindMe.db.query(AlarmMsg.TABLE_NAME, null, AlarmMsg.COL_ID+" = ?", new String[]{alarmMsgId}, null, null, null);
} else {
c = AlarmMsg.list(RemindMe.db, alarmId, startTime, endTime, status);
}
if (c.moveToFirst()) {
long now = System.currentTimeMillis();
long time, diff;
// long count = c.getCount();
// double MAX = alarmId!=null && count>30 ? Util.MONTH : Util.YEAR;
do {
i = new Intent(this, AlarmReceiver.class);
i.putExtra(AlarmMsg.COL_ID, c.getLong(c.getColumnIndex(AlarmMsg.COL_ID)));
i.putExtra(AlarmMsg.COL_ALARMID, c.getLong(c.getColumnIndex(AlarmMsg.COL_ALARMID)));
pi = PendingIntent.getBroadcast(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
// pi = PendingIntent.getService(context, requestCode, intent, flags);
time = c.getLong(c.getColumnIndex(AlarmMsg.COL_DATETIME));
diff = time-now + (long)Util.MIN;
if (CREATE.equals(action)) {
if (diff > 0 && diff < Util.YEAR)
am.set(AlarmManager.RTC_WAKEUP, time, pi);
//am.setRepeating(AlarmManager.RTC_WAKEUP, triggerAtTime, interval, operation);
} else if (CANCEL.equals(action)) {
am.cancel(pi);
}
} while(c.moveToNext());
}
c.close();
}
}
This code cancels the alarm like this:
} else if (CANCEL.equals(action)) {
am.cancel(pi);
This doesn't cancel the PendingIntent
, it just cancels the alarm.
This code will never set more than one alarm, because attempts to set a second alarm will automatically cancel the first one. This is because the same PendingIntent
is used every time.