首页 文章

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

提问于
浏览
201

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

17 回答

  • -3

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

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

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

    enter image description here

    enter image description here

  • 3

    仅供参考:如果图标没有出现,确保您的本地或远程通知配置包含正确的图标名称,即

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

    接受的答案不是(完全)正确的 . 当然,它会使通知图标显示为彩色,但这样做有一个很大的缺点 - 将目标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;
    }
    
  • -37

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

    为此,您需要制作像 Silhouette 这样的图标,并在任何想要添加 Colors 的地方创建 Transparent . 即,

    enter image description here

    您可以使用添加颜色

    .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 Notification Guide Lines处给出 .

    首选通知图标大小24x24dp

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

    有关更多信息,请参阅此链接以获取Notification Icon Sizes .

  • 3

    这是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 并且图标将保持彩色 . 这是一个丑陋的解决方法,但它做了预期的事情 . Anyway, I really suggest following Google's Design Guidelines: "Notification icons must be entirely white."

    Here is how you can implement it:

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

    defaultConfig {
        targetSdkVersion 20
    }
    

    否则(Eclipse等)使用 AndroidManifest.xml

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

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

    • 选择一张图片,在 IrfanView 打开,按F12为绘画工具,必要时清理图片(去除不需要的部分,光滑和抛光)

    • Image / Decrease Color Depth 至2(黑白图片)

    • Image / Negative (白色黑色图片)

    • Image / Resize/Resample 至144 x 144(使用尺寸方法"Resize"不"Resample",否则图片再次增加到每像素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's Android Asset Studio .

  • 68

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

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

    File system

    哪个应该是这样的:

    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”(或您选择调用它的任何内容) .

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

  • 1

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

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

  • 265

    在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"
    }
    
  • 7

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

  • 47

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

    错误的图标

    enter image description here

    右图标

    enter image description here

  • 0

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

    • alpha == 1 :像素显示白色

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

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

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

    几乎所有built-in drawables似乎都适合这种alpha图像,所以你可能会使用类似的东西:

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

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

    在Android 22上测试过 .

  • 23

    从manifest.xml中删除 android:targetSdkVersion="21" . 它会工作!从这里你的apk中没有任何概率它只是一个技巧,我应用这个,我发现通知中的彩色图标

  • 2

    通知是 greyscale ,如下所述 . 尽管其他人写过,但它们并非黑白分明 . 您可能已经看到了具有多种阴影的图标,例如网络强度条 .

    在API 21(Lollipop 5.0)之前,颜色图标有效 . 您可以强制您的应用程序以API 20为目标,但这限制了应用程序可用的功能,因此不建议这样做 . 您可以测试正在运行的API级别并适当地设置颜色图标或灰度图标,但这可能不值得 . 在大多数情况下,最好使用灰度图标 .

    图像有四个通道,RGBA(红色/绿色/蓝色/ alpha) . 对于通知图标,Android会忽略R,G和B通道 . 唯一重要的通道是Alpha,也称为不透明度 . 使用编辑器设计图标,使您可以控制绘图颜色的Alpha值 .

    How Alpha values generate a greyscale image:

    • Alpha = 0(透明) - 这些像素是透明的,显示背景颜色 .

    • Alpha = 255(不透明) - 这些像素为白色 .

    • Alpha = 1 ... 254 - 这些像素正是您所期望的,提供透明和白色之间的阴影 .

    Changing it up with setColor:

    • 致电 NotificationCompat.Builder.setColor(int argb) . 从 Notification.color 的文档:

    呈现此通知时,标准样式模板将应用的强调颜色(ARGB整数,如颜色中的常量) . 当前模板设计通过在该颜色的字段顶上覆盖图标图像(以白色印刷)来构建彩色 Headers 图像 . Alpha组件被忽略 .

    我使用setColor测试显示Alpha组件被 not 忽略;相反,他们仍然提供灰度 . 较高的Alpha值会使像素变为白色 . 较低的Alpha值会将一个像素变为通知区域中的背景颜色(我设备上的黑色),或者下拉通知中的指定颜色 . (似乎其他人报告的行为略有不同,所以要注意!)

  • 14

    发布android Lollipop发布android已更改了通知栏中显示通知图标的指南 . 官方文档说“更新或删除涉及颜色的资产 . 系统会忽略操作图标和主要通知图标中的所有非alpha通道 . 您应该假设这些图标仅为alpha . 系统以白色绘制通知图标暗灰色中的动作图标 . “现在,在外行人的术语中意味着”将您不想显示的图像的所有部分转换为透明像素 . 所有颜色和非透明像素均以白色显示“

    你可以在这里看截图来详细了解如何做到这一点https://blog.clevertap.com/fixing-notification-icon-for-android-lollipop-and-above/

    希望有所帮助

  • 9

    如果您正在使用GoogleFireBaseMessaging,则可以在“通知”有效负载中设置“icon id”(它可以帮助我解决白条图标问题):

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

    从R.drawable将 ic_notification 设置为您自己的id .

  • 0

    我在这方面也遇到了太多的问题,但在搜索了整个互联网后,我找到了解决这个问题的不同解决方案 . 让我总结所有解决方案并解释:

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

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

    你需要将你的android-targetSdkVersion值设置为小于21.因此设置此值后,通知图标图像将出现在Android 6(Marshmallow)中,它将无法在Android 7(Nougat)中运行 . 这个解决方案对我有用 .

    • 更改配置文件中的statusbarStyle . Example

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

    但此解决方案仅在您的应用程序打开时才有效 . 所以,我猜这个解决方案不是最好的解决方案,但它适用于许多用户 .

    • 使图标透明 . 这个解决方案适用于很多人 . 实际上,在本机应用程序的开发中,我们需要为它们提供三个图像:(a)应用程序图标(b)通知图标(c)状态栏图标图像,但是在混合移动应用程序开发的情况下,没有选项这样做 . 因此,使您的图标透明,此解决方案将解决您的问题 .

    我相信上述解决方案之一将适用于您的问题 .

相关问题