Powiadomienia push systemu Android: ikona nie wyświetla się w powiadomieniu, zamiast tego wyświetlany jest biały kwadrat

179

Moja aplikacja generuje powiadomienie, ale ikona, którą ustawiłem dla tego powiadomienia, nie jest wyświetlana. Zamiast tego otrzymuję biały kwadrat.

Próbowałem zmienić rozmiar png ikony (wymiary 720x720, 66x66, 44x44, 22x22). Co ciekawe, przy mniejszych wymiarach biały kwadrat jest mniejszy.

Wygooglowałem ten problem, jak również poprawny sposób generowania powiadomień iz tego co wyczytałem mój kod powinien być poprawny. Niestety nie jest tak, jak powinno.

Mój telefon to Nexus 5 z systemem Android 5.1.1. Problem występuje również na emulatorach, Samsung Galaxy s4 z Androidem 5.0.1 i Motorola Moto G z Androidem 5.0.1 (oba pożyczyłem i nie mam teraz)

Poniżej kod powiadomień i dwa zrzuty ekranu. Jeśli potrzebujesz więcej informacji, poproś o nie.

Dziękuję wam wszystkim.

@SuppressLint("NewApi") private void sendNotification(String msg, String title, String link, Bundle bundle) {
    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class);
    resultIntent.putExtras(bundle);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
            resultIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
    Notification notification;
    Uri sound = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.notificationsound);
    notification = new Notification.Builder(this)
                .setSmallIcon(R.drawable.lg_logo)
                .setContentTitle(title)
                .setStyle(new Notification.BigTextStyle().bigText(msg))
                .setAutoCancel(true)
                .setContentText(msg)
                .setContentIntent(contentIntent)
                .setSound(sound)
                .build();
    notificationManager.notify(0, notification);
}

bez otwierania powiadomienia powiadomienia otwarte

Blueriver
źródło
4
Prawdopodobny duplikat ikony paska powiadomień zmienia kolor na biały w Androidzie 5 Lollipop
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
Oto obejście stackoverflow.com/a/39142981/1939564
Muhammad Babar
rozwiązałeś ten problem? nadal mam ten sam problem, na górnym pasku stanu nadal widać białą przestrzeń dla powiadomienia, jeśli dodam przezroczysty obraz
AngelJanniee
Tak, rozwiązałem ten problem, tworząc przezroczystą ikonę lub kierując na SDK w wersji 20 lub starszej. Jeśli to nie rozwiąże problemu, być może podobny problem ma inną przyczynę. Proponuję ustawić docelową wersję SDK na 20 i sprawdzić, czy to coś zmienia. Jeśli tak się nie stanie, nie jestem pewien, czy to pytanie może ci pomóc :(
Blueriver

Odpowiedzi:

188

Przyczyna: W przypadku wersji 5.0 Lollipop „Ikony powiadomień muszą być całkowicie białe”.

Jeśli rozwiążemy problem z białą ikoną, ustawiając docelowy zestaw SDK na 20, nasza aplikacja nie będzie ukierunkowana na Androida Lollipop, co oznacza, że ​​nie możemy korzystać z funkcji specyficznych dla Lollipop.

Rozwiązanie dla docelowego Sdk 21

Jeśli chcesz obsługiwać ikony materiałów Lollipop, utwórz przezroczyste ikony dla wersji Lollipop i nowszych. Zobacz: https://design.google.com/icons/

Zajrzyj na http://developer.android.com/design/style/iconography.html , a zobaczymy, że biały styl to sposób wyświetlania powiadomień w Android Lollipop.

W Lollipopie Google sugeruje również użycie koloru, który będzie wyświetlany za białą ikoną powiadomienia. Odnieś Link: https://developer.android.com/about/versions/android-5.0-changes.html

Gdziekolwiek chcemy dodać kolory https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#setColor(int)

Implementacja Notification Builder dla wersji Lollipop OS poniżej i powyżej będzie wyglądać następująco:

Notification notification = new NotificationCompat.Builder(this);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    notification.setSmallIcon(R.drawable.icon_transperent);
    notification.setColor(getResources().getColor(R.color.notification_color));
} else { 
    notification.setSmallIcon(R.drawable.icon);
} 

Uwaga: funkcja setColor jest dostępna tylko w Lollipop i wpływa tylko na tło ikony.

