Incorrect timestamp on future notifications

2019-06-20 04:57发布

When my application is launched, it performs an API call and then schedules notifications based on the results. This amounts to around ~10 notifications being scheduled. There seems to be an issue with the timestamp displayed on the actual notification being incorrect.

Since I am creating these notifications and then scheduling an alarm with an AlarmManager, the default time present on the notification will be the time at which the notification is created (System.currentTimeMillis()).

I've tried to use the .setWhen() method on my Notification.Builder to set it to the time I am using to schedule the previously mentioned alarm. This is a little better, however, because notifications are not guaranteed to be delivered at the exact time specified, I often get notifications a few minutes in the past.

Additionally, I tried to manually override the when field on the notification in my BroadcastReceiver, right before .notify() is actually called:

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

    }
}

However, in the above scenario, it seems that .when is ignored.

Frankly, I am simply looking for a way to have the timestamp displayed on the notification be the time at which it is actually displayed.

2条回答
SAY GOODBYE
2楼-- · 2019-06-20 05:12

Your NotificationPublisher's onReceive() method will be invoked only when scheduled alarm triggers as specified time. When you crate a notification from onReceive() method, it will definitely show the current time. No need to require to use .when or .setWhen() method.

Try this one:

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

If you want to redirect to an activity when click on Notification, then you can use PendingIntent and set it to your 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);
    }
}

Hope this will help~

查看更多
来,给爷笑一个
3楼-- · 2019-06-20 05:33

I would suggest passing in your notification's information as extras then building the notification inside of the BroadcastReceiver. This will build the notification just before it is issued, so it will have the same time your AlarmManager triggers the BroadcastReceiver.

From wherever you're scheduling the notification:

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

Then, inside your BroadcastReceiver's 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());
查看更多
登录 后发表回答