package com.buddycloud.notifications; import java.io.IOException; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.annotation.TargetApi; import android.app.Activity; import android.app.Notification; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.Color; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.preference.PreferenceManager; import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat.Builder; import android.support.v4.app.TaskStackBuilder; import com.buddycloud.MainActivity; import com.buddycloud.R; import com.buddycloud.log.Logger; import com.buddycloud.model.ModelCallback; import com.buddycloud.model.NotificationMetadataModel; import com.buddycloud.preferences.Preferences; import com.buddycloud.utils.VersionUtils; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.gcm.GoogleCloudMessaging; public class GCMUtils { private static final String TAG = GCMUtils.class.getName(); private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000; /** * Check the device to make sure it has the Google Play Services APK. If * it doesn't, display a dialog that allows users to download the APK from * the Google Play Store or enable it in the device's system settings. */ public static boolean checkPlayServices(final Context context) { int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context); if (resultCode != ConnectionResult.SUCCESS) { if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) { GooglePlayServicesUtil.getErrorDialog(resultCode, (Activity)context, PLAY_SERVICES_RESOLUTION_REQUEST).show(); } else { Logger.info(TAG, "This device is not supported (Google Play Services APK)"); } return false; } return true; } public static void issueGCMRegistration(final Context context) { if (checkPlayServices(context)) { final String regId = getRegistrationId(context); if (regId == null || regId.equals("")) { NotificationMetadataModel.getInstance().getFromServer(context, new ModelCallback<JSONObject>() { @Override public void success(JSONObject response) { String sender = response.optString("google_project_id", null); if (sender != null) { registerInBackground(context, sender); } else { Logger.warn(TAG, "GCM project id not found."); } } @Override public void error(Throwable throwable) { Logger.error(TAG, "Failed to register in GCM.", throwable); } }); } else { GCMIntentService.sendToPusher(context, regId); } } else { Logger.info(TAG, "No valid Google Play Services APK found."); } } /** * This method register for GCM services in the background mode. * * @param context * @param senderId */ public static void registerInBackground(final Context context, final String senderId) { new AsyncTask<String, Void, String>() { @Override protected String doInBackground(String... params) { String senderId = params[0]; // project sender id String regId = null; try { GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context); regId = gcm.register(senderId); // new GCM registration id // register on server and save on disk. GCMIntentService.registerOnPusher(regId); } catch (IOException e) { Logger.error(TAG, "GCM Registration failed.", e); } return regId; } }.execute(senderId); } /** * This method unregister from the GCM services and also pusher * server in the background mode. * * @param context */ public static void unregisterInBackground(final Context context) { new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... params) { try { GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context); gcm.unregister(); // Unregister the GCM info from pusher server. String regId = Preferences.getPreference(context, Preferences.CURRENT_GCM_ID); GCMIntentService.removeFromPusher(context, regId); } catch (IOException e) { Logger.error(TAG, "GCM Un-registration failed.", e); } return null; } }.execute(); } /** * Gets the current registration ID for application on GCM service. * <p> * If result is empty, the app needs to register. * * @return registration ID, or empty string if there is no existing * registration ID. */ private static String getRegistrationId(final Context context) { String registrationId = Preferences.getPreference(context, Preferences.CURRENT_GCM_ID); if (registrationId == null || registrationId.equals("")) { Logger.info(TAG, "Registration not found."); return ""; } // Check if app was updated; if so, it must clear the registration ID // since the existing regID is not guaranteed to work with the new // app version. int registeredVersion = Integer.MIN_VALUE; int currentVersion; try { currentVersion = VersionUtils.getVersionCode(context); if (Preferences.getPreference(context, Preferences.APP_VERSION) != null) { registeredVersion = Integer.valueOf(Preferences.getPreference(context, Preferences.APP_VERSION)); } if (registeredVersion != currentVersion) { Logger.info(TAG, "App version changed."); return ""; } } catch (NameNotFoundException e) { Logger.error(TAG, "Version code not found.", e); } return registrationId; } public static void clearGCMAuthors(Context context) { Preferences.setPreference(context, GCMPostNotificationListener.GCM_NOTIFICATION_POST_AUTHORS, new JSONArray().toString()); } public static JSONArray getGCMAuthors(Context context) { String gcmStrArray = Preferences.getPreference(context, GCMPostNotificationListener.GCM_NOTIFICATION_POST_AUTHORS, new JSONArray().toString()); try { return new JSONArray(gcmStrArray); } catch (JSONException e) { return new JSONArray(); } } public static void addGCMAuthor(Context context, String author) { JSONArray gcmAuthors = getGCMAuthors(context); gcmAuthors.put(author); Preferences.setPreference(context, GCMPostNotificationListener.GCM_NOTIFICATION_POST_AUTHORS, gcmAuthors.toString()); } public static Builder createNotificationBuilder(Context context) { NotificationCompat.Builder builder = new NotificationCompat.Builder(context) .setSmallIcon(R.drawable.ic_notification) .setLights(context.getResources().getColor(R.color.bc_green_blue_color), 1000, 1000); SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context); boolean doVibrate = sharedPrefs.getBoolean("pref_key_enable_vibration", true); if (doVibrate) { builder.setVibrate(new long[] {500, 500, 500}); } boolean playAudio = sharedPrefs.getBoolean("pref_key_enable_sound", true); if (playAudio) { Uri soundUri = Uri.parse("android.resource://" + context.getPackageName() + "/" + R.raw.cp); builder.setSound(soundUri); } setPriority(builder); builder.setDeleteIntent(getDeleteIntent(context)); return builder; } @TargetApi(Build.VERSION_CODES.JELLY_BEAN) private static void setPriority(NotificationCompat.Builder mBuilder) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { mBuilder.setPriority(Notification.PRIORITY_DEFAULT); } } private static PendingIntent getDeleteIntent(Context context) { Intent intent = new Intent(context, GCMBroadcastReceiver.class); intent.setAction("com.buddycloud.NOTIFICATION_CANCELLED"); return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); } public static Notification build(Context context, NotificationCompat.Builder mBuilder, Intent resultIntent) { TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); stackBuilder.addParentStack(MainActivity.class); stackBuilder.addNextIntent(resultIntent); PendingIntent resultPendingIntent = stackBuilder.getPendingIntent( 0, PendingIntent.FLAG_UPDATE_CURRENT ); mBuilder.setContentIntent(resultPendingIntent); Notification notification = mBuilder.build(); notification.flags |= Notification.FLAG_AUTO_CANCEL; notification.flags |= Notification.FLAG_SHOW_LIGHTS; return notification; } }