Android Push Notifications: Icon not displaying in notification, white square shown instead

327.6k views Asked by At

My app generates a notification, but the icon I set for that notification is not being displayed. Instead, I get a white square.

I have tried resizing the png of the icon (dimensions 720x720, 66x66, 44x44, 22x22). Curiously, when using smaller dimensions the white square is smaller.

I have googled this problem, as well as the correct way of generating notifications, and from what I've read my code should be correct. Sadly things are not as they should be.

My phone is a Nexus 5 with Android 5.1.1. The problem is also present on emulators, a Samsung Galaxy s4 with Android 5.0.1 and a Motorola Moto G with Android 5.0.1 (both of which I borrowed, and don't have right now)

The code for notifications follows, and two screenshots. If you require more information, please feel free to ask for it.

Thank you all.

@SuppressLint("NewApi") private void sendNotification(String msg, String title, String link, Bundle bundle) {
    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class);
    resultIntent.putExtras(bundle);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
            resultIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
    Notification notification;
    Uri sound = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.notificationsound);
    notification = new Notification.Builder(this)
                .setSmallIcon(R.drawable.lg_logo)
                .setContentTitle(title)
                .setStyle(new Notification.BigTextStyle().bigText(msg))
                .setAutoCancel(true)
                .setContentText(msg)
                .setContentIntent(contentIntent)
                .setSound(sound)
                .build();
    notificationManager.notify(0, notification);
}

without opening the notification notifications opened

21

There are 21 answers

15
Garima Mathur On BEST ANSWER

Cause: For 5.0 Lollipop "Notification icons must be entirely white".

If we solve the white icon problem by setting target SDK to 20, our app will not target Android Lollipop, which means that we cannot use Lollipop-specific features.

Solution for target Sdk 21

If you want to support Lollipop Material Icons, then make transparent icons for Lollipop and the above version. Please refer to the following: https://design.google.com/icons/

Please look at http://developer.android.com/design/style/iconography.html, and we'll see that the white style is how notifications are meant to be displayed in Android Lollipop.

In Lollipop, Google also suggests that we use a color that will be displayed behind the white notification icon. Refer to the link: https://developer.android.com/about/versions/android-5.0-changes.html

Wherever we want to add Colors https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#setColor(int)

Implementation of Notification Builder for below and above Lollipop OS version would be:

Notification notification = new NotificationCompat.Builder(this);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    notification.setSmallIcon(R.drawable.icon_transperent);
    notification.setColor(getResources().getColor(R.color.notification_color));
} else { 
    notification.setSmallIcon(R.drawable.icon);
} 

Note: setColor is only available in Lollipop and it only affects the background of the icon.

It will solve your problem completely!!

10
N J On

According to Google's Design Guidelines:

Notification icons must be entirely white.

0
Haresh Chhelana On

If you wan to provide lollipop support notification icon then make two type notification icon :

  1. normal notification icon : for below lollipop version.
  2. notification icon with transparent background : for lollipop and above version.

Now set appropriate icon to notification builder at run time base on OS version :

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    mBuilder.setSmallIcon(R.drawable.ic_push_notification_transperent);
} else {
    mBuilder.setSmallIcon(R.drawable.ic_push_notification);
}
0
Aarush Timalsina On

I finally found the problem and solution after researching for 3 days!

From my experience the issue is due to tags in AndroidManifest.xml.

You should have two tags there:

<meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@drawable/lg_logo" />

        <meta-data
            android:name="com.google.firebase.messaging.default_notification_color"
            android:resource="@color/colorPrimary" />

If you already have these tags, they are probably inside service tag in MainFireBaseMessagingService of AndroidManifest.xml

Copy those two meta data and place it inside application tag too.

Note that the icon supplied must be white logo with transparent background.

That way in MIUI devices such as redmi and motorola, the plain white/black box notification icon issue won't come up.

0
Vouskopes On

When you want keep colorful icon - Workaround
Add pixel with slightly different color into icon.
In my case a have black icon with shades and light. When added dark blue pixel it works.

0
GS Nayma On

I found a link where we can generate our own white icon,

try this link to generate white icon of your launcher icon.

Open this Link and upload your ic_launcher or notification icon

0
Sunil On

i was facing same issue i tried lot of anwers but didn't get any solutions,finally i found the way to solve my problem.

  • make notification icon with transparent background .The app's width and height must be like below sizes and paste all these in your project->app->src->main->res

  • MDPI 24*24

  • HDPI 36*36

  • XHDPI 48*48

  • XXHDPI 72*72


