简体   繁体   English

Android 推送通知:通知中未显示图标,而是显示白色方块

[英]Android Push Notifications: Icon not displaying in notification, white square shown instead

My app generates a notification, but the icon I set for that notification is not being displayed.我的应用程序生成通知,但我为该通知设置的图标没有显示。 Instead, I get a white square.相反,我得到一个白色方块。

I have tried resizing the png of the icon (dimensions 720x720, 66x66, 44x44, 22x22).我尝试调整图标的 png 大小(尺寸 720x720、66x66、44x44、22x22)。 Curiously, when using smaller dimensions the white square is smaller.奇怪的是,当使用较小的尺寸时,白色方块会更小。

I have googled this problem, as well as the correct way of generating notifications, and from what I've read my code should be correct.我已经用谷歌搜索了这个问题,以及生成通知的正确方法,从我读过的内容来看,我的代码应该是正确的。 Sadly things are not as they should be.可悲的是,事情并非如此。

My phone is a Nexus 5 with Android 5.1.1.我的手机是带有 Android 5.1.1 的 Nexus 5。 The problem is also present on emulators, a Samsung Galaxy s4 with Android 5.0.1 and a Motorola Moto G with Android 5.0.1 (both of which I borrowed, and don't have right now)模拟器上也存在问题,三星 Galaxy s4 的 Android 5.0.1 和摩托罗拉 Moto G 的 Android 5.0.1(我都借了,现在没有)

The code for notifications follows, and two screenshots.通知代码如下,以及两个屏幕截图。 If you require more information, please feel free to ask for it.如果您需要更多信息,请随时询问。

Thank you all.谢谢你们。

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

不打开通知打开的通知

Cause: For 5.0 Lollipop "Notification icons must be entirely white".原因:对于 5.0 Lollipop,“通知图标必须全白”。

If we solve the white icon problem by setting target SDK to 20, our app will not target Android Lollipop, which means that we cannot use Lollipop-specific features.如果我们通过将 target SDK 设置为 20 来解决白色图标问题,我们的应用将不会以 Android Lollipop 为目标,这意味着我们无法使用 Lollipop 特定的功能。

Solution for target Sdk 21目标 SDK 21 的解决方案

If you want to support Lollipop Material Icons, then make transparent icons for Lollipop and the above version.如果要支持 Lollipop Material Icons,请为 Lollipop 及以上版本制作透明图标。 Please refer to the following: https://design.google.com/icons/请参考以下内容: https ://design.google.com/icons/

Please look at http://developer.android.com/design/style/iconography.html , and we'll see that the white style is how notifications are meant to be displayed in Android Lollipop.请查看http://developer.android.com/design/style/iconography.html ,我们将看到白色样式是通知在 Android Lollipop 中的显示方式。

In Lollipop, Google also suggests that we use a color that will be displayed behind the white notification icon.在 Lollipop 中,Google 还建议我们使用一种将显示在白色通知图标后面的颜色。 Refer to the link: https://developer.android.com/about/versions/android-5.0-changes.html参考链接: https ://developer.android.com/about/versions/android-5.0-changes.html

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

Implementation of Notification Builder for below and above Lollipop OS version would be:低于和高于 Lollipop OS 版本的 Notification Builder 的实现将是:

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

Note: setColor is only available in Lollipop and it only affects the background of the icon.注意: setColor 仅在 Lollipop 中可用,它只影响图标的背景。

It will solve your problem completely!!彻底解决你的问题!!

If you are using Google Cloud Messaging, then this issue will not be solved by simply changing your icon.如果您使用的是 Google Cloud Messaging,则仅通过更改图标无法解决此问题。 For example, this will not work:例如,这将不起作用:

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

Even if ic_notification is transparant and white.即使ic_notification 是透明的和白色的。 It must be also defined in the Manifest meta data, like so:它还必须在 Manifest 元数据中定义,如下所示:

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

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

Meta-data goes under the application tag, for reference.元数据位于application标签下,以供参考。

I really suggest following Google's Design Guidelines :我真的建议遵循Google 的设计指南

which says "Notification icons must be entirely white."上面写着“通知图标必须全白”。

Declare this code in Android Manifest:在 Android Manifest 中声明此代码:

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

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

(Android Studio 3.5) If you're using a recent version of Android Studio, you can generate your notification images. (Android Studio 3.5)如果您使用的是最新版本的 Android Studio,您可以生成通知图像。 Right-click on your res folder > New > Image Asset .右键单击您的 res 文件夹> New > Image Asset You will then see Configure Image Assets as shown in the image below.然后,您将看到配置图像资产,如下图所示。 Change Icon Type to Notification Icons .图标类型更改为通知图标 Your images must be white and transparent.您的图像必须是白色和透明的。 This Configure Image Assets will enforce that rule.配置图像资产将强制执行该规则。 配置图像资产 Important: If you want the icons to be used for cloud/push notifications, you must add the meta-data under your application tag to use the newly created notification icons.重要提示:如果您希望图标用于云/推送通知,则必须在应用程序标签下添加元数据才能使用新创建的通知图标。

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

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

Add this line in the manifest.xml file in the application block.在应用程序块的 manifest.xml 文件中添加这一行。

Try this尝试这个

i was facing same issue i tried lot of anwers but didn't get any solutions,finally i found the way to solve my problem.我遇到了同样的问题,我尝试了很多答案,但没有得到任何解决方案,最后我找到了解决问题的方法。

- make notification icon with transparent background .The app's width and height must be like below sizes and paste all these in your project->app->src->main->res - 制作具有透明背景的通知图标。应用程序的宽度和高度必须如下所示,并将所有这些粘贴到您的项目->应用程序->src->main->res

  • MDPI 24*24 MDPI 24*24

  • HDPI 36*36 HDPI 36*36

  • XHDPI 48*48 XHDPI 48*48

  • XXHDPI 72*72 XXHDPI 72*72


after the above paste this below line in your onMessageReceived method在上面粘贴下面这一行之后你的 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());

