草庐IT

android - 如何跟踪通知以了解何时显示摘要通知

coder 2023-11-23 原文

我想模拟 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 应用程序(忽略与浏览器版本的任何交互),然后离开它:

  1. 从那时起,如果用户收到新电子邮件,它将收到通知。
  2. 如果通知仍然存在并且用户收到一封新电子邮件,则通知将更新为包含自用户上次使用该应用以来最近 N 封电子邮件的标题的摘要。
  3. 如果用户关闭通知并且收到另一封电子邮件,则会发出另一封摘要通知。
  4. 如果用户导航回应用(无论是否通过点击通知),所有现有通知都将被忽略。

在 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 中找到如何进行序列化.

有了这个结构,基本上剩下要做的就是:

  • 当您必须发出通知时:

    1. 创建一个新的 NotificationBundle包含您要通知的信息。
    2. 检索您现有的 List<NotificationBundle>来自 SharedPreferences
    3. 如果您的 bundle 列表为空,您将发出一条通知。如果不是,您将发布摘要 - 在这种情况下,您可以使用 bundle 列表来构建摘要的内容。关于摘要通知的一篇好文章是 [Using Big View Styles]。
    4. 添加您的新 NotificationBundle (从 1)到您现有的 List<NotificationBundle> (来自 2)并将其保存到 SharedPreferences .
    5. 使用 NotificationManager.notify() 发出通知.如果您始终在此处使用相同的通知 id,那么如果当前您的应用中没有任何通知可见,它将创建一个新通知,或者如果之前的通知可见,它将只更新它。
  • 在您的 onResume() 上你的主要 Activity 的方法,确保用 NotificationManager.cancelAll() 关闭所有通知.还要确保从您的 SharedPreferences 中删除你现有的List<NotificationBundle> .

这应该可以解决问题。

关于android - 如何跟踪通知以了解何时显示摘要通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23273570/

有关android - 如何跟踪通知以了解何时显示摘要通知的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  7. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  8. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  9. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  10. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

随机推荐