L'icône de la barre de notification devient blanche dans Android 5 Lollipop

207

J'ai une application affichant des notifications personnalisées. Le problème est que lors de l'exécution sous Android 5, la petite icône dans la barre de notification est affichée en blanc. Comment puis-je réparer cela?

Alejandro Casanova
la source
Rahul Sharma et basiam ont une meilleure réponse ici - stackoverflow.com/questions/30795431/…
Rivu Chakraborty
Cela m'arrive lors de l'exécution dans Android 6, pas 5.
Jaime Montoya
Bien sûr, cela se produit avec Android 5+, bien sûr également sous Android 6 et 7. Au moment de la question, Android 5 était la dernière version et la fonctionnalité à l'origine de ce problème a été introduite dans Android 5.
Alejandro Casanova
Je pense qu'il est plus exact de dire API Level 21 (Android 5.0), API Level 22 (Android 5.1), API Level 23 (Android 6.0), etc. Le terme "Android 5" est ambigu car vous pourriez parler d'Android 5.0 ou Android 5.1, et lorsque j'ai testé les notifications et la façon dont les icônes apparaissent dans API Level 22 Vs. API niveau 23, j'ai réalisé qu'ils se comportent différemment.
Jaime Montoya

Réponses:

269

La réponse acceptée n'est pas (entièrement) correcte. Bien sûr, il fait apparaître les icônes de notification en couleur, mais il le fait avec un gros inconvénient - en définissant le SDK cible sur une valeur inférieure à Android Lollipop!

Si vous résolvez votre problème d'icône blanche en définissant votre SDK cible sur 20, comme suggéré, votre application ne ciblera pas Android Lollipop, ce qui signifie que vous ne pouvez pas utiliser les fonctionnalités spécifiques à Lollipop.

Jetez un œil à http://developer.android.com/design/style/iconography.html , et vous verrez que le style blanc est la façon dont les notifications sont censées être affichées dans Android Lollipop.

Dans Lollipop, Google suggère également d'utiliser une couleur qui sera affichée derrière l'icône de notification (blanche) - https://developer.android.com/about/versions/android-5.0-changes.html

Donc, je pense qu'une meilleure solution consiste à ajouter une icône de silhouette à l'application et à l'utiliser si l'appareil exécute Android Lollipop.

Par exemple:

Notification notification = new Notification.Builder(context)
            .setAutoCancel(true)
            .setContentTitle("My notification")
            .setContentText("Look, white in Lollipop, else color!")
            .setSmallIcon(getNotificationIcon())
            .build();

    return notification;

Et, dans la méthode 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;
}
Daniel Saidi
la source
34
Comment générez-vous la silhouette? Je suis développeur sans aucune compétence Photoshop et rendre l'arrière-plan transparent à l'aide d'outils en ligne donne toujours des icônes blanches.
Chaitanya du
6
@Chaitanya Use GIMP :)
ByteHamster
4
cette solution ne répond pas à la question de savoir pourquoi le processus de construction Android modifie un PNG parfaitement correct et le comprime et supprime le canal alpha.
philk
6
developer.android.com/design/style/iconography.html mène à material.google.com/style/icons.html et quand j'appuie ctrl+fet tape notificationsur cette page, il ne trouve rien ...
user25
4
au lieu de vérifier du modificateur de version de la plate-forme d'application de code au dossier dessinable - drawable / drawable-v21 et placer l'icône appropriée
Igor Wojda
72

Entièrement d'accord avec l'utilisateur Daniel Saidi. Afin d'avoir Colorpour NotificationIconj'écris cette réponse.

Pour cela, vous devez créer une icône Silhouetteet créer une section Transparentoù vous voulez ajouter votre Colors. c'est à dire,

entrez la description de l'image ici

Vous pouvez ajouter votre couleur en utilisant

.setColor(your_color_resource_here)

REMARQUE: setColorn'est disponible que dans Lollipop, vous devez vérifierOSVersion

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

Vous pouvez également y parvenir en utilisant Lollipopcomme cible SDK.

Toutes les instructions relatives NotificationIcondonné à la console Google Developer Guide notification lignes .

Taille de l'icône de notification préférée 24x24dp

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

