From df72660dd55111f6f7fe83df16299ec05e92b5ec Mon Sep 17 00:00:00 2001 From: David Truong Date: Tue, 18 Jul 2017 13:26:03 -0400 Subject: [PATCH 1/6] Working version of android notifications with images. --- .../iterableapi/IterableConstants.java | 5 +- .../iterableapi/IterableNotification.java | 46 ++++++++++++++++++- .../iterableapi/IterablePushReceiver.java | 37 +++++++-------- .../iterableapi/IterablePushRegistration.java | 35 -------------- 4 files changed, 63 insertions(+), 60 deletions(-) diff --git a/iterableapi/src/main/java/com/iterable/iterableapi/IterableConstants.java b/iterableapi/src/main/java/com/iterable/iterableapi/IterableConstants.java index ca534e362..687f70914 100644 --- a/iterableapi/src/main/java/com/iterable/iterableapi/IterableConstants.java +++ b/iterableapi/src/main/java/com/iterable/iterableapi/IterableConstants.java @@ -53,10 +53,11 @@ public final class IterableConstants { public static final String MESSAGING_PLATFORM_AMAZON = "ADM"; public static final String IS_GHOST_PUSH = "isGhostPush"; - public static final String ITERABLE_DATA_KEY = "itbl"; public static final String ITERABLE_DATA_BODY = "body"; - public static final String ITERABLE_DATA_TITLE = "title"; + public static final String ITERABLE_DATA_KEY = "itbl"; + public static final String ITERABLE_DATA_PUSH_IMAGE = "pushImage"; public static final String ITERABLE_DATA_SOUND = "sound"; + public static final String ITERABLE_DATA_TITLE = "title"; public static final String INSTANCE_ID_CLASS = "com.google.android.gms.iid.InstanceID"; public static final String FIREBASE_MESSAGING_CLASS = "com.google.firebase.messaging.FirebaseMessaging"; diff --git a/iterableapi/src/main/java/com/iterable/iterableapi/IterableNotification.java b/iterableapi/src/main/java/com/iterable/iterableapi/IterableNotification.java index 31518623c..f77461928 100644 --- a/iterableapi/src/main/java/com/iterable/iterableapi/IterableNotification.java +++ b/iterableapi/src/main/java/com/iterable/iterableapi/IterableNotification.java @@ -9,9 +9,12 @@ import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.support.v4.app.NotificationCompat; +import android.widget.RemoteViews; -import java.util.Date; +import com.squareup.picasso.Picasso; /** * @@ -20,6 +23,7 @@ public class IterableNotification extends NotificationCompat.Builder { static final String TAG = "IterableNotification"; private boolean isGhostPush; + private String imageUrl; int requestCode; IterableNotificationData iterableNotificationData; @@ -27,6 +31,31 @@ protected IterableNotification(Context context) { super(context); } + /** + * Combine all of the options that have been set and return a new {@link Notification} + * object. + */ + public Notification build() { + final Notification notification = super.build(); + + final int iconId = android.R.id.icon; + final int bigIconId = mContext.getResources().getIdentifier("android:id/big_picture", null, null); + + Handler handler = new Handler(Looper.getMainLooper()); + handler.post(new Runnable() { + @Override + public void run() { + final RemoteViews contentView = notification.contentView; + //Picasso.with(mContext).load(imageUrl).into(contentView, iconId, requestCode, notification); + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { + final RemoteViews bigContentView = notification.bigContentView; + Picasso.with(mContext).load(imageUrl).into(bigContentView, bigIconId, requestCode, notification); + } + } + }); + return notification; + } + /** * Creates and returns an instance of IterableNotification. * @param context @@ -40,6 +69,7 @@ public static IterableNotification createNotification(Context context, Bundle ex String notificationBody = null; String soundName = null; String messageId = null; + String pushImage = null; IterableNotification notificationBuilder = new IterableNotification(context); @@ -47,6 +77,7 @@ public static IterableNotification createNotification(Context context, Bundle ex applicationName = extras.getString(IterableConstants.ITERABLE_DATA_TITLE, applicationName); notificationBody = extras.getString(IterableConstants.ITERABLE_DATA_BODY); soundName = extras.getString(IterableConstants.ITERABLE_DATA_SOUND); + pushImage = extras.getString(IterableConstants.ITERABLE_DATA_PUSH_IMAGE); String iterableData = extras.getString(IterableConstants.ITERABLE_DATA_KEY); notificationBuilder.iterableNotificationData = new IterableNotificationData(iterableData); @@ -66,10 +97,20 @@ public static IterableNotification createNotification(Context context, Bundle ex .setTicker(applicationName).setWhen(0) .setAutoCancel(true) .setContentTitle(applicationName) - .setStyle(new NotificationCompat.BigTextStyle().bigText(notificationBody)) .setPriority(Notification.PRIORITY_HIGH) .setContentText(notificationBody); + if (pushImage != null) { + notificationBuilder.imageUrl = pushImage; + notificationBuilder.setContentText(notificationBody) + .setStyle(new NotificationCompat.BigPictureStyle() + .setBigContentTitle(applicationName) + .setSummaryText(notificationBody) + ); + } else { + notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(notificationBody)); + } + if (soundName != null) { //Removes the file type from the name String[] soundFile = soundName.split("\\."); @@ -142,6 +183,7 @@ private static int getIconId(Context context) { try { ApplicationInfo info = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA); iconId = info.metaData.getInt(IterableConstants.NOTIFICATION_ICON_NAME, 0); + IterableLogger.d(TAG, "iconID: "+ info.metaData.get(IterableConstants.NOTIFICATION_ICON_NAME)); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } diff --git a/iterableapi/src/main/java/com/iterable/iterableapi/IterablePushReceiver.java b/iterableapi/src/main/java/com/iterable/iterableapi/IterablePushReceiver.java index f3c21fa12..96d69ab43 100644 --- a/iterableapi/src/main/java/com/iterable/iterableapi/IterablePushReceiver.java +++ b/iterableapi/src/main/java/com/iterable/iterableapi/IterablePushReceiver.java @@ -5,8 +5,10 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; +import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; +import android.widget.RemoteViews; /** * @@ -37,24 +39,6 @@ public void onReceive(Context context, Intent intent) { } } -// /** -// * Handles the push registration data from the intent. -// * @param context -// * @param intent -// */ -// private void handlePushRegistration(Context context, Intent intent) { -// String iterableAppId = intent.getStringExtra(IterableConstants.PUSH_APP_ID); -// String projectNumber = intent.getStringExtra(IterableConstants.PUSH_GCM_PROJECT_NUMBER); -// boolean disablePush = intent.getBooleanExtra(IterableConstants.PUSH_DISABLE_AFTER_REGISTRATION, false); -// String messagingPlatform = intent.getStringExtra(IterableConstants.MESSAGING_PUSH_SERVICE_PLATFORM); -// -//// IterablePushRegistrationData data = new IterablePushRegistrationData(iterableAppId, projectNumber, disablePush, messagingPlatform); -//// new IterablePushRegistration().execute(data); -// IterableApi sharedInstance = IterableApi.sharedInstance; -// String token = sharedInstance.getDeviceToken(projectNumber, messagingPlatform); -// sharedInstance.registerDeviceToken(iterableAppId, token); -// } - /** * Handles receiving an incoming push notification from the intent. * @param context @@ -74,16 +58,27 @@ private void handlePushReceived(Context context, Intent intent) { try { mainClass = Class.forName(mainClassName); } catch (ClassNotFoundException e) { - e.printStackTrace(); + IterableLogger.w(TAG, e.toString()); } IterableNotification notificationBuilder = IterableNotification.createNotification( appContext, intent.getExtras(), mainClass); - - IterableNotification.postNotificationOnDevice(appContext, notificationBuilder); + new IterableNotificationBuilder().execute(notificationBuilder); } else { IterableLogger.d(TAG, "Iterable ghost silent push received"); } } } +} + +class IterableNotificationBuilder extends AsyncTask { + + @Override + protected Void doInBackground(IterableNotification... params) { + if ( params != null && params[0] != null) { + IterableNotification notificationBuilder = params[0]; + IterableNotification.postNotificationOnDevice(notificationBuilder.mContext, notificationBuilder); + } + return null; + } } \ No newline at end of file diff --git a/iterableapi/src/main/java/com/iterable/iterableapi/IterablePushRegistration.java b/iterableapi/src/main/java/com/iterable/iterableapi/IterablePushRegistration.java index 8e992e048..9d86784af 100644 --- a/iterableapi/src/main/java/com/iterable/iterableapi/IterablePushRegistration.java +++ b/iterableapi/src/main/java/com/iterable/iterableapi/IterablePushRegistration.java @@ -39,41 +39,6 @@ protected String doInBackground(IterablePushRegistrationData... params) { IterableApi.sharedInstance.disablePush(registrationToken); } } - -// Context mainContext = IterableApi.sharedInstance.getMainActivityContext(); -// if (mainContext != null) { -// -// int fbUrl = mainContext.getResources().getIdentifier("firebase_database_url", "string", mainContext.getPackageName()); -// if (fbUrl != 0 && iterablePushRegistrationData.messagingPlatform.equalsIgnoreCase(IterableConstants.MESSAGING_PLATFORM_FIREBASE)) { -// //FCM -// Class fireBaseMessaging = Class.forName(IterableConstants.FIREBASE_MESSAGING_CLASS); -// if (fireBaseMessaging != null) { -// FirebaseInstanceId instanceID = FirebaseInstanceId.getInstance(); -// registrationToken = instanceID.getToken(); -// if (!registrationToken.isEmpty()) { -// IterableLogger.e(TAG, "fcm token: " + registrationToken); -// IterableApi.sharedInstance.registerDeviceToken(iterablePushRegistrationData.iterableAppId, registrationToken); -// } -// } -// } else { -// //GCM -// Class instanceIdClass = Class.forName(IterableConstants.INSTANCE_ID_CLASS); -// if (instanceIdClass != null) { -// InstanceID instanceID = InstanceID.getInstance(mainContext); -// -// String idInstance = instanceID.getId(); -// registrationToken = instanceID.getToken(iterablePushRegistrationData.projectNumber, -// GoogleCloudMessaging.INSTANCE_ID_SCOPE); -// if (!registrationToken.isEmpty()) { -// IterableLogger.e(TAG, "android projectNumber: " + iterablePushRegistrationData.projectNumber); -// IterableLogger.e(TAG, "android token: " + registrationToken); -// IterableApi.sharedInstance.registerDeviceToken(iterablePushRegistrationData.iterableAppId, registrationToken); -// } -// } -// } -// } else { -// IterableLogger.e(TAG, "MainActivity Context is null"); -// } } else { IterableLogger.e("IterablePush", "The IterableAppId has not been added"); } From d00e2d3bdd1ff0e97b6c1d1adf5ca97683abf73f Mon Sep 17 00:00:00 2001 From: David Truong Date: Mon, 24 Jul 2017 10:01:00 -0400 Subject: [PATCH 2/6] Updating key for android push image. --- .../main/java/com/iterable/iterableapi/IterableConstants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iterableapi/src/main/java/com/iterable/iterableapi/IterableConstants.java b/iterableapi/src/main/java/com/iterable/iterableapi/IterableConstants.java index 687f70914..c04c78996 100644 --- a/iterableapi/src/main/java/com/iterable/iterableapi/IterableConstants.java +++ b/iterableapi/src/main/java/com/iterable/iterableapi/IterableConstants.java @@ -55,7 +55,7 @@ public final class IterableConstants { public static final String IS_GHOST_PUSH = "isGhostPush"; public static final String ITERABLE_DATA_BODY = "body"; public static final String ITERABLE_DATA_KEY = "itbl"; - public static final String ITERABLE_DATA_PUSH_IMAGE = "pushImage"; + public static final String ITERABLE_DATA_PUSH_IMAGE = "attachment_url"; public static final String ITERABLE_DATA_SOUND = "sound"; public static final String ITERABLE_DATA_TITLE = "title"; From 85fbe29cc75fee0c7dec701a0ac97e40efa528d4 Mon Sep 17 00:00:00 2001 From: David Truong Date: Mon, 24 Jul 2017 11:23:56 -0400 Subject: [PATCH 3/6] Checks for picasso before calling load. --- .../iterable/iterableapi/IterableNotification.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/iterableapi/src/main/java/com/iterable/iterableapi/IterableNotification.java b/iterableapi/src/main/java/com/iterable/iterableapi/IterableNotification.java index f77461928..419e578fe 100644 --- a/iterableapi/src/main/java/com/iterable/iterableapi/IterableNotification.java +++ b/iterableapi/src/main/java/com/iterable/iterableapi/IterableNotification.java @@ -46,10 +46,18 @@ public Notification build() { @Override public void run() { final RemoteViews contentView = notification.contentView; - //Picasso.with(mContext).load(imageUrl).into(contentView, iconId, requestCode, notification); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { final RemoteViews bigContentView = notification.bigContentView; - Picasso.with(mContext).load(imageUrl).into(bigContentView, bigIconId, requestCode, notification); + + try { + Class picassoClass = Class.forName(IterableConstants.PICASSO_CLASS); + if (picassoClass != null) { + Picasso.with(mContext).load(imageUrl).into(bigContentView, bigIconId, requestCode, notification); + } + } catch (ClassNotFoundException e) { + IterableLogger.w(TAG, "ClassNotFoundException: Check that picasso is added " + + "to the build dependencies", e); + } } } }); @@ -99,7 +107,7 @@ public static IterableNotification createNotification(Context context, Bundle ex .setContentTitle(applicationName) .setPriority(Notification.PRIORITY_HIGH) .setContentText(notificationBody); - + if (pushImage != null) { notificationBuilder.imageUrl = pushImage; notificationBuilder.setContentText(notificationBody) From 4070d16de28b32e17cb337d43b4b04433cf4d0a5 Mon Sep 17 00:00:00 2001 From: David Truong Date: Mon, 24 Jul 2017 11:29:26 -0400 Subject: [PATCH 4/6] Removes excess contentview variable --- .../java/com/iterable/iterableapi/IterableNotification.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/iterableapi/src/main/java/com/iterable/iterableapi/IterableNotification.java b/iterableapi/src/main/java/com/iterable/iterableapi/IterableNotification.java index 419e578fe..1818069b1 100644 --- a/iterableapi/src/main/java/com/iterable/iterableapi/IterableNotification.java +++ b/iterableapi/src/main/java/com/iterable/iterableapi/IterableNotification.java @@ -45,10 +45,8 @@ public Notification build() { handler.post(new Runnable() { @Override public void run() { - final RemoteViews contentView = notification.contentView; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { final RemoteViews bigContentView = notification.bigContentView; - try { Class picassoClass = Class.forName(IterableConstants.PICASSO_CLASS); if (picassoClass != null) { From f9e5c6779e1013a427dcfc8681007f0cd5ddded4 Mon Sep 17 00:00:00 2001 From: David Truong Date: Thu, 27 Jul 2017 17:38:13 -0400 Subject: [PATCH 5/6] Null checks the image url before loading via picasso. --- .../java/com/iterable/iterableapi/IterableInAppManager.java | 3 +-- .../java/com/iterable/iterableapi/IterableNotification.java | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/iterableapi/src/main/java/com/iterable/iterableapi/IterableInAppManager.java b/iterableapi/src/main/java/com/iterable/iterableapi/IterableInAppManager.java index 6ff5f84fe..a27a5dbbd 100644 --- a/iterableapi/src/main/java/com/iterable/iterableapi/IterableInAppManager.java +++ b/iterableapi/src/main/java/com/iterable/iterableapi/IterableInAppManager.java @@ -156,8 +156,7 @@ static void showFullScreenDialog(Context context, JSONObject dialogParameters, S verticalLayout.addView(imageView); try { Class picassoClass = Class.forName(IterableConstants.PICASSO_CLASS); - if (picassoClass != null) { - + if (picassoClass != null && dialogParameters.optString(IterableConstants.ITERABLE_IN_APP_MAIN_IMAGE) != null) { Picasso. with(context.getApplicationContext()). load(dialogParameters.optString(IterableConstants.ITERABLE_IN_APP_MAIN_IMAGE)). diff --git a/iterableapi/src/main/java/com/iterable/iterableapi/IterableNotification.java b/iterableapi/src/main/java/com/iterable/iterableapi/IterableNotification.java index 1818069b1..f7a8d897d 100644 --- a/iterableapi/src/main/java/com/iterable/iterableapi/IterableNotification.java +++ b/iterableapi/src/main/java/com/iterable/iterableapi/IterableNotification.java @@ -45,7 +45,7 @@ public Notification build() { handler.post(new Runnable() { @Override public void run() { - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN && imageUrl != null) { final RemoteViews bigContentView = notification.bigContentView; try { Class picassoClass = Class.forName(IterableConstants.PICASSO_CLASS); @@ -105,7 +105,7 @@ public static IterableNotification createNotification(Context context, Bundle ex .setContentTitle(applicationName) .setPriority(Notification.PRIORITY_HIGH) .setContentText(notificationBody); - + if (pushImage != null) { notificationBuilder.imageUrl = pushImage; notificationBuilder.setContentText(notificationBody) From 1ce1adc6127a473562cdb8a2a9ba77f2cb798cc7 Mon Sep 17 00:00:00 2001 From: David Truong Date: Thu, 27 Jul 2017 17:56:52 -0400 Subject: [PATCH 6/6] Changes the null check to a notEmpty check for imageUrl. --- .../java/com/iterable/iterableapi/IterableInAppManager.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iterableapi/src/main/java/com/iterable/iterableapi/IterableInAppManager.java b/iterableapi/src/main/java/com/iterable/iterableapi/IterableInAppManager.java index a27a5dbbd..dbe5a94a9 100644 --- a/iterableapi/src/main/java/com/iterable/iterableapi/IterableInAppManager.java +++ b/iterableapi/src/main/java/com/iterable/iterableapi/IterableInAppManager.java @@ -156,10 +156,11 @@ static void showFullScreenDialog(Context context, JSONObject dialogParameters, S verticalLayout.addView(imageView); try { Class picassoClass = Class.forName(IterableConstants.PICASSO_CLASS); - if (picassoClass != null && dialogParameters.optString(IterableConstants.ITERABLE_IN_APP_MAIN_IMAGE) != null) { + String imageUrl = dialogParameters.optString(IterableConstants.ITERABLE_IN_APP_MAIN_IMAGE); + if (picassoClass != null && !imageUrl.isEmpty()) { Picasso. with(context.getApplicationContext()). - load(dialogParameters.optString(IterableConstants.ITERABLE_IN_APP_MAIN_IMAGE)). + load(imageUrl). resize(dialogWidth, dialogHeight/2). centerInside(). into(imageView);