after the above paste this below line in your onMessageReceived method


Intent intent = new Intent(this, News.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                    PendingIntent.FLAG_ONE_SHOT);
            Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
            {
                notificationBuilder.setSmallIcon(R.drawable.notify)
                                      //            .setContentTitle(title)
                            //                        .setContentText(message)
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .setContentIntent(pendingIntent);
            } else
                {
                    notificationBuilder.setSmallIcon(R.drawable.notify)
                       //                                .setContentTitle(title)
                        //                        .setContentText(message)
                            .setAutoCancel(true)
                            .setSound(defaultSoundUri)
                            .setContentIntent(pendingIntent);
            }
            NotificationManager notificationManager =
                    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.notify(0, notificationBuilder.build());

Don't forget to add this code in manifest file

<meta-data 
android:name="com.google.firebase.messaging.default_notification_icon" 
android:resource="@drawable/app_icon" />
6
Ruchir Baronia On

If you are using Google Cloud Messaging, then this issue will not be solved by simply changing your icon. For example, this will not work:

 Notification notification  = new Notification.Builder(this)
                .setContentTitle(title)
                .setContentText(text)
                .setSmallIcon(R.drawable.ic_notification)
                .setContentIntent(pIntent)
                .setDefaults(Notification.DEFAULT_SOUND|Notification.DEFAULT_LIGHTS|Notification.DEFAULT_VIBRATE)
                .setAutoCancel(true)
                .build();

Even if ic_notification is transparant and white. It must be also defined in the Manifest meta data, like so:

  <meta-data android:name="com.google.firebase.messaging.default_notification_icon"

            android:resource="@drawable/ic_notification" />

Meta-data goes under the application tag, for reference.

0
Caat c On

For SDK >= 23, please add setLargeIcon

notification = new Notification.Builder(this)
            .setSmallIcon(R.drawable.ic_launcher)
            .setLargeIcon(context.getResources(), R.drawable.lg_logo))
            .setContentTitle(title)
            .setStyle(new Notification.BigTextStyle().bigText(msg))
            .setAutoCancel(true)
            .setContentText(msg)
            .setContentIntent(contentIntent)
            .setSound(sound)
            .build();
0
Jeremy Frank On

Notifications are greyscale as explained below. They are not black-and-white, despite what others have written. You have probably seen icons with multiple shades, like network strength bars.

Prior to API 21 (Lollipop 5.0), colour icons work. You could force your application to target API 20, but that limits the features available to your application, so it is not recommended. You could test the running API level and set either a colour icon or a greyscale icon appropriately, but this is likely not worthwhile. In most cases, it is best to go with a greyscale icon.

Images have four channels, RGBA (red / green / blue / alpha). For notification icons, Android ignores the R, G, and B channels. The only channel that counts is Alpha, also known as opacity. Design your icon with an editor that gives you control over the Alpha value of your drawing colours.

How Alpha values generate a greyscale image:

  • Alpha = 0 (transparent) — These pixels are transparent, showing the background colour.
  • Alpha = 255 (opaque) — These pixels are white.
  • Alpha = 1 ... 254 — These pixels are exactly what you would expect, providing the shades between transparent and white.

Changing it up with setColor:

  • Call NotificationCompat.Builder.setColor(int argb). From the documentation for Notification.color:

    Accent color (an ARGB integer like the constants in Color) to be applied by the standard Style templates when presenting this notification. The current template design constructs a colorful header image by overlaying the icon image (stenciled in white) atop a field of this color. Alpha components are ignored.

    My testing with setColor shows that Alpha components are not ignored. Higher Alpha values turn a pixel white. Lower Alpha values turn a pixel to the background colour (black on my device) in the notification area, or to the specified colour in the pull-down notification.

0
user7478049 On

Requirements to fix this issue:

  1. Image Format: 32-bit PNG (with alpha)

  2. Image should be Transparent

  3. Transparency Color Index: White (FFFFFF)

Source: http://gr1350.blogspot.com/2017/01/problem-with-setsmallicon.html

0
James On

(Android Studio 3.5) If you're using a recent version of Android Studio, you can generate your notification images. Right-click on your res folder > New > Image Asset. You will then see Configure Image Assets as shown in the image below. Change Icon Type to Notification Icons. Your images must be white and transparent. This Configure Image Assets will enforce that rule. Configure Image Assets Important: If you want the icons to be used for cloud/push notifications, you must add the meta-data under your application tag to use the newly created notification icons.

  <application>
      ...
      <meta-data android:name="com.google.firebase.messaging.default_notification_icon"
          android:resource="@drawable/ic_notification" />
