I am working on a Reminder that sends notification on fixed time to the user.
The alarm is getting off instantly ...
I tried most of the suggestions over s
Finally I found a way to do that by storing PendingIntent requestCode
in database (used ROOM) , then cancelling all the alarm by retrieving all the requestCode
from DB
AlarmIdPojo
@Entity
public class AlarmIdPojo {
@PrimaryKey(autoGenerate = true)
public int id;
private int requestCode;
public AlarmIdPojo() {
}
public int getRequestCode() {
return requestCode;
}
public void setRequestCode(int requestCode) {
this.requestCode = requestCode;
}
}
AlarmIdDAO
@Dao
public interface AlarmIdDAO {
@Query("select * from AlarmIdPojo")
List getAllRequestCode();
@Query("delete from AlarmIdPojo")
public void deleteAllRequestCode();
@Insert(onConflict = REPLACE)
void addRequestCode(AlarmIdPojo pojo);
}
AppDatabase
@Database(entities = {AlarmIdPojo.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract AlarmIdDAO requestIdPojo();
@Override
protected SupportSQLiteOpenHelper createOpenHelper(DatabaseConfiguration config) {
return null;
}
@Override
protected InvalidationTracker createInvalidationTracker() {
return null;
}
}
callReminder
private void callReminder() {
// java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
// because of this Exception , we are doing this in AsyncTask
new AsyncTask() {
@Override
protected Void doInBackground(Void... voids) {
List idList = appDatabase.requestIdPojo().getAllRequestCode();
Intent notifyIntent = new Intent(MainActivity.this, MyReceiver.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent;
for (int i = 0; i < idList.size(); i++) {
int requestId = idList.get(i).getRequestCode();
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, requestId, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
// Cancel alarms
try {
alarmManager.cancel(pendingIntent);
} catch (Exception e) {
Log.e(TAG, "AlarmManager update was not canceled. " + e.toString());
}
}
appDatabase.requestIdPojo().deleteAllRequestCode();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
// Once every request code is deleted , then once again call setReminderNotification() for fresh data.
setReminderNotification();
}
}.execute();
}
setReminderNotification
private void setReminderNotification() {
Intent notifyIntent = new Intent(this, MyReceiver.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent;
// Taking existing offline reminder data from sharePreference
Type type = new TypeToken>() {
}.getType();
List reminderList = new Gson().fromJson(sharedPrefUtils.getString(sharedPrefUtils.DEFAULT_REMINDERS), type);
for (int i = 0; i < reminderList.size(); i++) {
String time = reminderList.get(i).getTime();
String strSpit[] = time.split(":");
String strDays[] = reminderList.get(i).getDays().split(",");
Calendar todayWithTime = Calendar.getInstance();
todayWithTime.set(Calendar.SECOND, 0);
todayWithTime.set(Calendar.MILLISECOND, 0);
for (int j = 0; j < strDays.length; j++) {
Calendar alarm = Calendar.getInstance();
alarm.set(Calendar.SECOND, 0);
alarm.set(Calendar.MILLISECOND, 0);
alarm.set(Calendar.HOUR_OF_DAY, Integer.parseInt(strSpit[0]));
alarm.set(Calendar.MINUTE, Integer.parseInt(strSpit[1]));
alarm.set(Calendar.DAY_OF_WEEK, viewFunctions.getDayInt(strDays[j]));
int randomPendingIntentId = generateRandomId();
notifyIntent.putExtra(Constants.REMINDER_NAME, reminderList.get(i).getName());
notifyIntent.putExtra(Constants.ID, randomPendingIntentId); // passing it , so that we can cancel this PendingIntent with this Id, once notification is shown.This is done to prevent past time alarm firing
notifyIntent.putExtra(Constants.REMINDER_DAY, viewFunctions.getDayInt(strDays[j]));
pendingIntent = PendingIntent.getBroadcast(this, randomPendingIntentId, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if (alarm.before(todayWithTime)) {
alarm.add(Calendar.DATE, 7);
}
alarmManager.set(AlarmManager.RTC_WAKEUP, alarm.getTimeInMillis(), pendingIntent);
insertToDB(randomPendingIntentId);
}
}
}
insertToDB
// Saving to DB. keeping track of PendingIntent unique id.
private void insertToDB(int randomPendingIntentId) {
alarmIdPojo = new AlarmIdPojo();
alarmIdPojo.setRequestCode(randomPendingIntentId);
// java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
// because of this Exception , we are doing this in AsyncTask
new AsyncTask() {
@Override
protected Void doInBackground(Void... voids) {
appDatabase.requestIdPojo().addRequestCode(alarmIdPojo);
return null;
}
}.execute();
}