Java WorkManager仅在应用程序打开时执行周期性排队任务

Java WorkManager仅在应用程序打开时执行周期性排队任务,java,android,Java,Android,我的应用程序要求每天发送两次通知。出于测试目的,我将此时间缩短为1小时。当然,这必须在后台/当应用程序关闭时完成,所以我已经尝试了AlarmManager,但没有成功。因此,我转为工作经理。有人建议我使用周期性工作来完成任务,但问题是: WorkManager仅在应用程序打开时执行所有定期工作 另一件奇怪的事情是:如果我让应用程序单独运行3个小时,当我打开应用程序时,我会收到三个以上的通知 我知道WorkManager没有执行,因为每当调用doWork()时,我都实例化了一个Date对象,并且D

我的应用程序要求每天发送两次通知。出于测试目的,我将此时间缩短为1小时。当然,这必须在后台/当应用程序关闭时完成,所以我已经尝试了AlarmManager,但没有成功。因此,我转为工作经理。有人建议我使用周期性工作来完成任务,但问题是: WorkManager仅在应用程序打开时执行所有定期工作 另一件奇怪的事情是:如果我让应用程序单独运行3个小时,当我打开应用程序时,我会收到三个以上的通知

我知道WorkManager没有执行,因为每当调用doWork()时,我都实例化了一个Date对象,并且Date对象的时间戳会打印到通知中。打印的时间将始终显示为我打开应用程序的时间,这意味着当我打开应用程序时,所有排队的工作请求都会立即执行

以下是设置警报的方法。请注意,cancelAlarm()不会取消报警,而是重置我用于调试的共享首选项

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_enter);
        ToggleButton toggle = findViewById(R.id.toggleButton);
        toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if(isChecked) {
                    setAlarm();
                } else {
                    cancelAlarm();
                }
            }
        });
    }

    private void setAlarm() {
        Constraints constraints = Constraints.NONE;
        PeriodicWorkRequest testRequest = new PeriodicWorkRequest.Builder(ReminderWorker.class, 1, TimeUnit.HOURS)
                .setConstraints(constraints)
                .build();
        WorkManager.getInstance().enqueueUniquePeriodicWork("ReminderWork", ExistingPeriodicWorkPolicy.KEEP, testRequest);
    }

    private void cancelAlarm() {
        SharedPreferences savedSharedPreferences = getApplicationContext().getSharedPreferences("USER_PREFERENCES", Context.MODE_PRIVATE);
        final SharedPreferences.Editor editor = savedSharedPreferences.edit();
        editor.putInt("Test", 0);
        editor.commit();
    }
这是实际的ReminderWorker类,我放置了一个SharedReference变量来检查工人被解雇的次数,并放置了一个Date对象来检查被解雇的时间。这些都印在通知中

public class ReminderWorker extends Worker {
    int i;
    public final String CHANNEL_ID = "MainChannel";
    public ReminderWorker(@NonNull Context context, @NonNull WorkerParameters params) {
        super(context, params);
    }



    @NonNull
    @Override
    public Result doWork() {
        Date date = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        SharedPreferences savedSharedPreferences = getApplicationContext().getSharedPreferences("USER_PREFERENCES", Context.MODE_PRIVATE);
        final SharedPreferences.Editor editor = savedSharedPreferences.edit();
        i = savedSharedPreferences.getInt("Test", 0) + 1;
        editor.putInt("Test", i);
        editor.commit();
        createNotificationChannel();
        buildNotification(cal);
        return Result.success();
    }
    private void createNotificationChannel() {
        String name = "Birthday Notifications";
        String description = "Reminds you when your friends birthday approaches";
        int importance = NotificationManager.IMPORTANCE_HIGH;
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
        channel.setDescription(description);
        NotificationManager notificationManager = getApplicationContext().getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }
    private void buildNotification(Calendar cal) {
        Context context = getApplicationContext();
        Intent openTap = new Intent(context, EnterActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, openTap, 0);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID);
        builder.setSmallIcon(R.drawable.pix_cake);
        builder.setContentTitle("TestNotification");
        builder.setStyle(new NotificationCompat.BigTextStyle()
                .bigText("TestText" + i + " Time: " + cal.get(Calendar.HOUR) + ":" + cal.get(Calendar.MINUTE)));
        builder.setPriority(NotificationCompat.PRIORITY_MAX);
        builder.setContentIntent(pendingIntent);
        builder.setAutoCancel(true);

        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
        notificationManager.notify(i, builder.build());
        //notificationManager.cancelAll();
    }
}
如果需要,这里是我的AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myfirstapp">

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.SET_ALARM" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/main_icon"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/main_icon_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".ListOfDaysActivity" />
        <activity android:name=".MainActivity" />
        <activity android:name=".EnterActivity"
            android:launchMode="singleInstance">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>


没有抛出错误,只是不是预期的结果。我需要大约每小时显示一次通知,但这根本没有发生。有没有办法解决这个问题?

是否从任务管理器中删除该应用程序?您使用哪种设备进行测试?有些设备会强制关闭应用程序,一旦再次打开应用程序,WorkManager任务将被重新安排。 这个答案可能有助于您了解正在发生的事情-