Don't forget to add this code in manifest file不要忘记在清单文件中添加此代码

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

We can do like below:我们可以这样做:

Create a new object of notification builder and call setSmallIcon() using notification builder object like in below code.创建通知构建器的新对象并使用通知构建器对象调用setSmallIcon() ,如下面的代码所示。

Create a method in which we will check on which OS version we are installing our app .创建一个方法,我们将在其中检查我们正在安装我们的应用程序的操作系统版本。 If it is below Lolipop ie API 21 then it will take the normal app icon with background color else it will take the transparent app icon without any background.如果它低于 Lolipop 即 API 21,那么它将采用带有背景颜色的普通应用程序图标,否则它将采用没有任何背景的透明应用程序图标。 So the devices using os version >= 21 will set the background color of icon using method setColor() of Notification builder class.因此,使用 os version >= 21 的设备将使用 Notification builder 类的setColor()方法设置图标的背景颜色。

Sample Code:示例代码:

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

I have resolved the problem by adding below code to manifest,我已经通过将以下代码添加到清单来解决问题,

    <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" />

where ic_stat_name created on Android Studio Right Click on res >> New >>Image Assets >> IconType(Notification)其中ic_stat_name在 Android Studio 上创建 右键单击​​ res >> New >>Image Assets >> IconType(Notification)

And one more step I have to do on server php side with notification payload我必须在服务器 php 端使用通知有效负载再做一步

$message = [
    "message" => [
        "notification" => [
            "body"  => $title , 
            "title" => $message
        ],

        "token" => $token,

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

       "data" => [
            "title" => $title,
            "message" => $message
         ]


    ]
];

Note the section注意部分

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

where icon name is "icon" => "ic_stat_name" should be the same set on manifest.其中图标名称为"icon" => "ic_stat_name"应该与清单上的设置相同。

If you wan to provide lollipop support notification icon then make two type notification icon :如果您想提供棒棒糖支持通知图标,请制作两种类型的通知图标:

  1. normal notification icon : for below lollipop version.正常通知图标:适用于以下棒棒糖版本。
  2. notification icon with transparent background : for lollipop and above version.带有透明背景的通知图标:棒棒糖及以上版本。

Now set appropriate icon to notification builder at run time base on OS version :现在根据操作系统版本在运行时为通知生成器设置适当的图标:

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

Finally I've got the solution for this issue.最后我得到了这个问题的解决方案。

This issue occurs only when the app is not at all running.仅当应用程序根本未运行时才会出现此问题。 (neither in the background nor in the foreground) . (既不在后台也不在前台) When the app runs on either foreground or background the notification icon is displayed properly .(not the white square)应用程序在前台或后台运行时,通知图标会正确显示。(不是白色方块)

So what we've to set is the same configuration for notification icon in Backend APIs as that of Frontend.所以我们要设置的是后端API中通知图标的配置与前端相同。

In the frontend we've used React Native and for push notification we've used react-native-fcm npm package .在前端,我们使用了React Native ,对于推送通知,我们使用了react-native-fcm npm 包

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

We've used fcm-push npm package using Node.js as a backend for push notification and set the payload structure as follows.我们使用使用Node.jsfcm-push npm 包作为推送通知的后端,并将有效负载结构设置如下。

{
  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"
  }
}

What it basically searches for the notification_icon image stored locally in our Android system.它基本上搜索存储在我们的Android系统中本地的notification_icon图像。

Notifications are greyscale as explained below.通知是灰度的,如下所述。 They are not black-and-white, despite what others have written.尽管其他人已经写过,但它们并不是非黑即白的。 You have probably seen icons with multiple shades, like network strength bars.您可能已经看到具有多种阴影的图标,例如网络强度条。

