12

我正在实施 GCM - 我做的第一件事是调用 GCMRegistrar.getRegistrationId 来查看设备是否已注册。不是(返回空字符串),所以我对 GCMRegistrar.register 进行了异步调用。正如预期的那样,我的意图服务(从 GCMBaseIntentService 派生)调用了它的 onRegistered() 方法,以及我的服务器可以用来向该设备发送 GCM 消息的令牌。到现在为止还挺好。

但是,下次我运行该应用程序时,我希望第一次调用 GCMRegistrar.getRegistrationId 以返回我在意图服务的 onRegistered 函数中返回的令牌。但我又得到了空字符串。我认为 GCM 客户端库(gcm.jar)会将 GCM 注册 ID(令牌)保存到私有 SharedPreferences 对象——事实上,GCMRegistrar 类的文档(http://developer.android.com/guide/ google/gcm/client-javadoc/com/google/android/gcm/GCMRegistrar.html)声明“注意:此类使用私有 SharedPreferences 对象来跟踪注册令牌”

我没有取消注册设备、卸载应用程序或更新版本代码。有什么我想念的想法吗?谢谢

注意——这个问题已经发布在 android-gcm 标签下的谷歌群组中。网址在这里:

https://groups.google.com/forum/#!topic/android-gcm/4FPqZLzlvE4

马克·墨菲(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" />
4

7 回答 7

0

* "category android:name="写下你的完整包名" />"*

像上面一样在清单中提供您的包裹。

于 2012-09-13T09:34:13.763 回答
0

检查您是否GCMRegistrar.unregister(this);在应用关闭时调用的某个地方调用了方法。也许在onDestroy()?? 在我们的例子中,这是问题所在:)

该方法实际上是从 Google 服务中取消注册设备,因此在您打开应用程序并调用注册操作之前,它不会获得令牌。

于 2013-01-18T15:16:52.977 回答
0

请查看示例应用程序的文档。在清单中它说:

      By default, it must be named .GCMIntentService, unless the
      application uses a custom BroadcastReceiver that redefines its name.

在您的清单中,您正在使用

<service android:name=".push.GCMIntentService" />

您没有将此服务放在根级别,也没有制作自定义广播接收器。这应该是:

<service android:name=".GCMIntentService" />

我遇到了同样的问题,将服务移动到我的包的根目录解决了这个问题。不过,这是一种愚蠢的解决方案。

于 2014-04-02T12:39:55.020 回答
0

还将 GCM 权限添加到您的清单中并验证 google gmc 密钥。

应用接收 GCM 消息。

于 2014-04-29T06:27:59.850 回答
0

不用担心,如果 getRegistrationId 返回空字符串,那是因为有时注册到 GCM 云需要时间。您应该等待 onRegistration 方法在 GCMIntent 服务类中触发。

注册后,您将收到registrationID,然后您可以使用它做任何您想做的事情(很可能您必须将它发送到您的Web数据库,您可以从onRegistration回调方法调用Async)。

@Override 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.
}
于 2014-05-06T19:49:46.920 回答
0

我仔细检查了 AndroidManifest 以确保我们的服务定义正确。最后,我使用了一个涉及写入共享偏好的技巧。

于 2014-05-06T21:16:01.670 回答
-1

将派生自 GCMIntent 服务的服务类放在应用程序的根包中。我的意思是,如果您的应用程序包是 com.stackoverflow.android ,那么 您的服务类应该驻留在此包中,而不是在您的应用程序项目的其他包中。确保将所有必需的权限放在清单文件中

于 2014-05-02T21:41:56.060 回答