El icono de la barra de notificaciones se vuelve blanco en Android 5 Lollipop

207

Tengo una aplicación que muestra notificaciones personalizadas. El problema es que cuando se ejecuta en Android 5, el pequeño icono en la barra de notificaciones se muestra en blanco. ¿Cómo puedo arreglar esto?

Alejandro Casanova
fuente
Rahul Sharma y Basiam tienen una mejor respuesta aquí - stackoverflow.com/questions/30795431/…
Rivu Chakraborty
Me sucede cuando se ejecuta en Android 6, no 5.
Jaime Montoya
Claro, sucede con Android 5+, por supuesto, también en Android 6 y 7. En el momento de la pregunta, Android 5 era la última versión y la característica que causaba este problema se introdujo en Android 5.
Alejandro Casanova,
Creo que es más exacto decir API Level 21 (Android 5.0), API Level 22 (Android 5.1), API Level 23 (Android 6.0), etc. El término "Android 5" es ambiguo porque podría estar hablando de Android 5.0 o Android 5.1, y cuando he estado probando notificaciones y la forma en que aparecen los íconos en el Nivel API 22 vs. Nivel API 23, me di cuenta de que se comportan de manera diferente.
Jaime Montoya

Respuestas:

269

La respuesta aceptada no es (enteramente) correcta. Claro, hace que los iconos de notificación se muestren en color, pero lo hace con un GRAN inconveniente, ¡al establecer el SDK de destino en un nivel inferior a Android Lollipop!

Si resuelve su problema de íconos blancos configurando su SDK de destino en 20, como se sugiere, su aplicación no apuntará a Android Lollipop, lo que significa que no puede usar las funciones específicas de Lollipop.

Eche un vistazo a http://developer.android.com/design/style/iconography.html , y verá que el estilo blanco es cómo se deben mostrar las notificaciones en Android Lollipop.

En Lollipop, Google también sugiere que utilice un color que se mostrará detrás del ícono de notificación (blanco): https://developer.android.com/about/versions/android-5.0-changes.html

Entonces, creo que una mejor solución es agregar un ícono de silueta a la aplicación y usarlo si el dispositivo ejecuta Android Lollipop.

Por ejemplo:

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

    return notification;

Y, en el método 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
fuente
34
¿Cómo se genera la silueta? Soy desarrollador sin habilidades de photoshop y hacer que el fondo sea transparente usando herramientas en línea todavía da como resultado iconos blancos.
Chaitanya
66
@Chaitanya Use GIMP :)
ByteHamster
44
Esta solución no responde a la pregunta de por qué el proceso de compilación de Android modifica un PNG perfectamente correcto y lo comprime y elimina el canal alfa.
philk
66
developer.android.com/design/style/iconography.html conduce a material.google.com/style/icons.html~~V~~plural~~3rd y cuando presionar ctrl+fy escribir notificationen esa página no se puede encontrar nada ...
USER25
44
en lugar de verificar desde el modificador de versión de la plataforma de aplicación de código a la carpeta dibujable - drawable / drawable-v21 y colocar el ícono adecuado
Igor Wojda
72

Completamente de acuerdo con el usuario Daniel Saidi. Con el fin de tener Colorde NotificationIconque estoy escribiendo esta respuesta.

Para eso, debe hacer que el icono le guste Silhouettey crear una sección Transparentdonde quiera agregar su Colors. es decir,

ingrese la descripción de la imagen aquí

Puedes agregar tu color usando

.setColor(your_color_resource_here)

NOTA: setColorsolo está disponible en Lollipopmodo, debe verificarOSVersion

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

También puede lograr esto utilizando Lollipopcomo objetivo SDK.

Todas las instrucciones relativas NotificationIcona las líneas de guía de notificación de la Consola de desarrollador de Google .

Tamaño de icono de notificación preferido 24x24dp

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

Y también consulte este enlace para ver los tamaños de los iconos de notificación para obtener más información.

Jaydipsinh Zala
fuente
44
esta es una muy buena idea para establecer el color de fondo como notificación.setColor (your_color_resource_here)
TejaDroid
1
Así que he intentado esto, y el ícono de notificación tiene el fondo de color cuando abro el tono de notificación. Pero, en la bandeja misma, sigue siendo un ícono blanco
rabino sigiloso el
1
esta solución es correcta ... tiene un ícono de notificación que tiene el reverso transparente ... y por silueta, el ícono no necesita ser solo negro ... el ícono puede tener colores; es solo que el Android L convertirá el color del show en blanco ... y las versiones anteriores de Android mostrarán el ícono tal como está
Lakshay
Estoy añadiendo setColor por debajo de piruleta mostrando el icono fina ic_launcher pero en 6.0 mostrando cuadrado blanco icono de ayuda por favor
Harsa
He probado setColoren Kitkat (API 19) y IceCreamSandwich (API 15), en ambos casos ignoró el color pero no se bloqueó . Entonces, ¿puedo omitir con seguridad la comprobación de la versión del sistema operativo?
Maria
47