Et référez-vous également à ce lien pour les tailles d'icône de notification pour plus d'informations.

Jaydipsinh Zala
la source
4
c'est une très bonne idée pour définir la couleur d'arrière-plan comme notification.setColor (your_color_resource_here)
TejaDroid
1
J'ai donc essayé cela, et l'icône de notification a l'arrière-plan coloré lorsque je tire l'ombre de notification vers le bas. Mais, dans le bac lui-même, c'est toujours une icône blanche
Stealth Rabbi
1
cette solution est juste..avoir une icône de notification qui a un dos transparent..et par silhouette, l'icône n'a pas besoin d'être uniquement noire..l'icône peut avoir des couleurs; c'est juste que l'androïde L convertira la couleur d'affichage en blanc ... et les versions précédentes d'android montreront l'icône telle qu'elle est
Lakshay
j'ajoute setColor pour la sucette ci-dessous montrant l'icône ic_launcher bien mais en 6.0 montrant l'icône carrée blanche s'il vous plaît aidez-moi
Harsha
J'ai testé setColorsur Kitkat (API 19) et IceCreamSandwich (API 15), dans les deux cas, il a ignoré la couleur mais n'a pas planté . Puis-je donc omettre de vérifier la version du système d'exploitation en toute sécurité?
Maria
47

Voici le code qu'Android utilise pour afficher les icônes de notification:

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

Vous devez donc définir la version sdk cible sur quelque chose <21et les icônes resteront colorées. Il s'agit d'une solution de contournement laide, mais il fait ce qu'il est censé faire. Quoi qu'il en soit, je suggère vraiment de suivre les consignes de conception de Google : "Les icônes de notification doivent être entièrement blanches."

Voici comment vous pouvez l'implémenter:

Si vous utilisez Gradle / Android Studio pour créer vos applications, utilisez build.gradle:

defaultConfig {
    targetSdkVersion 20
}

Sinon (Eclipse etc.) utilisez AndroidManifest.xml:

<uses-sdk android:minSdkVersion="..." android:targetSdkVersion="20" />
ByteHamster
la source
Y a-t-il une solution de contournement? Ou que puis-je faire pour afficher correctement cette icône ou toute autre icône?
Alejandro Casanova
J'ai modifié ma réponse car j'ai trouvé une solution de contournement après avoir lu le code source Android.
ByteHamster
4
Un grand merci pour votre aide, mais merci de me fournir un peu de "contexte". Où dois-je faire ça? Qu'est-ce que "l'entrée"?
Alejandro Casanova
Le code a été tiré d'AOSP juste pour montrer comment j'ai trouvé la solution :) J'ai ajouté une petite explication sur la façon de l'implémenter.
ByteHamster
Cela fonctionne réellement. Avez-vous deviné pourquoi Google a fait cela? Est-ce un bug ou une fonctionnalité?
m02ph3u5
24

