将通知安排到特定日期和时间

Scheduling a notification to a specific date and time

我是 Call Manager 的开发者,我正在尝试为我的应用程序实现通知提醒功能。这个想法是用户可以给自己设置一个提醒来呼叫列表中的特定人。起初,在实现此功能时,通知会在没有计划的情况下立即显示 - 这是由于值设置不正确导致负毫秒。但是,既然我已经更正了这一点,即使我有正确的毫秒值来提供 AlarmManager,通知也根本不会被安排。

安排通知的方法如下:

public void scheduleReminder(Notification notification, String date, String time){
        String[] dateArray = date.split("/");
        String[] timeArray = time.split(":|\s+");
        Date currentDate = new Date();
        int notHour;

        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(System.currentTimeMillis());
        cal.clear();
        if(timeArray[2].equals("PM")){
            notHour = Integer.parseInt(timeArray[0]);
            notHour = notHour + 12;
            cal.set(Calendar.YEAR, Integer.parseInt(dateArray[2]));
            cal.set(Calendar.MONTH, Integer.parseInt(dateArray[0]) - 1);
            cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateArray[1]));
            cal.set(Calendar.HOUR_OF_DAY, notHour);
            cal.set(Calendar.MINUTE, Integer.parseInt(timeArray[1]));
        }
        else{
            cal.set(Calendar.YEAR, Integer.parseInt(dateArray[2]));
            cal.set(Calendar.MONTH, Integer.parseInt(dateArray[0]) - 1);
            cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateArray[1]));
            cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeArray[0]));
            cal.set(Calendar.MINUTE, Integer.parseInt(timeArray[1]));
        }

        Date reminderDate = cal.getTime();
        long diffInMillis  = reminderDate.getTime() - currentDate.getTime();

        Intent notificationIntent = new Intent(this, NotificationPublisher.class);
        notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID, 1);
        notificationIntent.putExtra(NotificationPublisher.NOTIFICATION, notification);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + diffInMillis, pendingIntent);
    }

我的广播接收器class如下:

package groovinchip.com.callmanager;

import android.app.Notification;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class NotificationPublisher extends BroadcastReceiver {

    public static String NOTIFICATION_ID = "notification-id";
    public static String NOTIFICATION = "notification";

    @Override
    public void onReceive(Context context, Intent intent) {
        NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);

        Notification notification  = intent.getParcelableExtra(NOTIFICATION);
        int id = intent.getIntExtra(NOTIFICATION_ID, 0);
        notificationManager.notify(id, notification);
    }
}

以及相关的Android清单声明如下:

<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<receiver android:name="groovinchip.com.callmanager.NotificationPublisher"
     android:enabled="true">
</receiver>

我很困惑为什么这不起作用 - 我仔细研究了我的 Google 结果试图弄明白。我在以下之间切换: 1) 设置 AlarmManagerSystem.ELAPSED_REALTIME_WAKEUP 2) 通过 SystemClock.elapsedRealTime() + diffInMillies 3) 仅通过 diffInMillis 4) 传递一个仅代表几秒而不是 diffInMillis 的整数值来查看它是否有效

有人能帮忙吗?非常感谢!

当您创建通知时,您是在设置频道 ID 吗?如果您在 API 26 上测试,如果没有一套,以及广播接收器中的一个频道,警报将不会响起。

我有两种方法可以创建和设置来自时间选择器的提醒和用户选择的闹钟。这是它们的源代码

private void createReminder(Notification notification) {
    Intent notificationIntent = new Intent(this, NotificationPublisher.class);
    notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID, 1);
    notificationIntent.putExtra(NotificationPublisher.NOTIFICATION, notification);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    long delay = alarmCalendar.getTimeInMillis() - Calendar.getInstance().getTimeInMillis();
    long futureInMillis = SystemClock.elapsedRealtime() + delay;
    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, futureInMillis, pendingIntent);
}

private Notification getNotification() {
    String channelId = "Reminders";
    PendingIntent newEntryActivityPendingIntent = PendingIntent.getActivity(this, 1, new Intent(this, NewEntryActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
            .setContentTitle(getString(R.string.app_name))
            .setContentText(getString(R.string.reminder_content))
            .setTicker(getString(R.string.app_name))
            .setSmallIcon(R.drawable.notebook_notification_white)
            .setDefaults(Notification.DEFAULT_SOUND)
            .setAutoCancel(true)
            .setContentIntent(newEntryActivityPendingIntent);
    Log.i(TAG, "notification built");
    return builder.build();
}

在我的应用程序中,我有一个通知提醒,我有一个单独的 class 用于我的广播接收器,类似于你,这就是我的样子

    public class NotificationPublisher extends BroadcastReceiver {

    private static final String TAG = "NotificationPublisher";
    public static String NOTIFICATION_ID = "notification-id";
    public static String NOTIFICATION = "notification";

    @Override
    public void onReceive(Context context, Intent intent) {
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= 26) {
            NotificationChannel channel = new NotificationChannel("Reminders", "Reminders", NotificationManager.IMPORTANCE_DEFAULT);
            notificationManager.createNotificationChannel(channel);
        }
        Notification notification = intent.getParcelableExtra(NOTIFICATION);
        int id = intent.getIntExtra(NOTIFICATION_ID, 0);
        Log.i(TAG, "notification sent");
        notificationManager.notify(id, notification);
    }
}

从外观上看,几乎和你的一模一样。

这对我来说效果很好。让我知道是否可以提供任何其他帮助。