Google cloud messaging registration giving null error message in android app - android

These are my two methods that are called from within my main activity, in onStart() and onStop() respectively.
private void registerForMessages()
{
Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");
registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));
registrationIntent.putExtra("sender", "my project id");
startService(registrationIntent);
}
private void unRegisterForMessages()
{
Intent unregIntent = new Intent("com.google.android.c2dm.intent.UNREGISTER");
unregIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));
startService(unregIntent);
}
Where "my project id" is my 12 digit project number with google cloud messaging for android enabled in the google api console.
Both times that these are called, I get the following log:
08-10 15:07:19.370: D/GCM(791): [C2DMRegistrar.143] Send register result null 0 0
I have the manifest file set up exactly the way I have seen it set up for others. My receiver class is never called anyway, the error here in the registration seems to stop it there.
Does anyone have any idea what the error message even is telling me? What kind of things could be causing this error?
It's a little confusing trying to look it up on the android official guides, because some of it is possibly referring to the deprecated methods, and some instructions contradict each other - some say do it this way, others want you to use a register method for it.

have a look on Android Push Notifications using Google Cloud Messaging (GCM), PHP and MySQL
http://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/
As per google’s documentation “Google Cloud Messaging for Android (GCM) is a service that helps developers send data from servers to their Android applications on Android devices”. Using this service you can send data to your application whenever new data is available instead of making requests to server in timely fashion. Integrating GCM in your android application enhances user experience and saves lot of battery power.
may help you..

Actually it's ok. I think that method of doing it must actually be deprecated or something. This worked:
gcm = GoogleCloudMessaging.getInstance(this);
Thread thread = new Thread()
{
#Override
public void run()
{
try
{
Log.d("IM", "registration thread happening");
String regid = gcm.register("project number");
Log.d("IM", "id: " + regid);
}
catch (IOException e)
{
Log.d("IM register", "io exception: ");
e.printStackTrace();
}
}
};
thread.start();
It was giving me an IOException until I stuck it in its own thread too but seems to work ok now. I think the official guide needs updated perhaps.

Related

Unable to register for push notifications on Android in Xamarin together with IntercomIO