Pour éviter que les icônes de notification deviennent blanches, utilisez les icônes "Silhouette" pour elles, par exemple. images d'arrière-plan blanc sur transparent. Vous pouvez utiliser Irfanview pour les construire:

  • choisissez une image, ouvrez-la IrfanView, appuyez sur F12 pour les outils de peinture, nettoyez l'image si nécessaire (supprimez les parties indésirables, lissez et polissez)
  • Image / Decrease Color Depth à 2 (pour une image en noir et blanc)
  • Image / Negative (pour une photo blanc sur noir)
  • Image / Resize/Resample à 144 x 144 (utilisez la méthode de taille "Redimensionner" et non pas "Rééchantillonner", sinon l'image est à nouveau augmentée à 24 bits de couleur par pixel (24 BPP)
  • File / Save as PNG, vérifiez Show option dialog, vérifiez Save Transparent Color, cliquez Save, puis cliquez sur la couleur noire dans l'image pour définir la couleur transparente

Android semble utiliser uniquement la résolution d'image drawable-xxhdpi (144 x 144), alors copiez votre ic_notification.pngfichier résultant dans \AndroidStudio\Projects\...\app\src\main\res\drawable-xxhdpi. Utilisez .setSmallIcon(R.drawable.ic_notification)dans votre code, ou utilisez getNotificationIcon()comme Daniel Saidi l'a suggéré ci-dessus.

Vous pouvez également utiliser Android Asset Studio de Roman Nurik .

Thomas H. Schmidt
la source
J'ai essayé de convertir mon icône en utilisant Photoshop, mais j'ai échoué, mais étant un fan d'irfanview, j'ai rapidement essayé cela quand je l'ai vu et cela a fonctionné à merveille. Merci!
Bruce
15

Une autre option consiste à tirer parti des répertoires dessinables spécifiques à la version (mipmap) pour fournir différents graphiques pour Lollipop et versions ultérieures.

Dans mon application, les répertoires "v21" contiennent des icônes avec du texte transparent tandis que les autres répertoires contiennent une version non transparente (pour les versions d'Android plus anciennes que Lollipop).

Système de fichiers

Qui devrait ressembler à ceci:

Android Studio

De cette façon, vous n'avez pas besoin de vérifier les numéros de version dans le code, par exemple

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

De même, vous pouvez référencer "ic_notification" (ou tout autre nom que vous choisissez pour l'appeler) dans votre charge utile GCM si vous utilisez l'attribut "icon".

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

Ian
la source
3
Cela fonctionne et ressemble à la solution la plus Android.
Sergey Galin
êtes-vous en train de dire que si Android choisira l'icône dans le dossier mipmap-21 si la version est lollipop, et si moins que lollipop, il choisira de drawable?
Lakshay
@Ian, l'approche des répertoires est bonne pour les ressources par version Android, mais comment pouvez-vous définir le setColor(sans impliquer de code supplémentaire) de cette façon?
Daniel
Les couleurs @Daniel peuvent également se trouver dans des répertoires spécifiques à la version, par exemple "valeurs" et "valeurs-v21".
Ian
12

Selon les directives de conception Android, vous devez utiliser une silhouette pour builder.setSmallIcon(R.drawable.some_notification_icon);Mais si vous voulez toujours afficher une icône colorée comme icône de notification, voici l'astuce pour la sucette et surtout l'utilisation ci-dessous le code. Le grandIcon agira comme une icône de notification principale et vous devez également fournir une silhouette pour smallIcon car elle sera affichée en bas à droite du grandIcon.

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

Et pré-sucette à utiliser uniquement .setSmallIcon(R.mipmap.ic_launcher)avec votre constructeur.

Muhammad Babar
la source
11

Maintenant, le studio Android fournit un plugin Image Asset , qui générera une icône dans tous les dossiers Drawbale requis

Image Asset Studio vous aide à créer différents types d'icônes à différentes densités et vous montre exactement où elles seront placées dans votre projet. Il comprend des outils pour ajuster vos icônes et ajouter des fonds d'écran, tout en affichant le résultat dans un volet d'aperçu, afin qu'ils apparaissent exactement comme vous le souhaitiez. Ces outils peuvent considérablement rationaliser le processus de conception et d'importation des icônes.

Vous pouvez accéder à Image Asset en cliquant sur nouveau> cliquez sur l'option Image Asset et il affichera une fenêtre comme celle-ci: -

entrez la description de l'image ici

entrez la description de l'image ici

Nishchal
la source
8

J'étais confronté au même problème et c'était parce que l'icône de notification de mon application n'était pas plate. Pour la version Android de la sucette ou même en dessous de la sucette, l'icône de notification de votre application doit être plate, n'utilisez pas l'icône avec des ombres, etc.

Voici le code qui a parfaitement fonctionné sur toutes les versions d'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());
}

Mauvaise icône
entrez la description de l'image ici

Icône de droite

entrez la description de l'image ici

Nauman Zubair
la source
1
Où résolvez-vous exactement le problème ici?
IgorGanapolsky
Comment créer la bonne icône. Il est possible de générer en ligne? n'importe quel outil ??
Jiks
@Jiks Oui, voici le lien
Muhammad Sohaib Ayub
7

le canal alpha est les seules données de l'image qu'Android utilise pour les icônes de notification:

  • alpha == 1: les pixels sont blancs
  • alpha == 0: les pixels apparaissent comme la couleur que vous avez choisie Notification.Builder#setColor(int)

Ceci est mentionné sur https://developer.android.com/about/versions/android-5.0-changes.html :

Le système ignore tous les canaux non alpha dans les icônes d'action et dans l'icône de notification principale. Vous devez supposer que ces icônes seront uniquement en alpha.

Presque tous les dessinables intégrés semblent être des images alpha appropriées pour cela, vous pouvez donc utiliser quelque chose comme:

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

mais je suis toujours à la recherche du document API qui le confirme officiellement.

Testé sur Android 22.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source
J'ai testé setColorsur Kitkat (API 19) et IceCreamSandwich (API 15), dans les deux cas, il a ignoré la couleur mais n'a pas planté . Alors, puis-je ignorer la version du système d'exploitation en toute sécurité?
Maria
@JohnLee Je ne pense pas qu'il puisse tomber en panne, seulement peut paraître mauvais si vous n'en tenez pas compte :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
3

supprimez le android:targetSdkVersion="21"manifeste.xml. ça va marcher! et de cela il n'y a aucun problème du tout dans votre apk c'est juste un truc j'applique cela et j'ai trouvé une icône colorée dans la notification

Bhanu Sharma
la source
9
Idée totalement mauvaise pour jouer des "trucs" avec le système! Pas une solution!
sud007
3

Les notifications sont en niveaux de gris comme expliqué ci-dessous. Ils ne sont pas en noir et blanc, malgré ce que d'autres ont écrit. Vous avez probablement vu des icônes avec plusieurs nuances, comme des barres de puissance réseau.

Avant API 21 (Lollipop 5.0), les icônes de couleur fonctionnent. Vous pouvez forcer votre application à cibler l'API 20, mais cela limite les fonctionnalités disponibles pour votre application, il n'est donc pas recommandé. Vous pouvez tester le niveau d'API en cours d'exécution et définir une icône de couleur ou une icône en niveaux de gris de manière appropriée, mais cela ne vaut probablement pas la peine. Dans la plupart des cas, il est préférable d'utiliser une icône en niveaux de gris.

Les images ont quatre canaux, RGBA (rouge / vert / bleu / alpha). Pour les icônes de notification, Android ignore les canaux R, G et B. Le seul canal qui compte est Alpha, également connu sous le nom d'opacité. Concevez votre icône avec un éditeur qui vous permet de contrôler la valeur alpha de vos couleurs de dessin.

Comment les valeurs Alpha génèrent une image en niveaux de gris:

  • Alpha = 0 (transparent) - Ces pixels sont transparents, montrant la couleur d'arrière-plan.
  • Alpha = 255 (opaque) - Ces pixels sont blancs.
  • Alpha = 1 ... 254 - Ces pixels sont exactement ce à quoi vous vous attendez, fournissant les nuances entre transparent et blanc.

Changer avec setColor:

  • Appelle NotificationCompat.Builder.setColor(int argb). De la documentation de Notification.color:

    Couleur d'accent (un entier ARGB comme les constantes de Color) à appliquer par les modèles de style standard lors de la présentation de cette notification. La conception de modèle actuelle construit une image d'en-tête colorée en superposant l'image d'icône (au pochoir en blanc) au-dessus d'un champ de cette couleur. Les composants alpha sont ignorés.

    Mes tests avec setColor montrent que les composants Alpha ne sont pas ignorés; au lieu de cela, ils fournissent toujours des niveaux de gris. Des valeurs alpha plus élevées deviennent un pixel blanc. Des valeurs alpha inférieures transforment un pixel en couleur d'arrière-plan (noir sur mon appareil) dans la zone de notification, ou en couleur spécifiée dans la notification déroulante. (Il semble que d'autres aient signalé un comportement légèrement différent, alors soyez conscient!)

Jeremy Frank
la source
2

Après la sortie d'Android Lollipop, Android a modifié les directives pour l'affichage des icônes de notification dans la barre de notification. La documentation officielle indique "Mettre à jour ou supprimer les actifs qui impliquent la couleur. Le système ignore tous les canaux non alpha dans les icônes d'action et dans l'icône de notification principale. Vous devez supposer que ces icônes seront uniquement en alpha. Le système dessine des icônes de notification en blanc et des icônes d'action en gris foncé. " Maintenant, cela signifie en termes profanes: "Convertissez toutes les parties de l'image que vous ne voulez pas montrer en pixels transparents. Toutes les couleurs et les pixels non transparents sont affichés en blanc "

Vous pouvez voir comment faire cela en détail avec des captures d'écran ici https://blog.clevertap.com/fixing-notification-icon-for-android-lollipop-and-above/

J'espère que cela pourra aider

Rohit Khanna
la source
2

Vous devez importer l'image PNG transparente unicolore. Vous pouvez donc définir la couleur de l'icône de la petite icône. Sinon, il sera affiché en blanc dans certains appareils comme MOTO

abhi.nalavade
la source
1

Si vous utilisez GoogleFireBaseMessaging, vous pouvez définir "icon id" dans la charge utile "notification" (cela m'aide à résoudre le problème d'icône de barre blanche):

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

définissez ic_notification sur votre propre identifiant à partir de R.drawable.

Maxim Firsoff
la source
Où avez-vous placé cette icône? Tout ce que je reçois est l'icône de mon application et tous les fichiers R.drawable que je trouve sont des fichiers de classe binaire.
shinzou
@kuhaku il fait référence à un fichier ic_launcher.png dans le dossier 'drawable'.
Johnson
0

J'ai également rencontré trop de problèmes dans ce domaine, mais après avoir cherché sur Internet, j'ai trouvé différentes solutions à ce problème.Je résume toutes les solutions et explique:

Remarque: Cette solution est destinée aux utilisateurs de Phonegap cordova

  1. Exemple

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

Vous devez définir votre valeur android-targetSdkVersion à moins de 21. Ainsi, après avoir défini cette valeur, l'icône d'icône de notification apparaîtra jusqu'à Android 6 (Marshmallow), cela ne fonctionnera pas dans Android 7 (Nougat). Cette solution a fonctionné pour moi.

  1. Modifiez le statusbarStyle dans votre fichier de configuration. Exemple

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

Mais cette solution ne fonctionnera que lorsque votre application sera ouverte. Donc, je suppose que cette solution n'est pas la meilleure, mais elle a fonctionné pour de nombreux utilisateurs.

  1. Rendez votre icône transparente. Cette solution a fonctionné pour de nombreuses personnes. En fait, dans le développement de l'application native, nous devons leur fournir trois images: (a) Icône de l'application (b) Icône de notification (c) Image de l'icône de la barre d'état, mais en cas de développement d'applications mobiles hybrides, il n'y a pas d'option pour faites-le. Rendez donc votre icône transparente et cette solution résoudra votre problème.

Et je suis sûr que l'une des solutions ci-dessus fonctionnera pour votre problème.

Rinku kumar
la source
0

FYI: Si l'icône n'apparaît pas, assurez-vous que votre configuration de notification locale ou distante contient le nom d'icône correct, c'est-à-dire

'largeIcon' => 'ic_launcher',
'smallIcon' => 'ic_launcher' // defaults to ic_launcher, 
phil
la source
0

Je pense qu'il est trop tard pour parler d'API 21, mais j'ai trouvé un moyen simple.

Lorsque vous utilisez des notifications personnalisées (mise en page personnalisée),

RemoteView's

setImageViewResource(int viewId, int srcId);

et

setImageViewUri(int viewId, Uri uri); 

rend ces images blanches sur Lollipop (API 21).

Mais lors de l'utilisation

setImageViewBitmap(int viewId, Bitmap bitmap);

L'image ne devient pas masquée de blanc!

Gâteau au citron vert
la source
0

Selon la documentation, l'icône de notification doit être blanche depuis Android 3.0 (API niveau 11) :

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

"Les icônes de la barre d'état sont composées simplement de pixels blancs sur un fond transparent, avec un mélange alpha utilisé pour des bords lisses et une texture interne le cas échéant."

Laurent
la source
-3

mélanger ces deux choses dans l'application 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"
}
wahid
la source
-38

android:targetSdkVersion="20"ce devrait être < 21.

Hemanth Dvshkk
la source
1
Veuillez ne pas suivre cette solution, bien sûr, cela pourrait fonctionner, mais au prix d'exécuter vos applications en mode de compatibilité pour les nouvelles versions d'Android.
king_below_my_lord