2

我终于让应用程序可以使用 GCM(Google Cloud Messaging)了。但我有一个问题。注册完成后的那一刻,我想获取registrationId。除了registrationId为空,除非我重新启动应用程序,否则它会返回一个值。

基本上我想要的是在注册完成后立即检索 registerId 。

这是我正在使用的代码:

checkNotNull(SENDER_ID, "SENDER_ID");

GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);

TextView mDisplay = (TextView) findViewById(R.id.display);

String regId = "";

if (!GCMRegistrar.isRegistered(this))
{
    mDisplay.setText("registering");
    GCMRegistrar.register(this, SENDER_ID);

    regId = GCMRegistrar.getRegistrationId(this);
    String url = "localhost/Google-Cloud-Messaging-Server-Test/registration.php?regId=" + regId;

    Log.i(TAG, "registration url: " + url);
    HttpRequest httprequest = new HttpRequest(url);
}
else
{
    regId = GCMRegistrar.getRegistrationId(this);

    mDisplay.setText(regId);
    Log.v(TAG, "Already registered");

    GCMRegistrar.unregister(this);
}

问题是代码到了这一步之后:

regId = GCMRegistrar.getRegistrationId(this);
String url = "localhost/Google-Cloud-Messaging-Server-Test/registration.php?regId=" + regId;

regId 为空。它应该有一个值,因为注册成功。难道我做错了什么?是否有可能在它实际上仍在经历注册过程时尝试获取registrationId?

在此先感谢,
马克

编辑: manifest.xml 内容

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.codeglue.google.cloud.messaging.test"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="10"
    android:targetSdkVersion="15" />

<permission
    android:name="com.codeglue.google.cloud.messaging.test.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

<uses-permission android:name="com.codeglue.google.cloud.messaging.test.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <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="com.codeglue.google.cloud.messaging.test" />
        </intent-filter>
    </receiver>

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

</application>

</manifest>
4

2 回答 2

2
  1. GCMregistrar.register()方法将com.google.android.c2dm.intent.REGISTERIntent(异步)发送到 google(查看注册 GCM文档和 GCMregistrar 源,尤其是registerinternalRegister方法)。

  2. 然后 Google 处理您的com.google.android.c2dm.intent.REGISTERIntent 并发送com.google.android.c2dm.intent.REGISTRATION带有注册 ID 的 Intent 作为响应。

  3. 然后当com.google.android.c2dm.intent.REGISTRATION意图来自谷歌(进入响应)时,广播接收器(注册用于处理这种类型的意图)将被调用,并且只有在该注册ID之后才会被保存到SharedPreferences.

我提醒getRegistrationId()方法从SharedPreferences您的设备(而不是从谷歌)获取 ID,这意味着在您可以从中获取 ID 之前SharedPreferences- 首先应该将其保存在那里。(只有com.google.android.c2dm.intent.REGISTRATION来自谷歌的 ID 才会保存在那里)。我不确定将 ID 保存到的确切放置 SharedPreferences的逻辑(我认为答案应该在 GCMRegistrar来源中)

所以。在您的程序中,您的registrationID字符串为空,因为:

  1. 你在方法GCMRegistrar.getRegistrationId之后调用GCMRegistrar.register方法。请记住,该register方法异步向 google 发送意图,这意味着当您调用getRegistrationId方法时,无法保证已经收到来自 google 的带有您 ID 的响应,并且您的 id 已经保存到SharedPreferences.

如果你想抓住 Intent 来自谷歌的那一刻com.google.android.c2dm.intent.REGISTRATION- 看看GCMIntentService'sonRegistered方法。

于 2012-09-14T15:12:09.180 回答
0

请检查 manifest.xml ,以便您正确添加所有使用权限和接收者。

     <uses-permission android:name="android.permission.INTERNET"/>
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
     <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<permission
    android:name="you_package_name.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />
<uses-permission
    android:name="you_package_name.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive data 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="you_package_name" />
         </intent-filter>
    </receiver>
于 2012-09-11T09:26:57.247 回答