GCMRegistrar getRegistrationId返回空ID

时间:2012-10-30 13:25:17

标签: android google-cloud-messaging

  

可能重复:
  Android GCM : GCMRegistrar gives empty registration ID

我已按照Writing the Server-side Application在我的应用程序中实现GCM,但

        final String regId = GCMRegistrar.getRegistrationId(this);

返回empy。一直以来。

我正确地放了所有权限。

代码:

    public void registerPush(){

  GCMRegistrar.checkDevice(this);
  GCMRegistrar.checkManifest(this);
  final String regId = GCMRegistrar.getRegistrationId(this);
  REG_ID = regId;
  if (regId.equals("")) {
   GCMRegistrar.register(this, this.getString(R.string.SENDER_ID));
  } else {
   if (GCMRegistrar.isRegisteredOnServer(this)) {
    // Skips registration.
   } else {
    // Try to register again, but not in the UI thread.
    // It's also necessary to cancel the thread onDestroy(),
    // hence the use of AsyncTask instead of a raw thread.
    final Context context = this;
    mRegisterTask = new AsyncTask<Void, Void, Void>() {
     @Override
     protected Void doInBackground(Void... params) {
      boolean registered = forceRegister(context, regId);
      // At this point all attempts to register with the app
      // server failed, so we need to unregister the device
      // from GCM - the app will try to register again when
      // it is restarted. Note that GCM will send an
      // unregistered callback upon completion, but
      // GCMIntentService.onUnregistered() will ignore it.


      if (!registered) {
       GCMRegistrar.unregister(context);
      }
      return null;
     }

     @Override
     protected void onPostExecute(Void result) {
      mRegisterTask = null;
     }

    };
    mRegisterTask.execute(null, null, null);
   }
  }
 }

感谢您的帮助!

编辑: manifest.xml

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="17" />

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

<permission
    android:name="package.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />
<uses-permission android:name="package.permission.C2D_MESSAGE" />

<application>
      <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="package" />
        </intent-filter>
    </receiver>

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

</application>

3 个答案:

答案 0 :(得分:20)

为我解决的问题是该设备卡在了WAKE LOCK中。

长话短说,日志指出它试图在这里找到我的服务:

  

IntentService类:com.myapppackage.GCMIntentService

我希望它指出:

  

IntentService类:com.myapppackage.gcm.GCMIntentService

所以我扩展了广播接收器如下:

package com.myapppackage.gcm;

import android.content.Context;

public class GCMBroadcastReceiver extends
        com.google.android.gcm.GCMBroadcastReceiver {

    @Override
    protected String getGCMIntentServiceClassName(Context context) {

        return "com.myapppackage.gcm.GCMIntentService";
    }
}

然后我更新了我的清单以反映这一变化:

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

这在文档中解释(第5点):

  

http://developer.android.com/guide/google/gcm/gs.html#android-app

     

此意向服务将由GCMBroadcastReceiver调用(其中   是由GCM库提供的,如下一步所示。肯定是   必须是com.google.android.gcm.GCMBaseIntentService的子类   包含一个公共构造函数,应该命名   my_app_package.GCMIntentService(除非你使用的子类   GCMBroadcastReceiver覆盖用于命名的方法   服务)。

我能说什么,我是金牛座我喜欢正确地组织我的东西!

答案 1 :(得分:2)

您正在致电

final String regId = GCMRegistrar.getRegistrationId(this);

GCMRegistrar.register(this, this.getString(R.string.SENDER_ID));

第一次运行应用时尚未注册。

还要检查GCMIntentService类是否有空构造函数:

public class GCMIntentService extends GCMBaseIntentService {

    public GCMIntentService() {
        super(SENDER_ID);
    }

    @Override
    protected void onRegistered(Context context, String registrationId) {       
        Log.i("GCMIntentService", "Device registered: regId = " + registrationId);
    }
}

并将SENDER_ID设为public static final String SENDER_ID = "YOUR_GOOGLE_PROYECT_ID";

希望它有所帮助。

答案 2 :(得分:0)

当您安装应用时,注册ID将在第一次出现时为空。所以请在这里创建字符串regestraionId static 并在GCMIntentService.java上更改

@Override
protected void onRegistered(Context context, String registrationId) {
    Log.i(TAG, "Device registered: regId = " + registrationId);
    yourcallingactivity.regId = registrationId;
    CommonUtilities.displayMessage(context, getString(R.string.gcm_registered));
    ServerUtilities.register(context, registrationId);

}