无法从Android GCM获取注册ID

18
尽管我尝试了其他关于这个问题的答案,但它不能被解决。 发件人ID是正确的,权限已添加,API密钥是正确的。
我使用这篇文章创建项目: http://developer.android.com/guide/google/gcm/gs.html#server-app
    GCMRegistrar.checkDevice(this);
    GCMRegistrar.checkManifest(this);
    String regId = GCMRegistrar.getRegistrationId(this);
    if (regId.equals("")) {
      GCMRegistrar.register(this, SENDER_ID);
      regId = GCMRegistrar.getRegistrationId(this);
    } else {
      Log.v(TAG, "Already registered");
    }
    String did = getDeviceID();
它返回空字符串。

请详细说明您的问题。是哪个返回了空字符串?在调用GCMRegistrar.register后,logcat输出了什么? - azgolfer
谢谢@azgolfer,问题已解决,但现在我无法将regid和device id发送到servlet,它们在servlet中似乎为空。你有相关的代码吗? - Anil Kocabiyik
我在这里使用了第一个答案:https://dev59.com/NnA75IYBdhLWcg3wB0ZP,我使用扩展的AsyncTask。 - Anil Kocabiyik
@azgolfer logcat 输出 08-03 09:24:21.974: V/GCMRegistrar(14590): 注册接收器 08-03 09:24:21.974: D/GCMRegistrar(14590): 重置 com.example.ilkgcm 的退避时间 08-03 09:24:21.984: V/GCMRegistrar(14590): 注册应用程序 com.example.ilkgcm,发送者为 "my_sender_id" 08-03 09:24:36.248: A/libc(14590): 致命信号 6 (SIGABRT) 发生于 0x0000012f (code=0) - Anil Kocabiyik
当调用GCMRegistrar.register时,logcat输出如上所示。10-15秒后会出现致命信号。 - Anil Kocabiyik
如果您的问题得到了解答,您应该接受这个答案... - Amir Uval
6个回答

49

你的应用程序根包中是否正确定义了GCMIntentService,请参考此处?

<receiver android:name="com.google.android.gcm.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="my_app_package" />
  </intent-filter>
</receiver>

确保"my_app_package"与您的应用程序的主包名称完全相同,否则您的id将返回一个空字符串。

还要注意:

    GCMRegistrar.register(this, "...");

是异步的。因此,在此之后立即调用GCMRegistrar.getRegistrationId(this)是不可靠的,因此您应避免这样做。

id将通过广播回调到您的GCMIntentService,作为注册过程的一部分。从那里,您可以将gcm/fcm密钥存储在任何您喜欢的地方,并在应用程序的其他部分中使用它(通常在服务器上)。


对于回调吗?它非常即时。它涉及与系统进程的通信,并且回调来自那里。如果您等待并且它没有到达,则意味着您的设置出了问题。 - Amir Uval
需要将类放在根包中吗? - stinepike
3
看起来是这样,但没有记录。我的第一次尝试使用GCM时不在默认包上进行,结果失败了。当移到根目录时它就成功了。 - Amir Uval
它非常有帮助,谢谢 :) - Umer Abid
谢谢,这很有帮助。虽然没有文档,但根据您的建议,GCM类应该在根包中。 - surhidamatya

11

如果您的应用程序第一次启动,您需要等待GCMIntentService.java文件中的OnRegistered回调。

GCMRegistrar.register(this, SENDER_ID);
// Android does NOT wait for registration ends and executes immediately line below
// So your regId will be empty.
regId = GCMRegistrar.getRegistrationId(this);

GCMIntentService.java:

@Override
protected void onRegistered(Context c, String regId) {
    // You can get it here!
}

编辑:Google Play服务库捆绑的更新版本GCM库等待响应并返回注册ID。因此,本答案适用于旧版GCM库。


谢谢...第一次没有获取到regId是空的,然后再次启动这个应用程序我们会得到regID,但是如果按照这些步骤进行操作,我将第一次启动应用程序并获取gcm令牌..!!! :) - Najib.Nj

5

我在经过一天的努力后,遇到了同样的问题。我找到了解决方案。首先,我把我的GCM相关代码放入了我的主包中,并根据我的包做出了相应的更改,同时在androidManifest.xml文件中进行了修改。

这里给你一个简单的例子。我的项目名为GCMExample,其中有三个包:1. com.examle.GCMExample(主包),2. com.examle.GCMExample.activity(第二包),3. com.example.GCMExample.adapter(第三包)

当我的GCM相关类文件被放入第二包时,我无法获取注册ID

我的GCM相关类如下:1. GCMIntentService,2. ServerUtilities,3. CommonUtilities 4. WakeLocker均放置于我的主包com.example.GCMExample中。

同时也需要修改我的androidManifest.xml文件。

     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.GET_ACCOUNTS" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.VIBRATE" />

     <permission android:name="com.example.GCMExample.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

     <uses-permission android:name="com.example.GCMExample.C2D_MESSAGE" />

    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<receiver
        android:name="com.google.android.gcm.GCMBroadcastReceiver"
        android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>
        <!-- Receives the actual messages. -->
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <!-- Receives the registration id. -->
        <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

        <category android:name="com.example.GCMExample" />
      </intent-filter>
</receiver>  

<service android:name="com.example.GCMExample.GCMIntentService" />

Patel Dhaval,你的神奇答案救了我的一天,但这太奇怪了 :) 感谢你的大力帮助!(点赞) - Saad Bilal

2

注册应用程序com.example.ilkgcm的发件人"my_sender_id"--这个错误表明您没有将您的'my_sender_id'更改为有效的发件人ID,该ID应该是一个12位字母代码。


1
例如,您的接收器类名称为:“MyCustomIntentService.java”,只需将此名称更改为“GCMIntentService.java” ,然后再次尝试。这是简单的解决方案。只需在SRC区域更改文件名即可。

1
如果您在注册过程中没有得到响应,其中一个主要原因是您的清单文件未正确配置......特别是在``标记中正确地给出“package_name”(您的应用程序包名称,例如com.xxx.yyy)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接