0
Haris On

I have resolved the problem by adding below code to manifest,

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/ic_stat_name" />

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/black" />

where ic_stat_name created on Android Studio Right Click on res >> New >>Image Assets >> IconType(Notification)

And one more step I have to do on server php side with notification payload

$message = [
    "message" => [
        "notification" => [
            "body"  => $title , 
            "title" => $message
        ],

        "token" => $token,

    "android" => [
           "notification" => [
            "sound"  => "default",
            "icon"  => "ic_stat_name"
            ]
        ],

       "data" => [
            "title" => $title,
            "message" => $message
         ]


    ]
];

Note the section

    "android" => [
           "notification" => [
            "sound"  => "default",
            "icon"  => "ic_stat_name"
            ]
        ]

where icon name is "icon" => "ic_stat_name" should be the same set on manifest.

0
Zeon On

I have similar issue on android 8.0. Try to use WHITE icon resource. I have white square when i'm trying to use colored image for icon, when i replace it to white icon, it's start work.

0
M Nasir Baloch On

remove the background of the icon using any of the website, suggested one is https://www.remove.bg/ and then simply use that image after downloading and your problem will be solved.

0
Bilal Şimşek On

for customized local notification, in AndroidManifest.xml add following meta-data then it will work.

 <application
    android:name="xxxxxx"
        android:label="xxxxxx"
        android:icon="@mipmap/ic_launcher"
        
        >

       <meta-data
                android:name="your_apps_bundle_id.default_notification_icon"
                android:resource="@drawable/ic_notif" />

......
0
Md. Al- Rasel On

You can use different icon for different versions. Simply set logic on your icon like this:

int icon = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? R.drawable.colored_: R.drawable.white_tint_icon_for_lolipop_or_upper;
1
rahul sharma On

We can do like below:

Create a new object of notification builder and call setSmallIcon() using notification builder object like in below code.

Create a method in which we will check on which OS version we are installing our app . If it is below Lolipop i.e API 21 then it will take the normal app icon with background color else it will take the transparent app icon without any background. So the devices using os version >= 21 will set the background color of icon using method setColor() of Notification builder class.

Sample Code:

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);

notificationBuilder.setSmallIcon(getNotificationIcon(notificationBuilder));

private int getNotificationIcon(NotificationCompat.Builder notificationBuilder) {

   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
             int color = 0x008000;
             notificationBuilder.setColor(color);
             return R.drawable.app_icon_lolipop_above;

    } 
    return R.drawable.app_icon_lolipop_below;
}
6
Vicky Mahale On

Declare this code in Android Manifest:

<meta-data android:name="com.google.firebase.messaging.default_notification_icon" 

android:resource="@drawable/ic_stat_name" />
1
dongkichan On

To reduce SDK specific versions, you could simply do this: (replace '#' to '0x')

Notification notification = new NotificationCompat.Builder(this);
notification.setSmallIcon(R.drawable.icon_transperent);
notification.setColor(0x169AB9); //for color: #169AB9
2
Aniruddha Shevle On

Finally I've got the solution for this issue.

This issue occurs only when the app is not at all running. (neither in the background nor in the foreground). When the app runs on either foreground or background the notification icon is displayed properly.(not the white square)

So what we've to set is the same configuration for notification icon in Backend APIs as that of Frontend.

In the frontend we've used React Native and for push notification we've used react-native-fcm npm package.

FCM.on("notification", notif => {
   FCM.presentLocalNotification({
       body: notif.fcm.body,
       title: notif.fcm.title,
       big_text: notif.fcm.body,
       priority: "high",
       large_icon: "notification_icon", // notification icon
       icon: "notification_icon",
       show_in_foreground: true,
       color: '#8bc34b',
       vibrate: 300,
       lights: true,
       status: notif.status
   });
});

We've used fcm-push npm package using Node.js as a backend for push notification and set the payload structure as follows.

{
  to: '/topics/user', // required
  data: {
    id:212,
    message: 'test message',
    title: 'test title'
  },
  notification: {
    title: 'test title',
    body: 'test message',
    icon : 'notification_icon', // same name as mentioned in the front end
    color : '#8bc34b',
    click_action : "BROADCAST"
  }
}

What it basically searches for the notification_icon image stored locally in our Android system.