To całkowicie rozwiąże Twój problem !!

Garima Mathur
źródło
Wow, dziękuję. Pomyślałem, że POWINNY być całkowicie białe, ponieważ niektóre aplikacje, które mam na telefonie, mają kolorowe ikony. Teraz widzę powód. Dziękuję Ci!
Blueriver,
3
Mówiąc targetSdkVersion 20 , uratowałeś mi dzień! wielkie dzięki.
Arshad Ali
11
To zła forma, aby ustawić docelową wersję SDK na <21 tylko ze względu na ikony. Lepiej to naprawić we właściwy sposób, jak opisano w tej odpowiedzi: stackoverflow.com/questions/27343202/ ...
user90766
1
ale w tle, gdy aplikacji nie ma na stosie, pokazuje białe ikony, co zrobić, aby w każdym przypadku uzyskać ten sam wynik
Pratik Vyas
1
Próbowałem wszystkiego, ale to nie działa. nadal pokazuje kropkę z kolorową wzmianką w pliku manifestu
Harsh Shah
67

Jeśli korzystasz z Google Cloud Messaging, ten problem nie zostanie rozwiązany przez zwykłą zmianę ikony. Na przykład to nie zadziała:

 Notification notification  = new Notification.Builder(this)
                .setContentTitle(title)
                .setContentText(text)
                .setSmallIcon(R.drawable.ic_notification)
                .setContentIntent(pIntent)
                .setDefaults(Notification.DEFAULT_SOUND|Notification.DEFAULT_LIGHTS|Notification.DEFAULT_VIBRATE)
                .setAutoCancel(true)
                .build();

Nawet jeśli ic_notification jest przezroczysty i biały. Musi być również zdefiniowany w metadanych Manifest, na przykład:

  <meta-data android:name="com.google.firebase.messaging.default_notification_icon"

            android:resource="@drawable/ic_notification" />

Metadane są umieszczane pod applicationtagiem, w celach informacyjnych.

Ruchir Baronia
źródło
6
Wielkie dzięki za wskazówkę dotyczącą metadanych w manifeście.
Eugen Timm
jak umieścić „@ drawable / ic_notification”? czy to jedna ikona? wiele? czy to jest PNG?
Luke Pighetti
1
@LukePighetti może ich być wiele, jeśli przesyłasz obrazy o różnych rozmiarach dla różnych rozdzielczości ekranu. W przeciwnym razie tak, może to być jeden plik PNG w katalogu do rysowania.
Ruchir Baronia
1
@RuchirBaronia więc dla powyższego przykładu res/drawable/ic_notification.pngo rozmiarze 196x196?
Luke Pighetti
thx @RuchirBaronia, głos za Meta-datasugestią tagu.
Ravi Vaniya
37

Naprawdę sugeruję przestrzeganie wytycznych Google dotyczących projektowania :

z komunikatem „Ikony powiadomień muszą być całkowicie białe”.

NJ
źródło
2
Twoja odpowiedź jest nawet lepsza niż ta, którą zaakceptowałem. Chciałabym też zaakceptować twoje. Nie mogę, ale masz moje +1 i wdzięczność. Twoje zdrowie!
Blueriver
2
To nie jest dobra odpowiedź. A co, jeśli interesariusze projektu musieliby kierować się na Androida 7? Nie mogę po prostu kierować reklamy na żadną wcześniejszą wersję SDK.
Neon Warge
1
Odrzuciłem tę odpowiedź, ponieważ jest zła. Pytający twierdzi, że nie mogę uruchomić mojej aplikacji na sdk21. Odpowiedź brzmi: „nie używaj SDK 21”
Utsav Gupta
1
To naprawdę nie jest rozwiązanie.
Jose Gómez,
1
Nie mogę znaleźć niczego w aktualnych wytycznych projektowych, które określałyby, że ikona musi być biała na przezroczystym tle. Mimo słabej dokumentacji nadal wydaje się, że tak jest.
imagio
29

Zadeklaruj ten kod w manifeście systemu Android:

<meta-data android:name="com.google.firebase.messaging.default_notification_icon" 

android:resource="@drawable/ic_stat_name" />

Mam nadzieję, że to ci się przyda.

