如何通过WorkManager和OneTimeWorkRequest在Android中的特定时间接收每日通知?

时间:2019-10-15 06:00:06

标签: android notifications android-notifications android-workmanager periodicity

我的目标

激活我的开关后,每8点接收一次通知

当前结果

-如果我第一次激活该开关,则每次启动该应用程序时都会收到通知

-我也收到通知,但没有随时启动应用程序

-此外,我一天之内会收到几则通知

我做了什么(我的代码)

-NotificationActivity(onCreate的一部分)

 private void onClickSwitch() {
        aSwitch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                retrieveKeyWord();
                retrieveCategories();

                keywordPref = mPreferences.getString(PREF_KEYWORD, null);
                categoriesPref = mPreferences.getString(PREF_CATEGORIES, null);

                mPreferences.edit().putString(PREF_KEYWORD, keyword).apply();
                mPreferences.edit().putString(PREF_CATEGORIES, categories).apply();

                Calendar currentDate = Calendar.getInstance();
                Calendar dueDate = Calendar.getInstance();

                dueDate.set(Calendar.HOUR_OF_DAY, 8);
                dueDate.set(Calendar.MINUTE, 0);
                dueDate.set(Calendar.SECOND, 0);

                if(dueDate.before(currentDate)) {
                    dueDate.add(Calendar.HOUR_OF_DAY, 24);
                }

                long timeDiff =  dueDate.getTimeInMillis() - currentDate.getTimeInMillis();


                Constraints constraints = new Constraints.Builder()
                        .setRequiredNetworkType(NetworkType.CONNECTED)
                        .build();

                OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(NotificationWorker.class).setInitialDelay(timeDiff, TimeUnit.MILLISECONDS)
                        .setConstraints(constraints)
                        .addTag("TAG_OUTPUT").build();


                WorkManager.getInstance().enqueue(oneTimeWorkRequest);

            }
        });
    }

-NotificationActivity->布局

layout

-NotificationWorker

public class NotificationWorker extends Worker {

    private SharedPreferences mPreference;
    private String keyword;
    private String categories;
    private ResultModel resultModel;
    private ResultContract.Model.OnFinishedListener onFinishedListener;
    private int numberOfArticle;


    public NotificationWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {

        mPreference = getApplicationContext().getSharedPreferences(NotificationActivity.PREFERENCE_FILE, MODE_PRIVATE);

        keyword = mPreference.getString(NotificationActivity.PREF_KEYWORD, null);
        categories = mPreference.getString(NotificationActivity.PREF_CATEGORIES, null);


        resultModel = new ResultModel();

        numberOfArticle = resultModel.getResultListWithoutDate(onFinishedListener, 1, keyword, categories);

        displayNotification(keyword);

        return Result.success();
    }


    private void displayNotification(String keyword) {

     NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(NOTIFICATION_SERVICE);

     if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
         NotificationChannel channel = new NotificationChannel("simplifiedcoding", "simplifiedcoding", NotificationManager.IMPORTANCE_DEFAULT);
         assert notificationManager != null;
         notificationManager.createNotificationChannel(channel);
     }

     NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), "simplifiedcoding")
             .setContentTitle("Articles sur : " + keyword)
             .setContentText("Nombre d'articles trouvés : " + numberOfArticle)
             .setPriority(NotificationCompat.PRIORITY_DEFAULT)
             .setSmallIcon(R.drawable.ic_launcher_background);

        assert notificationManager != null;
        notificationManager.notify(1, builder.build());

    }
}

如果需要更多信息,请告诉我,感谢谁会帮助我

3 个答案:

答案 0 :(得分:1)

这在使用 PeriodicWorkRequest 时确实有效。诀窍是使用 const BubbleSort = (array) =>{ let funarray = new Array(); funarray = [...array] ; for (let i = 0 ; i < funarray.length-1 ; i++){ for(let j = 0 ; j < funarray.length-1 ; j++){ if(funarray[j]>funarray[j+1]){ [funarray[j],funarray[j+1]] = [funarray[j+1],funarray[j]] setSteps([...steps,funarray]); } } } }

setInitialDelay

我会有一个间隔为 1 天(24 小时)的 fun Context.enqueueReminderWorker( localTime: LocalTime ) { val now = ZonedDateTime.now() val trigger = now.with(localTime) val realTrigger = when { trigger <= now -> trigger.plusDays(1) else -> trigger } val initialDelay = maxOf(1, realTrigger.toEpochSecond() - Instant.now().epochSecond) val notificationWork = PeriodicWorkRequest.Builder(NotificationWorker::class.java, 1, DAYS) .setInitialDelay(initialDelay, SECONDS) .build() WorkManager.getInstance(this) .enqueueUniquePeriodicWork(NotificationWorker.TAG, ExistingPeriodicWorkPolicy.REPLACE, notificationWork) } 并且使用 PeriodicWorkRequest 我可以将开始时间从现在转移到我想要的起点,例如早上8点。 setInitialDelay 很简单:

NotificationWorker

我在 class NotificationWorker( context: Context, workerParams: WorkerParameters ) : Worker(context, workerParams) { override fun doWork(): Result { // Your logic to show a notification. return Result.success() } companion object { const val TAG = "DailyReminder" } } 和用户更改首选时间时调用 Context#enqueueReminderWorker

答案 1 :(得分:0)

您可以通过3种方法解决它。

第一:

用户警报管理器,然后将其放在IF中,检查活动仍处于活动状态,因此如果您的应用程序已打开,它将可以正常工作。您可以从以下Google文档链接中获取更多信息:

AlarmManager Docs

第二个:

u可以使用带有任务的计时器来创建通知,您可以检查活动是否还活着,但是更好的用法是在前台服务上创建计时器。

第三:

即使您需要它,也可以从服务器使用PushNotification。 文档和信息(如果在下面链接):

Push Notification - One Signal

注意:

我建议您使用第三种方式解决问题。

编码良好,别忘了给我投票;)

答案 2 :(得分:0)

由于您的目标是每天早上8点接收通知,因此建议您使用 PeriodicWorkRequest而不是使用OneTimeWorkRequest

PeriodicWorkRequest(来自文档):

  

用于重复工作的WorkRequest。这项工作执行了多次   直到取消为止,并立即执行第一次执行   或一旦满足给定的约束。下一次执行将   在周期间隔内发生;请注意,执行可能会延迟   因为WorkManager需要进行OS电池优化,例如   打ze模式。

OneTimeWorkRequest(来自文档):

  

用于非重复性工作的WorkRequest。