Значок панели уведомлений становится белым в Android 5 Lollipop

207

У меня есть приложение, показывающее пользовательские уведомления. Проблема в том, что при работе в Android 5 маленький значок на панели уведомлений отображается белым цветом. Как я могу это исправить?

Алехандро Казанова
источник
У Рахула Шармы и Баиама есть лучший ответ здесь - stackoverflow.com/questions/30795431/…
Риву Чакраборти,
Это происходит со мной при работе в Android 6, а не 5.
Хайме Монтойя
Конечно, это происходит с Android 5+, конечно, также и в Android 6 и 7. К тому времени Android 5 был последней версией, и функция, вызывающая эту проблему, была представлена ​​в Android 5.
Алехандро Казанова
Я думаю, что точнее сказать API Level 21 (Android 5.0), API Level 22 (Android 5.1), API Level 23 (Android 6.0) и т. Д. Термин «Android 5» является неоднозначным, поскольку вы можете говорить об Android 5.0 или Android 5.1, и когда я тестировал уведомления и способ отображения значков в API Level 22 Vs. Уровень API 23, я понял, что они ведут себя по-разному.
Хайме Монтойя

Ответы:

269

Принятый ответ не является (полностью) правильным. Конечно, это заставляет значки уведомлений отображаться в цвете, но делает это с большим недостатком - устанавливая целевой 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;
}
Даниэль Саиди
источник
34
Как вы создаете силуэт? Я разработчик, у которого нет навыков работы с фотошопом, и делаю фон прозрачным с помощью онлайн-инструментов, и все равно получаю белые иконки.
Чайтанья
6
@Chaitanya Используйте GIMP :)
ByteHamster
4
Это решение не отвечает на вопрос, почему процесс сборки Android изменяет совершенно корректный PNG, сжимает его и удаляет альфа-канал.
Филк
6
developer.android.com/design/style/iconography.html ведет к material.google.com/style/icons.html, и когда я нажимаю ctrl+fи печатаю notificationна этой странице, он ничего не может найти ...
user25
4
вместо проверки из модификатора версии платформы приложения кода в папку drawable - drawable / drawable-v21 и размещение нужного значка
Игорь Войда
72

Полностью согласен с пользователем Daniel Saidi. Для того чтобы иметь Colorдля этого NotificationIconя пишу этот ответ.

Для этого вы должны сделать иконку похожей Silhouetteи создать раздел, Transparentгде бы вы ни хотели добавить свой Colors. т.е.

введите описание изображения здесь

Вы можете добавить свой цвет, используя

.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даны в Руководстве по уведомлению консоли разработчика .

Предпочтительный размер значка уведомления 24x24dp

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

А также обратитесь к этой ссылке для размеров значков уведомлений для получения дополнительной информации.

Джайдипсин Зала
источник
4
это очень хорошая идея для установки цвета фона в качестве уведомлений .setColor (your_color_resource_here)
TejaDroid
1
Итак, я попробовал это, и значок уведомления имеет цветной фон, когда я опускаю тень уведомления. Но в самом трее это все еще белый значок
Stealth Rabbi
1
это правильное решение ... иметь значок уведомления с прозрачной задней частью ... и по силуэту значок не обязательно должен быть только черным ... значок может иметь цвета; Это просто, что Android L будет преобразовывать показывать цвет как белый .. и предыдущие версии Android будут показывать значок, как он есть
Lakshay
Я добавляю setColor для леденца ниже, показывающего иконку ic_launcher, но в 6.0, показывающего белую квадратную иконку, пожалуйста, помогите мне
Harsha
Я тестировал setColorKitkat (API 19) и IceCreamSandwich (API 15), в обоих случаях он игнорировал цвет, но не падал . Так что я могу безопасно пропустить проверку версии ОС?
Мария
47

Этот код 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и значки будут оставаться цветными. Это уродливый обходной путь, но он делает то, что от него ожидают. В любом случае, я действительно рекомендую следовать Руководству по дизайну Google : «Значки уведомлений должны быть полностью белыми».

Вот как вы можете это реализовать:

Если вы используете Gradle / Android Studio для создания своих приложений, используйте build.gradle:

defaultConfig {
    targetSdkVersion 20
}

В противном случае (Eclipse и т. Д.) Используйте AndroidManifest.xml:

<uses-sdk android:minSdkVersion="..." android:targetSdkVersion="20" />
ByteHamster
источник
Есть ли обходной путь? Или что я могу сделать, чтобы правильно показать этот или любой другой значок?
Алехандро Казанова
Я отредактировал свой ответ, поскольку нашел обходной путь после прочтения исходного кода Android.
ByteHamster
4
Большое спасибо за вашу помощь, но, пожалуйста, предоставьте мне некоторый "контекст". Где мне нужно это сделать? Что такое «вход»?
Алехандро Казанова
Код был взят из AOSP только для того, чтобы показать, как я нашел обходной путь :) Я добавил небольшое объяснение о том, как его реализовать.
ByteHamster
Это на самом деле работает. Есть предположения, почему Google это сделал? Это ошибка или особенность?
m02ph3u5
24

Чтобы значки уведомлений не стали белыми, используйте для них значки «Силуэт», т.е. белые на прозрачном фоне изображения. Вы можете использовать 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)в своем коде или используйтеgetNotificationIcon() как Даниэль Саиди, предложенный выше.

Вы также можете использовать Android Asset Studio Романа Нурика .

Томас Х. Шмидт
источник
Я пытался преобразовать свою иконку с помощью фотошопа, но не смог, но, будучи фанатом irfanview, я быстро попробовал это, когда увидел, и это сработало чудесно. Спасибо!
Брюс
15

Другой вариант - воспользоваться каталогами для рисования (mipmap), зависящими от версии, для предоставления различной графики для Lollipop и выше.

В моем приложении каталоги "v21" содержат значки с прозрачным текстом, в то время как другие каталоги содержат непрозрачную версию (для версий Android, более старых, чем Lollipop).

Файловая система

Который должен выглядеть примерно так:

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

Аналогично, вы можете ссылаться на «ic_notification» (или как вы его называете) в полезной нагрузке GCM, если вы используете атрибут «icon».

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

Ян
источник
3
Это работает и выглядит как самое Android-решение.
Сергей Галин
Вы говорите, что если Android выберет значок из папки mipmap-21, если версия lollipop, и если меньше, чем lollipop, он выберет из drawable?
Лакшай
@ Ян, подход к каталогам хорош для ресурсов на версию для Android, но как вы можете установить setColor(без использования дополнительного кода) таким образом?
Даниил
@Daniel цвета также могут быть в каталогах, зависящих от версии, например, «values» и «values-v21».
Ян
12

В соответствии с рекомендациями по дизайну 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)с вашим строителем.

Мухаммед Бабар
источник
11

Теперь в Android Studio есть плагин Image Asset , который будет генерировать иконку во всех необходимых папках drawbale.

Image Asset Studio помогает вам создавать различные типы значков с различной плотностью и показывает, где именно они будут размещены в вашем проекте. Он включает в себя инструменты для настройки ваших значков и добавления фонов, все при отображении результата на панели предварительного просмотра, чтобы они выглядели точно так, как вы планировали. Эти инструменты могут значительно упростить процесс создания и импорта иконок.

Вы можете получить доступ к Image Asset , щелкнув новый> щелкните по опции Image Asset, и это будет окно показа, как это: -

введите описание изображения здесь

введите описание изображения здесь

Nishchal
источник
8

Я столкнулся с той же проблемой, и это было из-за того, что значок уведомления моего приложения не был плоским. Для леденца на андроид версии или даже ниже леденца на палочке значок уведомления вашего приложения должен быть плоским, не используйте значок с тенями и т. Д.

Ниже приведен код, который отлично работал на всех версиях 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());
}

Неправильный значок
введите описание изображения здесь

Правая иконка

введите описание изображения здесь

Науман Зубайр
источник
1
Где именно вы здесь решаете проблему?
Игорь Ганапольский
Как создать правильный значок. Можно ли в режиме онлайн генерировать? любой инструмент ??
Джикс
@Jiks Да, вот ссылка
Мухаммед Сохаиб Аюб
7

