Skip to content

Commit ef79171

Browse files
authored
fix(AndroidO/AdaptiveIcons): Fix for System crash when the client receive… (#120)
* fix(AndroidO/AdaptiveIcons): Fix for System crash when client receive push notification and using Adaptive icon on Android O.
1 parent 5a9552e commit ef79171

File tree

2 files changed

+96
-7
lines changed

2 files changed

+96
-7
lines changed

AndroidSDK/src/com/leanplum/LeanplumNotificationHelper.java

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import android.content.Context;
2626
import android.content.res.Resources;
2727
import android.graphics.Bitmap;
28+
import android.graphics.drawable.AdaptiveIconDrawable;
29+
import android.graphics.drawable.Drawable;
2830
import android.os.Build;
2931
import android.os.Bundle;
3032
import android.support.v4.app.NotificationCompat;
@@ -48,6 +50,7 @@ class LeanplumNotificationHelper {
4850

4951
private static final int BIGPICTURE_TEXT_TOP_PADDING = -14;
5052
private static final int BIGPICTURE_TEXT_SIZE = 14;
53+
private static final String LEANPLUM_DEFAULT_PUSH_ICON = "leanplum_default_push_icon";
5154

5255
/**
5356
* If notification channels are supported this method will try to create
@@ -192,17 +195,23 @@ static Notification.Builder getNotificationBuilder(Context context, Bundle messa
192195
* @param title String with title for push notification.
193196
* @param messageText String with text for push notification.
194197
* @param bigPicture Bitmap for BigPictureStyle notification.
198+
* @param defaultNotificationIconResourceId int Resource id for default push notification icon.
195199
* @return Notification.Builder or null.
196200
*/
197201
static Notification.Builder getNotificationBuilder(Context context, Bundle message,
198-
PendingIntent contentIntent, String title, final String messageText, Bitmap bigPicture) {
202+
PendingIntent contentIntent, String title, final String messageText, Bitmap bigPicture,
203+
int defaultNotificationIconResourceId) {
199204
if (Build.VERSION.SDK_INT < 16) {
200205
return null;
201206
}
202207
Notification.Builder notificationBuilder =
203208
getNotificationBuilder(context, message);
204-
notificationBuilder.setSmallIcon(context.getApplicationInfo().icon)
205-
.setContentTitle(title)
209+
if (defaultNotificationIconResourceId == 0) {
210+
notificationBuilder.setSmallIcon(context.getApplicationInfo().icon);
211+
} else {
212+
notificationBuilder.setSmallIcon(defaultNotificationIconResourceId);
213+
}
214+
notificationBuilder.setContentTitle(title)
206215
.setContentText(messageText);
207216
Notification.BigPictureStyle bigPictureStyle = new Notification.BigPictureStyle() {
208217
@Override
@@ -249,4 +258,61 @@ protected RemoteViews getStandardView(int layoutId) {
249258
notificationBuilder.setContentIntent(contentIntent);
250259
return notificationBuilder;
251260
}
261+
262+
/**
263+
* Checks a possibility to create icon drawable from current app icon.
264+
*
265+
* @param context Current application context.
266+
* @return boolean True if it is possible to create a drawable from current app icon.
267+
*/
268+
private static boolean canCreateIconDrawable(Context context) {
269+
try {
270+
// Try to create icon drawable.
271+
Drawable drawable = AdaptiveIconDrawable.createFromStream(
272+
context.getResources().openRawResource(context.getApplicationInfo().icon),
273+
"applicationInfo.icon");
274+
// If there was no crash, we still need to check for null.
275+
if (drawable != null) {
276+
return true;
277+
}
278+
} catch (Throwable ignored) {
279+
}
280+
return false;
281+
}
282+
283+
/**
284+
* Validation of Application icon for small icon on push notification.
285+
*
286+
* @param context Current application context.
287+
* @return boolean True if application icon can be used for small icon on push notification.
288+
*/
289+
static boolean isApplicationIconValid(Context context) {
290+
if (context == null) {
291+
return false;
292+
}
293+
294+
// TODO: Potentially there should be checked for Build.VERSION.SDK_INT != 26, but we need to
295+
// TODO: confirm that adaptive icon works well on 27, before to change it.
296+
if (Build.VERSION.SDK_INT < 26) {
297+
return true;
298+
}
299+
300+
return canCreateIconDrawable(context);
301+
}
302+
303+
/**
304+
* Gets default push notification resource id for LEANPLUM_DEFAULT_PUSH_ICON in drawable.
305+
*
306+
* @param context Current application context.
307+
* @return int Resource id.
308+
*/
309+
static int getDefaultPushNotificationIconResourceId(Context context) {
310+
try {
311+
Resources resources = context.getResources();
312+
return resources.getIdentifier(LEANPLUM_DEFAULT_PUSH_ICON, "drawable",
313+
context.getPackageName());
314+
} catch (Throwable ignored) {
315+
return 0;
316+
}
317+
}
252318
}

AndroidSDK/src/com/leanplum/LeanplumPushService.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,23 @@ private static void showNotification(Context context, final Bundle message) {
306306
return;
307307
}
308308

309+
int defaultIconId = 0;
310+
// If client will start to use adaptive icon, there can be a problem
311+
// https://issuetracker.google.com/issues/68716460 that can cause a factory reset of the device
312+
// on Android Version 26.
313+
if (!LeanplumNotificationHelper.isApplicationIconValid(context)) {
314+
defaultIconId = LeanplumNotificationHelper.getDefaultPushNotificationIconResourceId(context);
315+
if (defaultIconId == 0) {
316+
Log.e("You are using adaptive icons without having a fallback icon for push" +
317+
" notifications on Android Oreo. \n" + "This can cause a factory reset of the device" +
318+
" on Android Version 26. Please add regular icon with name " +
319+
"\"leanplum_default_push_icon.png\" to your \"drawable\" folder.\n" + "Google issue: " +
320+
"https://issuetracker.google.com/issues/68716460"
321+
);
322+
return;
323+
}
324+
}
325+
309326
final NotificationManager notificationManager = (NotificationManager)
310327
context.getSystemService(Context.NOTIFICATION_SERVICE);
311328

@@ -327,8 +344,14 @@ private static void showNotification(Context context, final Bundle message) {
327344
return;
328345
}
329346
final String messageText = message.getString(Keys.PUSH_MESSAGE_TEXT);
330-
notificationCompatBuilder.setSmallIcon(context.getApplicationInfo().icon)
331-
.setContentTitle(title)
347+
348+
if (defaultIconId == 0) {
349+
notificationCompatBuilder.setSmallIcon(context.getApplicationInfo().icon);
350+
} else {
351+
notificationCompatBuilder.setSmallIcon(defaultIconId);
352+
}
353+
354+
notificationCompatBuilder.setContentTitle(title)
332355
.setStyle(new NotificationCompat.BigTextStyle()
333356
.bigText(messageText))
334357
.setContentText(messageText);
@@ -346,8 +369,8 @@ private static void showNotification(Context context, final Bundle message) {
346369
.setBigContentTitle(title)
347370
.setSummaryText(messageText));
348371
} else {
349-
notificationBuilder = LeanplumNotificationHelper.getNotificationBuilder(context, message, contentIntent, title,
350-
messageText, bigPicture);
372+
notificationBuilder = LeanplumNotificationHelper.getNotificationBuilder(context, message,
373+
contentIntent, title, messageText, bigPicture, defaultIconId);
351374
}
352375
} else {
353376
Log.w(String.format("Image download failed for push notification with big picture. " +

0 commit comments

Comments
 (0)