Adding an item to RecyclerView at specific time every day

Micheal_ Moris :

I need code to add item to RecyclerView at 12 AM every day. I have tried many ways such as work manager and alarm manager but they don't achieve this target

Nicolas :

Here's an implementation of what I mentioned in my comment:

public class MainActivity extends AppCompatActivity {
    private static final String PREF_PAUSE_TIME_KEY = "exit_time";

    private static final Long MILLIS_IN_DAY = 86400000L;

    private static final int TRIGGER_HOUR = 12;
    private static final int TRIGGER_MIN = 0;
    private static final int TRIGGER_SEC = 0;

    private final Handler handler = new Handler();
    private SharedPreferences prefs;

    private final Calendar calendar = Calendar.getInstance();

    private final Runnable addItemRunnable = new Runnable() {
        @Override
        public void run() {
            handler.postDelayed(addItemRunnable, MILLIS_IN_DAY);
            addItem();
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //...

        prefs = PreferenceManager.getDefaultSharedPreferences(this);
    }

    @Override
    protected void onResume() {
        super.onResume();

        // Add missing events since onPause.
        long resumeTime = System.currentTimeMillis();
        long pauseTime = prefs.getLong(PREF_PAUSE_TIME_KEY, resumeTime);

        // Set calendar to trigger time on the day the app was paused.
        calendar.setTimeInMillis(pauseTime);
        calendar.set(Calendar.HOUR_OF_DAY, TRIGGER_HOUR);
        calendar.set(Calendar.MINUTE, TRIGGER_MIN);
        calendar.set(Calendar.SECOND, TRIGGER_SEC);

        long time;
        while (true) {
            // If calendar time is during the time that app was on pause, add item.
            time = calendar.getTimeInMillis();
            if (time > resumeTime) {
                // Past current time, all items were added.
                break;
            } else if (time >= pauseTime) {
                // This time happened when app was on pause, add item.
                addItem();
            }

            // Set calendar time to same hour on next day.
            calendar.add(Calendar.DATE, 1);
        }

        // Set handler to add item on trigger time.
        handler.postDelayed(addItemRunnable, time - resumeTime);
    }

    @Override
    protected void onPause() {
        super.onPause();

        // Save pause time so items can be added on resume.
        prefs.edit().putLong(PREF_PAUSE_TIME_KEY, System.currentTimeMillis()).apply();

        // Cancel handler callback to add item.
        handler.removeCallbacks(addItemRunnable);
    }

    private void addItem() {
        // Add item to database and RecyclerView.
    }
}
  • When onPause is called, the current time is saved in the preferences.
  • When onResume is called, the program add every item that should have been added while the app wasn't opened.
  • When the app is opened the program uses a Handler to post a task at a specific time.

You can move the code anywhere you want, most likely in your repository or view model if you have one. For the timer you can use RxJava for the in-app timer or anything else really.

If the user changes the time to a few days earlier, added items won't be removed. If user then sets it back to normal, items for some days will be duplicated. You can prevent this by only saving the time in onPause if it's greater than the last saved time.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=355900&siteId=1