简体   繁体   English

大图标位图在通知中显示为白色方块?

[英]Large Icon Bitmap appears as white square in notification?

I am having this problem where I generate a Bitmap from a URL that I use in my notification. 我有这个问题,我从我在通知中使用的URL生成一个Bitmap However, on my phone, the Bitmap shows up like a small white square. 但是,在我的手机上, Bitmap显示为一个小的白色方块。 I looked into it and found many posts like so talking about it: Icon not displaying in notification: white square shown instead 我调查了一下,发现很多帖子就像这样谈论它: 图标没有显示在通知中:显示的是白色方块

and I know for sure my Small Icon for the notification indeed is transparent. 我确信我的Small Icon通知确实是透明的。 However, for the Large Icon , I realize that the Large Icon cannot be transparent because it is actually a Bitmap that I generate from a URL. 但是,对于Large Icon ,我意识到Large Icon不能透明,因为它实际上是我从URL生成的Bitmap How can I get around this then and make sure that the image renders properly instead of having the Large Icon show up as a white square? 我如何解决这个问题并确保图像正确呈现而不是让Large Icon显示为白色方块? Here is my attempt: 这是我的尝试:

NotificationService.java: NotificationService.java:

    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
            .setContentTitle(getString(R.string.app_name))
            .setContentText(remoteMessage.getNotification().getBody())
            .setTicker(remoteMessage.getFrom() + " has responded!")
            .setLargeIcon(AndroidUtils.getBitmapFromURL(remoteMessage.getNotification().getIcon()))
            .setAutoCancel(true)
            .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
            .setStyle(new NotificationCompat.BigTextStyle().bigText(remoteMessage.getNotification().getBody()))
            .setSmallIcon(R.drawable.ic_tabs_notification_transparent);

AndroidUtils.java: AndroidUtils.java:

public static Bitmap getBitmapFromURL(String userId) {
        try {
            URL imgUrl = new URL("https://graph.facebook.com/" + userId + "/picture?type=large");
            InputStream in = (InputStream) imgUrl.getContent();
            Bitmap  bitmap = BitmapFactory.decodeStream(in);
            Bitmap output;
            Rect srcRect;
            if (bitmap.getWidth() > bitmap.getHeight()) {
                output = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
                srcRect = new Rect((bitmap.getWidth()-bitmap.getHeight())/2, 0, bitmap.getWidth()+(bitmap.getWidth()-bitmap.getHeight())/2, bitmap.getHeight());
            } else {
                output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getWidth(), Bitmap.Config.ARGB_8888);
                srcRect = new Rect(0, (bitmap.getHeight()-bitmap.getWidth())/2, bitmap.getWidth(), bitmap.getHeight()+(bitmap.getHeight()-bitmap.getWidth())/2);
            }

            Canvas canvas = new Canvas(output);

            final int color = 0xff424242;
            final Paint paint = new Paint();
            final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());

            float r;

            if (bitmap.getWidth() > bitmap.getHeight()) {
                r = bitmap.getHeight() / 2;
            } else {
                r = bitmap.getWidth() / 2;
            }

            paint.setAntiAlias(true);
            canvas.drawARGB(0, 0, 0, 0);
            paint.setColor(color);
            canvas.drawCircle(r, r, r, paint);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
            canvas.drawBitmap(bitmap, srcRect, rect, paint);
            return output;
        } catch (IOException e) {
            FirebaseCrash.report(e);
            return null;
        }

Image showing my problem: 图像显示我的问题:

在此输入图像描述