vicky mahale
źródło
O mój! Ten działa idealnie w przypadku powiadomień push FCM! Dzięki
Crono
1
Gdzie stawiasz ic_stat_name? Czy to jeden png? czy to dużo? proszę pomóż!
Luke Pighetti
3
@Luke Pighetti W Android Studio Kliknij prawym przyciskiem w aplikacji >> Nowa >> Zasoby obrazu >> IconType (powiadomienie)
vicky mahale
1
(Wiem, że minęło trochę czasu, ale) Czy mógłbyś to wyjaśnić? Co to ma zrobić? Czy renderuje pełnokolorową nieprzezroczystą ikonę, czy co?
afe
To właściwa odpowiedź na powiadomienia w chmurze Firebase.
Greg Ellis
11

(Android Studio 3.5) Jeśli posiadasz najnowszą wersję Android Studio, możesz wygenerować obrazy powiadomień. Kliknij prawym przyciskiem myszy folder res > Nowy> Zasób obrazu . Następnie zobaczysz Konfiguruj zasoby obrazu, jak pokazano na poniższym obrazku. Change Icon Type do powiadomień Ikony . Twoje obrazy muszą być białe i przezroczyste. Ta opcja Konfiguruj zasoby obrazu wymusi tę regułę. Skonfiguruj zasoby obrazu Ważne: jeśli chcesz, aby ikony były używane do powiadomień w chmurze / push, musisz dodać metadane pod tagiem aplikacji, aby korzystać z nowo utworzonych ikon powiadomień.

  <application>
      ...
      <meta-data android:name="com.google.firebase.messaging.default_notification_icon"
          android:resource="@drawable/ic_notification" />
olearyj234
źródło
10

Możemy zrobić jak poniżej:

Utwórz nowy obiekt kreatora powiadomień i wywołaj go setSmallIcon()za pomocą obiektu kreatora powiadomień, jak w poniższym kodzie.

Utwórz metodę, w której sprawdzimy, na jakiej wersji systemu operacyjnego instalujemy naszą aplikację. Jeśli jest poniżej Lolipop, czyli API 21, przyjmie zwykłą ikonę aplikacji z kolorem tła, w przeciwnym razie przyjmie przezroczystą ikonę aplikacji bez tła. Zatem urządzenia korzystające z wersji systemu operacyjnego> = 21 ustawią kolor tła ikony za pomocą metody setColor()klasy Notification builder.

Przykładowy kod:

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);

notificationBuilder.setSmallIcon(getNotificationIcon(notificationBuilder));

private int getNotificationIcon(NotificationCompat.Builder notificationBuilder) {

   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
             int color = 0x008000;
             notificationBuilder.setColor(color);
             return R.drawable.app_icon_lolipop_above;

    } 
    return R.drawable.app_icon_lolipop_below;
}
rahul sharma
źródło
Testowałem setColorna Kitkat (API 19) i IceCreamSandwich (API 15), w obu przypadkach zignorował kolor, ale się nie zawiesił . Czy mogę więc bezpiecznie pominąć sprawdzanie wersji systemu operacyjnego?
Maria
10

Spróbuj tego

napotkałem ten sam problem, próbowałem wielu odpowiedzi, ale nie znalazłem żadnych rozwiązań, w końcu znalazłem sposób na rozwiązanie mojego problemu.

- zrób ikonę powiadomienia z przezroczystym tłem. Szerokość i wysokość aplikacji musi być taka jak poniżej i wklej to wszystko w swoim projekcie-> app-> src-> main-> res

  • MDPI 24 * 24

  • HDPI 36 * 36

  • XHDPI 48 * 48

  • XXHDPI 72 * 72


po powyższym wklej poniższy wiersz w swojej metodzie onMessageReceived


Intent intent = new Intent(this, News.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                    PendingIntent.FLAG_ONE_SHOT);
            Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
            {
                notificationBuilder.setSmallIcon(R.drawable.notify)
                                      //            .setContentTitle(title)
                            //                        .setContentText(message)
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .setContentIntent(pendingIntent);
            } else
                {
                    notificationBuilder.setSmallIcon(R.drawable.notify)
                       //                                .setContentTitle(title)
                        //                        .setContentText(message)
                            .setAutoCancel(true)
                            .setSound(defaultSoundUri)
                            .setContentIntent(pendingIntent);
            }
            NotificationManager notificationManager =
                    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.notify(0, notificationBuilder.build());

Nie zapomnij dodać tego kodu w pliku manifestu

