通知栏图标在Android 5棒棒糖中变成白色

我有一个应用程序显示自定义通知。 问题是,在Android 5中运行时,通知栏中的小图标显示为白色。 我该如何解决这个问题?

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

如果您通过将目标SDK设置为20来解决白色图标问题,build议您的应用程序不会针对Android棒棒糖,这意味着您不能使用棒棒糖特定的function。

看看http://developer.android.com/design/style/iconography.html ,你会发现白色的风格是Android的棒棒糖显示通知。

在棒棒糖中,谷歌还build议你使用一个颜色,将显示在(白色)通知图标后面 – https://developer.android.com/about/versions/android-5.0-changes.html

所以,我认为更好的解决scheme是在应用程序中添加轮廓图标,并在设备运行Android棒棒糖时使用它。

例如:

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

而且,在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; } 

完全同意用户Daniel Saidi。 为了让ColorNotificationIcon我正在写这个答案。

为此,您必须制作“ Silhouette等图标,并在某处添加“ Transparent部分。 即

在这里输入图像描述

你可以使用添加你的颜色

.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) ... } 

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

所有关于NotificationIcon指令都在Google Developer Console通知指南中给出。

首选通知图标大小24x24dp

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

另请参阅此链接的通知图标大小了解更多信息。

这是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); } 

所以你需要将目标sdk版本设置为<21 ,图标将保持着色。 这是一个丑陋的解决方法,但是它可以完成预期的工作。 无论如何,我真的build议遵循Google的devise指南 : “通知图标必须是完全白色的。”

以下是你可以如何实现它:

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

 defaultConfig { targetSdkVersion 20 } 

否则(Eclipse等)使用AndroidManifest.xml

 <uses-sdk android:minSdkVersion="..." android:targetSdkVersion="20" /> 

要避免通知图标变成白色,请使用“剪影”图标,即。 白色透明的背景图像。 您可以使用Irfanview来构build它们:

  • select一张图片,在IrfanView打开,按F12键进行绘画工具,如果需要可以清理图片(去除不需要的部分,平滑和打磨)
  • Image / Decrease Color Depth到2(对于黑白图像)
  • Image / Negative (黑色图片上的白色)
  • Image / Resize/Resample到144 x 144(使用大小方法“resize”不是“重新采样”,否则图片被增加到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) ,或者像Daniel Saidi上面提到的那样使用getNotificationIcon()

您也可以使用Roman Nurik的Android资源工作室 。

另一种select是利用版本特定的可绘制(mipmap)目录来为棒棒糖和更高版本提供不同的graphics。

在我的应用程序中,“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); 

同样,如果您使用“icon”属性,则可以在GCM有效内容中引用“ic_notification”(或任何您select调用它的内容)。

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

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

Image Asset Studio可以帮助您以不同的密度创build各种types的图标,并且可以准确显示您的项目放置位置。 它包括用于调整图标和添加背景的工具,同时在预览窗格中显示结果,以便它们完全按照您的预期显示。 这些工具可以大大简化图标的devise和导入过程。

您可以通过点击新build>点击图像资产选项来访问图像资产 ,它将是这样的显示窗口: –

在这里输入图像描述

在这里输入图像描述

根据Androiddevise指南,您必须使用builder.setSmallIcon(R.drawable.some_notification_icon);的轮廓builder.setSmallIcon(R.drawable.some_notification_icon); 但是,如果你仍然想要显示一个彩色的图标作为通知图标这里是棒棒糖和以上使用代码下面的技巧。 largeIcon将作为主要通知图标,您还需要为smallIcon提供一个轮廓,因为它将显示在largeIcon的右下angular。

 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)); } 

和前棒棒糖一起使用.setSmallIcon(R.mipmap.ic_launcher)与你的build设者。

我面临同样的问题,这是因为我的应用程序通知图标不平坦。 对于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()); } 

错误的图标
在这里输入图像描述

正确的图标

在这里输入图像描述

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

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

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

系统忽略操作图标和主通知图标中的所有非alpha通道。 您应该假设这些图标将仅为阿尔法。

几乎所有的内置绘图似乎都是适合这个的alpha图像,所以你可以使用像这样的东西:

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

但我仍然在寻找官方证实的API文档 。

在Android 22上testing

