【问题标题】:How to fix periodic notification not send issue如何解决定期通知不发送问题
【发布时间】:2019-07-30 09:18:54
【问题描述】:

我有一个小应用程序,带有一个用于激活定期通知(工作经理定期工作请求)的按钮,它每 15 分钟发送一次测试通知

事情是当我按下按钮时,通知会立即发送,但只发送一次。即使我等待 20,30 分钟或将时间设置为 +1 小时,仅此而已

主活动:

private void initNotification() {

    sendNotifButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            enableNotification();
        }
    })

   private void enableNotification(){
    NotificationWorker.scheduleReminder();
}

通知工作者:

private SharedPreferences preferences;
private String notifMessage = "Notification numéro : ";
private int notifNumber = 1;
public static final int notif_id = 1;

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

@NonNull
@Override
public Result doWork() {
    preferences = getApplicationContext().getSharedPreferences("key", Context.MODE_PRIVATE);
    preferences.edit().putString("message", notifMessage).apply();
    preferences.edit().putInt("numero", notifNumber + 1).apply();

    sendNotification();

    return Result.success();
}

private void sendNotification() {
    String message = preferences.getString("message", null) + "" + preferences.getInt("numero", 50);
    NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext())
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle("title")
            .setContentText(message);

    Intent intent = new Intent(getApplicationContext(), MainActivity.class);

    PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
    builder.setContentIntent(pendingIntent);

    NotificationManager manager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
    manager.notify(notif_id, builder.build());
}

public static void cancelReminder() {
    WorkManager instance = WorkManager.getInstance();
    instance.cancelAllWorkByTag("worker_tag");
}

public static void scheduleReminder() {
    PeriodicWorkRequest.Builder notificationWork = new PeriodicWorkRequest.Builder(NotificationWorker.class,
            15, TimeUnit.MINUTES)
            //Set network connected required to periodicWorkRequest
            .setConstraints(new Constraints.Builder()
                    .setRequiredNetworkType(NetworkType.CONNECTED).build());
    PeriodicWorkRequest request = notificationWork.build();

    WorkManager.getInstance().enqueueUniquePeriodicWork("worker_tag", ExistingPeriodicWorkPolicy.REPLACE , request);
}

}

此功能必须在更大的项目中实现,但我无法每 15 分钟发送一次通知

【问题讨论】:

  • 您能分享一下您的日志中发生了什么吗?

标签: java android notifications android-workmanager periodic-task


【解决方案1】:

由于您有严格的时间间隔,我建议在这种情况下使用 AlarmManager 而不是 WorkManager。假设您希望在应用程序处于后台状态时也显示这些通知,请尝试使用AlarmManager#setExactAndAllowWhileIdle 方法。

【讨论】:

    【解决方案2】:

    我也不太了解enqueUniquePeriodicWork(...) 的工作原理,但一个简单的enque(...) 对我有用。
    我还有一个额外的要求是唯一的,并且一次只能运行我的 worker 类的一个实例,所以我编写了这个小单例类。以下代码:

    • 可以为某些工作人员MyWorker.class 创建定期工作请求,计划每 15 分钟无限制地运行一次
    • 有一个方便的isMyWorkerRunning() 方法,它可以返回天气你工人是否正在运行。请注意,enqueued,running or blocked state 将返回 true
    • 在内部,它在自己的共享首选项中维护处于运行状态的工作人员的id,以处理插入和检查。并在删除时使用请求的唯一tag
    public class WorkersHandler {
        private static WorkersHandler INSTANCE = null;
        private static final String TAG = "WorkersHandler";
        private static final String PREF_KEY_MY_WORKER = "my_Worker";
    
        private static final String TAG_WORKER_REQ = "Worker_req";
    
        private WorkManager workManagerObj;
        private SharedPreferences pref;
        private WorkersHandler(Context ctx) {
            Context appCtx = ctx.getApplicationContext();
            this.workManagerObj = WorkManager.getInstance(appCtx);
    
            String prefName = "WORKER_HANDLER";
            this.pref = ctx.getSharedPreferences(prefName, Context.MODE_PRIVATE);
        }
        public WorkersHandler getInstance(Context ctx) {
            if (INSTANCE == null) {
                INSTANCE = new WorkersHandler(ctx);
            }
            return INSTANCE;
        }
    
        public boolean isMyWorkerRunning() {
            boolean isRunning = false;
    
            UUID someWorkerID = getUUID(PREF_KEY_MY_WORKER);
            WorkInfo workInfo = getWorkInfoForWorker(someWorkerID);
    
            if (workInfo != null) {
                WorkInfo.State state = workInfo.getState();
                if (state == WorkInfo.State.RUNNING || state == WorkInfo.State.ENQUEUED || state == WorkInfo.State.BLOCKED) {
                    isRunning = true;
                }
            }
            else {
                //do nothing, the  work request associated with the give uuid doesn't exist in androidOS
                // schedular. simply return false
            }
    
            return isRunning;
        }
        @Nullable private WorkInfo getWorkInfoForWorker(UUID uuid) {
            WorkInfo workInfo = null;
            try {
                workInfo = workManagerObj.getWorkInfoById(uuid).get();
            } catch (ExecutionException | InterruptedException e) {
                e.printStackTrace();
            }
            return workInfo;
        }
        private UUID getUUID(String key) {
            //will return uuid of either a previous Worker running, or a garbage uuid(if
            // preferences doesn't have a value
            String garbageID = UUID.randomUUID().toString();
    
            UUID generatedID = UUID.fromString(pref.getString(key, garbageID));
    
            return generatedID;
        }
    
        public void startMyWorkerSingleton() {
            if (isMyWorkerRunning()) {
                Log.e(TAG, "startSingleTonLogWorker: Worker already running, therefore return");
                //return;
            } else {
                PeriodicWorkRequest LogWorkerRequest = buildMyWorkerRequest();
                putUUID(PREF_KEY_MY_WORKER, LogWorkerRequest.getId());
                workManagerObj.enqueue(LogWorkerRequest);
            }
        }
        private PeriodicWorkRequest buildMyWorkerRequest() {
            Constraints.Builder constraintsBuilder = new Constraints.Builder()
                    .setRequiresCharging(false)
                    .setRequiredNetworkType(NetworkType.NOT_REQUIRED)
                    .setRequiresBatteryNotLow(false)
                    .setRequiresStorageNotLow(false);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                constraintsBuilder.setRequiresDeviceIdle(false);
            }
    
            return new PeriodicWorkRequest
                    .Builder(LogsWorker.class, 15, TimeUnit.MINUTES)//<-- My workerclass. replace with yours
                    .setConstraints(constraintsBuilder.build())
                    .addTag(TAG_WORKER_REQ)
                    .build();
        }
        private void putUUID(String key, UUID uuidString) {
            //will put uuid in prefs
            Log.e(TAG, "putUUID: called for key" + key + "with uuid string" + uuidString);
            pref.edit().putString(key, uuidString.toString()).apply();
        }
    
        public void  stopMyWorker(){
            Log.e(TAG, "stopPeriodicNotifierService: called" );
            workManagerObj.cancelAllWorkByTag(TAG_WORKER_REQ);
            putUUID(PREF_KEY_MY_WORKER, UUID.randomUUID());
        }
    
    
    
        }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-23
      • 2018-04-29
      • 2019-11-08
      • 2011-11-06
      相关资源
      最近更新 更多