【问题标题】:Android Push Notifications: Icon not displaying in notification, white square shown insteadAndroid推送通知:通知中未显示图标,而是显示白色方块
【发布时间】:2015-08-28 00:18:26
【问题描述】:

我的应用生成通知,但我为该通知设置的图标没有显示。相反,我得到一个白色方块。

我已尝试调整图标的 png 大小(尺寸 720x720、66x66、44x44、22x22)。奇怪的是,当使用较小的尺寸时,白色方块会更小。

我已经用谷歌搜索了这个问题,以及生成通知的正确方法,从我阅读的内容来看,我的代码应该是正确的。可悲的是,事情并非如此。

我的手机是装有 Android 5.1.1 的 Nexus 5。这个问题也出现在模拟器上,一台装有 Android 5.0.1 的三星 Galaxy s4 和一台装有 Android 5.0.1 的摩托罗拉 Moto G(我都借了,现在没有)

通知代码如下,以及两个屏幕截图。如果您需要更多信息,请随时询问。

谢谢大家。

@SuppressLint("NewApi") private void sendNotification(String msg, String title, String link, Bundle bundle) {
    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class);
    resultIntent.putExtras(bundle);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
            resultIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
    Notification notification;
    Uri sound = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.notificationsound);
    notification = new Notification.Builder(this)
                .setSmallIcon(R.drawable.lg_logo)
                .setContentTitle(title)
                .setStyle(new Notification.BigTextStyle().bigText(msg))
                .setAutoCancel(true)
                .setContentText(msg)
                .setContentIntent(contentIntent)
                .setSound(sound)
                .build();
    notificationManager.notify(0, notification);
}

【问题讨论】:

  • 解决了这个问题吗?我仍然面临同样的问题,如果我添加透明图像,在顶部状态栏中仍然显示通知的空白区域
  • 是的,我通过创建透明图标或针对 SDK 20 或更低版本来修复它。如果这不能为您解决问题,那么您的类似问题可能有不同的原因。我建议将目标 SDK 版本设置为 20 并检查这是否有任何改变。如果没有,不确定这个问题是否可以帮助你:(

标签: android push-notification notifications firebase-cloud-messaging icons


【解决方案1】:

原因:对于 5.0 Lollipop“通知图标必须全白”。

如果我们通过将目标 SDK 设置为 20 来解决白色图标问题,我们的应用 will not target Android Lollipop,这意味着我们不能使用 棒棒糖特有的功能。

目标 SDK 21 的解决方案

如果要支持 Lollipop Material Icons,请为 Lollipop 及以上版本制作透明图标。请参考以下内容: https://design.google.com/icons/

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

在 Lollipop 中,Google 还建议我们使用将显示在白色通知图标后面的颜色。参考链接:https://developer.android.com/about/versions/android-5.0-changes.html

无论我们想在哪里添加颜色 https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#setColor(int)

对于 Lollipop OS 版本以下和以上版本的通知生成器的实现将是:

Notification notification = new NotificationCompat.Builder(this);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    notification.setSmallIcon(R.drawable.icon_transperent);
    notification.setColor(getResources().getColor(R.color.notification_color));
} else { 
    notification.setSmallIcon(R.drawable.icon);
} 

注意:setColor 仅在 Lollipop 中可用,并且只影响图标的背景。

它会彻底解决你的问题!!

【讨论】:

  • 哇,谢谢。我认为它们应该完全是白色的,因为我手机上的一些应用程序有彩色图标。现在我明白了原因。谢谢!
  • 通过说 targetSdkVersion 20,你拯救了我的一天!非常感谢。
  • 为了图标而将 targetSDK 版本设置为 stackoverflow.com/questions/27343202/…
  • 但在后台,当应用程序不在堆栈中时,它会显示白色图标,在任何情况下如何获得相同的结果
  • 我什么都试过了,但还是不行。它仍然在清单文件中显示带有颜色提及的点
【解决方案2】:

如果您使用的是 Google Cloud Messaging,则只需更改图标即可解决此问题。例如,这将不起作用:

 Notification notification  = new Notification.Builder(this)
                .setContentTitle(title)
                .setContentText(text)
                .setSmallIcon(R.drawable.ic_notification)
                .setContentIntent(pIntent)
                .setDefaults(Notification.DEFAULT_SOUND|Notification.DEFAULT_LIGHTS|Notification.DEFAULT_VIBRATE)
                .setAutoCancel(true)
                .build();

