Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCMRegistrar getRegistrationId return empty ID [duplicate]

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>

like image 347
F4Ke Avatar asked Oct 30 '12 13:10

F4Ke


2 Answers

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!

like image 116
HGPB Avatar answered Nov 08 '22 06:11

HGPB


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.

like image 22
nsemeniuk Avatar answered Nov 08 '22 06:11

nsemeniuk