简体   繁体   中英

BigTextStyle in NotificationCompat cause graphical bug

I have a Notification, that supports a private and a public version. The private version is shown as bigTextStyle. The icon for both versions is generated as LayerDrawable which is then converted to a bitmap. This works nice on all devices. Except on one Huawei Ascent Mate 7 that was forged in hell. (Android 4.4.2, EMUI 3.0)

In the not expanded Version it looks as it should. Round circle, fitting icon. 在此输入图像描述

But in the expanded version, it looks as if it was cut out of a scaled version of the icon. 在此输入图像描述

For the icon I do following:

        Drawable background = ContextCompat.getDrawable(this, R.drawable.shape_notification_circle);
        if (background != null) {
            PorterDuffColorFilter filter = new PorterDuffColorFilter(ThemeManager.getInstance().getTheme()
                    .getColorMainDark(), PorterDuff.Mode.SRC_ATOP);
            background.setColorFilter(filter);
        }

        Drawable[] layers = {background, ContextCompat.getDrawable(this, icon)};
        //icon is an int, containing the resource id
        LayerDrawable layerDrawable = new LayerDrawable(layers);

        int padding = dpToPx(24);

        layerDrawable.setLayerInset(1, padding, padding, padding, padding);

        Bitmap iconBitmap = drawableToBitmap(layerDrawable);

the method drawableToBitmap:

public static Bitmap drawableToBitmap(Drawable drawable) {
        Bitmap bitmap;

        if (drawable instanceof BitmapDrawable) {
            BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
            if (bitmapDrawable.getBitmap() != null) {
                return bitmapDrawable.getBitmap();
            }
        }

        if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
            bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of
            // 1x1 pixel
        } else {
            bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config
                    .ARGB_8888);
        }

        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);
        return bitmap;
    }

The Layout of shape_notification_circle

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="oval">

    <solid android:color="#666666"/>

    <size
        android:width="48dp"
        android:height="48dp"/>
</shape>

The icon drawable:

<?xml version="1.0" encoding="UTF-8"?>
<vector android:height="48dp"
        android:viewportHeight="1000.0"
        android:viewportWidth="1000.0"
        android:width="48dp"
        xmlns:android="http://schemas.android.com/apk/res/android">
    <path
        android:fillColor="#FFFFFF"
        android:pathData="M500,609.8l-75.20001,-72.79999l-299.69998,252.79999l749.80005,0l-299.7,-252.79999z"/>
    <path
        android:fillColor="#FFFFFF"
        android:pathData="M122.6,210.2l377.4,365l377.40002,-365z"/>
    <path
        android:fillColor="#FFFFFF"
        android:pathData="M406.3,519.7l-300.9,-292.2l0,546.3z"/>
    <path
        android:fillColor="#FFFFFF"
        android:pathData="M894.6,773.8l0,-546.3l-300.89996,292.2z"/>
</vector>

And finally, the creation of the notification. (notificationBuilder and notificationBuilderPublic used to be different, but are now same, except for the different bigTextStyle)

// @formatter:off
            NotificationCompat.Builder notificationBuilderPublic = new NotificationCompat.Builder(this)
                    .setLargeIcon(iconBitmap)
                    .setSmallIcon(R.drawable.ic_notification_launcher)
                    .setColor(ThemeManager.getInstance().getTheme().getColorAccent())
                    .setDefaults(Notification.DEFAULT_ALL)
                    .setContentTitle(getString(R.string.app_name))
                    .setContentText(title)
                    .setAutoCancel(true)
                    .setContentIntent(pendingIntent)
                    .setCategory(category)
                    .setPriority(priority)
                    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                    ;

            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                    .setLargeIcon(iconBitmap)
                    .setSmallIcon(R.drawable.ic_notification_launcher)
                    .setColor(ThemeManager.getInstance().getTheme().getColorAccent())
                    .setDefaults(Notification.DEFAULT_ALL)
                    .setContentTitle(getString(R.string.app_name))
                    .setContentText(title)
                    .setAutoCancel(true)
                    .setContentIntent(pendingIntent)
                    .setCategory(category)
                    .setPriority(priority)
                    .setVisibility(visibility)
                    ;
            // @formatter:on

            notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(text)
                    .setBigContentTitle(getString(R.string.app_name)).setSummaryText(extraSummary));


            notificationBuilder.setPublicVersion(notificationBuilderPublic.build());


        notificationManager.notify(pushId + "|" + ownermoduleid + "|" + fid, type.getId(), notificationBuilder.build());

What am I doing wrong?

EDIT : Added layout and icon XML

Finally I found... well, I will not call it a solution... a workaround. It seems, that setting insets on the layers of the LayerDrawable will cause the image to grow in size. Some devices seem to crop images instead of fitting them, if they are too large.

That leads me to resizing the iconBitmap before setting it as LargeIcon.

Bitmap iconBitmap = scaleDown(drawableToBitmap(layerDrawable), dpToPx(48), true);

And the scaling function

 public Bitmap scaleDown(Bitmap source, int size, boolean filter) {
            return Bitmap.createScaledBitmap(source, size, size, filter);
        }

This does still not work completely flawless. When expanding the notification, the image is a tiny bit smaller, but that is ok for me. Still better than cropped.

I still don't know, why this happens only when expanding the view. Maybe the guys at Huawei implemented the BigTextStyle different from the normal style. Or maybe it is just some black magic...

If someone comes up with a better solution, I will accept that one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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