I am getting the error "SERVICE_NOT_AVAILABLE" on my GoogleCloudMessaging.register() call on a Android 2.2 device.
I am writing an app that uses GoogleCloudMessaging using the new Google Play Services. I implemented it using the guidelines provided on the Android website and my source contains a lot of error checking and handling code such as making sure the Google Play Services is installed, or updated. The GCM registration code also implements a exponential backoff as google as suggested one to implement to handle the SERVICE_NOT_AVAILABLE error.
I have tested my application on a wide array of devices including ICS, JB, Honey Comb and even 2.3.x devices. The GCM registration works and I am able to send messages to it via GCM. However on a 2.2 device I am continuously getting a SERVICE_NOT_AVAILABLE error on the GoogleCloudMessaging.register() call even with the exponential backoff in place.
The device that GCM is failing on is a Samsung SGH-I896 to be exact and the phone has 2 google accounts on it. I've read that this error might be caused by a misconfigured time, but the time is set to be automatic. The phone is not moded and is running samsung stock ROM.
I have also tried rebooting the device as well as reinstalling Google Play Services without luck. Any help on this issue will be greatly appreciated.
EDIT: I tried to implement GCM using the old gcm.jar and GCMRegistrar and it ended up working on the device. However I hardly consider this a good solution to the problem as Google has stopped supporting this method afaik.
EDIT2: See the accepted answer.
I experienced the same problem. GCM works fine on my Tablet running Android 4.04, but always received a SERVICE_NOT_AVAILABLE on my smartphone running Android 2.3.
I found following workaround not using (so far as I know) any deprecated classes. Add the action "com.google.android.c2dm.intent.REGISTRATION" to the GCMBroadcastReceiver in your manifest. This will enable to receive the registration_id at your GCMBroadcastReceiver.
After that your GCMBroadcastReceiver is able to receive the registration_id:
Although I still get a SERVICE_NOT_AVAILABLE error, I can handle the registration_id in my GCMBroadcastReceiver and I am able to send messages to my smartphone. Quite weird, but it works for me.
SERVICE_NOT_AVAILABLE may be caused by an old or missing GooglePlayServices. Use GooglePlayServicesUtil to check the version and if wrong redirect to market so user can manually install it - this will fix the SERVICE_NOT_AVAILABLE and also get all improvements and bug fixes ( and new bugs :-).
If you can't do this - there is no point in using register(), the method expects the matching play service to retrieve the result. It does generate the same broadcast, for backward compatibility. Using the REGISTER intent directly or the deprecated library will continue to work - I would suggest using the intent, GCMRegistrar is tied to the old implementation in GoogleServicesFramework (it has a call to intent.setPackage(GSF_PACKAGE)), so it can't benefit from any fixes.
Having the latest version of GCM - by using GooglePlayServicesUtil to deal with devices that didn't get the automatic install - can help not only for registration.
After reading the post from marnanish, I tried the code below, and I have successfully got my Activity to receive a registration. Just add this:
in your AndroidManifest.xml
If the marked answer is not working for you (as it was for me), check the person in front of your device, maybe shake it and then enable the internet connection. Worked for me ;-)
Without internet, you receive the same Exception and I spent the afternoon chasing complex problems with the service....
So, there is another thing to watch out for that tripped me up. I had it working fine in emulator + with test application, but then I had issues deploying it on actual devices.
Was consistently getting the SERVICE_NOT_AVAILABLE error, and resorted to an approach similar to the answer above:
This sort-of worked. But it was taking an oddly long amount of time to receive this information, and in a wait-loop I had, it would ONLY ever retrieve it AFTER I'd given up and let things proceed.
This got me thinking that there might be another cause to the SERVICE_NOT_AVAILABLE msg.
This is the code I had to do the fetching/registration with GCM:
The main thing to look for here is the last line.
A "clever/cheating" way to block on asynchronous off-thread results.
It turns out, that IS what is causing the problem. As soon as I just had:
Let it pass through, and made the algorithm/code work with reporting back and not needing the registration id right away, then it was fine. I didn't even need the manual broadcast receiver, it just worked like it should.
I had the same problem but it was happening on all devices. It took me forever to find my problem but I thought I would post it in case it matches someone else's case. Here is a simplified version of my problem:
When I add the second AsyncTask with a return using get(), I would get the GCM 'SERVICE_NOT_AVAILABLE' every time even though I could still retrieve the registration id from the GcmBroadcastReceiver onReceive(). However, when I run:
the GCM would receive the registration id without issue.