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>
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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With