Альфа-канал - это единственные данные изображения, которые Android использует для значков уведомлений:

  • alpha == 1: пиксели показывают белый
  • alpha == 0: пиксели отображаются как выбранный вами цвет Notification.Builder#setColor(int)

Это упоминается по адресу https://developer.android.com/about/versions/android-5.0-changes.html :

Система игнорирует все не альфа-каналы в значках действий и в значке основного уведомления. Вы должны предположить, что эти значки будут только в альфа-формате.

Кажется, что почти все встроенные элементы рисования подходят для этого, поэтому вы можете использовать что-то вроде:

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

но я все еще ищу документацию API, которая официально подтверждает это.

Проверено на Android 22.

Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
источник
Я тестировал setColorKitkat (API 19) и IceCreamSandwich (API 15), в обоих случаях он игнорировал цвет, но не падал . Так что я могу безопасно пропустить проверку версии ОС?
Мария
@JohnLee Я не думаю, что это может привести к сбою, только может выглядеть плохо, если вы не принимаете это во внимание :-)
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
3

удалить android:targetSdkVersion="21"из файла manifest.xml. это сработает! и от этого нет никаких проблем в вашем apk, это просто трюк, я применяю это, и я нашел красочный значок в уведомлении

Бхану Шарма
источник
9
Совершенно плохая идея играть в "трюки" с системой! Не решение!
01:00
3

Уведомления серого цвета как описано ниже. Они не черно-белые, несмотря на то, что написали другие. Возможно, вы видели значки с несколькими оттенками, например, шкалы силы сети.

До API 21 (Lollipop 5.0) работали цветные значки. Вы можете принудительно настроить ваше приложение на API 20, но это ограничивает возможности, доступные для вашего приложения, поэтому это не рекомендуется. Вы можете проверить работающий уровень API и соответственно установить либо цветную иконку, либо иконку в оттенках серого, но это, вероятно, не стоит. В большинстве случаев лучше всего использовать значок в оттенках серого.

Изображения имеют четыре канала RGBA (красный / зеленый / синий / альфа). Для значков уведомлений Android игнорирует каналы R, G и B. Единственный канал, который учитывается, это Альфа, также известный как непрозрачность. Создайте свой значок с помощью редактора, который дает вам контроль над альфа-значением цветов вашего рисунка.

Как альфа-значения генерируют серое изображение:

  • Альфа = 0 (прозрачный) - эти пиксели являются прозрачными, показывая цвет фона.
  • Альфа = 255 (непрозрачный) - эти пиксели белого цвета.
  • Альфа = 1 ... 254 - эти пиксели в точности соответствуют вашим ожиданиям, обеспечивая оттенки между прозрачным и белым.

Изменяя это с setColor:

  • Вызов NotificationCompat.Builder.setColor(int argb). Из документации для Notification.color:

    Акцентный цвет (целое число ARGB, например, константы в цвете), применяемый стандартными шаблонами стилей при представлении этого уведомления. Текущий дизайн шаблона создает красочное изображение заголовка, накладывая изображение значка (трафаретное на белый) поверх поля этого цвета. Альфа-компоненты игнорируются.

    Мое тестирование с использованием setColor показывает, что компоненты Alpha не игнорируются; вместо этого они все еще предоставляют оттенки серого. Более высокие значения Alpha окрашивают пиксель в белый цвет. Более низкие значения альфа-канала превращают пиксель в цвет фона (черный на моем устройстве) в области уведомлений или в указанный цвет в раскрывающемся уведомлении. (Кажется, другие сообщали о несколько ином поведении, так что будьте внимательны!)

Джереми Фрэнк
источник
2

После выхода Android Lollipop релиз Android изменил правила отображения значков уведомлений в панели уведомлений. Официальная документация гласит: «Обновляйте или удаляйте ресурсы, связанные с цветом. Система игнорирует все не-альфа-каналы в значках действий и в основном значке уведомлений. Следует учитывать, что эти значки будут только в альфа-формате. Система отображает значки уведомлений белым цветом. и значки действий темно-серого цвета ». Теперь, что это означает в терминах непрофессионала: «Преобразуйте все части изображения, которые вы не хотите показывать, в прозрачные пиксели. Все цвета и непрозрачные пиксели отображаются белым »

