GCMRegistrar getRegistrationId возвращает пустой идентификатор

Возможный дубликат:
Android GCM: GCMRegistrar дает пустой идентификатор регистрации

Я выполнил Написание серверного приложения для реализации 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 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>

Ответ 1

Для меня было установлено, что устройство застревает в 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, который переопределяет метод, используемый для обозначения обслуживание).

Что я могу сказать, я Телец? Мне нравится правильно организовывать мои вещи!

Ответ 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";.

Надеюсь, что это поможет.

Ответ 3

Идентификатор Registraion будет иметь значение null в первый раз при установке приложения. поэтому, пожалуйста, введите string 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);

}