我正在实施GCM - 我要做的第一件事是调用GCMRegistrar.getRegistrationId来查看设备是否已注册。它不是(返回空字符串),所以我对GCMRegistrar.register进行异步调用。正如所料,我的意图服务(从GCMBaseIntentService派生)获取其调用的onRegistered()方法,以及我的服务器可用于向此设备发送GCM消息的令牌。到目前为止,非常好。
然而,下次我运行应用程序时,我希望第一次调用GCMRegistrar.getRegistrationId来返回我在intent服务的onRegistered函数中返回的令牌。但我又得到了空字符串。我认为GCM客户端库(gcm.jar)会将GCM注册ID(令牌)保存到私有SharedPreferences对象 - 事实上,GCMRegistrar类(http://developer.android.com/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMRegistrar.html)的文档声明“注意:此类使用私有SharedPreferences对象来跟踪注册令牌“
我没有取消注册设备,卸载应用程序或更新了versionCode。我缺少什么想法?感谢
注意 - 此问题已在android-gcm标记下的google groups中发布。网址在这里:
https://groups.google.com/forum/#!topic/android-gcm/4FPqZLzlvE4
Mark Murphy(一个Commons Guy)对这个问题的初步诊断非常有帮助,但没有具体的问题浮出水面
更新编辑 - 这是我的AndroidManifest.xml的相关部分
<receiver android:name=".push.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.myapp.package.name" />
</intent-filter>
</receiver>
<service android:name=".push.GCMIntentService" />
答案 0 :(得分:0)
* “类别android:name =”记下您的完整包裹名称“/&gt;”*
将您的包裹放在上面的清单中。
答案 1 :(得分:0)
检查在关闭应用时调用的某个地方是否有GCMRegistrar.unregister(this);
方法。也许在onDestroy()
??
在我们的例子中,这是问题:)
该方法实际上是从Google服务中取消注册设备,因此在您打开应用并调用注册操作之前,它不会获得令牌。
答案 2 :(得分:0)
请查看示例应用的文档。在清单中它说:
By default, it must be named .GCMIntentService, unless the
application uses a custom BroadcastReceiver that redefines its name.
在您的清单中,您正在使用
<service android:name=".push.GCMIntentService" />
您没有将此服务放在根级别而不是制作自定义BroadcastReceiver。这应该是:
<service android:name=".GCMIntentService" />
我遇到了同样的问题,将服务移到我的包的根目录解决了问题。这虽然是一种愚蠢的解决方案。
答案 3 :(得分:0)
还会在您的清单中添加GCM权限并验证google gmc密钥。
App收到GCM消息。
答案 4 :(得分:0)
不用担心,如果getRegistrationId返回空字符串,那是因为有时需要时间来注册GCM Cloud。您应该等待onRegistration方法在GCMIntent Service类中触发。
一旦注册,您将收到registrationID,然后您可以随意执行任何操作(很可能您必须将其发送到您的Web数据库,您可以通过onRegistration回调方法调用Async)。
@覆盖 protected void onRegistered(Context arg0,String arg1){
//Log.i("Registration", arg1.toString());
// This is where you need to call your server to record the device registration id.
}
答案 5 :(得分:0)
我仔细检查了AndroidManifest,以确保我们的服务定义正确,确实如此。最后,我参与了一个涉及写共享偏好的黑客攻击。
答案 6 :(得分:-1)
将从GCMIntent服务派生的服务类放在应用程序的根包中。 我的意思是,如果你的应用程序包 com.stackoverflow.android 你的服务类应该驻留在这个包中 而不是其中一个包装应用程序项目的包装。确保将所有必需的权限放在清单文件中