谷歌云消息逻辑解决方案
Posted
技术标签:
【中文标题】谷歌云消息逻辑解决方案【英文标题】:Google Cloud message logical solution 【发布时间】:2014-06-04 08:00:01 【问题描述】:请任何人就我对我的 android 应用程序的逻辑怀疑提出建议。
我的应用程序不需要注册即可使用。但我需要向所有用户发送推送通知(比如 GCM )。所以我做了一个数据库表如下
user_id | gcm_regid
-------------+-----------------------------------------------
1 | ( reg id get from google at register() )
-------------+-----------------------------------------------
2 | ( reg id get from google at register() )
-------------+-----------------------------------------------
所以逻辑如下
现在的问题是
案例1:当用户“清除手机中的数据”并重新启动应用程序时,会发生另一个注册过程。结果,当我们发送推送通知时,用户将获得多次(自我们数据库中存在的最后一个 gcmregid 以来)
由于它是一个简单的新闻应用程序,无需用户注册。所以有人请给我一个解决方案吗?
提前致谢
【问题讨论】:
【参考方案1】:通过将数据存储在设备的外部存储中,可以非常可靠地解决用户清除应用程序数据(或卸载和安装应用程序)的问题。如果数据在共享首选项中不可用,请尝试在存储在外部存储中的文件中找到它。卸载应用程序时不会删除此类文件。虽然它仍然可以由用户手动删除,但您无能为力。
大多数情况下,在同一设备上多次注册到 GCM 将返回相同的注册 ID,因此您的服务器不会有同一设备的多个注册 ID(假设它在更新之前检查注册 ID 是否存在)数据库)。
如果同一设备的注册 ID 发生更改,您可以通过为每个设备创建唯一的实例标识符并将该标识符与注册 ID 一起存储在您的数据库中来检测它。当您将该实例标识符 + 注册 ID 发送到您的服务器时,首先检查该实例标识符是否存在于您的数据库中。如果存在,请将旧的注册 ID(与该实例标识符相关联)替换为新的注册 ID。您应该将实例标识符存储在设备的外部存储中。
【讨论】:
【参考方案2】:您是否为特定设备创建相同的注册 ID(在 客户端)? 如果是,请执行以下操作
在服务器端,首先检查数据库中是否存在注册ID,然后更新其信息,例如updateTime,否则注册为新ID。在这种情况下,您的服务器将为每台设备发送每条消息。
其他 如果每个注册过程的注册 ID 不同,则 gcm 将自行处理,即一段时间后它不会向旧的注册 ID 发送消息。(在这种情况下,设备将只收到一条消息,因为它只有一个唯一的注册 ID)
编辑
在使用 GCM 进行设备重新注册时,大多数情况下它会创建相同的注册 ID,因此您可以像我上面提到的那样检查服务器端的 ID 重复。
有时 Google 会更改注册 ID,您将有多个 ID 与一台设备关联(仍然 google/GCM 仅向设备发送一个通知,因为 GCM 服务器向该设备的新 ID 发送消息 ),在这种情况下,请检查规范 ID。有关详细信息,请参阅Canonical IDs
【讨论】:
但根据问题中的提问,他看到多条消息发送到同一设备。无论如何,我发现另一篇文章解释了如何通过查看回复 (***.com/questions/15908886/…) 来删除旧的注册 ID。 @Raghu 但有问题的是,我认为他得到了相同的注册 id 而不是不同的 id。链接是针对两个不同的 id 的 我不完全确定。他清楚地说“......自从我们的数据库中出现最后一个 gcmregid ......”。此外,链接的问题还谈到了发送不同的注册 ID。如果他获得相同的 reg id,那么您的建议将正常工作。【参考方案3】:这里的代码可以解决你的问题.....
在启动画面中运行此代码.....
class GCMRegisterAsync extends AsyncTask<String, String, String>
@Override
protected String doInBackground(String... params)
GCMRegistrar.checkDevice(yourclass.this);
GCMRegistrar.checkManifest(yourclass.this);
final String regId = GCMRegistrar
.getRegistrationId(yourclass.this);
if (regId.equals(""))
GCMRegistrar.register(yourclass.this, "xxxxxxxxxxxx");
else
Log.d("test", "Already registered");
GCMRegistrar.checkDevice(yourclass.this);
Log.d("info",
"unregistereddd....."
+ GCMRegistrar.getRegistrationId(yourclass.this));
GCMRegistrar.checkManifest(yourclass.this);
if (GCMRegistrar.isRegistered(yourclass.this))
Log.e("info gcm id is ",
GCMRegistrar.getRegistrationId(yourclass.this));
secondclass.regId = GCMRegistrar
.getRegistrationId(yourclass.this);
if (RegisterHalf.regId.equals(""))
// replace this with the project ID
GCMRegistrar.register(yourclass.this, "xxxxxxxxxxxx");
Log.e("reg id is ",
GCMRegistrar.getRegistrationId(yourclass.this)
);
else
Log.e("info", "already registered as" + RegisterHalf.regId);
return null;
在此之后,将要保存 id 的代码粘贴到数据库中..
SharedPreferences pref = getSharedPreferences(
com.omega.expert.classes.SharedPrefConstants.pref_name, MODE_PRIVATE);
GCMRegistrar.checkDevice(yourclass.this);
GCMRegistrar.checkManifest(yourclass.this);
regId = GCMRegistrar.getRegistrationId(yourclass.this);
Log.e("test", "Reg id:" + regId);
pref.edit().putString(com.omega.expert.classes.SharedPrefConstants.key_gcmid, regId)
.commit();
regId 是您的设备 ID... 保存到数据库....
我已成功实施。这 您的多设备 id 问题将得到解决...
【讨论】:
以上是关于谷歌云消息逻辑解决方案的主要内容,如果未能解决你的问题,请参考以下文章