Піктограма панелі сповіщень стає білою в Android 5 Lollipop


207

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


Рахул Шарма і basiam має кращий відповідь тут - stackoverflow.com/questions/30795431 / ...
Rivu Чакраборті

Це трапляється зі мною під час роботи в Android 6, а не 5.
Jaime Montoya

Звичайно, це трапляється з Android 5+, звичайно, також і в Android 6 і 7. На момент запитання Android 5 була найновішою версією, а функція, що спричиняла цю проблему, була введена в Android 5.
Алехандро Казанова

Я вважаю, що точніше сказати API рівень 21 (Android 5.0), API рівень 22 (Android 5.1), API рівень 23 (Android 6.0) і т. Д. Термін "Android 5" неоднозначний, оскільки ви могли б говорити про Android 5.0 або Android 5.1, і коли я тестував сповіщення та спосіб відображення піктограм в API рівня 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
це рішення не дає відповіді на питання, чому процес збирання андроїда модифікує ідеально правильний PNG і стискає його та видаляє альфа-канал.
філк

6
developer.android.com/design/style/iconography.html призводить до material.google.com/style/icons.html, і коли я натискаю ctrl+fта notification
набираю

4
замість перевірки від модифікатора версії платформи коду до папки Dravable - dravable / dravable-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наведених у Посібнику з повідомлень консолі розробника Google .

Бажана піктограма сповіщення Розмір 24x24dp

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

А також перейдіть за цим посиланням для розмірів піктограм сповіщення для отримання додаткової інформації.


4
це дуже гарна ідея для встановлення кольору фону як повідомлення.setColor (your_color_resource_here)
TejaDroid

1
Тому я спробував це, і значок сповіщення має кольоровий фон, коли я тягніть відтінок сповіщення вниз. Але в самому лотку все ще є біла ікона
Стелс-раббі

1
це рішення правильне .. має піктограму сповіщення, яка має прозору спинку..і за силуетом, значок не повинен бути лише чорним .. значок може мати кольори; це просто те, що андроїд L перетворить показ кольору у білий колір. А попередні версії андроїда покажуть іконку такою, якою вона є
Lakshay

я додаю setColor для нижньої льодяника із зображенням значка ic_launcher відмінно, але в 6,0, що показує піктограму білого квадрата, будь ласка, допоможіть мені
Харша

Я тестував setColorна Kitkat (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
}

В іншому випадку (затемнення тощо) використовуйте AndroidManifest.xml:

<uses-sdk android:minSdkVersion="..." android:targetSdkVersion="20" />

Чи є якесь вирішення? Або що я можу зробити, щоб правильно відобразити ту чи іншу іконку?
Алехандро Казанова

Я відредагував свою відповідь, коли знайшов рішення після прочитання вихідного коду 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, здається, використовує лише графічну роздільну здатність зображення (144 x 144), тому скопіюйте отриманий ic_notification.pngфайл у \AndroidStudio\Projects\...\app\src\main\res\drawable-xxhdpi. Використовуйте .setSmallIcon(R.drawable.ic_notification)у своєму коді або використовуйте так, getNotificationIcon()як пропонував Даніель Саїді.

Ви також можете використовувати студію активів Android Романа Нурика .


Я спробував перетворити свою іконку за допомогою Photoshop, але не вдалося, але, будучи шанувальником 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, якщо версія є льодяник, а якщо менше, ніж льодяник, вона буде вибирати з малювання?
Лакшай

@Ian, підхід до каталогів хороший для ресурсів на версії Android, але як же ви можете встановити setColor(без залучення додаткового коду) таким чином?
Даніель

Кольори @Daniel також можуть бути в специфічних для версії каталогах, наприклад, "значення" та "значення-v21".
Ян

12

Відповідно до інструкцій щодо дизайну Android, ви повинні використовувати силует для. builder.setSmallIcon(R.drawable.some_notification_icon);Але якщо ви все ще хочете показати барвисту піктограму як значок сповіщення, тут є хитрість для льодяника та вище використання нижче коду. LargeIcon буде виконувати роль основного піктограми сповіщень, і вам також потрібно надати силует для smallIcon, оскільки він буде показаний в нижній правій частині bigIcon.

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

Тепер андроїд-студія надає плагін Image Asset , який буде генерувати значок у всій необхідній папці малюнка

