📜 ⬆️ ⬇️

Read more about the implementation of GCM support on the Android client

They have already written about GCM. What is this article for?


True, they wrote. Literally this week, the GCM article , a new push notification service from Google, was published on Habré (if you are not familiar with Google Cloud Messaging for Android, then I advise you to read it before reading this article, especially in my article the process of creating a project is not described with GCM). I do not know if the author of GCM used it in a real application or not, but I had to. That is why I want to describe something that had no place in the previous article, or that was not explained. Add this all with a comment in a previous article, I fear, an impossible task.


Required Permissions




Does the registration code change (registationId)?


Consider the code from the example application:
 final String regId = GCMRegistrar.getRegistrationId(this); if (regId.equals("")) { // Automatically registers application on startup. GCMRegistrar.register(this, SENDER_ID); } 


There seems to be no other conditions. So, does not change? If you follow this link: http://developer.android.com/intl/ru/guide/google/gcm/adv.html#reg-state , you can find out what can change. There are two such cases:
  1. Program update
  2. Backup and restore from it


To check for a software update, I wrote a small assistant class. Maybe someone will come in handy:
 import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.preference.PreferenceManager; public final class ApplicationVersionHelper { public static final String APP_VERSION_PREFS = "application_version"; public static boolean isApplicationVersionCodeEqualsSavedApplicationVersionCode(Context context) { return getApplicationVersionCode(context) == getApplicationVersionCodeFromPreferences(context); } public static int getApplicationVersionCode(Context context) { PackageManager pm = context.getPackageManager(); PackageInfo packageInfo; int applicationVersion = 1; try { packageInfo = pm.getPackageInfo(context.getPackageName(), 0); applicationVersion = packageInfo.versionCode; } catch (NameNotFoundException ignored) { } return applicationVersion; } public static int getApplicationVersionCodeFromPreferences(Context context) { return context.getSharedPreferences(APP_VERSION_PREFS, Context.MODE_PRIVATE).getInt("application_version_code", 0); } public static void putCurrentPackageVersionInPreferences(Context context) { context.getSharedPreferences(APP_VERSION_PREFS, Context.MODE_PRIVATE).edit().putInt("application_version_code", getApplicationVersionCode(context)).commit(); } } 


Note that the settings are not obtained through the PreferenceManager.getDefaultSharedPreferences , but through the named settings file. For what this is done, I will explain later.
Now we need to call putCurrentPackageVersionInPreferences after successful registration in GCM and on our service, and the registration verification code turns into:

 final String regId = GCMRegistrar.getRegistrationId(this); if (regId.equals("") || !isApplicationVersionCodeEqualsSavedApplicationVersionCode(this)) { // Automatically registers application on startup. GCMRegistrar.register(this, SENDER_ID); } 


To handle the creation of a backup (not everyone knows about this feature at all. If it became interesting, then read here - http://developer.android.com/intl/ru/guide/topics/data/backup.html ) I propose the following solution : just do not save the settings with the name from the ApplicationVersionHelper.APP_VERSION_PREFS constant when backing up. So the named settings file came in handy :) Then isApplicationVersionCodeEqualsSavedApplicationVersionCode will return false when recovering the data and we will send a request for registration.

Handlers in GCMIntentService


In GCMIntentService (class inherited from GCMBaseIntentService )
we have to override several methods. Briefly about them:


Clean for yourself!


Remember to cancel the registration process if it is running, and call GCMRegistrar.onDestroy in the onDestroy method of your main Activity. Here is how I do it:
 @Override protected void onDestroy() { if (registerTask != null) { registerTask.cancel(true); } try { CMRegistrar.onDestroy(this); } catch(Exception ignored) { } super.onDestroy(); } 
registerTask here - asynchronous task ( AsyncTask ).

Conclusion


I advise you to read http://developer.android.com/intl/ru/guide/google/gcm/index.html (and there are 5 points) before using GCM in your application, and if you have questions (how about WAKE_LOCK permissions), then Do not be afraid to get into the source code.

Source: https://habr.com/ru/post/147739/


All Articles