package com.malcom.library.android.module.notifications; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.util.Log; import com.google.android.gcm.GCMRegistrar; import com.malcom.library.android.module.core.MCMCoreAdapter; import com.malcom.library.android.module.notifications.gcm.MalcomNotificationReceiver; import com.malcom.library.android.utils.MCMUtils; import com.malcom.library.android.utils.ToolBox; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; /** * Malcom Notification module. * * - Registration. * 1.- Register the device for push with GCM. * 2.- Register with Malcom. * - Un-registration. * - Notification receival. * - Notification ACKs * * * @author Malcom Ventures, S.L. * @since 2012 * */ public class MCMNotificationModule { public static final String TAG = "MCMNotification"; private static MCMNotificationModule instance = null; public static final String CACHED_ACK_FILE_PREFIX = "ack_"; public static final String notification = "v3/notification"; public static final String notification_ack = notification+ "/ack/"; public static final String notification_registry = notification + "/registry/application"; public static final String notification_deregister = notification + "/registry/application/appCode/device/udid"; public static final String notification_deregister_param_appCode = "appCode"; public static final String notification_deregister_param_udid = "udid"; /** The key where the message of the notification is */ public static final String ANDROID_MESSAGE_EFFICACY_KEY = "notificationId"; public static final String ANDROID_MESSAGE_SEGMENT_KEY = "segmentId"; public static final String ANDROID_MESSAGE_KEY = "msg"; public static final String ANDROID_MESSAGE_RICHMEDIA_KEY = "web_url"; public static final String ANDROID_NOTIFICATION_SOUND_KEY = "sound"; /** Custom intent used to show the alert in the UI about a received push. */ public static final String SHOW_NOTIFICATION_ACTION = "com.malcom.library.android.gcm.DISPLAY_MESSAGE"; /** Notification parameters */ public static final String GCM_SENDER_ID ="GCM_SENDER_ID"; public static final String GCM_CLASS ="GCM_CLASS"; public static final String GCM_TITLE_NOTIFICATION ="GCM_TITLE_NOTIFICATION"; /** Intent extra that indicates if the intent carries a notification to be handled */ public static final String HAS_NOTIFICATION_TO_HANDLE = "hasNotificationToHandle"; /** * Google API project id registered to use GCM. */ public static String senderId = ""; public static String applicationCode = null; public static String applicationSecretkey = null; public static EnvironmentType environmentType = null; protected MCMNotificationModule() { // Exists only to defeat instantiation. } // Singleton public static MCMNotificationModule getInstance() { if (instance == null) { instance = new MCMNotificationModule(); } return instance; } // NOTIFICATIONS //GCM /** * Registers the device with Google Cloud Messaging system (GCM). * * NOTE: * The environment is set by looking for the application debug mode, * if is set to TRUE, the environment will be SANDBOX, otherwise PRODUCTION. * * @param context Context. * @param title Title for the notification * @param clazz Class to call when clicking in the notification */ public void gcmRegisterDevice(Context context, String title, Class<?> clazz) { EnvironmentType environment = EnvironmentType.PRODUCTION; if(ToolBox.application_isAppInDebugMode(context)){ environment = EnvironmentType.SANDBOX; } gcmRegisterDevice(context, environment, title, clazz); } /** * Registers the device with Google Cloud Messaging system (GCM) * * @param context Context. * @param environment Allows to set the environment type. * @param title Title for the notification * @param clazz Class to call when clicking in the notification */ public void gcmRegisterDevice(Context context, final EnvironmentType environment, String title, Class<?> clazz) { //Initializes the required variables senderId = MCMCoreAdapter.getInstance().coreGetProperty(MCMCoreAdapter.PROPERTIES_MALCOM_GCM_SENDERID); final SharedPreferences.Editor prefsEditor = context.getSharedPreferences( "GCM_SETTINGS", 0).edit(); if (senderId != null) { prefsEditor.putString(GCM_SENDER_ID, senderId); } if (clazz != null) { String className = clazz.getCanonicalName(); prefsEditor.putString(GCM_CLASS, className); } if (title != null) { prefsEditor.putString(GCM_TITLE_NOTIFICATION, title); } prefsEditor.commit(); environmentType = environment; applicationCode = MCMCoreAdapter.getInstance().coreGetProperty(MCMCoreAdapter.PROPERTIES_MALCOM_APPID); applicationSecretkey = MCMCoreAdapter.getInstance().coreGetProperty(MCMCoreAdapter.PROPERTIES_MALCOM_APPSECRETKEY); // Verifies that the device supports GCM and throws an exception if it does not //(for instance, if it is an emulator that does not contain the Google APIs) GCMRegistrar.checkDevice(context); // Makes sure the manifest was properly set GCMRegistrar.checkManifest(context); // Force the register in the GCMService to avoid MissmatchedSenderId when the registerId is updated GCMRegistrar.register(context, senderId); } /** * Returns the registration token from GCM. * * @param context * @return The token or null if the device is not registered. */ public String gcmGetRegistrationToken(Context context){ if(GCMRegistrar.isRegistered(context)) return GCMRegistrar.getRegistrationId(context); else return null; } /** * Returns the Android device unique id. * * @param context * @return The android device unique id. */ public String gcmGetDeviceUdid(Context context){ return ToolBox.device_getId(context); } /** * Unregister the device from Google Cloud Messaging system (GCM) * * @param context */ public void gcmUnregisterDevice(Context context){ if(GCMRegistrar.isRegistered(context)){ if (applicationCode == null) applicationCode = MCMCoreAdapter.getInstance().coreGetProperty(MCMCoreAdapter.PROPERTIES_MALCOM_APPID); if (applicationSecretkey == null) applicationSecretkey = MCMCoreAdapter.getInstance().coreGetProperty(MCMCoreAdapter.PROPERTIES_MALCOM_APPSECRETKEY); //Set the unregistration URL for later usage. String deviceId = MCMUtils.getEncodedUDID(ToolBox.device_getId(context)); String serverUrl = MCMCoreAdapter.getInstance().coreGetProperty(MCMCoreAdapter.PROPERTIES_MALCOM_BASEURL) + MCMNotificationModule.notification_deregister; serverUrl=serverUrl.replaceAll(MCMNotificationModule.notification_deregister_param_appCode, applicationCode); serverUrl=serverUrl.replaceAll(MCMNotificationModule.notification_deregister_param_udid, deviceId); //Un-register the device from GCM. GCMRegistrar.unregister(context); } } /** * If the activity intent comes from a notification a dialog is shown with the notification message. */ public void gcmCheckForNewNotification(Activity activity, NotificationHandler handler) { Intent intent = activity.getIntent(); if ( hasNotificationToHandle(intent) ) { Log.d(MCMNotificationModule.TAG,"Notification received. Displaying dialog."); // So the notification is not handled again intent.putExtra(HAS_NOTIFICATION_TO_HANDLE, false); // Trick to reuse receiver code until we properly refactor new MalcomNotificationReceiver(activity, intent, handler).handleNotification(); } } private boolean hasNotificationToHandle(Intent intent) { return intent.getExtras() != null && intent.getExtras().getBoolean(HAS_NOTIFICATION_TO_HANDLE, false); } }