Актив зображення Studio допомагає створювати різні типи піктограм різної щільності та показує, де саме вони будуть розміщені у вашому проекті. Він включає інструменти для налаштування ваших піктограм та додавання фонів, відображаючи результат на панелі попереднього перегляду, тому вони відображаються точно так, як ви задумали. Ці інструменти можуть різко впорядкувати процес розробки і імпорту значків.

Ви можете отримати доступ до Image Asset , натиснувши нове> натисніть на параметр Image Asset, і це покаже таке вікно:

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

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


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
Де саме ви тут вирішуєте проблему?
ІгорГанапольський

Як створити потрібний значок. Можна онлайн генерувати? будь-який інструмент ??
Джикс


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.


Я тестував setColorна Kitkat (API 19) та IceCreamSandwich (API 15), в обох випадках він ігнорував колір, але не вийшов з ладу . Тож чи можу я безпечно пропустити перевірку версії ОС?
Марія

@JohnLee Я не думаю, що це може вийти з ладу, може виглядати погано, якщо ви не
врахуєте

3

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


9
Зовсім погана Ідея грати в "трюки" із системою! Не рішення!
sud007

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 android Lollipop випуск Android змінив інструкції щодо відображення піктограм сповіщень на панелі сповіщень. В офіційній документації написано: "Оновіть або видаліть активи, що містять кольори. Система ігнорує всі не альфа-канали в значках дій та в головному значку сповіщень. Ви повинні припустити, що ці піктограми будуть лише альфа. Система малює піктограми сповіщень білим кольором та піктограми дій темно-сірого кольору ». Тепер це означає, що це означає "непрофесіонал": "Перетворити всі частини зображення, які ви не хочете показувати, у прозорі пікселі. Усі кольори та непрозорі пікселі відображаються білим кольором "

Тут ви можете подивитися, як це докладно зробити за допомогою скріншотів https://blog.clevertap.com/fixing-notification-icon-for-android-lollipop-and-above/

Сподіваюся, що це допомагає


2

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


1

Якщо ви використовуєте GoogleFireBaseMessaging, ви можете встановити "іконку" в корисному навантаженні "сповіщення" (це допомагає мені вирішити проблему зі значком білої смуги):

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

встановіть ic_notification на власний ідентифікатор від R.drawable.


Де ти помістив цю ікону? Все, що я отримую, це значок мого додатка, і всі файли R.dravable, які я знаходжу, - це файли бінарного класу.
shinzou

@kuhaku він має на увазі файл ic_launcher.png у папці "dravable".
Джонсон

0

Я також зіткнувся з занадто великою проблемою в цьому, але після пошуку в Інтернеті я знайшов різні рішення цього питання. Дозвольте підвести підсумки всіх рішень та пояснити:

Примітка. Це рішення призначене для користувачів Phonegap cordova

  1. Приклад

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

Потрібно встановити значення для android-targetSdkVersion менше 21. Отже, після встановлення цього значення зображення піктограми сповіщень з’явиться до Android 6 (Marshmallow), воно не працюватиме в Android 7 (Nougat). Це рішення спрацювало на мене.

  1. Змініть статусStyle у своєму конфігураційному файлі. Приклад

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

Але це рішення працюватиме лише тоді, коли ваш додаток відкриється. Отже, я думаю, це рішення не найкраще рішення, але воно працювало для багатьох користувачів.

  1. Зробіть ваш значок прозорим. Це рішення спрацювало для багатьох людей. Власне, річ полягає в тому, що при розробці програми "Рідні" нам потрібно надати їм три зображення: (a) Піктограма програми (b) Піктограма сповіщення (c) Зображення піктограми рядка стану, але у випадку розвитку гібридних мобільних додатків немає можливості зроби так. Тож зробіть ваш значок прозорим, і це рішення вирішить вашу проблему.

І я впевнений, що одне з вищезазначених рішень буде працювати для вашої проблеми.


0

FYI: Якщо значок не відображається, переконайтеся, що ваша локальна або віддалена конфігурація сповіщень містить правильну назву значка, тобто

'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 рівня 11) :

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

"Піктограми рядка стану складаються просто з білих пікселів на прозорому фоні, з альфа-змішуванням, що використовується для гладких країв та внутрішньої текстури, де це доречно."


-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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.