Reputation: 8556
I encountered a strange problem - I've been using GCM in my application for quite a long time and everything works perfectly. However, before a release to Google Play I changed my application package name from com.android.testapp
to com.android.recognition
and after this GCM stopped working. At first I got en error GCM sender id not set on constructor
and fixed it by overriding getSenderIds(Context context)
, but now I can't get a registration ID. Here are the messages from logcat:
How can I fix this? When I switched to a new package I changed everything in the manifest file to the new package:
<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="com.android.recognition" />
</intent-filter>
</receiver>
So what is the problem behind this? Can renaming the application package cause this or is there another reason?
Upvotes: 30
Views: 87720
Reputation: 1746
In my case, this happened because my mobile phone does not have a SIM card inside it.
I guess that having the sim card sets the Automatic time on the device, which resolves this.
Upvotes: 0
Reputation: 8308
I had a OnePlus2 which couldn’t receive pushes when on data. When I connected with logcat
, I saw a lot of this error, but am unsure if it is related.
I gave up trying to find a setting which corresponded to it and just factory reset the device. OnePlus devices running OxygenOS sometimes get weird configuration errors when installing software updates and a factory reset followed by restore from Google Backup gets things working again faster than it would take to understand the underlying issue (and it might be that the user doesn’t even have the right access to fix the underlying issue).
Upvotes: 0
Reputation: 1
After a long struggle i managed to sort out this issue. Make sure that Google Play Services app is up-to-date and that its background synchronization is not disabled on your phone.
Upvotes: -1
Reputation: 165
For me,SERVICE_NOT_AVAILABLE problem was in my application project because of the receiver class.
So I solved after implementing the receiver like the following.
<receiver
android:name="receiver name"
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"/>
</intent-filter>
</receiver>
I hope that will help you :-) .
Upvotes: 0
Reputation: 7347
For me, the problem was the phone was not connected to the internet. I disconnect and connect to Wi-Fi, and tested connectivity with Browser and tested again. Worked like a charm :-)
Upvotes: 2
Reputation: 1780
For me goolge blocked my IP!! I had to reset my DSL conn to get a new IP from the pool and everything worked again, idk why they blocked me, maybe for trying many apps? Anyway is working now, i hope this help somebody else :)
Upvotes: 0
Reputation: 1
I had turned of "Background Data Access" for google services. By unchecking "Restrict background data" in Data usage option It works for me !
Upvotes: 0
Reputation: 7906
SERVICE_NOT_AVAILABLE is one of the most frustrating problems with Google Cloud Messaging. It is an exception thrown by GoogleCloudMessaging.register(SENDER_ID)
, the function call that registers the device for push notifications and returns a registration ID.
Read more: http://eladnava.com/google-cloud-messaging-extremely-unreliable/
These issues alone were enough to get me to start looking for GCM alternatives. I’d get a 1-star review on my app every day or two, with a comment containing the error message displayed when a SERVICE_NOT_AVAILABLE was thrown. There was nothing I could do to help these users, because the majority of them were receiving it for reasons out of their control.
An Alternative to Google Cloud Messaging
Pushy (https://pushy.me/) is a standalone push notification gateway, completely independent of GCM. It maintains its own background socket connection, just like GCM, to receive push notifications. The underlying protocol is MQTT, an extremely light-weight pub/sub protocol, utilizing very little network bandwidth and battery.
A huge advantage of Pushy is that the code for sending a push notification (from the server), and registering the device for push notifications, is actually interchangeable between GCM and Pushy. This makes it super easy to switch to Pushy after implementing GCM and having to ditch it for its instability.
(Full disclosure: I founded Pushy for my own projects and realized many apps would benefit from such a service)
Upvotes: 24
Reputation: 1440
In my case, the solution was to add a new intent-filter action, REGISTRATION, to the manifest, per https://snowdog.co/blog/dealing-with-service_not_available-google-cloud-messaging/
<receiver
android:name=".RemoteNotificationReceiver"
android:permission="com.getset.getset.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.getset.getset.c2dm.intent.RECEIVE" />
<action android:name="com.getset.getset.c2dm.intent.REGISTRATION" />
<category android:name="com.getset.getset" />
</intent-filter>
</receiver>
I have to admit that I'm surprised that this works, given it's missing from the tutorial, but taking it out definitely turns a successful registration id into an exception.
Note: using Nexus 5 API 21 (Lollipop) emulator.
Upvotes: 3
Reputation: 6021
For me, I had turned of "Background Data Access" for google services by checking "Restrict background data" in Data usage option on my Galaxy S4. As soon as I turned it on problem resolved on cellarer network. On Wifi it was working fine.
Upvotes: 3
Reputation: 21087
For me there was connection problem. Change internet connection solved my problem
Upvotes: 3
Reputation: 13218
For me - the device time wasn't correct. I changed the device settings to use "Automatic date & time", tried again and all good.
Cheers
Upvotes: 13
Reputation: 31
I had a similar problem. Worked fine on a google nexus (Android 4.4.2) but not on a Samsung galaxy s3 (Android 4.1.2). I was getting SERVICE_NOT_AVAILABLE on registration on the Samsung. It turned out the time on Samsung was off. It was not set to auto update with Network Time. Once I fixed that GCM worked like a charm. Thanks - Umesh
Upvotes: 3
Reputation: 1812
I had the same problem but none of the above solutions solved the problem in my case. Fortunately I recently solved it and I want to explain how, hopping it will help others:
In my case, I was registering the push service in a custom application class (which is executed before any activity and I think is due to this that some things have not been initialized propertly). Changing it to the main activity solved the problem.
public class MyCustomApp extends Application {
@Override
public void onCreate() {
super.onCreate();
PushService.register(this); //BAD IDEA, don't register pushes in Application Class
}
}
Upvotes: 3
Reputation: 3579
The problem is answered, in my case it was little more complicated.
Wrong clock caused problem for me. :)
Upvotes: 45
Reputation: 393771
Make sure that you changed the package name in the permissions part of your manifest :
<permission android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE" />
I had a similar error due to an incorrect package name in that part.
Upvotes: 18
Reputation: 82938
This SERVICE_NOT_AVAILABLE
error says that GCM Service
is not available in current. Wait and try after some time.
This happens many time (As my experience), so don't worry about it.
See the GCMConstants
class of GCM Lib.
/**
* The device can't read the response, or there was a 500/503 from the
* server that can be retried later. The application should use exponential
* back off and retry.
*/
public static final String ERROR_SERVICE_NOT_AVAILABLE =
"SERVICE_NOT_AVAILABLE";
For more investigation see handleRegistration()
of GCMBaseIntentService
private void handleRegistration(final Context context, Intent intent) {
String registrationId = intent.getStringExtra(EXTRA_REGISTRATION_ID);
String error = intent.getStringExtra(EXTRA_ERROR);
String unregistered = intent.getStringExtra(EXTRA_UNREGISTERED);
Log.d(TAG, "handleRegistration: registrationId = " + registrationId +
", error = " + error + ", unregistered = " + unregistered);
// registration succeeded
if (registrationId != null) {
GCMRegistrar.resetBackoff(context);
GCMRegistrar.setRegistrationId(context, registrationId);
onRegistered(context, registrationId);
return;
}
// unregistration succeeded
if (unregistered != null) {
// Remember we are unregistered
GCMRegistrar.resetBackoff(context);
String oldRegistrationId =
GCMRegistrar.clearRegistrationId(context);
onUnregistered(context, oldRegistrationId);
return;
}
// last operation (registration or unregistration) returned an error;
Log.d(TAG, "Registration error: " + error);
// Registration failed
if (ERROR_SERVICE_NOT_AVAILABLE.equals(error)) {
boolean retry = onRecoverableError(context, error);
if (retry) {
int backoffTimeMs = GCMRegistrar.getBackoff(context);
int nextAttempt = backoffTimeMs / 2 +
sRandom.nextInt(backoffTimeMs);
Log.d(TAG, "Scheduling registration retry, backoff = " +
nextAttempt + " (" + backoffTimeMs + ")");
Intent retryIntent =
new Intent(INTENT_FROM_GCM_LIBRARY_RETRY);
retryIntent.putExtra(EXTRA_TOKEN, TOKEN);
PendingIntent retryPendingIntent = PendingIntent
.getBroadcast(context, 0, retryIntent, 0);
AlarmManager am = (AlarmManager)
context.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + nextAttempt,
retryPendingIntent);
// Next retry should wait longer.
if (backoffTimeMs < MAX_BACKOFF_MS) {
GCMRegistrar.setBackoff(context, backoffTimeMs * 2);
}
} else {
Log.d(TAG, "Not retrying failed operation");
}
} else {
// Unrecoverable error, notify app
onError(context, error);
}
}
Upvotes: 34