[英]Notification bar icon turns white in Android 5 Lollipop
我有一个显示自定义通知的应用。 问题是,在Android 5中运行时,通知栏中的小图标显示为白色。 我怎样才能解决这个问题?
接受的答案不是(完全)正确的。 当然,它会使通知图标显示为彩色,但这样做有一个很大的缺点 - 通过将目标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;
并且,在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。 为了获得NotificationIcon
Color
,我正在写这个答案。
为此你要制作像Silhouette
这样的图标,并在任何想要添加Colors
地方制作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
,并且图标将保持彩色。 这是一个丑陋的解决方法,但它做了预期的事情。 无论如何,我真的建议遵循谷歌的设计指南 : “通知图标必须完全是白色的。”
以下是如何实现它:
如果您使用Gradle / Android Studio构建应用程序,请使用build.gradle
:
defaultConfig {
targetSdkVersion 20
}
否则(Eclipse等)使用AndroidManifest.xml
:
<uses-sdk android:minSdkVersion="..." android:targetSdkVersion="20" />
要避免通知图标变为白色,请使用“轮廓”图标,即。 白色透明背景图像。 您可以使用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)
,或使用上面提到的Daniel Saidi建议的getNotificationIcon()
。
您也可以使用Roman Nurik的Android Asset Studio 。
另一个选择是利用特定于版本的可绘制(mipmap)目录为Lollipop及更高版本提供不同的图形。
在我的应用程序中,“v21”目录包含带透明文本的图标,而其他目录包含非透明版本(对于早于Lollipop的Android版本)。
哪个应该是这样的:
这样,您无需在代码中检查版本号,例如
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”(或您选择调用它的任何内容)。
https://developers.google.com/cloud-messaging/http-server-ref#notification-payload-support
根据Android设计指南,您必须使用builder.setSmallIcon(R.drawable.some_notification_icon);
的轮廓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));
}
并且pre-lollipop仅使用.setSmallIcon(R.mipmap.ic_launcher)
与您的构建器。
我面临同样的问题,这是因为我的应用程序通知图标不平坦。 对于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-channel是Android用于通知图标的图像的唯一数据:
alpha == 1
:像素显示白色 alpha == 0
:像素显示您在Notification.Builder#setColor(int)
选择的颜色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)
但我仍然在寻找正式确认的API文档 。
在Android 22上测试过。
从manifest.xml中删除android:targetSdkVersion="21"
。 它会工作! 从这里你的apk没有任何概率它只是一个技巧,我应用这个,我发现通知中的彩色图标
通知是灰度的 ,如下所述。 尽管别人写过,但它们并非黑白分明。 您可能已经看到了具有多种阴影的图标,例如网络强度条。
在API 21(Lollipop 5.0)之前,颜色图标有效。 您可以强制您的应用程序以API 20为目标,但这限制了应用程序可用的功能,因此不建议这样做。 您可以测试正在运行的API级别并适当地设置颜色图标或灰度图标,但这可能不值得。 在大多数情况下,最好使用灰度图标。
图像有四个通道,RGBA(红色/绿色/蓝色/ alpha)。 对于通知图标,Android会忽略R,G和B通道。 唯一重要的通道是Alpha,也称为不透明度。 使用编辑器设计图标,使您可以控制绘图颜色的Alpha值。
Alpha值如何生成灰度图像:
使用setColor
更改它:
调用NotificationCompat.Builder.setColor(int argb)
。 从Notification.color
的文档:
呈现此通知时,标准样式模板应用的强调颜色(ARGB整数,如颜色中的常量)。 当前模板设计通过在该颜色的字段顶上覆盖图标图像(以白色印刷)来构造彩色标题图像。 Alpha组件被忽略。
我使用setColor进行测试表明不会忽略Alpha组件; 相反,他们仍然提供灰度。 较高的Alpha值会使像素变为白色。 较低的Alpha值会将一个像素转换为通知区域中的背景颜色(我的设备上为黑色),或者为下拉通知中的指定颜色。 (似乎其他人报告的行为略有不同,所以要注意!)
发布android Lollipop发布android已经改变了通知栏中显示通知图标的指导原则。 官方文档说“更新或删除涉及颜色的资产。系统会忽略操作图标和主要通知图标中的所有非alpha通道。您应该假设这些图标仅为alpha。系统以白色绘制通知图标暗灰色中的动作图标。“现在,在外行人的术语中意味着”将您不想显示的图像的所有部分转换为透明像素。 所有颜色和非透明像素均以白色显示“
您可以通过此处的屏幕截图详细了解如何执行此操作https://blog.clevertap.com/fixing-notification-icon-for-android-lollipop-and-above/
希望有所帮助
您需要导入单色透明PNG图像。 所以你可以设置小图标的图标颜色。 否则它将在某些设备(如MOTO)中显示为白色
如果你正在使用GoogleFireBaseMessaging,你可以在“通知”有效负载中设置“icon id”(这有助于我解决白条图标问题):
{
"to":"<fb_id>",
"priority" : "high",
"notification" :
{
"title" : "title",
"body" : "body" ,
"sound" : "default",
"icon" : "ic_notification"
}
}
从R.drawable将ic_notification设置为您自己的id。
我在这方面也遇到了太多问题,但在搜索了整个互联网后,我找到了解决这个问题的不同解决方案。让我总结所有解决方案并解释:
注意:此解决方案适用于Phonegap cordova用户
<preference name="android-targetSdkVersion" value="20"/>
你需要将你的android-targetSdkVersion值设置为小于21.因此设置此值后,通知图标图像将出现在Android 6(Marshmallow)中,它将无法在Android 7(Nougat)中运行。 这个解决方案对我有用。
<preference name="StatusBarStyle" value="lightcontent" />
但此解决方案仅在您的应用程序打开时才有效。 所以,我猜这个解决方案不是最好的解决方案,但它适用于许多用户。
我相信上述解决方案之一将适用于您的问题。
仅供参考:如果未显示图标,请确保您的本地或远程通知配置包含正确的图标名称,即
'largeIcon' => 'ic_launcher',
'smallIcon' => 'ic_launcher' // defaults to ic_launcher,
我认为现在谈论API 21为时已晚,但我找到了一个简单的方法。
使用“自定义通知(自定义布局)”时,
远程视窗的
setImageViewResource(int viewId, int srcId);
和
setImageViewUri(int viewId, Uri uri);
在Lollipop(API 21)上使这些图像变白。
但是在使用时
setImageViewBitmap(int viewId, Bitmap bitmap);
图像不会变成白色蒙版!
根据文档,自Android 3.0(API级别11)起,通知图标必须为白色:
https://developer.android.com/guide/practices/ui_guidelines/icon_design_status_bar
“状态栏图标仅由透明背景上的白色像素组成,alpha混合用于平滑边缘和内部纹理。”
在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"
}
android:targetSdkVersion="20"
它应该< 21
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.