多任务托盘停止应用程序时,Android 应用程序无法接收 Firebase 通知

80
我在SO上看到了一个类似的问题,但是从中没有得到正确的答案。
我们的系统向约500个设备发送通知,但不幸的是,许多设备没有收到通知。我发现OPPO F1系列手机特别容易出现这种情况。
我观察到,如果应用程序从多任务托盘中停止,则会发生这种情况。如何解决这个问题?
更新:我注意到,当我从任务托盘中关闭应用程序时,我的应用程序在应用程序管理器中被强制停止。而当我关闭WhatsApp时,它仍然没有被强制停止。WhatsApp是如何处理这个问题的?

1
同样的问题已经被解决,可以通过以下链接找到解决方法:https://dev59.com/3qPia4cB1Zd3GeqPsQvr#45810771 - Rahul Devanavar
https://dev59.com/wlcO5IYBdhLWcg3ww0Vt#45406863 - Don Chakkappan
6个回答

59

更新于 2017 年 03 月 - 包括我在这里的回答。

关于 滑动关闭/杀死/强制停止应用程序 这个话题已经讨论了相当长一段时间,似乎没有确定的答案。在我的测试中,如果我 滑动关闭 我的应用程序,我仍然可以接收到消息(使用一个 data-only 消息负载进行测试)。但是当我从“设置”菜单中 强制停止 它时,我就不能接收到任何消息了。请注意,这并不总是这样的行为。

有些设备被设计为,当您 滑动关闭 应用程序时,它将与 强制停止 相同(请参见这里的我的回答)。

还有一些设备,即使应用程序只是简单地被 滑动关闭,尽管它没有被 强制停止,但设备本身也会阻止它接收消息。其他人说这不可能是这种情况,因为 WhatsApp 等应用程序能做到。目前我了解到的原因是设备制造商已经为大多数知名应用程序 加入白名单 以使其成为可能。

这并没有在任何地方记录,因为(在我看来),这是一个还取决于设备,并且 FCM 没有 完全控制权 的主题。


原始回答:

由于这是设备特定的(正如您在帖子中提到的:OPPO F1系列手机),当在该设备上的应用程序从 多任务托盘中停止 时实际上可能会导致其被 强制关闭,并导致与其关联的服务和其他后台进程也被销毁。参见此答案,以更好地了解我的意思。

如果您在社区中搜索,常见建议是使用 START_STICKY 标志。但是,我曾经看到过先前针对 FirebaseMessagingService (请参阅此帖子,ArthurThompson 的评论):

这些服务将由 Google Play 服务启动,它始终在设备上运行。您不必自己启动/停止这些服务。

话虽如此,还存在这样的可能性(再次来自评论):

设备上可能有一个允许 / 禁止此操作的设置。


我建议进行进一步的测试,以确定服务是否由设备本身终止,或者查看是否有阻止通知的设置。


2
@AL 是正确的(我没有说错),但这并不能防止您收到推送通知。 Google Play Services 与 GCM/FCM 有永久连接,一旦收到消息,它就会启动您声明的服务来传递消息给您。因此,如果您已经正确实现了 GCM,那么无论您的应用程序是否完全关闭,您都将能够接收到消息。 - tomacco
1
@AL。好的,看这个:https://stuff.mit.edu/afs/sipb/project/android/docs/google/gcm/gcm.html虽然他们没有详细讲解,但这是一份有趣的文档。你也可以在其他SO答案中找到更多信息。https://dev59.com/WXfZa4cB1Zd3GeqPR3Y0 - tomacco
2
@milanm 许多中国厂商,包括OPPO在内,都有模仿iOS的倾向。在我们公司,我们发现许多人认为在“最近使用”屏幕中关闭应用程序与强制停止应用程序是相同的,更重要的是这种行为并没有得到统一执行,即受欢迎的即时通讯应用程序不受此行为的影响。因此,我建议您下载其他不太流行的应用程序并测试它们的行为。 - Kai
3
@KapilRajput,你有支持你观点的链接可以给我吗?这样我就可以向我的老板展示了 :D - lelloman
2
@AL,它是一个带有Google API的原始安卓25的模拟器,只要应用程序未被强制关闭,就可以使用。你有任何解决此问题的建议吗?同样适用于安卓7.1.1上的OnePlus 3T机型。 - lelloman
显示剩余15条评论

