11

可能重复:
Android GCM:GCMRegistrar 提供空注册 ID

我已经按照编写服务器端应用程序在我的应用程序中实现 GCM,但是

        final String regId = GCMRegistrar.getRegistrationId(this);

返回空。每时每刻。

我正确放置了所有权限。

有代码:

    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);
   }
  }
 }

谢谢您的帮助!

编辑:清单.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>

4

3 回答 3

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 的子类)。

我能说什么,我是金牛座,我喜欢妥善整理我的东西!

于 2012-10-31T00:50:07.653 回答
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_IDpublic static final String SENDER_ID = "YOUR_GOOGLE_PROYECT_ID";.

希望能帮助到你。

于 2012-10-30T13:49:25.030 回答
0

当您安装应用程序时,Registraion id 将在第一次为空。所以请在此处将字符串 regestraionId 设为静态并在 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);

} 
于 2012-10-30T13:43:35.967 回答