在 Android 通知中添加 "Remind me later" 选项

Adding "Remind me later" option in Android notification

我正在开发一个简单的 Water Reminder 应用程序。剩下要实现的最后一件事是在提醒通知弹出时添加“稍后提醒我”选项。我搜索了许多类似的问题和文章,但没有找到解决方案。问题是我什至不知道我应该做什么...开始一些 activity,或者发送一些东西到广播接收器或其他东西。我什至不知道如何开始尝试不同的方法。如果有人帮助我,我将非常感激!下面是代码。我可以在代码中添加什么来实现这个功能?

public class ReminderManager {

public void createNotificationChannel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

        Uri soundUri = Uri.parse(Constants.PATH_TO_NOTIFICATION_RINGTONE);
        AudioAttributes audioAttributes = new AudioAttributes.Builder()
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .setUsage(AudioAttributes.USAGE_ALARM)
                .build();

        NotificationChannel notificationChannel = new NotificationChannel
                (Constants.NOTIFICATION_CHANNEL_ID, "WaterReminderChannel", NotificationManager.IMPORTANCE_HIGH);
        notificationChannel.setSound(soundUri, audioAttributes);
        notificationChannel.setDescription("Channel for Water Reminder");

        NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(notificationChannel);
    }
}

public void setReminder() {
    Intent intent = new Intent(context, ReminderBroadcastReceiver.class);
    PendingIntent pendingIntentForBroadcast = PendingIntent.getBroadcast(context, 0, intent, 0);

    AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
    AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager, AlarmManager.RTC_WAKEUP,
            System.currentTimeMillis() + MainActivity.reminderTime, pendingIntentForBroadcast);
}



public class ReminderBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent i) {
    if (MainActivity.reminderTime > 0 && !MainActivity.dayFinished) {
        Intent intent = new Intent(context, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

        Uri soundUri = Uri.parse(Constants.PATH_TO_NOTIFICATION_RINGTONE);

        Notification notification = new NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_ID)
                .setSmallIcon(R.mipmap.water)
                .setContentTitle("Water Reminder")
                .setContentText("It's time to drink something!")
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setSound(soundUri)
                .setDefaults(Notification.DEFAULT_VIBRATE)
                .setContentIntent(pendingIntent)
                .setAutoCancel(true)
                .build();

        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
        notificationManager.notify(1, notification);
    }
}

如果我没理解错的话,我相信处理这个问题的最简单方法是使用通知“操作按钮”。有关详细信息,请参阅 https://developer.android.com/training/notify-user/build-notification

谢谢。你的信息帮助我解决了问题。我已经成功了,想分享我的代码,因为它非常简单,也许会节省别人的时间,而不是像我那样搜索很多复杂的解决方案。

因此,下面是为用户指定的时间设置警报的代码,然后在该时间发生后,即使 phone 处于空闲状态,广播接收器也会被触发,这要归功于“AlarmManagerCompat.setExactAndAllowWhileIdle "(适用于较旧和较新的 Android 版本)。然后接收器检查触发了哪个动作——SNOOZE 或 REMINDER。如果是 SNOOZE,它会调用我的自定义 ReminderManager class 的 setReminder() 方法来重置闹钟,然后调用 notificationManager.cancelAll() 来删除之前的通知横幅。如果是 REMINDER,那么它会调用 showNotification() 方法来构建通知并将其显示给用户(我发现在 AlarmManager 设置为触发接收器之前不需要构建通知)。

在我的 ReminderManager class 中,我有更新 Android 版本所需的 createNotificationChannel() 方法,我在 MainActivity 的 onCreate 中调用它。 setReminder() 方法从需要设置提醒的地方调用(当用户设置通知时,如上所述从 BroadcastReciever 调用),showNotification() 方法从 BroadcastReciever 调用,如上所述。

public class BroadcastReceiver extends android.content.BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    ReminderManager reminderManager = new ReminderManager(context);
    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);

    if (intent.getAction().equals(Constants.SNOOZE_ACTION)) {
        reminderManager.setReminder();
        notificationManager.cancelAll();
    } else if (intent.getAction().equals(Constants.REMINDER_ACTION)) {
        reminderManager.showNotification();
    }
}

}

public class ReminderManager {

private final Context context;

public ReminderManager(Context context) {
    this.context = context;
}

public void createNotificationChannel() {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        AudioAttributes audioAttributes = new AudioAttributes.Builder()
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .setUsage(AudioAttributes.USAGE_ALARM)
                .build();

        NotificationChannel notificationChannel = new NotificationChannel
                (Constants.NOTIFICATION_CHANNEL_ID, "WaterReminderChannel",
                        NotificationManager.IMPORTANCE_HIGH);
        notificationChannel.setSound
                (RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), audioAttributes);
        notificationChannel.setDescription("Channel for Water Reminder");

        NotificationManager notificationManager =
                context.getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(notificationChannel);
    }
}

public void setReminder() {
    Intent intent = new Intent(context, BroadcastReceiver.class);
    intent.setAction(Constants.REMINDER_ACTION);
    PendingIntent pendingIntentForBroadcast =
            PendingIntent.getBroadcast(context, 0, intent, 0);

    AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
    AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager, AlarmManager.RTC_WAKEUP,
            System.currentTimeMillis()
                    + MainActivity.reminderTime, pendingIntentForBroadcast);
}

public void showNotification() {
    Intent maniActivityIntent = new Intent(context, MainActivity.class);
    PendingIntent mainActivityPendingIntent =
            PendingIntent.getActivity(context, 0, maniActivityIntent, 0);

    Intent snoozeIntent = new Intent(context, BroadcastReceiver.class);
    snoozeIntent.setAction(Constants.SNOOZE_ACTION);
    PendingIntent snoozePendingIntent =
            PendingIntent.getBroadcast(context, 0, snoozeIntent, 0);

    Notification notification = new NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_ID)
            .setSmallIcon(R.mipmap.water)
            .setContentTitle("Water Reminder")
            .setContentText("It's time to drink something!")
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
            .setDefaults(Notification.DEFAULT_VIBRATE)
            .setContentIntent(mainActivityPendingIntent)
            .addAction(android.R.drawable.ic_lock_idle_alarm, "Remind me later", snoozePendingIntent)
            .setAutoCancel(true)
            .build();

    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
    notificationManager.notify(0, notification);
}

}