从manifest.xml中删除android:targetSdkVersion="21" 。 它会工作! 从这里没有任何问题在你的apk只是一个把戏我申请这个,我发现通知彩色图标

发布android棒棒糖发布android已经改变了在通知栏中显示通知图标的指导原则。 官方文档中提到“更新或删除涉及颜色的资源,系统忽略操作图标和主要通知图标中的所有非alpha通道,应该假设这些图标是alpha-only。系统将通知图标绘制成白色和行动图标在深灰色。“现在,这是什么意思,俗话说是”将您不想显示的图像的所有部分转换为透明像素。 所有颜色和不透明像素都以白色显示“

你可以看到详细的截图在这里https://blog.clevertap.com/fixing-notification-icon-for-android-lollipop-and-above/

希望有所帮助

通知灰度如下所述。 他们不是黑白的,尽pipe其他人已经写了。 您可能已经看到了多个色调的图标,如networking强度条。

API 21之前(棒棒堂5.0),颜色图标的工作。 您可以强制您的应用程序定位到API 20,但是这会限制您的应用程序可用的function,所以不build议这样做。 您可以testing运行的API级别,并适当地设置颜色图标或灰度图标,但这可能不值得。 在大多数情况下,最好使用灰度图标。

图像有四个通道,RGBA(红/绿/蓝/阿尔法)。 对于通知图标,Android会忽略R,G和B通道。 唯一的重要渠道是阿尔法,也被称为不透明。 用一个编辑器devise你的图标,让你控制你的绘画颜色的Alpha值。

Alpha值如何生成灰度图像:

  • Alpha = 0(透明) – 这些像素是透明的,显示背景颜色。
  • Alpha = 255(不透明) – 这些像素是白色的。
  • Alpha = 1 … 254 – 这些像素正是您所期望的,提供透明和白色之间的阴影。

setColor改变它:

  • 调用NotificationCompat.Builder.setColor(int argb) 。 从Notification.color的文档:

    在呈现此通知时由标准样式模板应用的强调颜色(类似于Color中的常量的ARGB整数)。 当前的模板devise通过将图标图像(以白色印刷)叠加在该颜色的字段上来构造彩色标题图像。 Alpha组件被忽略。

    我用setColor进行testing表明Alpha组件被忽略。 相反,他们仍然提供灰度。 较高的Alpha值将像素变成白色。 较低的Alpha值在通知区域中将像素转换为背景颜色(在我的设备上为黑色),或在下拉通知中将其指定为指定的颜色。 (看来其他人报告的行为略有不同,所以要注意!)

如果您使用GoogleFireBaseMessaging,则可以在“通知”有效内容中设置“图标ID”(它可以帮助我解决白色条形图标问题):

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

设置ic_notification从R.drawable你自己的ID。

我也遇到了太多的问题,但是在search整个互联网之后,我发现了这个问题的不同解决scheme。让我总结所有的解决scheme,并解释:

注意:此解决scheme适用于Phonegap cordova用户

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

您需要将您的android-targetSdkVersion值设置为小于21.所以设置此值后,通知图标图像将出现,直到Android 6(棉花糖),它不会在Android 7(牛轧糖)中工作。 这个解决scheme为我工作。

  1. 在configuration文件中更改statusbarStyle。 例

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

但是这个解决scheme只有在你的应用程序打开时才能使用 所以,我想这个解决scheme不是最好的解决scheme,但是它对很多用户都有效。

  1. 让你的图标透明。 这个解决scheme适用于很多人。 事实上,在开发本地应用程序时,我们需要为它们提供三个图像:(a)应用程序图标(b)通知图标(c)状态栏图标图像,但是在混合移动应用程序开发的情况下,这样做。 所以让你的图标透明,这个解决scheme将解决你的问题。

我相信上述解决scheme之一将适用于您的问题。

仅供参考:如果图标不显示,请确保您的本地或远程通知configuration包含正确的图标名称,即

 'largeIcon' => 'ic_launcher', 'smallIcon' => 'ic_launcher' // defaults to ic_launcher, 

在应用程序gradle中混合这两个东西

  defaultConfig { applicationId "com.example.abdulwahidvi.notificationproblem" minSdkVersion 16 targetSdkVersion 26 <----------- default // my code targetSdkVersion 20 <--------- mine versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } 

android:targetSdkVersion="20"应该是< 21