我如何在 Worker 中访问我的 Activity 中的对象? (定期更改通知)

How can I access objects from my Activity in a Worker? (to periodically change a notification)

我想定期更改 Worker 中的通知文本。 (androidx.work.WorkManager)

我的 MainActivity 看起来像这样

public class MainActivity extends AppCompatActivity {

    ...

    private NotificationManagerCompat notificationManagerCompat;
    private NotificationCompat.Builder notificationBuilder;

    ...

    private void startNotification() {

        ...

        notificationBuilder =
                    new NotificationCompat.Builder(getApplicationContext(), warnotifier_notification_channel)
                            .setSmallIcon(R.drawable.notification_icon)
                            .setContentTitle(notificationTitle)
                            .setContentText(notificationText)
                            .setContentIntent(pendingIntent)
                            .setAutoCancel(true)
                            .setPriority(NotificationCompat.PRIORITY_LOW)
                            .setOngoing(true);

        notificationManagerCompat = NotificationManagerCompat.from(getApplicationContext());

        notificationManagerCompat.notify(1, notificationBuilder.build());

        PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(NotificationWorker.class, PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS, TimeUnit.MILLISECONDS)
                    .addTag(workTag)
                    .build();

        WorkManager.getInstance(getApplicationContext()).enqueue(periodicWorkRequest);
    }

   ...

}

我的 Worker 看起来像这样

public class NotificationWorker extends Worker {
    public NotificationWorker(@NonNull Context context, @NonNull WorkerParameters params) {
        super(context, params);
    }

    @NonNull
    @Override
    public Result doWork() {
        String notificationText = "Time: " + calendar.get(Calendar.HOUR_OF_DAY) + ":" + calendar.get(Calendar.MINUTE) + ":" + calendar.get(Calendar.SECOND);
        notificationBuilder.setContentText(notificationText);
        notificationManagerCompat.notify(1, notificationBuilder.build());
        return Result.success();
    }
}

不幸的是,Android 不允许我将 Worker 作为嵌套 class 放入我的 MainActivity 中,因此我无法像上面那样访问 NotificationManagerCompat 和 NotificationCompat.Builder 实例.

我知道我可以使用 periodicWorkRequest.setInputData(inputData) 将简单数据传递给 Worker,但我认为这没有帮助...

有什么想法吗?提前致谢。

您可以创建一个具有相同 ID 的通知(因此请为您的通知保持一个不变的 ID)并通知。它会自动更新现有的

NotificationManager notificationManager = (NotificationManager) getSystemService(
            Context.NOTIFICATION_SERVICE);
    if (notificationManager != null) {
        Create a notification object with same ID as previous one and use notify to update the existing one.
    }

Unfortunately, Android does not allow me to put the Worker as a nested class in my MainActivity, and therefore I can't access the NotificationManagerCompat and NotificationCompat.Builder instances like above.

为什么需要在 MainActivity 中添加 NotificationWorker class?

正如您提到的,您只想从 Worker class 访问 NotificationManagerCompatNotificationCompat.Builder 并且对此没有任何限制,因此要构建您的通知已经有一个上下文传递给 Worker class 构造函数,而且您仍然可以从 Worker class 调用 getApplicationContext()。 我已经测试过了,没有任何问题。

希望对您有所帮助。如果您有任何疑问,欢迎我。

Update

In my Worker class I wanted to access the notificationManagerCompat and notificationBuilder instances I created in MainActivity.

您不必在 MainActivity 中创建 notificationManagerCompat & notificationBuilder 个实例,您通常可以在 NotificationWorker

中创建它们

这是您的代码的演示

public class NotificationWorker extends Worker {
    private final NotificationManagerCompat notificationManagerCompat;
    private final NotificationCompat.Builder notificationBuilder;

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

        PendingIntent pendingIntent = PendingIntent.getActivity
                (context, 0, new Intent(context, MainActivity.class),
                        PendingIntent.FLAG_UPDATE_CURRENT);

                        notificationBuilder =
                new NotificationCompat.Builder(getApplicationContext(), warnotifier_notification_channel)
                        .setSmallIcon(R.drawable.notification_icon)
                        .setContentTitle(notificationTitle)
                        .setContentText(notificationText)
                        .setContentIntent(pendingIntent)
                        .setAutoCancel(true)
                        .setPriority(NotificationCompat.PRIORITY_LOW)
                        .setOngoing(true);

        notificationManagerCompat = NotificationManagerCompat.from(getApplicationContext());

    }

    @NonNull
    @Override
    public Result doWork() {
        Calendar calendar = new GregorianCalendar();
        String notificationText = "Time: " + calendar.get(Calendar.HOUR_OF_DAY) + ":" + calendar.get(Calendar.MINUTE) + ":" + calendar.get(Calendar.SECOND);
        notificationBuilder.setContentText(notificationText);
        notificationManagerCompat.notify(1, notificationBuilder.build());
        return Result.success();
    }
}

您可以使用 R.string.XX 从 res/string 获得 notificationTitlenotificationText,使用 [=52= 从 res/drawable 获得 notification_icon ].

有了这个,您可以从您的 Worker 使用 NotificationManagerCompatNotificationCompat.Builder,您只需要一个上下文,不需要 activity。

希望这能回答您的问题。