在Android 5 Lollipop中,通知栏图标变为白色

Ale*_*ova 204 android android-notifications android-5.0-lollipop

我有一个显示自定义通知的应用.问题是,在Android 5中运行时,通知栏中的小图标显示为白色.我怎样才能解决这个问题?

Dan*_*idi 268

接受的答案不是(完全)正确的.当然,它会使通知图标显示为彩色,但这样做有一个很大的缺点 - 通过将目标SDK设置为低于Android Lollipop!

如果您按照建议将目标SDK设置为20来解决白色图标问题,那么您的应用将无法定位Android Lollipop,这意味着您无法使用Lollipop特有的功能.

看看http://developer.android.com/design/style/iconography.html,您会看到白色样式是Android Lollipop中显示通知的方式.

在Lollipop中,Google还建议您使用将显示在(白色)通知图标后面的颜色 - https://developer.android.com/about/versions/android-5.0-changes.html

所以,我认为更好的解决方案是在应用程序中添加一个轮廓图标,并在设备运行Android Lollipop时使用它.

例如:

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

    return notification;
Run Code Online (Sandbox Code Playgroud)

并且,在getNotificationIcon方法中:

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 你如何产生轮廓?我是开发人员,没有photoshop技能,使用在线工具使背景透明仍然导致白色图标. (33认同)
  • @Chaitanya使用GIMP :) (6认同)
  • http://developer.android.com/design/style/iconography.html导致https://material.google.com/style/icons.html,当我按下`ctrl + f`并在其上键入`notification`时页面找不到任何东西...... (6认同)
  • 这个解决方案没有回答为什么android构建过程修改完全正确的PNG并压缩它并删除alpha通道的问题. (4认同)
  • 而不是从代码applay平台版本修改器检查到drawable文件夹 - drawable/drawable-v21并放置正确的图标 (4认同)
  • 我有 GIMP,但我没有生成剪影的技能。我能做些什么? (2认同)

Jay*_*ala 71

完全同意用户Daniel Saidi.为了有ColorNotificationIcon我写这个答案.

为此,你必须制作图标,SilhouetteTransparent在你想要添加你的地方做一些部分Colors.即

在此输入图像描述

您可以使用添加颜色

.setColor(your_color_resource_here)

注意:setColor只有Lollipop这样,您需要检查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)
    ...            
}
Run Code Online (Sandbox Code Playgroud)

您也可以使用Lollipop目标作为目标SDK.

有关Google Developer Console通知指南行中NotificationIcon给出的所有说明.

首选通知图标大小24x24dp

mdpi    @ 24.00dp   = 24.00px
hdpi    @ 24.00dp   = 36.00px
xhdpi   @ 24.00dp   = 48.00px
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅此链接以获取通知图标大小.

  • 这是设置背景颜色的好主意**notification.setColor(your_color_resource_here)** (4认同)

Byt*_*ter 47

这是Android用于显示通知图标的代码:

// 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);
}
Run Code Online (Sandbox Code Playgroud)

因此,您需要将目标sdk版本设置为某些内容<21,并且图标将保持彩色.这是一个丑陋的解决方法,但它做了预期的事情.无论如何,我真的建议遵循谷歌的设计指南: "通知图标必须完全是白色的."

以下是如何实现它:

如果您使用Gradle/Android Studio构建应用程序,请使用build.gradle:

defaultConfig {
    targetSdkVersion 20
}
Run Code Online (Sandbox Code Playgroud)

否则(Eclipse等)使用AndroidManifest.xml:

<uses-sdk android:minSdkVersion="..." android:targetSdkVersion="20" />
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢你的帮助,但请你提供一些"背景".我在哪里需要这样做?什么是"入门"? (4认同)

Tho*_*idt 23

