Android:获取通知的唯一ID

16

我有一个看起来像这样的 for 循环块:

for(int counter = 0; counter < sList.size(); counter++){
            String s = sList.get(counter);
            Notification notification = new NotificationCompat.Builder(this).setContentTitle("Title").setContentText(s).setSmallIcon(R.drawable.ic_launcher).setContentIntent(pendingIntent).build();
            notification.flags |= Notification.FLAG_AUTO_CANCEL;
            notificationManager.notify(counter, notification);
}
这个代码块位于一个由AlarmManager触发的服务中。因此,在用户看到通知之前,该代码块可能会被执行多次。 当在sList中添加了某些内容并重新执行此代码块时,它会覆盖当前通知,因为通知的ID是相同的。 如何防止这种情况发生?如何每次获取唯一的ID?或者,也许可以避免整个ID部分,比如告诉Android无论ID是什么都必须显示通知? 提前感谢!

这里有一个简单的方法,可以确保ID的唯一性:https://dev59.com/W18e5IYBdhLWcg3wd6Q6#58786832 - ImBatman
3个回答

22
long time = new Date().getTime();
String tmpStr = String.valueOf(time);
String last4Str = tmpStr.substring(tmpStr.length() - 5);
int notificationId = Integer.valueOf(last4Str);

notificationManager.notify(notificationId, notif);

它获取当前系统时间,然后我只从中读取最后4位数字。我使用它来创建每次显示通知时的唯一ID,以避免获取相同或重置的通知ID的概率。


您介意添加一些解释,以便我们理解您的代码是做什么的吗? - David
它获取当前系统时间。然后我只从中读取最后4位数字。我使用它来创建每次显示通知时的唯一ID。这样可以避免获得相同或重置通知ID的概率。 - satyapol
2
谢谢,我会将您的回答解释添加进去。这个回答解释了我为什么写了第一条评论。 - David
9
您可以使用以下代码代替:(int)((new Date().getTime() / 1000L) % Integer.MAX_VALUE),它可以为您提供每秒钟一个新的ID,并且在68年内不会重复,或者将其除以1000而不是除以1000L,这将为您提供每微秒一个新的ID,并且在24天内不会重复。 - racs

12

我相信你不应该一次性收到太多用户通知。你应该像 Gmail 客户端一样,显示一个汇总了一组事件信息的单个通知。为此,请使用 Notification.Builder

NotificationCompat.Builder b = new NotificationCompat.Builder(c);
       b.setNumber(g_push.Counter)
        .setLargeIcon(BitmapFactory.decodeResource(c.getResources(), R.drawable.list_avatar))
        .setSmallIcon(R.drawable.ic_stat_example)
        .setAutoCancel(true)
        .setContentTitle(pushCount > 1 ? c.getString(R.string.stat_messages_title) + pushCount : title)
        .setContentText(pushCount > 1 ? push.ProfileID : mess)
        .setWhen(g_push.Timestamp)
        .setContentIntent(PendingIntent.getActivity(c, 0, it, PendingIntent.FLAG_UPDATE_CURRENT))
        .setDeleteIntent(PendingIntent.getBroadcast(c, 0, new Intent(ACTION_CLEAR_NOTIFICATION), PendingIntent.FLAG_CANCEL_CURRENT))
        .setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE)
        .setSound(Uri.parse(prefs.getString(
                SharedPreferencesID.PREFERENCE_ID_PUSH_SOUND_URI,
                "android.resource://ru.mail.mailapp/raw/new_message_bells")));

如果你仍需要大量状态栏通知,则应该在某处保存计数器的最后一个值,并使用以下for循环:

    int counter = loadLastCounterValue();
    for(String s : sList){
            Notification notification = new NotificationCompat.Builder(this).setContentTitle("Title").setContentText(s).setSmallIcon(R.drawable.ic_launcher).setContentIntent(pendingIntent).build();
            notification.flags |= Notification.FLAG_AUTO_CANCEL;
            notificationManager.notify(++counter, notification);
    }
    saveCounter(counter);

但正如我所说,我认为这是一个不好的解决方案,会导致您的应用程序用户体验不佳。


使用支持库构建通知,现在可以将通知捆绑(分组)在一起。https://developer.android.com/guide/topics/ui/notifiers/notifications.html#bundle - Raphael C

9

在通知构建器中,您可以简单地指定一个ID。
相同的ID = 通知更新
不同的ID = 新通知。

此外,两个不同的应用程序可以使用相同的通知ID,它将产生2个不同的通知而不会出现问题。系统会查看ID和其来源的应用程序。


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