我有一个带有按钮的小应用程序,用于激活定期通知(工作经理定期工作请求),每15分钟发送一次测试通知
当我按下按钮时,通知会立即发送,但仅发送一次。即使我等待20,30分钟或将时间设置为+1小时,也没什么
MainActivity:
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分钟发送一次通知
答案 0 :(得分:0)
由于您有严格的时间间隔,因此在这种情况下,建议您使用AlarmManager而不是WorkManager。假设即使应用处于后台状态,您也希望显示这些通知,请尝试使用AlarmManager#setExactAndAllowWhileIdle方法。
答案 1 :(得分:0)
我对enqueUniquePeriodicWork(...)
的作品也不太了解,但是一个简单的enque(...)
在为我工作。
我还具有唯一性的附加要求,并且一次只能运行worker
类的一个实例,因此我编写了这个小型单例类。以下代码:
MyWorker.class
创建一个定期工作请求,该工作预定每15分钟不受限制地运行isMyWorkerRunning()
方法,该方法可以返回您的工作者是否正在运行的天气。请注意,它将对enqueued,running or blocked state 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());
}
}