I added the IntercomIO SDK to our Xamarin.Forms app through a couple binding libraries this week and I'm currently trying to get the Push Notifications to work but soon after I call PushHandlerService.Register(this) in the MainActivity the app crashes saying that it can't find the class com.google.android.gms.gcm.GcmReceiver which isn't even being caught by the try catch block around this call.
Here is the method inside the MainActivity which is responsible for setting up the push notifications on Android.
public void registerForPushNotifications()
{
try
{
GcmClient.CheckDevice(this);
GcmClient.CheckManifest(this);
//Register the app for push notifications.
PushHandlerService.Initialize(this);
//if (!GcmClient.IsRegistered(this))//Temporarily force the app to register for push notifications
{
System.Diagnostics.Debug.WriteLine("Registering");
// Register for GCM
PushHandlerService.Register(this);
}
LocalBroadcastManager lbc = LocalBroadcastManager.GetInstance(this);
PushActionReceiver rec = new PushActionReceiver(this);
lbc.RegisterReceiver(rec, new IntentFilter("pushaction"));
}
catch (Java.Net.MalformedURLException)
{
var e = new Exception("There was an error creating the Mobile Service. Verify the URL");
System.Diagnostics.Debug.Fail(String.Format(#"Exception at {0}: {1}", this.GetType().Name, e.Message));
Insights.Report(e);
}
catch (Exception e)
{
System.Diagnostics.Debug.Fail(String.Format(#"Exception at {0}: {1}", this.GetType().Name, e.Message));
if (e.GetType() != typeof(TaskCanceledException))
Insights.Report(e);
}
}
And in the Manifest I added the receiver definition for Intercom
<receiver android:name="io.intercom.android.sdk.gcm.GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND"></receiver>
The issue doesn't happen when I don't call PushHandlerService.Register(this) but then obviously I can't receive any push notifications anymore (including the ones from our own system)
What's going on here? I have the libraries and dependancies setup properly but it doesn't seem to be able to find the GcmReceiver class..
Apparently updating to the latest SDK's in the SDK Manager solved this crash. I am still not receiving any push notifications but I'm guessing this is due to a different issue. At least the app doesn't crash anymore when trying to register for the push notifications.
Dale from Intercom here. Are you using any other third party push providers, or do you have your own GCM receiver? It's possible that they are consuming our push and not passing them on. This can be difficult in Xamarin, Phonegap, Cordova ect. as often the registration and receiver services are not available. I have included below a link to our GCM doc and the section that may be most relevant to you. If this doesn't help fix the issue get in touch with us on the cordova repo: https://github.com/intercom/intercom-cordova or reach out to us in your Intercom dashboard/ email us at team#intercom.io.
We have GCM docs here: https://docs.intercom.com/configure-intercom-for-your-product-or-site/configure-intercom-for-mobile/enable-push-notifications-with-intercom-for-android-gcm
The issue that might be causing you difficulty in your setup is:
Step 7. Using Intercom with other GCM setups (Optional)
This only applies to applications that also use GCM for their own content, or use a third party service for GCM. You’ll need to update the your GcmListenerService and the class where you generate your device token.
You should have a class that generates a push device token and sends it to your backend. In addition to sending the token to your backend you will need to forward it to Intercom, like this:
private final IntercomPushClient intercomPushClient = new IntercomPushClient();
public void onHandleIntent(Intent intent) {
InstanceID instanceId = InstanceID.getInstance(this);
String senderId = "YOUR_SENDER_ID";
String token = instanceId.getToken(senderId,
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
pushClient.sendTokenToIntercom(getApplication(), token);
}
You should have a class that extends GcmListenerService. That service will consume pushes intended for Intercom. To allow us to draw the Intercom push set up your GcmListenerService, like this:
private final IntercomPushClient intercomPushClient = new IntercomPushClient();
public void onMessageReceived(String from, Bundle message) {
if (intercomPushClient.isIntercomPush(message)) {
intercomPushClient.handlePush(getApplication(), message);
} else {
//DO HOST LOGIC HERE
}
}

Parse.com push notifications not consistently working receiving "GCM -MISMATCH SENDER ID" error

Push notifications from parse.com is not consistently working. Randomly push notifications will fail, resulting in a GCM - MISMATCH SENDER ID" error. It is my understanding that programmatically we do not have to do anything with the GCM because parse.com sends the objectId to GCM. In either case, I have not been able to pinpoint any specific reason why this error occurs sometimes and other times it doesn't. Additionally, I am using Parse version, 1.10.2.
My Application class has the following
Parse.initialize(this, APPLICATION_ID_DEBUG, CLIENT_KEY_DEBUG);
Parse.setLogLevel(Parse.LOG_LEVEL_VERBOSE);
ParsePush.subscribeInBackground(Constants.CHANNEL, new SaveCallback() {
#Override
public void done(ParseException e) {
if (Utils.checkIfNull(e)) {
// subscribed to channel
} else {
// failed to subscribe to channel
}
}
});
After the user logs into my app I attach a channel to them. The channel data I save is just the user's unique id I am getting from server.
List<String> arryChannel = new ArrayList<>();
arryChannel.add(uniqueUserId);
final ParseInstallation parseInstallation = ParseInstallation.getCurrentInstallation();
parseInstallation.put(Constants.CHANNEL, arryChannel);
parseInstallation.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (Utils.checkIfNull(e)) {
// update channel with user's unique id
} else {
// failed to update channel with user unique id
}
}
});
Finally, when the user logs out I unsubscribe them from their channel. I added unsubscribe to try and prevent any one device from receiving multiple push notifications because they have logged in as multiple users into the app and subscribed to multiple channels. The following is how my code looks when you log out.
ParsePush.unsubscribeInBackground(Constants.CHANNEL, new SaveCallback() {
#Override
public void done(ParseException e) {
if (Utils.checkIfNull(e)) {
// successfully unsubscribed to channel
// save the updated (unsubscribed) parse installation
final ParseInstallation parseInstallation = ParseInstallation.getCurrentInstallation();
parseInstallation.put(Constants.CHANNEL, new ArrayList<String>());
parseInstallation.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (Utils.checkIfNull(e)) {
// add whatever logs here to check for any issues with unsubscribing
} else {
// failed to update channel
}
}
});
} else {
Logger.e("PARSE", "failed to unsubscribed to channel: " + e.getMessage());
}
}
});
The result of this implementation is that when push notifications are not working, it will continue to fail for about 50-100 times. Then it will start working for about 150-200 times. Then it goes back to not working. It is not a work, not-work type back and forth. It is more of a fail, fail, fail multiples times and then success, success, success multiple times. Any help on what I am missing in my implementation is appreciated. Thanks in advance.
I have finally figured out the answer to this question! The issue had nothing to do with my implementation. For anyone else experiencing this same conflict, please look for any other 3rd party services that also are using push notifications. For me, Mixpanel was the culprit. When I deleted mixpanel.initPushHandling() from my codebase, all started working. And this makes sense, because when you initialize push notifications for mixpanel, you pass in a value that is used for GCMSenderID. Parse push notifications work differently. With parse.com, you do not have to send a GCMSenderID, because parse will automatically send in an objectId to perform their push notifications. Between the two, this causes a GCM-MISMATCH-SENDER error.
So the solution is, remove any sort of services that may be conflicting with parse.com. And feel free to use my implementation, it is good. Cheers!
I faced the problem and after some rummage, finally found the solution. As Parse said in it's docs you should provide each Sender_ID that your app uses to push messages, if you use another push provider in addition to Parse. Take a look at below:
The Parse Android SDK chooses a reasonable default configuration so that you do not have to worry about GCM registration ids, sender ids, or API keys. In particular, the SDK will automatically register your app for push at startup time using Parse's sender ID (1076345567071) and will store the resulting registration ID in the deviceToken field of the app's current ParseInstallation.
However, as an advanced feature for developers that want to send pushes from multiple push providers, Parse allows you to optionally register your app for pushes with additional GCM sender IDs. To do this, specify the additional GCM sender ID with the following <meta-data> tag as a child of the <application> element in your app's AndroidManifest.xml:
<meta-data android:name="com.parse.push.gcm_sender_id"
android:value="id:YOUR_SENDER_ID" />;
In the sample snippet above, YOUR_SENDER_ID should be replaced by a numeric GCM sender ID. Note that the Parse SDK expects you to prefix your sender ID with an id: prefix, as shown in the sample snippet.
If you want to register your app with multiple additional sender IDs, then the android:value in the <meta-data> element above should hold a comma-delimited list of sender IDs, as in the following snippet:
<meta-data android:name="com.parse.push.gcm_sender_id"
android:value="id:YOUR_SENDER_ID_1,YOUR_SENDER_ID_2,YOUR_SENDER_ID_3" />;

