【问题标题】:How to avoid delay in Android GCM messages / change heartbeat如何避免 Android GCM 消息延迟/更改心跳
【发布时间】:2013-11-02 20:04:53
【问题描述】:

我已经阅读了许多关于影响某些人的 GCM 问题的帖子。似乎在某些设备/路由器/运营商中,通知会出现延迟。我的路由器遇到过这个问题:消息在 WIFI 上延迟很多,但在我禁用 WIFI 并连接到移动网络时立即出现。

似乎有一种解决方法可以从 Android 应用程序中完成。诸如增加心跳以使 GCM 连接保持活跃之类的东西。

谁能告诉我们应该怎么做才能避免延迟?我们如何从 Android 应用程序保持与 GCM 的连接?一个代码示例(以及在何处以及如何使用它)将非常有帮助。

This post 解释了这个问题。它说“我们可以通过 GCM 服务器(免费)每两分钟 ping 一次来保持连接处于活动状态”。我们该怎么做?

非常感谢


以下应用似乎可以解决问题。令人惊讶的是,第一个不需要任何权限,第二个是互联网连接,第三个仅适用于 root 手机:

https://play.google.com/store/apps/details?id=at.pansy.droid.gcmWifiFix

https://play.google.com/store/apps/details?id=com.elotro.pushheartbeat

https://play.google.com/store/apps/details?id=com.andqlimax.pushfixer

【问题讨论】:

  • 这很可能是由 GCM/FCM 中不切实际的心跳间隔引起的。请考虑pushy.me,这是一种替代推送通知网关,可大大提高 Android 上的通知速度和可靠性(完全披露 - 我创立了 Pushy)。

标签: android push-notification wifi google-cloud-messaging android-wifi


【解决方案1】:

我会将此作为评论放在第一个答案中,但我没有足够的声誉。

我有一个类似的问题,我在调用我的 web 服务之前执行下面的代码解决了它。

context.sendBroadcast(new Intent("com.google.android.intent.action.GTALK_HEARTBEAT"));
context.sendBroadcast(new Intent("com.google.android.intent.action.MCS_HEARTBEAT"));

希望对你有帮助!

【讨论】:

  • 您可以访问上下文对象(应用程序、活动、服务)的任何地方。例如,如果您在 Activity 中使用它,只需调用 getContext() 并使用上面的代码。
  • cordova 可以做到这一点吗?
  • 在我的三星 Note 4 上无法使用,但在我检查过的所有其他设备(大约 10 台来自不同供应商的设备)上都可以正常使用。
  • @RenanGrativol 嗨,我面临同样的问题,我可以在我的 Singleton 类中使用上述代码吗?有这个参考? this.sendBroadcast(new Intent("com.google.android.intent.action.GTALK_HEARTBEAT")); tihs.sendBroadcast(new Intent("com.google.android.intent.action.MCS_HEARTBEAT"));
  • 如果您可以使用这些方法,那么,是的。您可以访问上下文对象(应用程序、活动、服务等)的任何地方
【解决方案2】:

不需要将心跳从 GCM 服务器发送到手机,你可以强制 android 自己更快地发送心跳,否则它会这样做。

我查看了我测试并为我工作的 Push Notifications Fixer 应用程序,看来您需要做的就是广播以下意图:

com.google.android.intent.action.MCS_HEARTBEAT
com.google.android.intent.action.GTALK_HEARTBEAT

我不知道为什么它会发送两个,你可以只尝试一个,看看它是否有效。这是应用程序的链接(我不是开发人员): https://play.google.com/store/apps/details?id=com.andqlimax.pushfixer.noroot

【讨论】:

    【解决方案3】:

    如果您有 root 权限,另一种解决方案 - 您可以手动检查和更改 GCM 检测信号时间。默认值为 900000(15 分钟)。为了安全并避免 5 分钟路由器超时,我设置为 240000(4 分钟)。

    检查心跳时间(shell)

    adb shell
    su
    sqlite3 /data/data/com.google.android.gsf/databases/gservices.db "SELECT * FROM main WHERE name ='gtalk_max_server_heartbeat_time';"
    sqlite3 /data/data/com.google.android.gsf/databases/gservices.db "SELECT * FROM main WHERE name LIKE 'gtalk_%heartbeat_ping_interval_ms';"
    

    更改心跳时间(shell)

    sqlite3 /data/data/com.google.android.gsf/databases/gservices.db "UPDATE main SET value = '240000' WHERE name = 'gtalk_max_server_heartbeat_time'
    sqlite3 /data/data/com.google.android.gsf/databases/gservices.db "UPDATE main SET value = '240000' WHERE name LIKE 'gtalk_%heartbeat_ping_interval_ms'
    

    更改心跳时间(Android)

    Process proc = Runtime.getRuntime().exec("su");
    DataOutputStream os = new DataOutputStream(proc.getOutputStream());
    os.writeBytes("sqlite3 /data/data/com.google.android.gsf/databases/gservices.db \"UPDATE main SET value = '240000' WHERE name = 'gtalk_max_server_heartbeat_time'\"\n");
    os.writeBytes("sqlite3 /data/data/com.google.android.gsf/databases/gservices.db \"UPDATE main SET value = '240000' WHERE name LIKE 'gtalk_%heartbeat_ping_interval_ms'\"\n");
    os.writeBytes("exit\n");
    os.writeBytes("exit\n");
    os.flush();
    os.close();
    proc.waitFor();
    

    【讨论】:

      【解决方案4】:

      重要的不是你如何接收推送,而是你如何发送它。

      您可以将消息的优先级设置为“高”(从您发送推送的位置,您的服务器)

      https://developers.google.com/cloud-messaging/concept-options#setting-the-priority-of-a-message

      【讨论】:

      • 这对我有用,似乎也适用于 FCM,我觉得其他答案已经过时了?
      【解决方案5】:

      "we could keep the connection alive with a ping every two minutes from the GCM server (which is free)". How can we do that?

      您可以通过将 GCM 消息从您的服务器发送到您希望执行此 ping 的所有设备来做到这一点。您可以在该消息中放置一些特殊的有效负载,设备上的应用程序会静默处理这些有效负载(并且不显示任何通知)。但是,此类 ping 会缩短使用此应用的设备的电池寿命。

      【讨论】:

      • 谢谢伊兰。我们不能这样做,因为我们必须发送太多通知——我们有数百万注册设备。我们可以从设备(从 Android 应用)执行“ping”操作吗?
      • @FerranMaylinch 这也许是可能的。我从未尝试从设备向自身发送通知,但没有理由它不应该工作(毕竟设备有自己的注册 ID,它所要做的就是向 GCM 服务器发布 HTTP 请求) .唯一的问题是它只能在应用程序运行时工作。
      猜你喜欢
      • 1970-01-01
      • 2014-02-11
      • 1970-01-01
      • 2012-02-03
      • 2021-12-18
      • 1970-01-01
      • 1970-01-01
      • 2012-11-16
      • 1970-01-01
      相关资源
      最近更新 更多