The purpose of the article is to familiarize with the most common pitfalls in working with the notification service from Google.
The source was a very useful, in my opinion, article
Keeping Google Cloud Messaging For Android Working Reliably from the developers of
Pushbullet , a convenient application for synchronizing notifications between Android devices and the Chrome browser.
I hope all of you are already familiar with the articles on Google Cloud Messaging:
Lesson # 1: Get ready to receive SERVICE_NOT_AVAILABLE often
This moment is completely ignored in the official documentation of the
Implementing GCM Client . Thus, this is one of the most important details that you need to know when registering a GCM.
Call
gcm.register (SENDER_ID); very often leads to an error with the exception IOException "SERVICE_NOT_AVAILABLE".
')
There is a possibility that it will never happen on your test devices and you may not be ready for it. This can lead to a very negative effect, since the reliability of your application can be seriously affected, at the moment when your application is already published, and this happens very often.
How to be? It is quite simple. This message means that GCM was unable to register and you need to try again.
Documentation for this case recommends
exponentially waiting time and trying again, this is excellent advice.
Lesson # 2: Be prepared for repeated register call errors, even if the worker registration ID is created
This advice is rather strange and may not be relevant, but since there is no way to confirm that the error in GCM has been corrected, we will also consider this.
The error is as follows:
It doesn't matter how many times you called
gcm.register (SENDER_ID); it constantly crashes with some devices. Even if the worker registration ID was successfully created, but it was never returned as a result of the function.
To get this registration ID, register your GCM BroadcastReceiver for the following event:
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
You will get the opportunity to get a working registration ID:
final String registrationId = intent.getStringExtra("registration_id");
In case this variable is not null and is not empty, you will get a working registration ID. Further, you can save it and transfer to your server as you usually do.
The two tips above will help you make sure your devices are successfully registered.
The following two tips will tell you when you need to register your device again and how to do it effectively to keep your messaging service running continuously.
Lesson # 3: Make sure you re-register your device whenever you update your app.
This advice is taken from official
documentation , but it is very easy to skip it, so do not forget about it.
It is unlikely that the user will open your application immediately after updating from the market, so it is very important to register the application again automatically. It is very important to maintain the serviceability of the message service immediately after the update.
The best way to activate the automatic registration process is to declare a class BroadcastReceiver in AndroidManifest that will listen for the
PACKAGE_REPLACED event:
<receiver android:name=".UpdateReceiver"> <intent-filter> <action android:name="android.intent.action.PACKAGE_REPLACED" /> <data android:path="<YOUR_PACKAGE_NAME_HERE>" android:scheme="package" /> </intent-filter> </receiver>
The moment the
onReceive method is called, you can initiate a GCM registration. Then replace the current registration ID with a new one and send it to your server.
I hope you remember that cause
gcm = GoogleCloudMessaging.getInstance(activity); regid = gcm.register(SENDER_ID);
Directly in onReceive BroadcastReceiver is not worth it, since this method will be called in the main application stream (MAIN_THREAD) and should not work directly with the network.
For these purposes, it is recommended to use AsyncTask , either a specially created background service, or Thread at worst.
Lesson # 4: Make sure you re-register your device if the Android version is updated on the device
This is not documented anywhere (as far as I know), but it is known that the registration ID depends on the Android device ID.
Which may change if the device firmware changes or the user makes a factory reset (factory reset). Thus, you need to register the device again if there has been a change in Android ID.
As with the application update, the user is unlikely to immediately launch your application, which could initiate the GCM registration process at startup. You must take care of automatically re-registering the device in order to ensure the operation of the messaging service without waiting for the user to start the application.
What is the best way to do this? There is only one way to do this, even though this method is not perfect. You need to register your application whenever the phone restarts. To do this, you need to give the application in AndroidManifest a new permission:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
And set up a BroadcastReceiver to receive the
BOOT_COMPLETED event:
<receiver android:name=".BootReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
Now, each time you call
onReceive this listener, you will be able to register your device with GCM again.
Perhaps it would be more correct to call the device registration only if the Android ID has really changed. It is important that with the help of this seemingly non-obligatory work we would be sure that the device was registered even when it was not possible, we can’t be 100% sure that the Android ID will change.
That's all. Sadly, in order to ensure the smooth operation of GCM, I had to go to such “dances with a tambourine” and even sadder that most of these moments are not documented at all by Google itself.
Errors and typos in PM