在用户定义的时间显示多个通知

Displaying multiple notifications at user-defined times

我在 Android 中编程已经一年多了,但之前从未使用过通知,我的一个应用程序需要通知。

在应用程序中,可以设置不同时间的事件。显然,用户可以选择更改这些时间或 add/remove 个事件。

我计划使用通知在活动开始前 5 分钟通知用户。

我已通读 Android 开发人员文档 Building a Notification and Services (which I am also new to). I have decided to use Services because I figured that the notification would need to be shown even when the app not running. To help me, I have been referring to one particular SO answer 作为指导。

我首先在 NotificationService class 中对通知生成器 classes 进行了一些试验,如下所示:

public class NotificationService extends IntentService {

    private static final int NOTIFICATION_ID = 1;

    public NotificationService() {
        super(NotificationService.class.getSimpleName());
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        showNotification();
    }

    private void showNotification() {
        Intent intent = new Intent(this, MainActivity.class);

        PendingIntent pendingIntent = PendingIntent.getActivity(
                this, NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setContentTitle("Test notification")
                .setSmallIcon(R.drawable.ic_event_black_24dp)
                .setContentText("Test description")
                .setContentIntent(pendingIntent);

        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        manager.notify(NOTIFICATION_ID, builder.build());
    }

}

我还使用以下内容在我的应用程序的初始屏幕中启动此 Service

Intent serviceIntent = new Intent(this, NotificationService.class);
startService(serviceIntent);

要在特定时间显示通知,我已经阅读了有关 AlarmManager 的内容,主要是通过 SO questions like this one。我也知道要显示多个通知,我需要不同的通知 ID(比如我的常量 NOTIFICATION_ID)。

但是,我不确定的是每次添加、删除或更改事件时动态更新通知显示的时间。

有人可以指导我如何实现这一目标吗?

您实现了通知部分。要在特定时间通知用户,您应该设置 AlarmManager。我粘贴您需要的完整代码,然后解释每个部分:

public class AlarmReceiver extends WakefulBroadcastReceiver {

    AlarmManager mAlarmManager;
    PendingIntent mPendingIntent;

    @Override
    public void onReceive(Context context, Intent intent) {

        int mReceivedID = Integer.parseInt(intent.getStringExtra(AddReminderActivity.EXTRA_REMINDER_ID));

        // Get notification title from Reminder Database
        ReminderDatabase rb = new ReminderDatabase(context);
        ApiReminderModel reminder = rb.getReminder(mReceivedID);
        String mTitle = reminder.getName();

        // Create intent to open ReminderEditActivity on notification click

        // handling when you click on Notification what should happen
        Intent editIntent = YourActivity.createActivity(context, reminder.getChannelId(), reminder.getStartTime());
        PendingIntent mClick = PendingIntent.getActivity(context, mReceivedID, editIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        // Create Notification
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
                .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_logo))
                .setSmallIcon(R.drawable.ic_logo)
                .setContentTitle(context.getResources().getString(R.string.app_name))
                .setTicker(mTitle)
                .setContentText(mTitle)
                .setContentIntent(mClick)
                .setSound(ringtoneUri)
                .setAutoCancel(true)
                .setOnlyAlertOnce(true);

        NotificationManager nManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        nManager.notify(mReceivedID, mBuilder.build());
    }

    public void setAlarm(Context context, Calendar calendar, int ID) {
        mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

        // Put Reminder ID in Intent Extra
        Intent intent = new Intent(context, AlarmReceiver.class);
        intent.putExtra(AddReminderActivity.EXTRA_REMINDER_ID, Integer.toString(ID));
        mPendingIntent = PendingIntent.getBroadcast(context, ID, intent, PendingIntent.FLAG_CANCEL_CURRENT);

        // Calculate notification time
        Calendar c = Calendar.getInstance();
        long currentTime = c.getTimeInMillis();
        long diffTime = calendar.getTimeInMillis() - currentTime;

        // Start alarm using notification time
        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + diffTime, mPendingIntent);

        // Restart alarm if device is rebooted
        ComponentName receiver = new ComponentName(context, BootReceiver.class);
        PackageManager pm = context.getPackageManager();
        pm.setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);
    }


    public void cancelAlarm(Context context, int ID) {
        mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

        // Cancel Alarm using Reminder ID
        mPendingIntent = PendingIntent.getBroadcast(context, ID, new Intent(context, AlarmReceiver.class), 0);
        mAlarmManager.cancel(mPendingIntent);

        // Disable alarm
        ComponentName receiver = new ComponentName(context, BootReceiver.class);
        PackageManager pm = context.getPackageManager();
        pm.setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);
    }
}

如您所见,我们有 setAlarm 可以在特定时间通知用户。我还传递了之前启动的日历实例(分配一个应该通知用户的时间)。

 Calendar mCalendar = Calendar.getInstance();
         mCalendar.add(Calendar.DAY_OF_YEAR, 7);// assume you want send notification 7 days later

        new AlarmReceiver().setAlarm(getApplicationContext(), mCalendar, id);

我们还有另一种方法cancelAlarm。如果你想删除一个 Alaram,只需传递唯一的警报 ID(已用于创建警报)。

另外不要忘记将此Service添加到您的AndroidManifest.xml:

<receiver android:name=".service.AlarmReceiver" />

只有剩下的东西 当您重新启动设备时,您应该再次设置 AlarmsManager,因此您需要 BootRecivier 服务。