Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCM SERVICE_NOT_AVAILABLE on Android 2.2

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.

like image 908
idunnololz Avatar asked Jul 12 '13 15:07

idunnololz


3 Answers

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.

<receiver
   android:name="YOUR_PACKAGE_NAME.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="YOUR_PACKAGE_NAME" />
      </intent-filter>
</receiver>

After that your GCMBroadcastReceiver is able to receive the registration_id:

public void onReceive(Context context, Intent intent) {
   String regId = intent.getExtras().getString("registration_id");
   if(regId != null && !regId.equals("")) {
      /* Do what ever you want with the regId eg. send it to your server */
   }
}

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.

like image 104
marnaish Avatar answered Nov 09 '22 20:11

marnaish


This error also occurred to me, but it did because I was trying to register in the GCM through a firewall of my company. And in the documentation I found:

"Note: If your organization has a firewall that restricts the traffic to or from the Internet, you need to configure it to allow connectivity with GCM in order for your Android devices to receive messages. The ports to open are: 5228, 5229, and 5230. GCM typically only uses 5228, but it sometimes uses 5229 and 5230. GCM doesn't provide specific IPs, so you should allow your firewall to accept outgoing connections to all IP addresses contained in the IP blocks listed in Google's ASN of 15169."

Once I opened the ports or tried from another network, it worked.

like image 31
Edison Spencer Avatar answered Nov 09 '22 19:11

Edison Spencer


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.

like image 3
Costin Manolache Avatar answered Nov 09 '22 20:11

Costin Manolache