Вы можете увидеть, как сделать это подробно со скриншотами здесь https://blog.clevertap.com/fixing-notification-icon-for-android-lollipop-and-above/

надеюсь, это поможет

Рохит Ханна
источник
2

Вам необходимо импортировать одноцветное прозрачное изображение PNG. Таким образом, вы можете установить цвет значка маленького значка. В противном случае он будет показан белым на некоторых устройствах, таких как MOTO

abhi.nalavade
источник
1

Если вы используете GoogleFireBaseMessaging, вы можете установить «идентификатор значка» в полезной нагрузке «уведомления» (это помогает мне решить проблему с иконкой белой полосы):

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

установите ic_notification для вашего собственного идентификатора из R.drawable.

Максим Фирсофф
источник
Где вы разместили эту икону? Все, что я получаю, это значок моего приложения, и все файлы R.drawable, которые я нахожу, являются файлами бинарных классов.
Синдзоу
@kuhaku он ссылается на файл ic_launcher.png в папке «drawable».
Джонсон
0

Я также столкнулся со слишком многими проблемами в этом, но после поиска по всему интернету я нашел различные решения для этой проблемы. Позвольте мне суммировать все решения и объяснить:

Примечание. Это решение предназначено для пользователей PhoneGap Cordova.

  1. пример

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

Вам нужно установить значение android-targetSdkVersion меньше 21. Поэтому после установки этого значения изображение значка уведомления будет отображаться до Android 6 (Marshmallow), оно не будет работать в Android 7 (Nougat). Это решение сработало для меня.

  1. Измените statusbarStyle в вашем конфигурационном файле. пример

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

Но это решение будет работать только тогда, когда ваше приложение открыто. Итак, я думаю, что это решение не лучшее решение, но оно работало для многих пользователей.

  1. Сделайте ваш значок прозрачным. Это решение работало для многих людей. На самом деле дело в том, что при разработке собственных приложений нам нужно предоставить им три изображения: (a) значок приложения (b) значок уведомления (c) изображение значка строки состояния, но в случае разработки гибридного мобильного приложения нет возможности Сделай так. Сделайте вашу иконку прозрачной, и это решение решит вашу проблему.

И я уверен, что одно из приведенных выше решений будет работать для вашей проблемы.

Ринку Кумар
источник
0

К вашему сведению: если значок не отображается, убедитесь, что в вашей локальной или удаленной конфигурации уведомлений указано правильное имя значка, т.е.

'largeIcon' => 'ic_launcher',
'smallIcon' => 'ic_launcher' // defaults to ic_launcher, 
Фил
источник
0

Я думаю, что уже слишком поздно говорить об API 21, но я нашел простой способ.

При использовании пользовательских уведомлений (пользовательский макет),

RemoteView-х

setImageViewResource(int viewId, int srcId);

и

setImageViewUri(int viewId, Uri uri); 

делает эти изображения белыми на Lollipop (API 21).

Но при использовании

setImageViewBitmap(int viewId, Bitmap bitmap);

Изображение не становится белой маской!

Торт Лайм
источник
0

Согласно документации, значок уведомления должен быть белым начиная с Android 3.0 (API Level 11) :

https://developer.android.com/guide/practices/ui_guidelines/icon_design_status_bar

«Значки строки состояния состоят просто из белых пикселей на прозрачном фоне с альфа-смешиванием, используемым для сглаживания краев и внутренней текстуры, где это уместно».

Laurent
источник
-3

смешать эти две вещи в приложении 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"
}
вахид
источник
-38

android:targetSdkVersion="20"это должно быть < 21.

Хемант Двшкк
источник
1
Пожалуйста, не следуйте этому решению, конечно, оно может работать, но за счет запуска ваших приложений в режиме совместимости для более новых версий Android.
king_below_my_lord