11

Possible Duplicate:
Android GCM : GCMRegistrar gives empty registration ID

I have followed Writing the Server-side Application to implement GCM in my application, but

        final String regId = GCMRegistrar.getRegistrationId(this);

return empy. All the time.

I put all permissions properly.

There's the code :

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

Thanks for the help!

EDIT: 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>

Community
  • 1
  • 1
F4Ke
  • 1,631
  • 1
  • 20
  • 49
  • Got the same issue. Empty id every time. My log registers the following: V/GCMRegistrar(2409): Registering app com.myapp of senders 12345678912 and V/GCMBroadcastReceiver(2409): onReceive: com.google.android.c2dm.intent.REGISTRATION and V/GCMBroadcastReceiver(2409): GCM IntentService class: com.myapp.GCMIntentService and V/GCMBaseIntentService(2409): Acquiring wakelock – HGPB Oct 30 '12 at 20:49
  • Check the constructor of the GCMIntentService, make sure you have a constructor like `public GCMIntentService() {super(SENDER_ID);}` and in the manifest check the package: – nsemeniuk Oct 30 '12 at 22:10
  • @nsemeniuk could it be anything else because I have my service set up properly (same as gcm demo example). My manifest is similar to above. – HGPB Oct 30 '12 at 23:00
  • But you are stuck in the wakelock... i think is because GCMRegistrar doesn't find the receiver, or the receiver is not properly set. I had similar issues and they were caused by a wrong package name. – nsemeniuk Oct 30 '12 at 23:12
  • @nsemeniuk Well, for starters it prints the following in the log: V/GCMBroadcastReceiver(1508): GCM IntentService class: com.myapp.GCMIntentService. This is wrong and should be com.myapp.gcm.GCMIntentService (note the gcm). But how do I get the Broadcast receiver to know this. – HGPB Oct 30 '12 at 23:26
  • You should use `` because you didn't put the GCMIntentService class on the main package, you put it on gcm package. I imagine you used `` before. – nsemeniuk Oct 30 '12 at 23:31
  • @nsemeniuk Thanks for your help by the way. My service reads as `` (note the prefix .). But I will try your way (no prefix .). My category is set as you've described. – HGPB Oct 30 '12 at 23:34
  • @nsemeniuk Nope! Bloody app is still looking here: 'com.myapp.GCMIntentService`. I wonder if it has to be this way... – HGPB Oct 30 '12 at 23:37
  • 1
    let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/18828/discussion-between-nsemeniuk-and-haraldo) – nsemeniuk Oct 30 '12 at 23:38

3 Answers3

20

What fixed it for me was that the device was getting stuck in WAKE LOCK.

Long story short, the log pointed at the fact it was trying to find my service here:

IntentService class: com.myapppackage.GCMIntentService

I wanted it to point here:

IntentService class: com.myapppackage.gcm.GCMIntentService

So I extended the broadcasts receiver as follows:

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

Then I updated my manifest to reflect the change:

<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>

This is explained in the docs here(point 5):

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

This intent service will be called by the GCMBroadcastReceiver (which is is provided by GCM library), as shown in the next step. It must be a subclass of com.google.android.gcm.GCMBaseIntentService, must contain a public constructor, and should be named my_app_package.GCMIntentService (unless you use a subclass of GCMBroadcastReceiver that overrides the method used to name the service).

What can I say, I'm a Taurus I like to organise my stuff properly!

HGPB
  • 4,346
  • 8
  • 50
  • 86
  • Thanks a bunch, specially for the link to the explanation. – M Granja Aug 20 '13 at 20:03
  • I am facing issue for very first time registration, key coming always blank ..but it come everytime for next registration...any idea..why it's coming blank for first time? – CoDe Jan 30 '14 at 20:02
  • OMG Haraldo, Can i marry your brain? It really works fine. I was breaking my head for the past one hour. You saved me. I upvoted your answer. – Rethinavel Feb 21 '14 at 13:20
  • Thanks sooooo much! I got the same issues and spent 3 days but cannot resolve until got your advices! It works for me now! – Tran Khanh Tung Apr 04 '15 at 11:35
2

You are calling

final String regId = GCMRegistrar.getRegistrationId(this);

before

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

it is not registered yet the first time you run the app.

Check also that the GCMIntentService class has an empty constructor:

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

And also put SENDER_ID as public static final String SENDER_ID = "YOUR_GOOGLE_PROYECT_ID";.

Hope it helps.

nsemeniuk
  • 1,171
  • 1
  • 13
  • 24
0

Registraion id will come null at very first time when you install app. so please make string regestraionId static here and change on 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);

} 
Sanket Kachhela
  • 10,861
  • 8
  • 50
  • 75