<meta-data 
android:name="com.google.firebase.messaging.default_notification_icon" 
android:resource="@drawable/app_icon" />
Sunil
źródło
10
 <meta-data android:name="com.google.firebase.messaging.default_notification_icon"

        android:resource="@drawable/ic_notification" />

dodaj tę linię do pliku manifest.xml w bloku aplikacji

Sajidh Zahir
źródło
7

Jeśli chcesz zapewnić ikonę powiadomienia pomocy technicznej Lollipop, utwórz ikonę powiadomienia dwóch typów:

  1. normalna ikona powiadomienia: dla poniższej wersji Lollipop.
  2. ikona powiadomienia z przezroczystym tłem: dla wersji Lollipop i nowszych.

Teraz ustaw odpowiednią ikonę do konstruktora powiadomień w czasie wykonywania w wersji systemu operacyjnego:

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    mBuilder.setSmallIcon(R.drawable.ic_push_notification_transperent);
} else {
    mBuilder.setSmallIcon(R.drawable.ic_push_notification);
}
Haresh Chhelana
źródło
7

Wreszcie mam rozwiązanie tego problemu.

Ten problem występuje tylko wtedy, gdy aplikacja w ogóle nie jest uruchomiona. (ani w tle, ani na pierwszym planie) . Gdy aplikacja działa na pierwszym planie lub w tle, ikona powiadomienia jest wyświetlana prawidłowo . (Nie biały kwadrat)

Musimy więc ustawić taką samą konfigurację ikony powiadomień w interfejsach API zaplecza, co we Frontend.

We frontendzie użyliśmy React Native, a do powiadomień push wykorzystaliśmy pakiet act-native-fcm npm .

FCM.on("notification", notif => {
   FCM.presentLocalNotification({
       body: notif.fcm.body,
       title: notif.fcm.title,
       big_text: notif.fcm.body,
       priority: "high",
       large_icon: "notification_icon", // notification icon
       icon: "notification_icon",
       show_in_foreground: true,
       color: '#8bc34b',
       vibrate: 300,
       lights: true,
       status: notif.status
   });
});

Użyliśmy pakietu fcm-push npm przy użyciu Node.js jako zaplecza dla powiadomień wypychanych i ustawiliśmy strukturę ładunku w następujący sposób.

{
  to: '/topics/user', // required
  data: {
    id:212,
    message: 'test message',
    title: 'test title'
  },
  notification: {
    title: 'test title',
    body: 'test message',
    icon : 'notification_icon', // same name as mentioned in the front end
    color : '#8bc34b',
    click_action : "BROADCAST"
  }
}

To, co w zasadzie wyszukuje dla obrazu notification_icon przechowywanego lokalnie w naszym systemie Android.

Aniruddha Shevle
źródło
1
Twój problem BARDZO różni się od mojego, chociaż ma ten sam skutek. Dziękujemy za opublikowanie tej odpowiedzi, prawdopodobnie pomoże to komuś, kto korzysta z tego samego stosu technologii, którego używasz.
Blueriver
1
@IanWarburton: Nie ma potrzeby.
Aniruddha Shevle
5

Powiadomienia są w skali szarości jak wyjaśniono poniżej. Nie są czarno-białe, wbrew temu, co napisali inni. Prawdopodobnie widziałeś ikony z wieloma odcieniami, takie jak paski siły sieci.

Przed API 21 (Lollipop 5.0) działają kolorowe ikony. Możesz wymusić na aplikacji docelowe API 20, ale ogranicza to funkcje dostępne dla aplikacji, więc nie jest to zalecane. Możesz przetestować działający poziom interfejsu API i odpowiednio ustawić ikonę koloru lub ikonę w skali szarości, ale prawdopodobnie nie jest to opłacalne. W większości przypadków najlepiej jest wybrać ikonę w skali szarości.

Obrazy mają cztery kanały RGBA (czerwony / zielony / niebieski / alfa). W przypadku ikon powiadomień system Android ignoruje kanały R, G i B. Jedynym kanałem, który się liczy, jest alfa, znany również jako krycie. Zaprojektuj swoją ikonę za pomocą edytora, który zapewnia kontrolę nad wartością alfa kolorów rysowania.