19

您是否尝试在服务类上使用stopWithTask属性?

<service
    android:name="com.yourapp.YourPushService"
    android:stopWithTask="false" />

如果设置为true,则此服务将在用户删除由该应用程序拥有的活动根任务时自动停止。默认值为false。

如果标志位为false,则在您的Service类中有一个onTaskRemoved回调函数。

在这种情况下,您可以检测到“滑动”事件,并实现解决方法。


这对我有用。在 com.yourapp.YourPushService 中,您需要输入扩展 FirebaseMessagingService 的类 :) - Michele La Ferla
1
设置 true 或 false?以防止杀死服务。 - Farzad
23
stopWithTask的默认值为false,那它的意义何在? - codepeaker
根据问题描述,即使应用程序从系统托盘中关闭,FirebaseMessagingService 仍在运行。我同意 @codepeaker 的观点。 - Faizan Mubasher

12

我遇到的问题和您类似,只不过是小米手机而不是Oppo手机。实际上,当您从系统托盘中关闭应用时,系统会完全终止该应用程序。这意味着您的应用程序将无法通过GCM/FCM接收通知。WAKE_LOCK权限也无济于事。

这并不意味着手机没有接收到通知。它收到了,但不允许应用程序显示它。您可以通过从adb发送广播并查看日志来验证此操作。

解决此问题的一种可能方法是使用SyncAdapter。虽然这样做不建议,但我已经看到一些应用程序在使用它。其他可能的解决方案是使用某种始终在后台运行的背景服务。有些人还使用AlarmManager,因为它几乎不会被杀死。我的观点是- 您不能依靠GCM / FCM来获取您的通知。

现在让我们谈谈WhatsApp-

在小米手机中,他们根据特定标准对应用进行白名单或黑名单处理。如果您下载一个应用程序,并且它在他们的白名单中,他们将允许应用程序显示通知。如果不是,您已经知道会发生什么。但好消息是您可以更改这些设置。搜索名为Security的应用程序。如果您撤销正确的权限,甚至WhatsApp也将停止显示通知。


1
您能详细说明如何利用SyncAdapter来发送通知吗?我们已经在使用SyncAdapter同步我们的数据。那么我们如何处理推送通知呢? - SepehrM
请提供如何在此情况下使用 SyncAdapter 的示例。 - blueware

4

我之前也遇到了同样的问题,但是在经过大量调试后,我意识到我停止了接收 Firebase 通知的服务,在一个活动的 onStop 方法中。

  1. 请检查您是否在应用程序中任何地方停止了这些服务。
  2. 确保您正在使用服务而不是 intent-service。
  3. 滑动应用程序永远不会停止服务。因此,请尝试为前两点调试应用程序。

2

答案在这里找到了。

没有办法从通知控制台发送数据消息。

但是有其他方法可以向设备发送通知,并且它们将在onMessageReceived内被捕获!

您需要使用终端(Mac或Linux)或类似Postman的服务,向此链接发送Post请求:https://fcm.googleapis.com/fcm/send

并使用以下正文:

{
    "to": "/topics/your_topic_here",
   "data": {
       "text":"text",
       "text1":"text1",
       ...
   }
}

您需要添加两个头部信息:
  1. Authorization - key=您的服务器密钥
  2. Content-Type - application/json
要获取您的服务器密钥,您可以在Firebase控制台中找到它:您的项目 -> 设置 -> 项目设置 -> 云消息传递 -> 服务器密钥 enter image description here enter image description here

0

我正在使用MoEngage推送通知服务发送推送通知。

解决方案是在Android的Application类中初始化PushNotification对象/服务,而不是MainActivity。

然后通知也将在被杀死的状态下接收到。

如何从Application类调用

在androidManifest.xml文件中的application标签中声明将作为Application类的类名。

<application
        android:name="App" //class name that will be an Application class
        android:label="@string/app_name"
        android:fullBackupContent="@xml/backup_descriptor"
        android:usesCleartextTraffic="true"
        android:icon="@mipmap/ic_launcher">

这将是App.kt类

class App: FlutterApplication() {
    override fun onCreate() {

        super.onCreate()
       //initialize your notification service here
      }
}

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