Este es el código que usa Android para mostrar iconos de notificación:

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

Por lo tanto, debe establecer la versión de SDK de destino en algo <21y los iconos permanecerán coloreados. Esta es una solución fea pero hace lo que se espera que haga. De todos modos, realmente sugiero seguir las pautas de diseño de Google : "Los iconos de notificación deben ser completamente blancos".

Así es como puede implementarlo:

Si está utilizando Gradle / Android Studio para crear sus aplicaciones, use build.gradle:

defaultConfig {
    targetSdkVersion 20
}

De lo contrario (Eclipse, etc.) use AndroidManifest.xml:

<uses-sdk android:minSdkVersion="..." android:targetSdkVersion="20" />
ByteHamster
fuente
¿Hay algún trabajo alrededor? ¿O qué puedo hacer para mostrar ese o cualquier otro icono correctamente?
Alejandro Casanova
He editado mi respuesta ya que he encontrado una solución después de leer el código fuente de Android.
ByteHamster
44
Muchas gracias por tu ayuda, pero por favor, por favor, dame algo de "contexto". ¿Dónde necesito hacer eso? ¿Qué es "entrada"?
Alejandro Casanova
El código fue tomado de AOSP solo para mostrar cómo encontré la solución :) He agregado una pequeña explicación sobre cómo implementarlo.
ByteHamster
Esto realmente funciona. ¿Alguna idea de por qué Google hizo esto? ¿Es esto un error o una característica?
m02ph3u5
24

Para evitar que los iconos de notificación se vuelvan blancos, use los iconos "Silueta" para ellos, es decir. imágenes de fondo blanco sobre transparente. Puedes usar Irfanview para construirlos:

  • elija una imagen, ábrala IrfanView, presione F12 para las herramientas de pintura, limpie la imagen si es necesario (elimine las partes no deseadas, alise y pula)
  • Image / Decrease Color Depth a 2 (para una imagen en blanco y negro)
  • Image / Negative (para una imagen en blanco sobre negro)
  • Image / Resize/Resample a 144 x 144 (use el Método de tamaño "Cambiar tamaño" no "Volver a muestrear", de lo contrario, la imagen se aumenta a 24 bits de color por píxel (24 BPP) nuevamente
  • File / Save as PNG, verifique Show option dialog, verifique Save Transparent Color, haga clic Save, luego haga clic en el color negro en la imagen para establecer el color transparente

Android parece estar usando la resolución de imagen dibujable-xxhdpi (144 x 144) solamente, así que copie el ic_notification.pngarchivo resultante en \AndroidStudio\Projects\...\app\src\main\res\drawable-xxhdpi. Úselo .setSmallIcon(R.drawable.ic_notification)en su código, o getNotificationIcon()úselo como Daniel Saidi sugirió anteriormente.

También puede usar el Android Asset Studio de Roman Nurik .

Thomas H. Schmidt
fuente
Traté de convertir mi ícono usando Photoshop, pero fallé, pero siendo un fanático de irfanview probé esto rápidamente cuando lo vi y funcionó maravillosamente. ¡Gracias!
Bruce
15

Otra opción es aprovechar los directorios dibujables (mipmap) específicos de la versión para proporcionar diferentes gráficos para Lollipop y superiores.

En mi aplicación, los directorios "v21" contienen iconos con texto transparente, mientras que los otros directorios contienen versiones no transparentes (para versiones de Android anteriores a Lollipop).

Sistema de archivos

Que debería verse más o menos así:

Android Studio

De esta manera, no necesita verificar los números de versión en el código, p. Ej.

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

Del mismo modo, puede hacer referencia a "ic_notification" (o como quiera llamarlo) en su carga de GCM si usa el atributo "icon".

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

Ian
fuente
3
Esto funciona y parece la solución más Android.
Sergey Galin
¿Estás diciendo que si Android elegirá el ícono de la carpeta mipmap-21 si la versión es lollipop, y si es menor que lollipop, elegirá de dibujable?
Lakshay
@ Ian, el enfoque de directorios es bueno para los recursos por versión de Android, pero ¿cómo puede configurar el setColor(sin involucrar código adicional) de esa manera?
Daniel
Los colores de @Daniel también pueden estar en directorios específicos de la versión, por ejemplo, "valores" y "valores-v21".
Ian
12

De acuerdo con las pautas de diseño de Android, debe usar una silueta para builder.setSmallIcon(R.drawable.some_notification_icon);Pero si aún desea mostrar un ícono colorido como ícono de notificación, aquí está el truco para la piruleta y el uso debajo del código siguiente. LargeIcon actuará como un icono de notificación principal y también debe proporcionar una silueta para smallIcon, ya que se mostrará en la parte inferior derecha de 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));
}

