GCM - 多个通知
Posted
技术标签:
【中文标题】GCM - 多个通知【英文标题】:GCM - multiple notifications 【发布时间】:2014-04-14 16:04:07 【问题描述】:我正在使用 Google Cloud Messaging(仅一种方式,即服务器到客户端)来接收推送通知。 我收到了这些,起初一切都很好,但现在,一个多星期后,我收到了多个通知;一台设备上 3 个,另一台设备上 7 个。
我的理论是设备使用不同的 id 注册,因此会收到多个通知。
但为什么会这样呢?我正在使用 Google 的示例 android 项目,将其改编为我的项目,但看不出是什么导致了这些多次注册。 是不是因为注册ID过期了?
编辑:但是,服务器上的所有 registrationId 都不同。
EDIT2:我想我在活动的 onDestroy() 方法中调用了 GCMRegistrar(context),但实际上并没有在我的服务器上取消注册注册 ID。这可能是问题吗?注册id未注册是什么意思?
【问题讨论】:
您将注册的设备 ID 存储在哪里? 它们存储在服务器上(我没有实现)。服务器是否要检查注册id是否过期? 服务器是否检查ID是否已经存储?听起来你要多次发送它,因为它被存储了多次 【参考方案1】:即使没有看到你的代码,我猜问题如下:
服务器未检查注册设备是否已在数据库中注册,因此您有重复的条目,因此您向同一个客户端多次发送相同的通知。
即使这样做,您需要实施超时策略。在我的项目中,我有一个Thread
,它每 X 次都会向第三方服务器发送一个虚拟 HTTP 请求,所以如果设备在合理的时间后未能发送它,那就是超时,我将它从数据库。
我想解决这两个问题就能解决你的问题。
【讨论】:
所有的registrationIds都不同。 那么问题出在发送GCM
消息的脚本中,或者在处理接收到的消息的代码中。这三个之一。没有其他可能。
所以我不用担心registrationIds过期?
在您的后端多次注册设备是导致此故障的原因,正如本答案中所指出的那样。可能您正处于开发阶段,因此您必须在测试设备上多次卸载并重新安装该应用程序,这就是造成这种情况的原因。您可以简单地使用一个布尔变量来识别您是否已经向 GCM 注册了设备。
是的,你应该这样做。您的数据库将包含所有所谓的active
ID,您应该实施一些机制来使其保持最新状态(一种方式就是我描述的方式)。否则,您可能会向未注册的设备以及已更改 ID 的设备发送通知(Google 有时可能会不时更改分配给设备的 ID)【参考方案2】:
在反思您的最新评论后 (GCM 引擎可能会在确定需要时更改注册 ID,这可能会在没有事先警告的情况下随时发生,这就是为什么您应该始终检查最后一个注册 ID 是否与当前注册 ID 匹配),我有这个解决方案:
-
具有registerDevice(GCM_ID,DeviceID)等webservice功能
现在从 DB 获取 GCMIdColumn,其中 DeviceIDColumn = DeviceID。如果此 GCMIdColumn != GCM_ID,则更新。否则什么都不做。
如果没有 DeviceIDColumn = DeviceID 的行,则插入 (GCM_ID,DeviceID)。
DeviceID:从应用中获取的 ID。 GCM_ID:GCM 返回的 ID。
现在您唯一必须确定的是,您从应用生成的 DeviceID 应该是唯一的。您可以组合设备配置的 2 个或更多属性以使其独一无二。
生成设备 ID
public String getDeviceID(Context context)
TelephonyManager TelephonyMgr = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
String szImei = TelephonyMgr.getDeviceId(); // Requires READ_PHONE_STATE
String m_szDevIDShort = "35" + //we make this look like a valid IMEI
Build.BOARD.length()%10+ Build.BRAND.length()%10 +
Build.CPU_ABI.length()%10 + Build.DEVICE.length()%10 +
Build.DISPLAY.length()%10 + Build.HOST.length()%10 +
Build.ID.length()%10 + Build.MANUFACTURER.length()%10 +
Build.MODEL.length()%10 + Build.PRODUCT.length()%10 +
Build.TAGS.length()%10 + Build.TYPE.length()%10 +
Build.USER.length()%10 ; //13 digits
if(Utills.debug)
Log.i("getDeviceID",szImei+"==XXX=="+m_szDevIDShort);
return szImei+"==XXX=="+m_szDevIDShort;
希望这是您正在寻找的解决方案!
【讨论】:
这听起来是个好主意,关于如何为一台设备创建自定义唯一 ID 的任何想法?也许使用 IMEI? @deimos1988 请查看更新后的答案。这是我在一个项目中使用的 sn-p。您可以根据需要更新/修改它。 感谢您的代码,我读到可能存在问题(除了可能的隐私问题),所以我决定使用 wlan-的 MAC 地址的哈希值模块作为唯一 ID。 我会的,只要它在服务器上实现并且我可以测试它:) 对不起,如果我听起来像一个 Repo Hungry Freak,请慢慢来!【参考方案3】:这不是对您的答案的直接解决方案/修复,但 GCMRegistrar(context)
已经被弃用了一段时间。我会远离它,因为它不建议使用。
包 com.google.android.gcm 已弃用 — 请使用 GoogleCloudMessaging API 而不是这个客户端帮助程序库 - 请参阅 GCM 客户端了解更多信息。
【讨论】:
【参考方案4】:很可能它从服务器端发送了多次
【讨论】:
这似乎是我的答案,可能是这个用户猜错了,但当然这是答案 GCM - 多个通知,因为Most probably its sent multiple times from server side
?以上是关于GCM - 多个通知的主要内容,如果未能解决你的问题,请参考以下文章
如何在phonegap上使用GCM处理android中的多个推送通知