EDIT: Build.gradle file showing: 编辑:Build.gradle文件显示:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
    defaultConfig {
        applicationId '<ID>'
        multiDexEnabled true
        minSdkVersion 21
        targetSdkVersion 23
        versionCode 12
        versionName ".12"
        signingConfig signingConfigs.Tabs
    }
    buildTypes {
        release {
            minifyEnabled false
            shrinkResources false
            zipAlignEnabled true
            debuggable false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.Tabs
        }
        debug {
            applicationIdSuffix ".debug"
            debuggable true
            minifyEnabled false
            signingConfig signingConfigs.Tabs
        }
    }
    //DatabaseReference stuff
    packagingOptions {
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE-FIREBASE.txt'
        exclude 'META-INF/NOTICE'
    }
    dexOptions {
        javaMaxHeapSize "4g"
    }
    productFlavors {
    }
}
try {
            NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
            mBuilder.setSmallIcon(getNotificationIcon());
            Bitmap icon = BitmapFactory.decodeResource(CXGcmListenerService.this.getResources(), R.drawable.ic_launcher);
            mBuilder.setLargeIcon(icon);
            //Define sound URI
            Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            mBuilder.setContentIntent(pendingIntent);
            mBuilder.setContentText(msg);
            mBuilder.setStyle(new NotificationCompat.BigTextStyle()
                    .bigText(msg));
            mBuilder.setContentTitle(getString(R.string.app_name));
            mBuilder.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
            mBuilder.setAutoCancel(true);
            mBuilder.setSound(soundUri); //This sets the sound to play
            Intent intent = new Intent(CXGcmListenerService.this, CXMainActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            PendingIntent notificationIntent = PendingIntent.getActivity(this, 0, intent, 0);
            mBuilder.setContentIntent(notificationIntent);

            NotificationManager notifyManager = (NotificationManager) CXGcmListenerService.this.getSystemService(Context.NOTIFICATION_SERVICE);
            NOTIFICATION_ID++;
            notifyManager.notify("" + System.currentTimeMillis(), NOTIFICATION_ID, mBuilder.build());
        } catch (Resources.NotFoundException e) {
            CXLog.e(TAG, "" + e.getLocalizedMessage(), e);
        }

Please try this to get the icon in the notification. 请尝试此操作以获取通知中的图标。

您可以为不同的版本使用不同的图标:

int bigIcon = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? R.drawable.logo_who_is_not_white: R.drawable.logo_who_is_in_whit_tint;

I think you have been downloading the image from an URL right?. 我想你一直在从URL下载图片吗? So, please place an Asynctask to download the image from the url and then use the notification builder to show the notification as like this SO post: https://stackoverflow.com/a/24866080/6452886 所以,请放置一个Asynctask从URL下载图像,然后使用通知构建器显示通知,如下所示SO帖子: https//stackoverflow.com/a/24866080/6452886

Lilipop have this problem exists, You just look at other phone prior to Lolipop that have no problem. Lilipop存在这个问题,你只需看看Lolipop之前的其他手机就没问题了。

please refer these following links 请参考以下链接

https://material.google.com/style/icons.html https://material.google.com/style/icons.html

https://developer.android.com/about/versions/android-5.0-changes.html https://developer.android.com/about/versions/android-5.0-changes.html

otherwise you can change the compiled SDK 否则你可以改变已编译的SDK

There is a change in the notification for Lollipop and later on android API levels. Lollipop及后来的Android API级别的通知发生了变化。 To override this problem you can follow these ways: 要覆盖此问题,您可以按照以下方式:

Way1: Either change you targetSdkVersion from 23 to 19 in build.gradle of your app module. 方式1:在app模块的build.gradle中将targetSdkVersion从23更改为19。 This will solve the problem for that. 这将解决问题。

Note: Maybe this solution will create issue in your build system(I prefer you should not go with this way, but you can check your issue with this way) 注意:也许这个解决方案会在你的构建系统中产生问题(我更喜欢你不应该这样,但你可以用这种方式检查你的问题)

Way2: Change your notification icon with a black and white icon. 方式2:使用黑白图标更改通知图标。 Because notification builder doesn't support color icons from lollipop API level. 因为通知构建器不支持棒棒糖API级别的颜色图标。

Way to get black and white icon in Android Studio: 在Android Studio中获取黑白图标的方法:

  1. Right-Click Drawable folder > Add image asset (any resource folder should do) 右键单击Drawable文件夹>添加图像资源(任何资源文件夹应该执行) 在此输入图像描述

  2. Click on Notification Icon from the top drop-down list (default is Launcher Icon) 单击顶部下拉列表中的通知图标(默认为启动器图标) 在此输入图像描述

  3. Select Image > Browse to image> click ok 选择图像>浏览到图像>单击确定 在此输入图像描述

this is normal since the Lollipop SDK (API 21 - Ver 5.0.1) only allows this type of color scheme 这是正常的,因为Lollipop SDK(API 21 - Ver 5.0.1)仅允许这种类型的配色方案

Or you can generate from here: http://romannurik.github.io/AndroidAssetStudio/icons-notification.html 或者你可以从这里生成: http//romannurik.github.io/AndroidAssetStudio/icons-notification.html

I think the problem is with image size, Status bar icons size follows as below - 我认为问题在于图像大小,状态栏图标大小如下 -

ldpi - 18 x 18 px
mdpi - 24 x 24 px
hdpi - 36 x 36 px
xhdpi - 48 x 48 px

you can also take a look at this developer doc 您还可以查看此开发人员文档

you need to change dimension of received bitmap to above mentioned sizes and it should work. 您需要将接收到的位图的尺寸更改为上述尺寸,它应该可以工作。

Well its because google has changed notification style in API 21+, and recommend to use white notification icon 好吧,因为谷歌已经改变了API 21+的通知风格,并建​​议使用白色通知图标

Though you can use silhouette icon on 21+ and older icon on all other devices, Something like below 虽然您可以在所有其他设备上使用21+及更旧图标上的剪影图标,如下所示

private int getNotificationIcon() {
    boolean icon = (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP);
    return icon ? R.drawable.silhouette : R.drawable.ic_launcher;
}

and here is the actual notification builder code: 这是实际的通知构建器代码:

Notification builder = new Notification.Builder(context)
        .setSmallIcon(getNotificationIcon())
        .build();

Per the setColor() documentation 根据setColor()文档

Parameters 参数

argb -The accent color to use

You are passing in 2, which is not a valid ARGB color, hence why the background color of your small icon does not appear correctly. 您传入2,这不是有效的ARGB颜色,因此您的小图标的背景颜色无法正确显示。 Instead, choose a valid ARGB color. 而是选择有效的ARGB颜色。

If you have a color resource you'd like to use, you can use code such as 如果您有想要使用的颜色资源,可以使用如下代码

.setColor(context.getResources().getColor(R.color.notification_color))

In addition, note the Android 5.0 changes state: 另外,请注意Android 5.0更改状态:

Update or remove assets that involve color. 更新或删除涉及颜色的资产。 The system ignores all non-alpha channels in action icons and in the main notification icon. 系统会忽略操作图标和主通知图标中的所有非Alpha通道。 You should assume that these icons will be alpha-only. 您应该假设这些图标仅为alpha。 The system draws notification icons in white and action icons in dark gray. 系统以白色绘制通知图标,以深灰色绘制动作图标。

Your small icon should be entirely white and transparent - you can use tools such as the Notification Icon Generator to generate an appropriate icon. 您的小图标应该是完全白色和透明的 - 您可以使用通知图标生成器等工具生成适当的图标。

or you can try this : 或者你可以尝试这个:

int icon = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? R.drawable.your_logo_for_Kitkat : R.mipmap.your_logo_for_Lolipop_and_uper_version;
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
            .setSmallIcon(icon)
            .setContentTitle(remoteMessage.getData().get("title"))
            .setContentText(remoteMessage.getData().get("shortDescription"))
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setColor(Color.RED)
            .setStyle(notiStyle)
            .setContentIntent(pendingIntent);

For Url image Load: 对于Url图像加载:

 private class sendNotification extends AsyncTask<String, Void, Bitmap> {

        Context ctx;
        String message;

        public sendNotification(Context context) {
            super();
            this.ctx = context;
        }

        @Override
        protected Bitmap doInBackground(String... params) {

            InputStream in;
            message = params[0] + params[1];
            try {

 URL url = new URL(params[2]);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoInput(true);
        connection.connect();
        in = connection.getInputStream();
        Bitmap myBitmap = BitmapFactory.decodeStream(in);
        return myBitmap;




            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Bitmap result) {

            super.onPostExecute(result);
            try {
                NotificationManager notificationManager = (NotificationManager) ctx
                        .getSystemService(Context.NOTIFICATION_SERVICE);

                Intent intent = new Intent(ctx, NotificationsActivity.class);
                intent.putExtra("isFromBadge", false);


                Notification notification = new Notification.Builder(ctx)
                        .setContentTitle(
                                ctx.getResources().getString(R.string.app_name))
                        .setContentText(message)
                        .setSmallIcon(R.drawable.ic_launcher)
                        .setLargeIcon(result).build();

                // hide the notification after its selected
                notification.flags |= Notification.FLAG_AUTO_CANCEL;

                notificationManager.notify(1, notification);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

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

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