即使 ic_notification 是透明且白色的。它还必须在 Manifest 元数据中定义,如下所示:

  <meta-data android:name="com.google.firebase.messaging.default_notification_icon"

            android:resource="@drawable/ic_notification" />

元数据在application标签下,供参考。

【讨论】:

  • 非常感谢您提供清单中元数据的提示。
  • 如何放置“@drawable/ic_notification”?它是一个图标吗?许多?是PNG吗?
  • @LukePighetti 如果您要为多种屏幕分辨率上传不同尺寸的图像,它可能会很多。否则,是的,它可能是您的可绘制目录中的一个 PNG 文件。
  • @RuchirBaronia 所以对于上面的例子res/drawable/ic_notification.png 大小为 196x196?
  • 感谢@RuchirBaronia,支持Meta-data 标签建议。
【解决方案3】:

我真的建议关注Google's Design Guidelines:

上面写着“通知图标必须全白。”

【讨论】:

  • 你的回答比我接受的还要好。希望我也能接受你的。我不能,但你有我的 +1 和我的感激之情。干杯!
  • 这不是一个很好的答案。如果项目的利益相关者需要针对 Android 7 怎么办?在此之前,我不能只针对任何 SDK 版本。
  • 否决了这个答案,因为它是错误的。提问者说我无法在 sdk21 上运行我的应用程序。答案是“不要使用 sdk 21”
  • 这真的不是解决办法。
  • 我在当前的设计指南中找不到任何规定图标必须在透明背景上为白色的内容。尽管文档很差,但情况似乎仍然如此。
【解决方案4】:

在 Android Manifest 中声明此代码:

<meta-data android:name="com.google.firebase.messaging.default_notification_icon" 

android:resource="@drawable/ic_stat_name" />

我希望这对你有用。

【讨论】:

  • 天哪!这个非常适合 FCM 推送通知!谢谢
  • 你把ic_stat_name放在哪里?是一个png吗?很多吗?请帮忙!
  • @Luke Pighetti 在 Android Studio 中右键单击应用>>新建>>图像资源>>图标类型(通知)
  • (我知道已经有一段时间了,但是)你能解释一下吗?它应该做什么?它会呈现全彩色不透明图标还是什么?
  • 这是 Firebase 云消息通知的正确答案。
【解决方案5】:

(Android Studio 3.5) 如果您使用的是最新版本的 Android Studio,则可以生成通知图像。 右键单击您的 res 文件夹 > New > Image Asset。然后您将看到配置图像资产,如下图所示。将图标类型更改为通知图标。您的图像必须是白色和透明的。此配置图像资产将强制执行该规则。 重要提示:如果您希望图标用于云/推送通知,您必须在您的应用程序标签下添加元数据才能使用新创建的通知图标。

  <application>
      ...
      <meta-data android:name="com.google.firebase.messaging.default_notification_icon"
          android:resource="@drawable/ic_notification" />

【讨论】:

  • 你绝对是一个救生员。非常感谢你
【解决方案6】:
 <meta-data android:name="com.google.firebase.messaging.default_notification_icon"

        android:resource="@drawable/ic_notification" />

在应用程序块的 manifest.xml 文件中添加这一行。

