Ícone da barra de notificação fica branco no Android 5 Lollipop


207

Eu tenho um aplicativo mostrando notificações personalizadas. O problema é que, quando executado no Android 5, o pequeno ícone na barra de Notificação é mostrado em branco. Como posso consertar isso?


Rahul Sharma e basiam tem uma resposta melhor aqui - stackoverflow.com/questions/30795431/...
Rivu Chakraborty

Acontece-me quando rodando em Android 6, não 5.
Jaime Montoya

Claro, isso acontece com 5+ Android, é claro, também no Android 6 e 7. No momento da pergunta Android 5 foi a última versão e o recurso a causar este problema foi introduzido no Android 5.
Alejandro Casanova

Eu acho que é mais preciso dizer API Nível 21 (Android 5.0), API Nível 22 (Android 5.1), API Nível 23 (Android 6.0) etc. O termo "Android 5" é ambíguo porque você pode estar falando sobre o Android 5.0 ou Android 5.1 e quando testo as notificações e a maneira como os ícones aparecem no nível 22 da API vs. API nível 23, percebi que eles se comportam de maneira diferente.
Jaime Montoya

Respostas:


269

A resposta aceita não está (totalmente) correta. Certamente, ele faz com que os ícones de notificação sejam exibidos em cores, mas com uma GRANDE desvantagem - definindo o SDK de destino como inferior ao Android Lollipop!

Se você resolver o problema do ícone branco, definindo o SDK de destino como 20, conforme sugerido, o aplicativo não segmentará o Android Lollipop, o que significa que você não poderá usar os recursos específicos do Lollipop.

Dê uma olhada em http://developer.android.com/design/style/iconography.html e você verá que o estilo branco é como as notificações devem ser exibidas no Android Lollipop.

No Lollipop, o Google também sugere que você use uma cor que será exibida atrás do ícone de notificação (branco) - https://developer.android.com/about/versions/android-5.0-changes.html

Então, acho que a melhor solução é adicionar um ícone de silhueta ao aplicativo e usá-lo se o dispositivo estiver executando o Android Lollipop.

Por exemplo:

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

    return notification;

E, no 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;
}

34
Como você gera a silhueta? Sou desenvolvedor sem habilidades de photoshop e transparente de fundo usando ferramentas on-line ainda resulta em ícones brancos.
Chaitanya

6
@Chaitanya Use GIMP :)
ByteHamster

4
Essa solução não responde à pergunta por que o processo de compilação do Android modifica um PNG perfeitamente correto e o comprime e remove o canal alfa.
philk


4
em vez de verificar a partir applay código de versão da plataforma modificador para a pasta drawable - drawable / drawable-v21 e coloque ícone correto
Igor Wojda

72

Concordo totalmente com o usuário Daniel Saidi. Para se ter Colorpor NotificationIconque estou escrevendo esta resposta.

Para isso, você deve criar um ícone Silhouettee criar uma seção Transparentonde quiser adicionar o seu Colors. ou seja,

insira a descrição da imagem aqui

Você pode adicionar sua cor usando

.setColor(your_color_resource_here)

OBSERVAÇÃO: setColorestá disponível apenas Lollipoppara que você verifiqueOSVersion

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

Você também pode conseguir isso usando Lollipopcomo alvo SDK.

Todas as instruções NotificationIconfornecidas nas Linhas de guia de notificação do Google Developer Console .

Tamanho do ícone de notificação preferencial 24x24dp

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

E também consulte este link para Tamanhos de ícones de notificação para obter mais informações.


4
isto é muito boa idéia para definir a cor de fundo como notification.setColor (your_color_resource_here)
TejaDroid

1
Então, eu tentei isso, e o ícone de notificação tem o plano de fundo colorido quando abro a sombra da notificação. Mas, na própria bandeja, ainda é um ícone branco
Discrição rabino

1
esta solução está correta .. possui um ícone de notificação com costas transparentes .. e por silhueta, o ícone não precisa ser apenas preto .. o ícone pode ter cores; seu justo que o L android irá converter show de cores como white..and versões do Android anteriores mostrará o ícone como é
Lakshay

estou adicionando setColor para abaixo pirulito mostrando ícone fina ic_launcher mas em 6,0 mostrando quadrado branco ícone de ajuda por favor me
Harsha

Eu testei setColorno Kitkat (API 19) e IceCreamSandwich (API 15), em ambos os casos, ignorou a cor, mas não travou . Então, posso omitir com segurança a verificação da versão do sistema operacional?
Maria

47

Este é o código que o Android usa para exibir ícones de notificação:

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

Portanto, você precisa definir a versão sdk de destino para algo <21e os ícones permanecerão coloridos. Essa é uma solução feia, mas faz o que se espera que seja feito. De qualquer forma, eu realmente sugiro seguir as Diretrizes de design do Google : "Os ícones de notificação devem ser totalmente brancos".

Aqui está como você pode implementá-lo:

Se você estiver usando o Gradle / Android Studio para criar seus aplicativos, use build.gradle:

defaultConfig {
    targetSdkVersion 20
}

Caso contrário (Eclipse etc), use AndroidManifest.xml:

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

Existe alguma solução alternativa? Ou o que posso fazer para mostrar esse ou qualquer outro ícone corretamente?
Alejandro Casanova

Editei minha resposta porque encontrei uma solução alternativa depois de ler o código-fonte do Android.
ByteHamster 7/02

4
Muito obrigado por sua ajuda, mas, por favor, forneça-me algum "contexto". Onde eu preciso fazer isso? O que é "entrada"?
Alejandro Casanova

O código foi retirado do AOSP apenas para mostrar como encontrei a solução alternativa :) Adicionei uma pequena explicação sobre como implementá-lo.
ByteHamster 7/02

Isso realmente funciona. Algum palpite por que o Google fez isso? isso é um erro ou uma característica?
M02ph3u5

24

Para evitar que os ícones de notificação fiquem brancos, use os ícones "Silhouette" para eles, por exemplo. imagens de fundo branco sobre transparente. Você pode usar o Irfanview para construí-los:

  • escolha uma imagem, abra IrfanView, pressione F12 para as ferramentas de pintura, limpe a imagem, se necessário (remova as partes indesejadas, alise e polonês)
  • Image / Decrease Color Depth a 2 (para uma foto em preto e branco)
  • Image / Negative (para uma imagem em branco sobre preto)
  • Image / Resize/Resample para 144 x 144 (use o Método de tamanho "Redimensionar" e não "Reamostrar", caso contrário, a imagem será aumentada para 24 bits de cor por pixel (24 BPP) novamente
  • File / Save as PNG, marque Show option dialog, marque Save Transparent Color, clique Savee clique na cor preta na imagem para definir a cor transparente

O Android parece estar usando apenas a resolução da imagem drawable-xxhdpi (144 x 144), então copie o ic_notification.pngarquivo resultante para \AndroidStudio\Projects\...\app\src\main\res\drawable-xxhdpi. Use .setSmallIcon(R.drawable.ic_notification)no seu código ou use getNotificationIcon()como Daniel Saidi sugeriu acima.

Você também pode usar o Android Asset Studio de Roman Nurik .


Tentei converter meu ícone usando o photoshop, mas não consegui, mas como fã do irfanview, tentei rapidamente quando o vi e funcionou maravilhosamente. Obrigado!
Bruce

15

Outra opção é tirar proveito dos diretórios drawable específicos da versão (mipmap) para fornecer gráficos diferentes para o Lollipop e versões posteriores.

No meu aplicativo, os diretórios "v21" contêm ícones com texto transparente, enquanto os outros diretórios contêm versão não transparente (para versões do Android anteriores ao Lollipop).

Sistema de arquivo

Que deve ser algo como isto:

Android Studio

Dessa forma, você não precisa procurar números de versão no código, por exemplo,

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

Da mesma forma, você pode fazer referência a "ic_notification" (ou o que você escolher) na sua carga útil do GCM, se você usar o atributo "icon".

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


3
Isso funciona e se parece com a solução mais Android.
Sergey Galin

você está dizendo que, se o Android escolher o ícone da pasta mipmap-21, se a versão for pirulito, e se for menor que o pirulito, será possível desenhar no drawable?
Lakshay

@ Ian, a abordagem de diretórios é boa para recursos por versão do Android, mas como você pode definir o setColor(sem envolver código extra) dessa maneira?
Daniel

As cores do @ Daniel também podem estar em diretórios específicos de versão, por exemplo, "values" e "values-v21".
Ian

12

De acordo com as diretrizes de design do Android, você deve usar uma silhueta para builder.setSmallIcon(R.drawable.some_notification_icon);Mas se você ainda deseja mostrar um ícone colorido como um ícone de notificação, aqui está o truque para pirulito e, acima, use o código abaixo. O largeIcon atuará como um ícone de notificação principal e você também precisará fornecer uma silhueta para o smallIcon, pois será mostrado na parte inferior direita do 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));
}

E use antes do pirulito apenas .setSmallIcon(R.mipmap.ic_launcher)com o seu construtor.


11

Agora, o Android Studio fornece um plug-in Image Asset , que será gerado ícone em todas as pastas de drawbale necessárias

O Image Asset Studio ajuda a criar vários tipos de ícones em diferentes densidades e mostra exatamente onde eles serão colocados no seu projeto. Ele inclui ferramentas para ajustar seus ícones e adicionar cenários, enquanto exibe o resultado em um painel de visualização, para que apareçam exatamente como você pretendia. Essas ferramentas podem otimizar drasticamente o processo de design e importação de ícones.

Você pode acessar o Image Asset clicando em novo> clique na opção Image Asset e a janela será exibida assim: -

insira a descrição da imagem aqui

insira a descrição da imagem aqui


8

Eu estava enfrentando o mesmo problema e foi por causa do meu ícone de notificação do aplicativo não estar plano. Para pirulito versão Android ou mesmo pirulito abaixo, o ícone de notificação do aplicativo deve ser plano, não use o ícone com sombras etc.

Abaixo está o código que funcionou perfeitamente em todas as versões do 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());
}

Ícone errado
insira a descrição da imagem aqui

Ícone direito

insira a descrição da imagem aqui


1
Onde exatamente você está corrigindo o problema aqui?
IgorGanapolsky

Como criar o ícone certo. É possível gerar online? qualquer ferramenta ??
Jiks

@Jiks Sim, aqui está o link
Muhammad Sohaib Ayub

7

O canal alfa é o único dado da imagem que o Android usa para ícones de notificação:

  • alpha == 1: pixels mostram branco
  • alpha == 0: os pixels são exibidos como a cor escolhida em Notification.Builder#setColor(int)

Isso é mencionado em https://developer.android.com/about/versions/android-5.0-changes.html :

O sistema ignora todos os canais não alfa nos ícones de ação e no ícone principal de notificação. Você deve assumir que esses ícones serão apenas alfa.

Quase todos os drawables internos parecem ser imagens alfa adequadas para isso, então você pode usar algo como:

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

mas ainda estou procurando o documento da API que confirma oficialmente isso.

Testado no Android 22.


Eu testei setColorno Kitkat (API 19) e IceCreamSandwich (API 15), em ambos os casos, ignorou a cor, mas não travou . Então, posso omitir com segurança a verificação da versão do sistema operacional?
Maria

@JohnLee Eu não acho que ele pode falhar, só pode parecer ruim se você não levar em conta :-)
Ciro Santilli 8 冠状 病 六四 事件

3

remova o android:targetSdkVersion="21"manifest.xml. vai funcionar! e a partir disso, não há nenhum problema no seu apk, apenas um truque eu aplico isso e encontrei o ícone colorido na notificação


9
Idéia totalmente ruim para fazer "truques" com o sistema! Não é uma solução!
sud007

3

As notificações estão em escala de cinza, conforme explicado abaixo. Eles não são em preto e branco, apesar do que outros escreveram. Você provavelmente já viu ícones com vários tons, como barras de força da rede.

Antes da API 21 (Lollipop 5.0), os ícones de cores funcionavam. Você pode forçar seu aplicativo a segmentar a API 20, mas isso limita os recursos disponíveis para ele, portanto, não é recomendado. Você pode testar o nível da API em execução e definir um ícone de cor ou em escala de cinza adequadamente, mas isso provavelmente não vale a pena. Na maioria dos casos, é melhor usar um ícone em escala de cinza.

As imagens têm quatro canais, RGBA (vermelho / verde / azul / alfa). Para ícones de notificação, o Android ignora os canais R, G e B. O único canal que conta é o Alpha, também conhecido como opacidade. Crie seu ícone com um editor que lhe dê controle sobre o valor Alfa de suas cores de desenho.

Como os valores Alpha geram uma imagem em escala de cinza:

  • Alfa = 0 (transparente) - esses pixels são transparentes, mostrando a cor de fundo.
  • Alfa = 255 (opaco) - esses pixels são brancos.
  • Alfa = 1 ... 254 - Esses pixels são exatamente o que você esperaria, fornecendo os tons entre transparente e branco.

Alterando-o com setColor:

  • Ligue NotificationCompat.Builder.setColor(int argb). A partir da documentação para Notification.color:

    Cor de destaque (um número inteiro ARGB como as constantes em Cor) a ser aplicado pelos modelos de estilo padrão ao apresentar esta notificação. O design atual do modelo constrói uma imagem de cabeçalho colorida sobrepondo a imagem do ícone (impressa em branco) sobre um campo dessa cor. Componentes alfa são ignorados.

    Meus testes com setColor mostram que os componentes Alpha não são ignorados; em vez disso, eles ainda fornecem escala de cinza. Valores alfa mais altos tornam um pixel branco. Os valores alfa mais baixos transformam um pixel na cor de fundo (preta no meu dispositivo) na área de notificação ou na cor especificada na notificação suspensa. (Parece que outros relataram comportamentos ligeiramente diferentes, portanto, esteja ciente!)


2

Post android Lollipop release android mudou as diretrizes para exibir ícones de notificação na barra de notificações. A documentação oficial diz "Atualizar ou remover ativos que envolvem cores. O sistema ignora todos os canais não alfa nos ícones de ação e no ícone principal de notificação. Você deve assumir que esses ícones serão apenas alfa. O sistema desenha ícones de notificação em branco e ícones de ação em cinza escuro. " Agora, o que isso significa em termos de leigos é "Converta todas as partes da imagem que você não deseja mostrar em pixels transparentes. Todas as cores e pixels não transparentes são exibidos em branco "

Você pode ver como fazer isso em detalhes com as capturas de tela aqui https://blog.clevertap.com/fixing-notification-icon-for-android-lollipop-and-above/

espero que ajude


2

Você precisa importar a imagem PNG transparente de cor única. Assim, você pode definir a cor do ícone no ícone pequeno. Caso contrário, será mostrado em branco em alguns dispositivos como o MOTO


1

Se você estiver usando o GoogleFireBaseMessaging, poderá definir "id do ícone" na carga útil "notificação" (isso ajuda a resolver o problema do ícone da barra branca):

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

defina ic_notification como seu próprio ID em R.drawable.


Onde você colocou esse ícone? Tudo o que recebo é o ícone do meu aplicativo e todos os arquivos R.drawable que encontro são arquivos de classe binária.
Shinzou 11/08/19

@kuhaku ele está se referindo a um arquivo ic_launcher.png na pasta 'drawable'.
Johnson

0

Eu também enfrentei muitos problemas com isso, mas depois de pesquisar em toda a Internet, encontrei soluções diferentes para esse problema. Deixe-me resumir todas as soluções e explicar:

Nota: Esta solução é para usuários do Phonegap cordova

  1. Exemplo

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

Você precisa definir seu valor android-targetSdkVersion como menor que 21. Portanto, depois de definir esse valor, a imagem do ícone de notificação aparecerá até o Android 6 (Marshmallow), e não funcionará no Android 7 (Nougat). Esta solução funcionou para mim.

  1. Mude o statusbarStyle no seu arquivo de configuração. Exemplo

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

Mas essa solução funcionará apenas quando o aplicativo for aberto. Então, acho que essa solução não é a melhor, mas funcionou para muitos usuários.

  1. Faça seu ícone transparente. Esta solução funcionou para muitas pessoas. Na verdade, o problema é que, no desenvolvimento de aplicativos nativos, precisamos fornecer três imagens: (a) Ícone do aplicativo (b) Ícone de notificação (c) Imagem do ícone da barra de status, mas no caso do desenvolvimento de aplicativos móveis híbridos, não há opção para faça isso. Portanto, torne seu ícone transparente e esta solução resolverá seu problema.

E tenho certeza de que uma das soluções acima funcionará para o seu problema.


0

FYI: Se o ícone não aparecer, verifique se a sua configuração de notificação local ou remota contém o nome correto do ícone, ou seja

'largeIcon' => 'ic_launcher',
'smallIcon' => 'ic_launcher' // defaults to ic_launcher, 

0

Acho que é tarde demais para falar sobre a API 21, mas achei uma maneira fácil.

Ao usar as 'Notificações personalizadas (layout personalizado)',

RemoteView

setImageViewResource(int viewId, int srcId);

e

setImageViewUri(int viewId, Uri uri); 

torna essas imagens brancas no pirulito (API 21).

Mas ao usar

setImageViewBitmap(int viewId, Bitmap bitmap);

A imagem não fica com máscara branca!



-3

misture essas duas coisas no app 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"deve ser < 21.


1
Por favor, não siga esta solução, com certeza pode funcionar, mas com o custo de executar seus aplicativos no modo de compatibilidade para as versões mais recentes do Android.
king_below_my_lord
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.