我想模拟 Gmail 应用关于通知栏通知的行为,它符合推荐的 Android 模式:http://developer.android.com/design/patterns/notifications.html
当应用程序处于后台并且我收到一封新电子邮件时,我会在通知栏中收到如下通知:
Line 1 : Jane Smith
Line 2 : Hi John, this is a sample message...
也就是说,特定于单个消息的通知,点击它会导致显示该特定电子邮件的屏幕。如果我通过滑动通知或使用“全部清除”来清除通知,那么当我收到一条新消息时,我将收到另一条消息特定的通知。但是,如果我不清除它并且收到另一封电子邮件,那么该通知将变成一个摘要通知,上面写着“2 条新消息”,点击它会转到收件箱。
我知道如何更新通知,问题是我如何找出通知栏中仍然存在哪些通知(如果有)。答案并不那么简单,因为通知不会反射(reflect)我有多少条未读消息,它必须反射(reflect)哪些消息仍未被用户通过点击通知或清除通知确认。
我是否应该通过保留我们启动的通知列表、点击的通知(内容 Intent )和清除的通知(删除 Intent )来跟踪通知?我认为这种方法不够安全......例如:如果通知因为我启动手机而被清除会怎样?我应该在哪里跟踪仍在显示的通知?共享首选项?
你通常如何解决这个问题?
最佳答案
我刚刚遇到了同样的问题,我还查看了 Gmail 的适当行为。我首先研究了以下场景:
假设用户正在积极使用 Gmail 应用程序(忽略与浏览器版本的任何交互),然后离开它:
- 从那时起,如果用户收到新电子邮件,它将收到通知。
- 如果通知仍然存在并且用户收到一封新电子邮件,则通知将更新为包含自用户上次使用该应用以来最近 N 封电子邮件的标题的摘要。
- 如果用户关闭通知并且收到另一封电子邮件,则会发出另一封摘要通知。
- 如果用户导航回应用(无论是否通过点击通知),所有现有通知都将被忽略。
在 API 18 中,Android 添加了对使用 NotificationListenerService 检索 Activity 通知的支持,但是这对于我正在开发的应用程序来说太新了(最小 API 14),更不用说如果它已经被用户关闭,您不能依赖它来获取现有的通知信息。
因此我找到的解决方案是保留有关已在本地发出的通知的信息,使用该信息创建单个通知或摘要,并在用户再次打开应用程序时清除所有内容。
为了持久化通知信息,我创建了一个类似于下面的简单模型:
public class NotificationBundle {
private String mText;
// Add any other relevant information about your notification here,
// particularly what you used to create your notification intent
// i.e. an item/message id to highlight, maybe?
public String getText() {
return mText;
}
public void setText(final String text) {
mText = text;
}
}
我们的想法是为您发出的每个通知创建一个实例。
然后您必须有一种方法来保留您的 NotificationBundle
列表对象。我用了SharedPreferences
这样做,但您可以使用其他更适合您的方法(如数据库表)。坚持 List<NotificationBundle>
在SharedPreferences
我用了Gson
将数组序列化为json,然后将其保存为字符串。假设您可以使用 SharedPreferences
,您可以在 answer 中找到如何进行序列化.
有了这个结构,基本上剩下要做的就是:
当您必须发出通知时:
- 创建一个新的
NotificationBundle
包含您要通知的信息。 - 检索您现有的
List<NotificationBundle>
来自SharedPreferences
- 如果您的 bundle 列表为空,您将发出一条通知。如果不是,您将发布摘要 - 在这种情况下,您可以使用 bundle 列表来构建摘要的内容。关于摘要通知的一篇好文章是 [Using Big View Styles]。
- 添加您的新
NotificationBundle
(从 1)到您现有的List<NotificationBundle>
(来自 2)并将其保存到SharedPreferences
. - 使用
NotificationManager.notify()
发出通知.如果您始终在此处使用相同的通知 id,那么如果当前您的应用中没有任何通知可见,它将创建一个新通知,或者如果之前的通知可见,它将只更新它。
- 创建一个新的
在您的
onResume()
上你的主要 Activity 的方法,确保用NotificationManager.cancelAll()
关闭所有通知.还要确保从您的SharedPreferences
中删除你现有的List<NotificationBundle>
.
这应该可以解决问题。
关于android - 如何跟踪通知以了解何时显示摘要通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23273570/