Alarm Notification fires instantly. Android

后端 未结 5 2032
忘掉有多难
忘掉有多难 2021-02-15 18:15

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

5条回答
  •  借酒劲吻你
    2021-02-15 19:06

    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();
    
        }
    

提交回复
热议问题