Jak wartości alfa generują obraz w skali szarości:

  • Alfa = 0 (przezroczysty) - te piksele są przezroczyste i pokazują kolor tła.
  • Alpha = 255 (nieprzezroczyste) - te piksele są białe.
  • Alpha = 1 ... 254 - te piksele są dokładnie tym, czego można się spodziewać, zapewniając odcienie między przezroczystym a białym.

Zmiana tego za pomocą setColor:

  • Zadzwoń NotificationCompat.Builder.setColor(int argb). Z dokumentacji dla Notification.color:

    Kolor akcentujący (liczba całkowita ARGB, podobnie jak stałe w kolorze), który ma być stosowany przez standardowe szablony stylów podczas prezentowania tego powiadomienia. Bieżący projekt szablonu tworzy kolorowy obraz nagłówka, nakładając obraz ikony (z szablonem w kolorze białym) na pole tego koloru. Składniki alfa są ignorowane.

    Moje testy z setColor pokazują, że komponenty Alpha nie są ignorowane. Wyższe wartości alfa powodują zmianę koloru piksela na biały. Niższe wartości alfa powodują zmianę koloru piksela na kolor tła (czarny na moim urządzeniu) w obszarze powiadomień lub kolor określony w rozwijanym powiadomieniu.

Jeremy Frank
źródło
5

Rozwiązałem problem dodając poniższy kod do manifestu,

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/ic_stat_name" />

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/black" />

gdzie ic_stat_nameutworzono w Android Studio Kliknij prawym przyciskiem myszy na res >> Nowy >> Zasoby obrazu >> IconType (Powiadomienie)

I jeszcze jeden krok, który muszę zrobić po stronie php serwera z ładunkiem powiadomienia

$message = [
    "message" => [
        "notification" => [
            "body"  => $title , 
            "title" => $message
        ],

        "token" => $token,

    "android" => [
           "notification" => [
            "sound"  => "default",
            "icon"  => "ic_stat_name"
            ]
        ],

       "data" => [
            "title" => $title,
            "message" => $message
         ]


    ]
];

Zwróć uwagę na sekcję

    "android" => [
           "notification" => [
            "sound"  => "default",
            "icon"  => "ic_stat_name"
            ]
        ]

gdzie nazwa ikony "icon" => "ic_stat_name"powinna być taka sama jak zestaw w manifeście.

Haris
źródło
4

Znalazłem link, w którym możemy wygenerować własną białą ikonę,

wypróbuj ten link, aby wygenerować białą ikonę ikony Twojego programu uruchamiającego.

Otwórz ten link i prześlij swój ic_launcher lub ikonę powiadomienia

Ghanshyam Nayma
źródło
1

Możesz użyć różnych ikon dla różnych wersji. Po prostu ustaw logikę swojej ikony w następujący sposób:

int icon = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? R.drawable.colored_: R.drawable.white_tint_icon_for_lolipop_or_upper;
Md. Al-Rasel
źródło
1

Dla SDK> = 23 dodaj setLargeIcon

notification = new Notification.Builder(this)
            .setSmallIcon(R.drawable.ic_launcher)
            .setLargeIcon(context.getResources(), R.drawable.lg_logo))
            .setContentTitle(title)
            .setStyle(new Notification.BigTextStyle().bigText(msg))
            .setAutoCancel(true)
            .setContentText(msg)
            .setContentIntent(contentIntent)
            .setSound(sound)
            .build();
Caat c
źródło
1

Aby zredukować określone wersje SDK, możesz po prostu zrobić to: (zamień „#” na „0x”)

Notification notification = new NotificationCompat.Builder(this);
notification.setSmallIcon(R.drawable.icon_transperent);
notification.setColor(0x169AB9); //for color: #169AB9
dongkichan
źródło
0xFF169AB9, brakuje ci całkowicie nieprzezroczystego kanału alfa.
Eugen Pechanec
0

Jeśli chcesz zachować kolorową ikonę - Obejście problemu
Dodaj piksel o nieco innym kolorze do ikony.
W moim przypadku mam czarną ikonę z odcieniami i światłem. Po dodaniu ciemnoniebieskiego piksela działa.

Vouskopes
źródło
0

Mam podobny problem na Androidzie 8.0. Spróbuj użyć BIAŁEGO zasobu ikon. Mam biały kwadrat, kiedy próbuję użyć kolorowego obrazu dla ikony, kiedy zastępuję go białą ikoną, zaczyna działać.

Zeon
źródło