Y use pre-lollipop solo .setSmallIcon(R.mipmap.ic_launcher)con su constructor.

Muhammad Babar
fuente
11

Ahora Android Studio proporciona un complemento Image Asset , que generará un ícono en toda la carpeta de drawbale requerida

Image Asset Studio lo ayuda a crear varios tipos de iconos a diferentes densidades y le muestra exactamente dónde se colocarán en su proyecto. Incluye herramientas para ajustar sus íconos y agregar fondos, todo mientras muestra el resultado en un panel de vista previa, para que aparezcan exactamente como usted pretendía. Estas herramientas pueden optimizar drásticamente el proceso de diseño e importación de iconos.

Puede acceder a Image Asset haciendo clic en nuevo> haga clic en la opción Image Asset y se mostrará una ventana como esta: -

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

Nishchal
fuente
8

Estaba enfrentando el mismo problema y fue porque el ícono de notificación de mi aplicación no era plano. Para la versión de Android lollipop o incluso debajo de lollipop, el ícono de notificación de la aplicación debe ser plano, no use íconos con sombras, etc.

A continuación se muestra el código que funcionó perfectamente bien en todas las versiones de 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());
}

Icono equivocado
ingrese la descripción de la imagen aquí

Icono derecho

ingrese la descripción de la imagen aquí

Nauman Zubair
fuente
1
¿Dónde exactamente está solucionando el problema aquí?
IgorGanapolsky
Cómo crear el ícono correcto. ¿Es posible generar en línea? alguna herramienta ??
Jiks
@Jiks Sí, aquí está el enlace
Muhammad Sohaib Ayub
7

el canal alfa es el único dato de la imagen que Android usa para los íconos de notificación:

  • alpha == 1: los píxeles muestran blanco
  • alpha == 0: los píxeles se muestran como el color que eligió en Notification.Builder#setColor(int)

Esto se menciona en https://developer.android.com/about/versions/android-5.0-changes.html :

El sistema ignora todos los canales no alfa en los iconos de acción y en el icono de notificación principal. Debe suponer que estos íconos serán solo alfa.

Casi todos los dibujos incorporados parecen ser imágenes alfa adecuadas para esto, por lo que puede usar algo como:

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

pero todavía estoy buscando el documento API que oficialmente lo confirma.

Probado en Android 22.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
He probado setColoren Kitkat (API 19) y IceCreamSandwich (API 15), en ambos casos ignoró el color pero no se bloqueó . Entonces, ¿puedo omitir con seguridad la comprobación de la versión del sistema operativo?
Maria
@JohnLee No creo que pueda fallar, solo puede verse mal si no lo tienes en cuenta :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
3

eliminar el android:targetSdkVersion="21"de manifest.xml. ¡funcionará! y de esto no hay ningún problema en su apk, solo es un truco, aplico esto y encontré un ícono colorido en la notificación

Bhanu Sharma
fuente
9
¡Una idea totalmente mala para jugar "trucos" con el sistema! ¡No es una solución!
sud007
3

Las notificaciones son en escala de grises como se explica a continuación. No son en blanco y negro, a pesar de lo que otros han escrito. Probablemente haya visto iconos con varios tonos, como barras de fuerza de red.

Antes de API 21 (Lollipop 5.0), los iconos de color funcionan. Podría obligar a su aplicación a apuntar a la API 20, pero eso limita las características disponibles para su aplicación, por lo que no se recomienda. Puede probar el nivel de API en ejecución y establecer un icono de color o un icono de escala de grises de manera adecuada, pero probablemente no valga la pena. En la mayoría de los casos, es mejor ir con un ícono en escala de grises.

Las imágenes tienen cuatro canales, RGBA (rojo / verde / azul / alfa). Para los iconos de notificación, Android ignora los canales R, G y B. El único canal que cuenta es Alpha, también conocido como opacidad. Diseñe su icono con un editor que le dé control sobre el valor Alfa de los colores de su dibujo.

Cómo los valores alfa generan una imagen en escala de grises:

  • Alfa = 0 (transparente): estos píxeles son transparentes y muestran el color de fondo.
  • Alfa = 255 (opaco): estos píxeles son blancos.
  • Alfa = 1 ... 254: estos píxeles son exactamente lo que esperarías, proporcionando los tonos entre transparente y blanco.

Cambiándolo con setColor:

  • Llamar NotificationCompat.Builder.setColor(int argb). De la documentación para Notification.color:

    Color de acento (un número entero ARGB como las constantes en color) que las plantillas de estilo estándar deben aplicar al presentar esta notificación. El diseño actual de la plantilla construye una imagen de encabezado colorida superponiendo la imagen del icono (estampada en blanco) sobre un campo de este color. Los componentes alfa son ignorados.

    Mi prueba con setColor muestra que los componentes Alpha no se ignoran; en cambio, todavía proporcionan escala de grises. Los valores alfa más altos convierten un píxel en blanco. Los valores alfa más bajos convierten un píxel al color de fondo (negro en mi dispositivo) en el área de notificación, o al color especificado en la notificación desplegable. (Parece que otros han informado un comportamiento ligeramente diferente, ¡así que ten en cuenta!)

Jeremy Frank
fuente
2

Publicar el lanzamiento de Android Lollipop Android ha cambiado las pautas para mostrar iconos de notificación en la barra de notificaciones. La documentación oficial dice "Actualice o elimine los activos que involucran color. El sistema ignora todos los canales no alfa en los íconos de acción y en el ícono de notificación principal. Debe suponer que estos íconos serán solo alfa. El sistema dibuja íconos de notificación en blanco e iconos de acción en gris oscuro ". Ahora, lo que eso significa en términos simples es "Convertir todas las partes de la imagen que no desea mostrar a píxeles transparentes. Todos los colores y píxeles no transparentes se muestran en blanco "

Puede ver cómo hacer esto en detalle con capturas de pantalla aquí https://blog.clevertap.com/fixing-notification-icon-for-android-lollipop-and-above/

Espero que ayude

Rohit Khanna
fuente
2

Necesita importar la imagen PNG transparente de un solo color. Por lo tanto, puede establecer el color del icono del icono pequeño. De lo contrario, se mostrará en blanco en algunos dispositivos como MOTO

abhi.nalavade
fuente
1

Si está utilizando GoogleFireBaseMessaging, puede establecer la "identificación del icono" en la carga útil de "notificación" (me ayuda a resolver el problema del icono de la barra blanca):

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

establezca ic_notification en su propia identificación de R.drawable.

Maxim Firsoff
fuente
¿Dónde colocaste ese icono? Todo lo que obtengo es el ícono de mi aplicación y todos los archivos R.drawable que encuentro son archivos de clase binarios.
shinzou
@kuhaku se está refiriendo a un archivo ic_launcher.png en la carpeta 'dibujable'.
Johnson
0

También enfrenté demasiados problemas en esto, pero después de buscar en Internet encontré diferentes soluciones para este problema. Permítanme resumir todas las soluciones y explicar:

Nota: esta solución es para usuarios de Phonegap cordova

  1. Ejemplo

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

Debe establecer su valor android-targetSdkVersion en menos de 21. Entonces, después de configurar este valor, la imagen del icono de notificación aparecerá hasta Android 6 (Marshmallow), no funcionará en Android 7 (Nougat). Esta solución funcionó para mí.

  1. Cambie el statusbarStyle en su archivo de configuración. Ejemplo

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

Pero esta solución solo funcionará cuando se abra su aplicación. Entonces, supongo que esta solución no es la mejor solución, pero funcionó para muchos usuarios.

  1. Haz que tu ícono sea transparente. Esta solución funcionó para muchas personas. En realidad, en el desarrollo de la aplicación nativa, debemos proporcionarles tres imágenes: (a) Icono de la aplicación (b) Icono de notificación (c) Imagen del icono de la barra de estado, pero en el caso del desarrollo de aplicaciones móviles híbridas no hay opción para hazlo Así que haga que su icono sea transparente y esta solución resolverá su problema.

Y estoy seguro de que una de las soluciones anteriores funcionará para su problema.

Rinku Kumar
fuente
0

FYI: Si el icono no aparece, asegúrese de que su configuración de notificación local o remota contenga el nombre correcto del icono, es decir

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

Creo que es demasiado tarde para hablar sobre API 21, pero encontré una manera fácil.

Al usar 'Notificación personalizada (diseño personalizado)' s,

RemoteView's

setImageViewResource(int viewId, int srcId);

y

setImageViewUri(int viewId, Uri uri); 

hace que esas imágenes sean blancas en Lollipop (API 21).

Pero cuando se usa

setImageViewBitmap(int viewId, Bitmap bitmap);

¡La imagen no se enmascara en blanco!

Pastel de lima
fuente
-3

mezclar estas dos cosas en la aplicación 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
fuente
-38

android:targetSdkVersion="20"debería ser < 21.

Hemanth Dvshkk
fuente
1
No siga esta solución, seguro que podría funcionar, pero a costa de ejecutar sus aplicaciones en modo de compatibilidad para las versiones más recientes de Android.
king_below_my_lord