未来通知的时间戳不正确



当我的应用程序启动时,它执行API调用,然后根据结果安排通知。这相当于安排了大约10个通知。实际通知上显示的时间戳似乎不正确。

由于我正在创建这些通知,然后使用AlarmManager调度警报,因此通知上的默认时间将是创建通知的时间(System.currentTimeMillis())。

我已经尝试在我的Notification.Builder上使用.setWhen()方法将其设置为我用来安排前面提到的警报的时间。然而,这要好一点,因为通知不能保证在指定的确切时间送达,我经常在几分钟后收到通知。

此外,我尝试手动覆盖BroadcastReceiver中通知上的when字段,就在.notify()被实际调用之前:

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

坦率地说,我只是在寻找一种方法,让通知上显示的时间戳成为它实际显示的时间。

我建议将通知的信息作为额外信息传递,然后在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());

我也为此挣扎了一段时间,但你的问题实际上给了我最好的答案。我检查了setWhen(),现在看起来这一切都很好(使用API 30和31级进行了检查)。由于这篇文章已有几年的历史,也许这个问题在此期间得到了解决。以下是我在科特林的表现:

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)
}

只有当计划的alarm按指定的time触发时,NotificationPublisher的onReceive()方法才会是invoked。当您从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);
}
}

如果您想在单击Notification时重定向到activity,则可以使用PendingIntent并将其设置为Notification

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);
}
}

希望这将有所帮助~

最新更新