未来通知的时间戳不正确

7
当我的应用程序启动时,它会执行一个API调用,然后根据结果安排通知。这大约涉及到安排 ~10 个通知。实际通知上显示的时间戳似乎有问题。
由于我正在创建这些通知并使用 AlarmManager 安排闹钟,因此默认时间将是创建通知的时间 (System.currentTimeMillis())。
我尝试在我的 Notification.Builder 上使用 .setWhen() 方法将其设置为我用于安排先前提到的闹钟的时间。这样稍微好一些,但是由于不能保证通知能够准确地在指定的时间传递,因此我经常收到过去几分钟的通知。
此外,在实际调用 .notify() 之前,我尝试在我的 BroadcastReceiver 中手动覆盖通知中的 when 字段:
public class NotificationPublisher extends BroadcastReceiver {

    public static String NOTIFICATION_ID = "notification_id";
    public static String NOTIFICATION = "notification";

    public void onReceive(Context context, Intent intent) {

        NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);

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

    }
}

然而,在上述情况下,似乎忽略了.when。坦白地说,我只是在寻找一种方法,使通知显示的时间戳是实际显示的时间。
3个回答

3
我建议将通知信息作为额外参数传递,然后在BroadcastReceiver内部构建通知。这样可以在广播接收器发出通知之前构建通知,因此它将与AlarmManager触发BroadcastReceiver的时间相同。
无论你从哪里调度通知:
private void scheduleNotification(){

    // Create an intent to the broadcast receiver you will send the notification from
    Intent notificationIntent = new Intent(this, SendNotification.class);

    // Pass your extra information in
    notificationIntent.putExtra("notification_extra", "any extra information to pass in");

    int requestCode = 1;

    // Create a pending intent to handle the broadcast intent
    PendingIntent alarmIntent = PendingIntent
                .getBroadcast(this, requestCode, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    // Set your notification's trigger time
    Calendar alarmStart = Calendar.getInstance();
    alarmStart.setTimeInMillis(System.currentTimeMillis());
    alarmStart.set(Calendar.HOUR_OF_DAY, 6); // This example is set to approximately 6am

    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

    // Set the alarm with the pending intent
    // be sure to use set, setExact, setRepeating, & setInexactRepeating 
    // as well as RTC_WAKEUP, ELAPSED_REALTIME_WAKEUP, etc. 
    // where appropriate
    alarmManager.set(AlarmManager.RTC_WAKEUP, alarmStart.getTimeInMillis(), alarmIntent);
}

接下来,在你的BroadcastReceiver的onReceive中:

String notificationExtra = null;

// Retrieve your extra data
if(intent.hasExtra("notification_extra")){
    notificationExtra = intent.getStringExtra("notification_extra");
}

//Build the notification
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context);
mBuilder.setSmallIcon(notificationIcon)
        .setContentTitle(notificationTitle)
        .setContentText(notificationMessage)
        .setAutoCancel(true); // Use AutoCancel true to dismiss the notification when selected

// Check if notificationExtra has a value
if(notificationExtra != null){
    // Use the value to build onto the notification
}

//Define the notification's action
Intent resultIntent = new Intent(context, MainActivity.class); // This example opens MainActivity when clicked

int requestCode = 0;

PendingIntent resultPendingIntent =
        PendingIntent.getActivity(
                context,
                requestCode,
                resultIntent,
                PendingIntent.FLAG_UPDATE_CURRENT
        );

//Set notification's click behavior
mBuilder.setContentIntent(resultPendingIntent);

// Sets an ID for the notification
int mNotificationId = 1;

// Gets an instance of the NotificationManager service
NotificationManager mNotifyMgr =
        (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

// Builds the notification and issues it.
mNotifyMgr.notify(mNotificationId, mBuilder.build());

你能告诉我如何创建多个通知吗?可以通过提供mNotificationId来完成吗?然后我需要取消相同的通知! - xbadal
还有一个问题。如果我点击通知,我会进入新的活动,但通知仍然存在。如何清除它?setAutoCancel(true)不起作用。就这些了。谢谢您的帮助。 - xbadal
@xbadal 是的,要创建多个通知,您需要为每个通知提供不同的ID。据我所知,.setAutoCancel() 与默认的通知点击行为配合使用。您在构建通知时是否使用了 .addAction() 或者有任何会将焦点从默认通知点击中移开的内容?如果是这样,您可能需要调用 Notification Manager 的 .cancel(notificationId) 来解除通知。 - Sammy T
1
我使用与创建通知时相同的标签和id来取消,现在它可以工作了。是的,我使用.addAction()在单击时关闭通知,我使用notification.flags |= Notification.FLAG_AUTO_CANCEL;解决了所有问题。谢谢@sammy - xbadal

0

我也曾经为此苦苦挣扎,但是你的问题实际上带给了我最好的答案。我查看了setWhen(),现在它似乎完美地工作了(使用API lvl 30和31进行了检查)。由于这篇文章已经几年了,也许这个问题在此期间已经得到解决。所以这就是我在Kotlin中的做法:

class NotificationPublisher : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
    val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    val notification = intent.getParcelableExtra<Notification>(NOTIFICATION)
    notification?.`when` = System.currentTimeMillis()                               // overwriting the creation time to show the current trigger time when the notification is shown
    val postId = intent.getIntExtra(NOTIFICATION_ID, 0)

    notificationManager.notify(postId, notification)
}

-1

当您的NotificationPublisher的onReceive()方法在指定时间触发预定的alarm时,它将被调用。当您从onReceive()方法创建通知时,它一定会显示当前时间。无需使用.when.setWhen()方法。

试试这个:

public class NotificationPublisher extends BroadcastReceiver {

    public static String NOTIFICATION_ID = "notification_id";
    public static String NOTIFICATION = "notification";

    public void onReceive(Context context, Intent intent) {

        int id = intent.getIntExtra(NOTIFICATION_ID, 0);

        // Notification
        Notification notification = new Notification.Builder(context)       
            .setContentTitle("This is notification title")
            .setContentText("This is notification text")
            .setSmallIcon(R.mipmap.ic_launcher).build();

        notification.flags |= Notification.FLAG_AUTO_CANCEL;

        // Notification Manager
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager .notify(id, notification);
    }
}

如果你想在点击通知时重定向到一个活动,那么你可以使用PendingIntent并将其设置为你的通知。
public class NotificationPublisher extends BroadcastReceiver {

    public static String NOTIFICATION_ID = "notification_id";
    public static String NOTIFICATION = "notification";

    public void onReceive(Context context, Intent intent) {

        int id = intent.getIntExtra(NOTIFICATION_ID, 0);

        Intent intent = new Intent(context, YourTargetActivity.class);
        intent.putExtra("KEY_ID", id); // Pass extra values if needed

        PendingIntent pI = PendingIntent.getActivity(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        // Notification
        Notification notification = new Notification.Builder(context)       
            .setContentTitle("This is notification title")
            .setContentText("This is notification text")
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentIntent(pI).build();

        notification.flags |= Notification.FLAG_AUTO_CANCEL;

        // Notification Manager
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager .notify(id, notification);
    }
}

希望这能有所帮助~

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接