Prior to API 21 (Lollipop 5.0), colour icons work.在 API 21 (Lollipop 5.0) 之前,彩色图标有效。 You could force your application to target API 20, but that limits the features available to your application, so it is not recommended.您可以强制您的应用程序以 API 20 为目标,但这会限制您的应用程序可用的功能,因此不建议这样做。 You could test the running API level and set either a colour icon or a greyscale icon appropriately, but this is likely not worthwhile.您可以测试正在运行的 API 级别并适当地设置彩色图标或灰度图标,但这可能不值得。 In most cases, it is best to go with a greyscale icon.在大多数情况下,最好使用灰度图标。

Images have four channels, RGBA (red / green / blue / alpha).图像有四个通道,RGBA(红/绿/蓝/alpha)。 For notification icons, Android ignores the R, G, and B channels.对于通知图标,Android 会忽略 R、G 和 B 通道。 The only channel that counts is Alpha, also known as opacity.唯一重要的通道是 Alpha,也称为不透明度。 Design your icon with an editor that gives you control over the Alpha value of your drawing colours.使用可让您控制绘图颜色的 Alpha 值的编辑器设计您的图标。

How Alpha values generate a greyscale image: Alpha 值如何生成灰度图像:

  • Alpha = 0 (transparent) — These pixels are transparent, showing the background colour. Alpha = 0(透明)- 这些像素是透明的,显示背景颜色。
  • Alpha = 255 (opaque) — These pixels are white. Alpha = 255(不透明)——这些像素是白色的。
  • Alpha = 1 ... 254 — These pixels are exactly what you would expect, providing the shades between transparent and white. Alpha = 1 ... 254 — 这些像素正是您所期望的,提供透明和白色之间的阴影。

Changing it up with setColor :setColor改变它:

  • Call NotificationCompat.Builder.setColor(int argb) .调用NotificationCompat.Builder.setColor(int argb) From the documentation for Notification.color :Notification.color的文档中:

    Accent color (an ARGB integer like the constants in Color) to be applied by the standard Style templates when presenting this notification.标准样式模板在呈现此通知时应用的强调色(一个 ARGB 整数,如 Color 中的常量)。 The current template design constructs a colorful header image by overlaying the icon image (stenciled in white) atop a field of this color.当前的模板设计通过在此颜色的字段顶部覆盖图标图像(以白色印刷)来构建彩色标题图像。 Alpha components are ignored. Alpha 分量被忽略。

    My testing with setColor shows that Alpha components are not ignored.我对 setColor 的测试表明 Alpha 组件未被忽略。 Higher Alpha values turn a pixel white.较高的 Alpha 值会将像素变为白色。 Lower Alpha values turn a pixel to the background colour (black on my device) in the notification area, or to the specified colour in the pull-down notification.较低的 Alpha 值将像素转换为通知区域中的背景颜色(我的设备上为黑色),或下拉通知中的指定颜色。

Requirements to fix this issue:解决此问题的要求:

  1. Image Format: 32-bit PNG (with alpha)图像格式:32 位 PNG(带 alpha)

  2. Image should be Transparent图像应该是透明的

  3. Transparency Color Index: White (FFFFFF)透明色指数:白色 (FFFFFF)

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

I found a link where we can generate our own white icon,我找到了一个链接,我们可以在其中生成我们自己的白色图标,

try this link to generate white icon of your launcher icon.尝试此链接以生成启动器图标的白色图标。

Open this Link and upload your ic_launcher or notification icon打开此链接并上传您的 ic_launcher 或通知图标

for customized local notification, in AndroidManifest.xml add following meta-data then it will work.对于自定义的本地通知,在 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" />

......

I have similar issue on android 8.0.我在 android 8.0 上有类似的问题。 Try to use WHITE icon resource.尝试使用白色图标资源。 I have white square when i'm trying to use colored image for icon, when i replace it to white icon, it's start work.当我尝试使用彩色图像作为图标时,我有白色方块,当我将它替换为白色图标时,它就开始工作了。

You can use different icon for different versions.您可以为不同的版本使用不同的图标。 Simply set logic on your icon like this:只需在您的图标上设置逻辑,如下所示:

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

For SDK >= 23, please add setLargeIcon对于 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();

When you want keep colorful icon - Workaround当您想要保留彩色图标时 - 解决方法
Add pixel with slightly different color into icon.将颜色略有不同的像素添加到图标中。
In my case a have black icon with shades and light.在我的情况下,一个带有阴影和光线的黑色图标。 When added dark blue pixel it works.当添加深蓝色像素时,它可以工作。

To reduce SDK specific versions, you could simply do this: (replace '#' to '0x')要减少 SDK 特定版本,您可以简单地执行以下操作:(将 '#' 替换为 '0x')

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

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

remove the background of the icon using any of the website, suggested one is https://www.remove.bg/ and then simply use that image after downloading and your problem will be solved.使用任何网站删除图标的背景,建议一个是https://www.remove.bg/然后只需在下载后使用该图像即可解决您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM