213

I have an app showing custom notifications. The problem is that when running in Android 5 the small icon in the Notification bar is shown in white. How can I fix this?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Alejandro Casanova
  • 3,633
  • 4
  • 31
  • 46
  • Rahul Sharma and basiam has a better answer here - http://stackoverflow.com/questions/30795431/icon-not-displaying-in-notification-white-square-shown-instead/33608653#33608653 – Rivu Chakraborty Oct 24 '16 at 07:34
  • It happens to me when running in Android 6, not 5. – Jaime Montoya Apr 06 '17 at 16:49
  • Sure, it happens with Android 5+, of course also in Android 6 and 7. By the time of the question Android 5 was the latest version and the feature causing this issue was introduced in Android 5. – Alejandro Casanova Apr 06 '17 at 20:20
  • 1
    I think it is more accurate to say API Level 21 (Android 5.0), API Level 22 (Android 5.1), API Level 23 (Android 6.0), etc. The term "Android 5" is ambiguous because you could be talking about Android 5.0 or Android 5.1, and when I have been testing notifications and the way icons appear in API Level 22 Vs. API Level 23, I have realized that they behave differently. – Jaime Montoya Apr 06 '17 at 22:58
  • 1
    Possible duplicate of [Why do icons set with Notification.Builder.setSmallIcon in Android Lollipop show as a white square?](https://stackoverflow.com/questions/27188689/why-do-icons-set-with-notification-builder-setsmallicon-in-android-lollipop-show) – AdamHurwitz Jun 09 '19 at 02:26

20 Answers20

272

The accepted answer is not (entirely) correct. Sure, it makes notification icons show in color, but does so with a BIG drawback - by setting the target SDK to lower than Android Lollipop!

If you solve your white icon problem by setting your target SDK to 20, as suggested, your app will not target Android Lollipop, which means that you cannot use Lollipop-specific features.

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

In Lollipop, Google also suggest that you use a color that will be displayed behind the (white) notification icon - https://developer.android.com/about/versions/android-5.0-changes.html

So, I think that a better solution is to add a silhouette icon to the app and use it if the device is running Android Lollipop.

For instance:

Notification notification = new Notification.Builder(context)
            .setAutoCancel(true)
            .setContentTitle("My notification")
            .setContentText("Look, white in Lollipop, else color!")
            .setSmallIcon(getNotificationIcon())
            .build();

    return notification;

And, in the getNotificationIcon method:

private int getNotificationIcon() {
    boolean useWhiteIcon = (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP);
    return useWhiteIcon ? R.drawable.icon_silhouette : R.drawable.ic_launcher;
}
Daniel Saidi
  • 6,079
  • 4
  • 27
  • 29
  • 1
    `targetSdkVersion` != `maxSdkVersion` => If you do not use new APIs introduced in Lollipop, this is not a problem. The app will run without any problems. (Of course you should follow the design guidelines and consider to switch to a white icon in the future) – ByteHamster Mar 23 '15 at 12:29
  • 1
    Yeah, that is what I meant, but you're correct in that my text was somewhat unclear. I've modified that section and hope that it's easier to understand. Thanks! – Daniel Saidi Mar 23 '15 at 15:15
  • 40
    How do you generate the silhouette? I am developer with no photoshop skills and making background transparent using online tools still results in white icons. – Chaitanya Jul 01 '15 at 23:30
  • 6
    @Chaitanya Use GIMP :) – ByteHamster Jul 11 '15 at 07:54
  • i try setLargeIcon + setSmallIcon and I see a icon white –  Oct 19 '15 at 14:35
  • could you give me a valid icon please? I've tried a square white icon,it doesn't work on 5.0 too. my email is zhangruofan@meizu.com thx – Allen Vork May 19 '16 at 14:05
  • 4
    this solution does not answer the question why the android build process modifies a perfectly well correct PNG and compresses it and removes the alpha channel. – philk Jun 18 '16 at 06:25
  • 8
    http://developer.android.com/design/style/iconography.html leads to https://material.google.com/style/icons.html and when I pressing `ctrl+f` and typing `notification` on that page it can't find anything... – user25 Sep 17 '16 at 11:19
  • 2
    I have GIMP but I don't have the skill to generate silhouette. What can I do? – Romulus Urakagi Ts'ai Mar 17 '17 at 04:13
  • I have a 72 x 72 icon.png file that has a white background and my logo sitting on top of that white background. From what I understand, instead of my icon.png I should use icon_silhouette.png, which would be a file with transparency instead of a white background, and my logo sitting on top of the transparent background. Is this correct? – Jaime Montoya Mar 17 '17 at 15:35
  • 1
    I am reading the following at https://developer.android.com/about/versions/android-5.0-changes.html: "The system ignores all non-alpha channels in action icons and in the main notification icon. You should assume that these icons will be alpha-only." So basically instead of my icon.png (PNG file with white background and no transparency), I should generate the icon_silhouette.png file (PNG file with transparency instead of a white background), and that should solve the problem, correct? – Jaime Montoya Mar 17 '17 at 15:45
  • 5
    instead of checking from code applay platform version modifier to drawable folder - drawable / drawable-v21 and place proper icon – Igor Mar 21 '17 at 15:21
  • I have a white logo with transparent background as my notification. All the correctly sized hdpi, xhdpi versions created using the online tool mentioned, but the notification disappears when a different app turns the notification bar white. My notification icon doesn't change - it's still white, but all the others change to dark grey to become visible. Any ideas what I'm doing wrong? – controlbox Nov 20 '17 at 16:56
  • This is a new [notification icon guideline](https://developer.android.com/guide/practices/ui_guidelines/icon_design_status_bar) from Google. – soshial Jul 05 '18 at 13:41
  • Very helpful. I spend a whole day to solve this in coding part. But actual problem is silhouette icon. Thanks a lot. – Pooja Oct 02 '19 at 18:36
  • 1
    There are archived versions of [the icon guidelines](http://web.archive.org/web/20150209195038/http://developer.android.com/design/style/iconography.html#notification) and [the Android 5 (API level 21) changes](http://web.archive.org/web/20150207071452/https://developer.android.com/about/versions/android-5.0-changes.html#BehaviorNotifications) – caw Mar 15 '21 at 03:55
71

Completely agree with user Daniel Saidi. In Order to have Color for NotificationIcon I'm writing this answer.

For that you've to make icon like Silhouette and make some section Transparent wherever you wants to add your Colors. i.e,

enter image description here

You can add your color using

.setColor(your_color_resource_here)

NOTE : setColor is only available in Lollipop so, you've to check OSVersion

if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
    Notification notification = new Notification.Builder(context)
    ...
} else {
    // Lollipop specific setColor method goes here.
    Notification notification = new Notification.Builder(context)
    ...
    notification.setColor(your_color)
    ...            
}

You can also achieve this using Lollipop as the target SDK.

All instruction regarding NotificationIcon given at Google Developer Console Notification Guide Lines.

Preferred Notification Icon Size 24x24dp

mdpi    @ 24.00dp   = 24.00px
hdpi    @ 24.00dp   = 36.00px
xhdpi   @ 24.00dp   = 48.00px

And also refer this link for Notification Icon Sizes for more info.

Jaydipsinh Zala
  • 16,558
  • 7
  • 41
  • 45
  • 4
    this is very good idea for set background color as **notification.setColor(your_color_resource_here)** – TejaDroid Apr 04 '15 at 12:20
  • 1
    So I've tried this, and the notification icon has the colored background when I pull the notification shade down. But, in the tray itself, it's still a white icon – Stealth Rabbi Jan 22 '16 at 17:41
  • 1
    this solution is right..have a notification icon that has transparent back..and by silhouette, the icon need not be black only..the icon can have colors; its just that the android L will convert show color as white..and previous android versions will show the icon as it is – Lakshay Dulani Jun 09 '16 at 06:54
  • am adding setColor for below lollipop showing ic_launcher icon fine but in 6.0 showing white square icon please help me – Harsha Nov 16 '16 at 11:08
  • I've tested `setColor` on Kitkat (API 19) and IceCreamSandwich (API 15), in both case it ignored the color but **didn't crash**. So can I safely omit checking OS version? – Maria Aug 08 '17 at 10:19
48

This is the code Android uses to display notification icons:

// android_frameworks_base/packages/SystemUI/src/com/android/systemui/
//   statusbar/BaseStatusBar.java

if (entry.targetSdk >= Build.VERSION_CODES.LOLLIPOP) {
    entry.icon.setColorFilter(mContext.getResources().getColor(android.R.color.white));
} else {
    entry.icon.setColorFilter(null);
}

So you need to set the target sdk version to something <21 and the icons will stay colored. This is an ugly workaround but it does what it is expected to do. Anyway, I really suggest following Google's Design Guidelines: "Notification icons must be entirely white."

Here is how you can implement it:

If you are using Gradle/Android Studio to build your apps, use build.gradle:

defaultConfig {
    targetSdkVersion 20
}

Otherwise (Eclipse etc) use AndroidManifest.xml:

<uses-sdk android:minSdkVersion="..." android:targetSdkVersion="20" />
ByteHamster
  • 4,884
  • 9
  • 38
  • 53
  • Is there any workaround? Or what can I do to show that or any other icon properly? – Alejandro Casanova Feb 07 '15 at 21:47
  • I have edited my answer as I have found a workaround after reading the Android source code. – ByteHamster Feb 07 '15 at 22:14
  • 4
    Great thanks for your help, but cud you pleae provide me with some "context". Where do I need to do that? Whats is "entry"? – Alejandro Casanova Feb 07 '15 at 22:29
  • The code was taken from AOSP just to show how I found the workaround :) I have added a small explanation on how to implement it. – ByteHamster Feb 07 '15 at 22:46
  • This actually works. Any guesses why Google did this? Is this a bug or a feature? – m02ph3u5 Feb 27 '15 at 13:30
  • @m02ph3u5: seems like it is intended for compatibility reasons (eg give app developers time to add a new white icon). Anyway, this method might not work in newer versions of Android. In my opinion you should follow Googles design guidelines and use white icons. – ByteHamster Feb 27 '15 at 13:42
  • @ByteHamser white icons? It ain't showing any icon at all, just a white circle. – m02ph3u5 Feb 28 '15 at 14:44
  • It displays the silhouette of your icon. You should create an icon with a unique silhouette – ByteHamster Feb 28 '15 at 16:49
  • How is setting down the target SDK so that your app does NOT compile for Android Lollipop a solution? – Daniel Saidi Mar 23 '15 at 09:32
  • @meh: Yes, they decided that white icons fit better to Material Design. There is no guarantee that my answer will continue to work in later Android versions, so you should consider creating a special icon. – ByteHamster Apr 15 '15 at 20:47
  • Doesn't lowering the target version affect the app? – Munib Jul 19 '17 at 00:20
  • Yes, it affects the app. This is why I stated that it's an ugly workaround and suggested not to do it this way. As you might notice, this answer is over 2 years old. This was a proper solution to get more time for creating the white assets back then. Today, you shouldn't really do that anymore. – ByteHamster Jul 19 '17 at 04:16
25

To avoid Notification icons to turn white, use "Silhouette" icons for them, ie. white-on-transparent background images. You may use Irfanview to build them:

  • choose a picture, open in IrfanView, press F12 for the painting tools, clean picture if necessary (remove unwanted parts, smooth and polish)
  • Image / Decrease Color Depth to 2 (for a black & white picture)
  • Image / Negative (for a white on black picture)
  • Image / Resize/Resample to 144 x 144 (use Size Method "Resize" not "Resample", otherwise picture is increased to 24 color bits per pixel (24 BPP) again
  • File / Save as PNG, check Show option dialog, check Save Transparent Color, click Save, then click on the black color in the image to set the transparent color

Android seems to be using the drawable-xxhdpi picture resolution (144 x 144) only, so copy your resulting ic_notification.png file to \AndroidStudio\Projects\...\app\src\main\res\drawable-xxhdpi. Use .setSmallIcon(R.drawable.ic_notification) in your code, or use getNotificationIcon() as Daniel Saidi suggested above.

You may also use Roman Nurik's Android Asset Studio.

  • I tried to convert my icon using photoshop but failed, but being an irfanview fan I quickly tried this when I saw it and it worked wonderfully. Thanks! – Bruce Aug 23 '15 at 09:22
15

Another option is to take advantage of version-specific drawable (mipmap) directories to supply different graphics for Lollipop and above.

In my app, the "v21" directories contain icons with transparent text while the other directories contain non-transparent version (for versions of Android older than Lollipop).

File system

Which should look something like this:

Android Studio

This way, you don't need to check for version numbers in code, e.g.

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
            PendingIntent.FLAG_ONE_SHOT);

Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
        .setSmallIcon(R.mipmap.ic_notification)
        .setContentTitle(title)
        .setContentText(message)
        .setAutoCancel(true)
        .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent);

Likewise, you can reference "ic_notification" (or whatever you choose to call it) in your GCM payload if you use the "icon" attribute.

https://developers.google.com/cloud-messaging/http-server-ref#notification-payload-support

Ian
  • 7,480
  • 2
  • 47
  • 51
  • 3
    This works and looks like the most Android-way solution. – Sergey Galin Apr 04 '16 at 10:18
  • are your saying that if android will pick icon from folder mipmap-21 if version is lollipop, and if less than lollipop it will pick from drawable? – Lakshay Dulani Jun 08 '16 at 12:47
  • @Ian , the directories approach is good for resource per android version, but how can you set the `setColor` (without involving extra code) in that way ? – Daniel May 28 '18 at 13:59
  • @Daniel colors can be in version-specific directories too, e.g. "values" and "values-v21". – Ian May 29 '18 at 08:30
13

Now android studio is provide a plugin Image Asset, which will be generate icon in all required drawbale folder

Image Asset Studio helps you create various types of icons at different densities and shows you exactly where they'll be placed in your project. It includes tools for adjusting your icons and adding backdrops, all while displaying the result in a preview pane, so they appear exactly as you intended. These tools can dramatically streamline the icon design and import process.

You can access Image Asset by click new> click on Image Asset option and it will be show window like this :-

enter image description here

enter image description here

Nishchal Sharma
  • 1,070
  • 9
  • 16
12

According to the Android design guidelines you must use a silhouette for builder.setSmallIcon(R.drawable.some_notification_icon); But if you still wants to show a colorful icon as a notification icon here is the trick for lollipop and above use below code. The largeIcon will act as a primary notification icon and you also need to provide a silhouette for smallIcon as it will be shown over the bottom right of the largeIcon.

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
     builder.setColor(context.getResources().getColor(R.color.red));
     builder.setSmallIcon(R.drawable.some_notification_icon);
     builder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher));
}

And pre-lollipop use only .setSmallIcon(R.mipmap.ic_launcher) with your builder.

Muhammad Babar
  • 8,084
  • 5
  • 39
  • 56
8

I was facing same issue and it was because of my app notification icon was not flat. For android version lollipop or even below lollipop your app notification icon should be flat, don't use icon with shadows etc.

Below is the code that worked perfectly fine on all android versions.

private void sendNotification(String msg) {

    NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);

    Intent intent = new Intent(this, CheckOutActivity.class);

    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
            this).setSmallIcon(R.drawable.ic_notification)
            .setContentTitle(getString(R.string.app_name))
            .setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
            .setContentText(msg).setLights(Color.GREEN, 300, 300)
            .setVibrate(new long[] { 100, 250 })
            .setDefaults(Notification.DEFAULT_SOUND).setAutoCancel(true);

    mBuilder.setContentIntent(contentIntent);
    mNotificationManager.notify(new Random().nextInt(), mBuilder.build());
}

Wrong icon
enter image description here

Right Icon

enter image description here

Nauman Zubair
  • 1,208
  • 15
  • 27
7

alpha-channel is the only data of the image that Android uses for notification icons:

  • alpha == 1: pixels show white
  • alpha == 0: pixels show as the color you chose at Notification.Builder#setColor(int)

This is mentioned at https://developer.android.com/about/versions/android-5.0-changes.html :

The system ignores all non-alpha channels in action icons and in the main notification icon. You should assume that these icons will be alpha-only.

Almost all built-in drawables seem to be suitable alpha images for this, so you might use something like:

Notification.Builder.setColor(Color.RED)
                    .setSmallIcon(android.R.drawable.star_on)

but I'm still looking for the API doc that officially confirms that.

Tested on Android 22.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
3

remove the android:targetSdkVersion="21" from manifest.xml. it will work! and from this there is no prob at all in your apk it just a trick i apply this and i found colorful icon in notification

Bhanu Sharma
  • 5,135
  • 2
  • 24
  • 49
3

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; instead, they still provide greyscale. 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. (It seems others have reported slightly different behavior, so be aware!)

Jeremy Frank
  • 743
  • 1
  • 7
  • 10
2

Post android Lollipop release android has changed the guidelines for displaying notification icons in the Notification bar. The official documentation says "Update or remove assets that involve color. The system ignores all non-alpha channels in action icons and in the main notification icon. You should assume that these icons will be alpha-only. The system draws notification icons in white and action icons in dark gray.” Now what that means in lay man terms is "Convert all parts of the image that you don’t want to show to transparent pixels. All colors and non transparent pixels are displayed in white"

You can see how to do this in detail with screenshots here https://blog.clevertap.com/fixing-notification-icon-for-android-lollipop-and-above/

Hope that helps

Rohit Khanna
  • 41
  • 1
  • 7
2

You Need to import the single color transparent PNG image. So You can set the Icon color of the small icon. Otherwise it will be shown white in some devices like MOTO

abhi.nalavade
  • 196
  • 3
  • 10
1

If you're using GoogleFireBaseMessaging, you can set "icon id" in the "notification" payload (it helps me to solve the white bar icon problem):

{
    "to":"<fb_id>",
    "priority" : "high",
    "notification" : 
    {
        "title" : "title",
        "body" : "body" ,
        "sound" : "default",
        "icon" : "ic_notification"
    }
}

set ic_notification to your own id from R.drawable.

masud_moni
  • 1,121
  • 16
  • 33
Maxim Firsoff
  • 2,038
  • 22
  • 28
  • Where did you place that icon? All I get is the icon of my app and all the R.drawable files I find are binary class files. – shinzou Aug 11 '17 at 22:15
  • @kuhaku he is referring to an ic_launcher.png file in the 'drawable' folder. – Johnson Sep 02 '17 at 16:32
0

I also faced too many problem in this but after searching all over the internet i found different solutions for this issue.Let me sum up all the solutions and explain:

Note:This solution is for Phonegap cordova users

  1. Example

<preference name="android-targetSdkVersion" value="20"/>

You need to set your android-targetSdkVersion value to less than 21. So after setting this value Notification icon image will appear till Android 6(Marshmallow), It won't work in Android 7(Nougat). This solution worked for me.

  1. Change the statusbarStyle in your config file. Example

<preference name="StatusBarStyle" value="lightcontent" />

But this solution will work only when your app is opened. So, I guess this solution is not the best solution but it worked for many users.

  1. Make your icon transparent. This solution worked for many people. Actually the thing is, In the development of Native aplication we need to provide them three images: (a)App icon (b)Notification icon (c)Status bar icon image, but in case of Hybrid mobile application development there is no option to do so. So make your icon transparent and this solution will solve your problem.

And I am sure one of the above solution will work for your issue.

0

FYI: If the Icon doesn't appear, ensure your local or remote notification configuration contains the correct icon name i.e

'largeIcon' => 'ic_launcher',
'smallIcon' => 'ic_launcher' // defaults to ic_launcher, 
Philip E
  • 838
  • 9
  • 15
0

I think it's too late to talk about API 21, but I found a easy way.

When using 'Custom Notification(custom layout)'s,

RemoteView's

setImageViewResource(int viewId, int srcId);

and

setImageViewUri(int viewId, Uri uri); 

makes those image white on Lollipop (API 21).

But when using

setImageViewBitmap(int viewId, Bitmap bitmap);

Image doesn't become white-masked!

LimeCake
  • 1
  • 3
0

According to the documentation, notification icon must be white since Android 3.0 (API Level 11) :

https://developer.android.com/guide/practices/ui_guidelines/icon_design_status_bar

"Status bar icons are composed simply of white pixels on a transparent backdrop, with alpha blending used for smooth edges and internal texture where appropriate."

Laurent
  • 469
  • 3
  • 7
-3

mix these two things in app gradle

 defaultConfig {
    applicationId "com.example.abdulwahidvi.notificationproblem"
    minSdkVersion 16
    //This is the version that was added by project by default
    targetSdkVersion 26 <------ default
    // Changed it to version 20
    targetSdkVersion 20 <------ mine

    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
Ahmad Ayyaz
  • 774
  • 8
  • 25
wahid
  • 55
  • 1
  • 1
-40

android:targetSdkVersion="20" it should be < 21.

IKavanagh
  • 6,089
  • 11
  • 42
  • 47
  • 2
    Please don't follow this solution, sure it might work but at the cost of running your apps in compatibility mode for the newer versions of Android. – king_below_my_lord Jul 26 '17 at 19:54