要避免通知图标变为白色,请使用"轮廓"图标,即.白色透明背景图像.您可以使用Irfanview来构建它们:

  • 选择一张图片,打开IrfanView,按F12绘画工具,必要时清洁图片(去除不需要的部分,光滑和抛光)
  • Image / Decrease Color Depth 到2(黑白照片)
  • Image / Negative (黑白照片上的白色)
  • Image / Resize/Resample 至144 x 144(使用尺寸方法"调整大小"而不是"重新采样",否则图片再次增加到每像素24个色位(24 BPP)
  • File / Save as PNG,检查Show option dialog,检查Save Transparent Color,单击Save,然后单击图像中的黑色以设置透明色

Android似乎只使用drawable-xxhdpi图片分辨率(144 x 144),因此将生成的ic_notification.png文件复制到\AndroidStudio\Projects\...\app\src\main\res\drawable-xxhdpi.使用.setSmallIcon(R.drawable.ic_notification)在你的代码,或使用getNotificationIcon()如丹尼尔·赛义迪以上建议.

您也可以使用Roman Nurik的Android Asset Studio.


Ian*_*Ian 15

另一个选择是利用特定于版本的可绘制(mipmap)目录为Lollipop及更高版本提供不同的图形.

在我的应用程序中,"v21"目录包含带透明文本的图标,而其他目录包含非透明版本(对于早于Lollipop的Android版本).

文件系统

哪个应该是这样的:

Android Studio

这样,您无需在代码中检查版本号,例如

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);
Run Code Online (Sandbox Code Playgroud)

同样,如果使用"icon"属性,则可以在GCM有效内容中引用"ic_notification"(或您选择调用它的任何内容).

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

  • 这可行,看起来像Android方式解决方案. (3认同)

Muh*_*bar 12

根据Android设计指南,你必须使用一个剪影builder.setSmallIcon(R.drawable.some_notification_icon);但如果你仍然想要显示一个彩色图标作为通知图标这里是棒棒糖及以上使用下面代码的技巧.largeIcon将作为主要通知图标,您还需要为smallIcon提供一个轮廓,因为它将显示在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));
}
Run Code Online (Sandbox Code Playgroud)

前棒棒糖仅.setSmallIcon(R.mipmap.ic_launcher)与您的建造者一起使用.


Nis*_*hal 11

现在android studio提供了一个插件 Image Asset,它将在所有必需的drawbale文件夹中生成图标

Image Asset Studio可帮助您以不同的密度创建各种类型的图标,并向您显示它们在项目中的确切位置.它包括用于调整图标和添加背景的工具,同时在预览窗格中显示结果,因此它们完全按照您的意图显示.这些工具可以极大地简化图标设计和导入过程.

您可以通过单击新建>单击图像资源选项来访问 图像资产,它将显示如下: -

在此输入图像描述

在此输入图像描述


Nau*_*air 8

我面临同样的问题,这是因为我的应用程序通知图标不平坦.对于Android版棒棒糖或甚至低于棒棒糖,你的应用程序通知图标应该是平的,不要使用带阴影的图标等.

以下是在所有Android版本上完美运行的代码.

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());
}
Run Code Online (Sandbox Code Playgroud)

错误的图标
在此输入图像描述

右图标

在此输入图像描述

  • 您到底要解决哪里的问题? (2认同)

Cir*_*四事件 7

alpha-channel是Android用于通知图标的图像的唯一数据:

  • alpha == 1:像素显示白色
  • alpha == 0:像素显示为您选择的颜色 Notification.Builder#setColor(int)

这在https://developer.android.com/about/versions/android-5.0-changes.html中提到:

系统会忽略操作图标和主通知图标中的所有非Alpha通道.您应该假设这些图标仅为alpha.

几乎所有内置的drawable似乎都适合这个alpha图像,所以你可能会使用类似的东西:

Notification.Builder.setColor(Color.RED)
                    .setSmallIcon(android.R.drawable.star_on)
Run Code Online (Sandbox Code Playgroud)

但我仍然在寻找正式确认的API文档.

在Android 22上测试过.