我有一个使用GCM的大型用户群的Android应用。服务器端配置错误导致我们的GCM注册数据库零备份(非常糟糕!),现在无法向这些应用程序发送消息。
我的问题是:哪些客户端或服务器系统事件会导致GCM重新注册服务器?例如客户端apk版本更新,客户端谷歌播放服务更新等
作为替代方案,服务器是否有办法基本上使所有令牌注册失效,以便所有Android客户端都被迫重新注册?
答案 0 :(得分:1)
您必须发布一个新版本的应用程序(如果您当前的逻辑尚未执行此操作)应该注册到GCM并将注册ID发送到您的服务器。遗憾的是,这只会为您提供安装新版本的设备的注册ID,但您无能为力。
您可以为新应用版本添加逻辑,以便在下次发生时能够克服此问题,这次无需新版本。例如,每次启动应用程序时,都会对服务器进行API调用,其中包含应用程序实例的唯一ID(不一定是注册ID),以及服务器是否在您的数据库中找不到该ID(或者不是找不到与之关联的注册ID,您强制应用程序实例经历一些注册过程,这将要求应用程序将注册ID重新发送到您的服务器。这仍然无法帮助您恢复未启动应用的设备的注册ID,但至少您可以恢复所有活跃用户的注册ID。
答案 1 :(得分:0)
我不知道这种方法有多大可行,但它仍然有用。
您需要发布应用的新版本。
每当在GCM注册的应用程序启动时,它都会查找注册ID并调用getRegistrationId()
功能。我们将它存储在应用数据中的共享首选项中。
以下是官方文档中的一些代码:
private String getRegistrationId(Context context)
{
final SharedPreferences prefs = getGCMPreferences(context);
String registrationId = prefs.getString(PROPERTY_REG_ID, "");
if (registrationId.isEmpty())
{
Log.i(TAG, "Registration not found.");
return "";
}
int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
int currentVersion = getAppVersion(context);
if (registeredVersion != currentVersion)
{
Log.i(TAG, "App version changed.");
return "";
}
return registrationId;
}
我们使用特定密钥将注册ID存储在共享首选项中(此处为 PROPERTY_REG_ID ,已定义为public static final String PROPERTY_REG_ID = "registration_id";
)。每次我们的应用程序启动时,它都会检查是否存在此密钥。
所以我建议的是更改注册ID的这个共享首选项密钥。
这肯定不会在共享首选项中找到,并且会要求从GCM重新注册并调用registerInBackground()
函数。
private void registerInBackground()
{
new AsyncTask()
{
@Override
protected String doInBackground(Void... params)
{
String msg = "";
try
{
if (gcm == null)
{
gcm = GoogleCloudMessaging.getInstance(context);
}
regid = gcm.register(SENDER_ID);
msg = "Device registered, registration ID=" + regid;
sendRegistrationIdToBackend();
storeRegistrationId(context, regid);
}
catch (IOException ex)
{
msg = "Error :" + ex.getMessage();
}
return msg;
}
@Override
protected void onPostExecute(String msg)
{
mDisplay.append(msg + "\n");
}
}.execute(null, null, null);
}
注册后,您需要使用新的共享首选项密钥来存储新的注册ID。
这一切的缺点是,您只能获得更新应用的用户的注册ID。