Looking for an example of the new Android API setMediaButtonReceiver

Currently I am using
mAudioManager.registerMediaButtonEventReceiver(mRemoteControlResponder);
but this is now deprecated in 5.0 and replaced by setMediaButtonReceiver. There are 5 links in Google all pointing to developer.android.com.
Has anyone used this yet? If so can you provide an example?
Check this page: http://grepcode.com/file/repo1.maven.org/maven2/org.robolectric/android-all/5.0.0_r2-robolectric-0/android/media/session/MediaSession.java It is a rather large example of the complete flow.Here one of the most relevant parts
Set a pending intent for your media button receiver to allow restarting playback after the session has been stopped. If your app is started in this way an android.content.Intent.ACTION_MEDIA_BUTTON intent will be sent via the pending intent.
Parameters: nullmbr The android.app.PendingIntent to send the media button event to.
public void More ...setMediaButtonReceiver(#Nullable PendingIntent mbr) {
try {
mBinder.setMediaButtonReceiver(mbr);
} catch (RemoteException e) {
Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e);
}
}

Google Cloud Messaging register AUTHENTICATION_FAILED

I want to try Google Cloud Messaging (GCM) service, and I am faced with a problem at the beginning.
I get an error AUTHENTICATION_FAILED while trying to register a device to GCM.
I searched and all I found were variations of the incorrect password. My password is correct and I am using just one account.
There are two ways to implement GCM client on Android:
GCM library with additional jar, now deprecated.
Google Play Services API
I started with the second of course and got this issue.
I thought the problem is in my phone, but then decided to try the first way, which worked!
However, it is deprecated and requires an additional jar, which doesn't seem like the right way.
In an attempt to understand the reasons for the error, I decompiled Google Play Services jar and compared it with GCM library.
It turns out they both have a similar method, something like:
void register(Context context, String senderIds) {
Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER");
intent.setPackage("com.google.android.gms"); // this one row are different
setPackageNameExtra(context, intent);
intent.putExtra("sender", senderIds);
context.startService(intent);
}
The difference in one row:
In GCM library it is com.google.android.gsf, where gsf is Google Services Framework (I guess), and it works!
In Google Play Services API jar it is com.google.android.gms, And it does not work (AUTHENTICATION_FAILED error).
Then in GCM library I replaced "gsf" to "gms" and run. And I got the same AUTHENTICATION_FAILED error! If I enter another package, then it is not working.
What do I need to do to make it work? Should I set up something in the phone? Or is it a bug in Google Play Services? Have someone encountered such a problem?
Thanks in advance!
I ran into the same problem, and it doesn't seem like google is in any hurry to fix it.
I didn't want to add the deprecated client helper gcm.jar to my app, so I coded a minimal solution that works on my Android 2.3.6 Nexus One phone that fails registration as in the question above
try {
gcm = GoogleCloudMessaging.getInstance(context);
regID = gcm.register(SENDER_ID);
storeRegistrationId(regID);
msg = "Device registered, registration ID=" + regID;
sendRegistrationIdToBackend();
} catch (IOException ex) {
msg = "Exception registering for GCM :" + ex.getMessage();
// If there is an error, don't just keep trying to register.
oldSchoolRegister();
}
The AUTHENTICATION_FAILED triggers the IOException in the code above
private void oldSchoolRegister() {
Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER");
intent.setPackage("com.google.android.gsf");
setRegCallbackIntent(context, intent);
intent.putExtra("sender", SENDER_ID);
context.startService(intent);
}
private static synchronized void setRegCallbackIntent(Context context, Intent intent) {
regCallback = PendingIntent.getBroadcast(context, 0, new Intent(), 0);
intent.putExtra("app", regCallback);
}
public static synchronized void cancelRegCallbackIntent() {
if (regCallback != null) {
regCallback.cancel();
regCallback = null;
}
}
I added the above code to my app. They are simplified methods from the Client Helper gcm.jar (so you don't need to add the jar to your app)
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null && !extras.isEmpty()) { // has effect of unparcelling Bundle
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
if (messageType != null) {
if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
showMessage(extras.getString("message")); // call your code
Logger.d(TAG, "Received message: " + message.alert + ": " + message.url);
} else if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
Logger.e(TAG, "Send error: " + extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
Logger.e(TAG, "Deleted messages on server: " + extras.toString());
}
} else {
String regID = extras.getString("registration_id");
if (regID != null && !regID.isEmpty()) {
doRegistration(regID); // send to your server etc.
GCMSetup.storeRegistrationId(regID);
GCMSetup.cancelRegCallbackIntent();
}
}
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
GCMBroadcastReceiver.completeWakefulIntent(intent);
}
This code is in the intent service, and has a few lines to store the ID received from GCM. As you can see only about 20 extra lines of code compared to a basic implementation, and no additional dependencies! You only need to update your AndroidManifest.xml to make sure you can receive the REGISTRATION intent.
<receiver android:name="com.camiolog.android.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.camiolog.android"/>
</intent-filter>
</receiver>
I hope this helps until google gets their act together!
This seems like a bug. Here's what an Android developer says about it in the android-gcm Google Group:
Some background: Froyo and Gingerbread registration is implemented in
GoogleServicesFramework, using the Google account for registration.
This has resulted in a lot of auth errors for people where the account
was not in a good state.
Starting with ICS, GCM doesn't depend or uses the Google account - you
can use it before you add an account or without any accounts.
The "Play Services" update is implementing the new scheme on all
devices - but it seems a small number of devices have problems with
this, we're investigating - but the numbers are far lower than those
with the old scheme.
If you want to use the code in GSF, for Froyo and Gingerbread - you
need to use the previous library, which sets package name explicitly.
The new library in GCM is using the new registration code.
The actual connection to google is following the same path - we're
gradually (and slowly) moving devices to the new code in play
services.
So far I have 2 bugreports, and we have a few suspects. We know that
if a device is not connected for >9 months it's going to be in this
state, and a factory reset will be needed.
We had some reports where a factory reset didn't solve the problem -
but I have no bugreport or information to confirm or trace this. The
only case I identified where a factory reset wouldn't help is if the
phone is sending bad information to the server in the initial checkin
- we're adding extra checks for this.
Apparently, a factory reset may solve the problem, but they're still investigating.
So it looks like the solution to avoid this problem is to fall back to the old deprecated GCM client library in case the AUTHENTICATION_FAILED error happens on FROYO and GINGERBREAD.
Here is a simple code snippet of how I upgraded the new Gcm client to fallback to use the old client:
#Override
protected void onPostExecute(Integer resultCode) {
if(resultCode == EXCEPTION_THROWED) {
//Android 2.2 gmc bug http://stackoverflow.com/questions/19269607/google-cloud-messaging-register-authentication-failed
//fall back to old deprecated GCM client library
GCMRegistrar.checkDevice(StartActivity.this);
GCMRegistrar.checkManifest(StartActivity.this);
final String registrationId = GCMRegistrar.getRegistrationId(StartActivity.this);
if (registrationId.equals("")) {
GCMRegistrar.register(StartActivity.this, SENDER_ID);
}
//Toast.makeText(context, "Orders and menus won't be sync with other devices since GoogleCloudMessaging is not working correctly on this device. Please notify the developer.", Toast.LENGTH_LONG).show();
}
}
You can find the old deprecated GCM Client helpher here: http://developer.android.com/google/gcm/helper.html
You can find the code of the GCM client on your computer on the path:
ANDROID_SDK_ROOT/extras/google/gcm-client (given you've downloaded this extra using the Android SDK Manager).
I put the old gcm client in a new package named com.google.android.gcm.deprecated to try to remember myself to not use this for other stuff.

new gcm api, GoogleCloudMessaging authentification fail on some device [duplicate]

I want to try Google Cloud Messaging (GCM) service, and I am faced with a problem at the beginning.
I get an error AUTHENTICATION_FAILED while trying to register a device to GCM.
I searched and all I found were variations of the incorrect password. My password is correct and I am using just one account.
There are two ways to implement GCM client on Android:
GCM library with additional jar, now deprecated.
Google Play Services API
I started with the second of course and got this issue.
I thought the problem is in my phone, but then decided to try the first way, which worked!
However, it is deprecated and requires an additional jar, which doesn't seem like the right way.
In an attempt to understand the reasons for the error, I decompiled Google Play Services jar and compared it with GCM library.
It turns out they both have a similar method, something like:
void register(Context context, String senderIds) {
Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER");
intent.setPackage("com.google.android.gms"); // this one row are different
setPackageNameExtra(context, intent);
intent.putExtra("sender", senderIds);
context.startService(intent);
}
The difference in one row:
In GCM library it is com.google.android.gsf, where gsf is Google Services Framework (I guess), and it works!
In Google Play Services API jar it is com.google.android.gms, And it does not work (AUTHENTICATION_FAILED error).
Then in GCM library I replaced "gsf" to "gms" and run. And I got the same AUTHENTICATION_FAILED error! If I enter another package, then it is not working.
What do I need to do to make it work? Should I set up something in the phone? Or is it a bug in Google Play Services? Have someone encountered such a problem?
Thanks in advance!
I ran into the same problem, and it doesn't seem like google is in any hurry to fix it.
I didn't want to add the deprecated client helper gcm.jar to my app, so I coded a minimal solution that works on my Android 2.3.6 Nexus One phone that fails registration as in the question above
try {
gcm = GoogleCloudMessaging.getInstance(context);
regID = gcm.register(SENDER_ID);
storeRegistrationId(regID);
msg = "Device registered, registration ID=" + regID;
sendRegistrationIdToBackend();
} catch (IOException ex) {
msg = "Exception registering for GCM :" + ex.getMessage();
// If there is an error, don't just keep trying to register.
oldSchoolRegister();
}
The AUTHENTICATION_FAILED triggers the IOException in the code above
private void oldSchoolRegister() {
Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER");
intent.setPackage("com.google.android.gsf");
setRegCallbackIntent(context, intent);
intent.putExtra("sender", SENDER_ID);
context.startService(intent);
}
private static synchronized void setRegCallbackIntent(Context context, Intent intent) {
regCallback = PendingIntent.getBroadcast(context, 0, new Intent(), 0);
intent.putExtra("app", regCallback);
}
public static synchronized void cancelRegCallbackIntent() {
if (regCallback != null) {
regCallback.cancel();
regCallback = null;
}
}
I added the above code to my app. They are simplified methods from the Client Helper gcm.jar (so you don't need to add the jar to your app)
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null && !extras.isEmpty()) { // has effect of unparcelling Bundle
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
if (messageType != null) {
if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
showMessage(extras.getString("message")); // call your code
Logger.d(TAG, "Received message: " + message.alert + ": " + message.url);
} else if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
Logger.e(TAG, "Send error: " + extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
Logger.e(TAG, "Deleted messages on server: " + extras.toString());
}
} else {
String regID = extras.getString("registration_id");
if (regID != null && !regID.isEmpty()) {
doRegistration(regID); // send to your server etc.
GCMSetup.storeRegistrationId(regID);
GCMSetup.cancelRegCallbackIntent();
}
}
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
GCMBroadcastReceiver.completeWakefulIntent(intent);
}
This code is in the intent service, and has a few lines to store the ID received from GCM. As you can see only about 20 extra lines of code compared to a basic implementation, and no additional dependencies! You only need to update your AndroidManifest.xml to make sure you can receive the REGISTRATION intent.
<receiver android:name="com.camiolog.android.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.camiolog.android"/>
</intent-filter>
</receiver>
I hope this helps until google gets their act together!
This seems like a bug. Here's what an Android developer says about it in the android-gcm Google Group:
Some background: Froyo and Gingerbread registration is implemented in
GoogleServicesFramework, using the Google account for registration.
This has resulted in a lot of auth errors for people where the account
was not in a good state.
Starting with ICS, GCM doesn't depend or uses the Google account - you
can use it before you add an account or without any accounts.
The "Play Services" update is implementing the new scheme on all
devices - but it seems a small number of devices have problems with
this, we're investigating - but the numbers are far lower than those
with the old scheme.
If you want to use the code in GSF, for Froyo and Gingerbread - you
need to use the previous library, which sets package name explicitly.
The new library in GCM is using the new registration code.
The actual connection to google is following the same path - we're
gradually (and slowly) moving devices to the new code in play
services.
So far I have 2 bugreports, and we have a few suspects. We know that
if a device is not connected for >9 months it's going to be in this
state, and a factory reset will be needed.
We had some reports where a factory reset didn't solve the problem -
but I have no bugreport or information to confirm or trace this. The
only case I identified where a factory reset wouldn't help is if the
phone is sending bad information to the server in the initial checkin
- we're adding extra checks for this.
Apparently, a factory reset may solve the problem, but they're still investigating.
So it looks like the solution to avoid this problem is to fall back to the old deprecated GCM client library in case the AUTHENTICATION_FAILED error happens on FROYO and GINGERBREAD.
Here is a simple code snippet of how I upgraded the new Gcm client to fallback to use the old client:
#Override
protected void onPostExecute(Integer resultCode) {
if(resultCode == EXCEPTION_THROWED) {
//Android 2.2 gmc bug http://stackoverflow.com/questions/19269607/google-cloud-messaging-register-authentication-failed
//fall back to old deprecated GCM client library
GCMRegistrar.checkDevice(StartActivity.this);
GCMRegistrar.checkManifest(StartActivity.this);
final String registrationId = GCMRegistrar.getRegistrationId(StartActivity.this);
if (registrationId.equals("")) {
GCMRegistrar.register(StartActivity.this, SENDER_ID);
}
//Toast.makeText(context, "Orders and menus won't be sync with other devices since GoogleCloudMessaging is not working correctly on this device. Please notify the developer.", Toast.LENGTH_LONG).show();
}
}
You can find the old deprecated GCM Client helpher here: http://developer.android.com/google/gcm/helper.html
You can find the code of the GCM client on your computer on the path:
ANDROID_SDK_ROOT/extras/google/gcm-client (given you've downloaded this extra using the Android SDK Manager).
I put the old gcm client in a new package named com.google.android.gcm.deprecated to try to remember myself to not use this for other stuff.

Categories

Resources