【讨论】:

    【解决方案7】:

    我们可以这样做:

    创建一个新的通知生成器对象并使用通知生成器对象调用setSmallIcon(),如下面的代码所示。

    创建一个方法,我们将在其中检查我们正在安装我们的应用程序的操作系统版本。如果它低于 Lolipop 即 API 21,那么它将采用带有背景颜色的普通应用程序图标,否则它将采用没有任何背景的透明应用程序图标。因此,使用 os version >= 21 的设备将使用 Notification builder 类的方法 setColor() 设置图标的背景颜色。

    示例代码:

    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
    
    notificationBuilder.setSmallIcon(getNotificationIcon(notificationBuilder));
    
    private int getNotificationIcon(NotificationCompat.Builder notificationBuilder) {
    
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                 int color = 0x008000;
                 notificationBuilder.setColor(color);
                 return R.drawable.app_icon_lolipop_above;
    
        } 
        return R.drawable.app_icon_lolipop_below;
    }
    

    【讨论】:

    • 我在 Kitkat (API 19) 和 IceCreamSandwich (API 15) 上测试了 setColor,在这两种情况下它都忽略了颜色,但没有崩溃。那么我可以安全地省略检查操作系统版本吗?
    【解决方案8】:

    试试这个

    我遇到了同样的问题,我尝试了很多答案,但没有得到任何解决方案,最后我找到了解决问题的方法。

    - 制作具有透明背景的通知图标。应用程序的宽度和高度必须如下图所示,并将所有这些粘贴到您的项目->应用程序->src->main->res

    • MDPI 24*24

    • HDPI 36*36

    • XHDPI 48*48

    • XXHDPI 72*72


    在您的 onMessageReceived 方法中粘贴以下行


    Intent intent = new Intent(this, News.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                        PendingIntent.FLAG_ONE_SHOT);
                Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
                NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
                if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
                {
                    notificationBuilder.setSmallIcon(R.drawable.notify)
                                          //            .setContentTitle(title)
                                //                        .setContentText(message)
                            .setAutoCancel(true)
                            .setSound(defaultSoundUri)
                            .setContentIntent(pendingIntent);
                } else
                    {
                        notificationBuilder.setSmallIcon(R.drawable.notify)
                           //                                .setContentTitle(title)
                            //                        .setContentText(message)
                                .setAutoCancel(true)
                                .setSound(defaultSoundUri)
                                .setContentIntent(pendingIntent);
                }
                NotificationManager notificationManager =
                        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                notificationManager.notify(0, notificationBuilder.build());
    

    不要忘记在清单文件中添加此代码

    <meta-data 
    android:name="com.google.firebase.messaging.default_notification_icon" 
    android:resource="@drawable/app_icon" />
    

    【讨论】:

      【解决方案9】:

      我已通过将以下代码添加到清单来解决问题,

          <meta-data
              android:name="com.google.firebase.messaging.default_notification_icon"
              android:resource="@drawable/ic_stat_name" />
      
          <meta-data
              android:name="com.google.firebase.messaging.default_notification_color"
              android:resource="@color/black" />
      

      其中ic_stat_name在Android Studio上创建右键res >> New >>Image Assets >> IconType(Notification)

      我必须在服务器 php 端使用通知有效负载再做一步

      $message = [
          "message" => [
              "notification" => [
                  "body"  => $title , 
                  "title" => $message
              ],
      
              "token" => $token,
      
          "android" => [
                 "notification" => [
                  "sound"  => "default",
                  "icon"  => "ic_stat_name"
                  ]
              ],
      
             "data" => [
                  "title" => $title,
                  "message" => $message
               ]
      
      
          ]
      ];
      

      注意部分

          "android" => [
                 "notification" => [
                  "sound"  => "default",
                  "icon"  => "ic_stat_name"
                  ]
              ]
      

      图标名称为"icon" =&gt; "ic_stat_name" 的位置应与清单上的设置相同。

      【讨论】:

        【解决方案10】:

        如果您想提供棒棒糖支持通知图标,请制作两种通知图标:

        1. 正常通知图标:适用于以下棒棒糖版本。
        2. 带有透明背景的通知图标:棒棒糖及以上版本。

        现在在运行时根据操作系统版本为通知生成器设置适当的图标:

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mBuilder.setSmallIcon(R.drawable.ic_push_notification_transperent);
        } else {
            mBuilder.setSmallIcon(R.drawable.ic_push_notification);
        }
        

        【讨论】:

          【解决方案11】:

          我终于找到了解决这个问题的办法。

          仅当应用程序完全未运行时才会出现此问题。 (既不在后台也不在前台)。当应用在前台或后台运行时,通知图标会正确显示。(不是白色方块)

          所以我们要在后端 API 中设置与前端相同的通知图标配置。

          在前端,我们使用了 React Native,对于推送通知,我们使用了react-native-fcm npm package

          FCM.on("notification", notif => {
             FCM.presentLocalNotification({
                 body: notif.fcm.body,
                 title: notif.fcm.title,
                 big_text: notif.fcm.body,
                 priority: "high",
                 large_icon: "notification_icon", // notification icon
                 icon: "notification_icon",
                 show_in_foreground: true,
                 color: '#8bc34b',
                 vibrate: 300,
                 lights: true,
                 status: notif.status
             });
          });
          

          我们使用fcm-push npm package 使用 Node.js 作为推送通知的后端,并将有效负载结构设置如下。

          {
            to: '/topics/user', // required
            data: {
              id:212,
              message: 'test message',
              title: 'test title'
            },
            notification: {
              title: 'test title',
              body: 'test message',
              icon : 'notification_icon', // same name as mentioned in the front end
              color : '#8bc34b',
              click_action : "BROADCAST"
            }
          }
          

          它主要搜索我们Android系统本地存储的notification_icon图像。

          【讨论】:

          • 你的问题和我的很不一样,虽然效果一样。感谢您发布此答案,它可能会帮助使用您正在使用的相同技术堆栈的人。
          • @IanWarburton:不需要。
          【解决方案12】:

          通知是灰度,如下所述。尽管其他人已经写过,但它们并不是非黑即白的。您可能见过带有多种阴影的图标,例如网络强度条。

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

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

          Alpha 值如何生成灰度图像:

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

          改用setColor:

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

            标准样式模板在呈现此通知时应用的强调色(一个 ARGB 整数,类似于 Color 中的常量)。当前的模板设计通过在此颜色的字段顶部覆盖图标图像(以白色印刷)来构建彩色标题图像。 Alpha 分量被忽略。

            我对 setColor 的测试表明 Alpha 组件没有被忽略。较高的 Alpha 值会将像素变为白色。较低的 Alpha 值将像素转换为通知区域中的背景颜色(我的设备上为黑色),或下拉通知中的指定颜色。

          【讨论】:

            【解决方案13】:

            解决此问题的要求:

            1. 图像格式:32 位 PNG(带 alpha)

            2. 图像应该是透明的

            3. 透明色指数:白色 (FFFFFF)

            来源:http://gr1350.blogspot.com/2017/01/problem-with-setsmallicon.html

            【讨论】:

              【解决方案14】:

              我找到了一个链接,我们可以在其中生成我们自己的白色图标,

              尝试使用此链接生成启动器图标的白色图标。

              打开此Link 并上传您的 ic_launcher 或通知图标

              【讨论】:

                【解决方案15】:

                对于自定义的本地通知,在 AndroidManifest.xml 中添加以下元数据即可。

                 <application
                    android:name="xxxxxx"
                        android:label="xxxxxx"
                        android:icon="@mipmap/ic_launcher"
                        
                        >
                
                       <meta-data
                                android:name="your_apps_bundle_id.default_notification_icon"
                                android:resource="@drawable/ic_notif" />
                
                ......
                

                【讨论】:

                  【解决方案16】:

                  我在 android 8.0 上有类似的问题。尝试使用白色图标资源。当我尝试使用彩色图像作为图标时,我有白色方块,当我将其替换为白色图标时,它就开始工作了。

                  【讨论】:

                    【解决方案17】:

                    您可以为不同的版本使用不同的图标。只需像这样在您的图标上设置逻辑:

                    int icon = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? R.drawable.colored_: R.drawable.white_tint_icon_for_lolipop_or_upper;
                    

                    【讨论】:

                      【解决方案18】:

                      对于 SDK >= 23,请添加 setLargeIcon

                      notification = new Notification.Builder(this)
                                  .setSmallIcon(R.drawable.ic_launcher)
                                  .setLargeIcon(context.getResources(), R.drawable.lg_logo))
                                  .setContentTitle(title)
                                  .setStyle(new Notification.BigTextStyle().bigText(msg))
                                  .setAutoCancel(true)
                                  .setContentText(msg)
                                  .setContentIntent(contentIntent)
                                  .setSound(sound)
                                  .build();
                      

                      【讨论】:

                        【解决方案19】:

                        当您想要保留彩色图标时 - 解决方法
                        将颜色稍有不同的像素添加到图标中。
                        在我的例子中,一个带有阴影和光线的黑色图标。当添加深蓝色像素时,它可以工作。

                        【讨论】:

                          【解决方案20】:

                          要减少 SDK 特定版本,您可以这样做:(将“#”替换为“0x”)

                          Notification notification = new NotificationCompat.Builder(this);
                          notification.setSmallIcon(R.drawable.icon_transperent);
                          notification.setColor(0x169AB9); //for color: #169AB9
                          

                          【讨论】:

                          • 0xFF169AB9,您缺少完全不透明的 Alpha 通道。
                          【解决方案21】:

                          我只是将我的png转换为透明png,然后图标与图片的形状相同,但颜色不同

                          【讨论】: