Jak naprawić: android.app.RemoteServiceException: Złe powiadomienie wysłane z pakietu *: Nie można utworzyć ikony: StatusBarIcon

127

W dziennikach awarii widzę następujący wyjątek:

android.app.RemoteServiceException: Bad notification posted from package com.my.package: Couldn't create icon: StatusBarIcon(pkg=com.my.package user=0 id=0x7f02015d level=0 visible=true num=0 )
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1456)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:146)
    at android.app.ActivityThread.main(ActivityThread.java:5487)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
    at dalvik.system.NativeStart.main(Native Method)

Publikuję moje powiadomienie z IntentService z zestawu PendingIntent za pośrednictwem AlarmManager przy użyciu następującej metody. Wszystkie wartości przekazywane tutaj pochodzą z dodatków pakietu w PendingIntent / IntentService.

/**
 * Notification 
 *
 * @param c
 * @param intent
 * @param notificationId
 * @param title
 * @param message
 * @param largeIcon
 * @param smallIcon
 */
public static void showNotification(Context c, Intent intent,
        int notificationId, String title, String message, int largeIcon,
        int smallIcon) {
    PendingIntent detailsIntent = PendingIntent.getActivity(c,
            notificationId, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    // BUILD
    NotificationCompat.Builder mNotifyBuilder = new NotificationCompat.Builder(
            c);
    // TITLE
    mNotifyBuilder.setContentTitle(title).setContentText(message);

    // ICONS
    mNotifyBuilder.setSmallIcon(smallIcon);
    if (Util.isAndroidOSAtLeast(Build.VERSION_CODES.HONEYCOMB)) {
        Bitmap large_icon_bmp = ((BitmapDrawable) c.getResources()
                .getDrawable(largeIcon)).getBitmap();
        mNotifyBuilder.setLargeIcon(large_icon_bmp);
    }

    mNotifyBuilder.setContentIntent(detailsIntent);
    mNotifyBuilder.setVibrate(new long[] { 500, 1500 });
    mNotifyBuilder.setTicker(message);
    mNotifyBuilder.setContentText(message);

    // NOTIFY
    NotificationManager nm = (NotificationManager) c
            .getSystemService(Context.NOTIFICATION_SERVICE);
    nm.notify(notificationId, mNotifyBuilder.build());
}

Z tego, co widziałem w przypadku innych odpowiedzi - wyjątek, który widzę, ma miejsce, gdy setSmallIcon()nie jest poprawnie wywołany.

Sprawdziłem i dwukrotnie sprawdziłem, czy przekazywane identyfikatory zasobów są poprawne.

FishStix
źródło
3
Mam ten sam błąd (raporty o awariach z działającej aplikacji). Nie mogę odtworzyć tego na moim urządzeniu. Obecnie myślę, że to dlatego, że ludzie zmodyfikowali plik .apk
przyciemnij
Chłopaki, w jaki sposób mogę rozwiązać ten problem. Używam png, ale bardzo rzadko
dochodzi do

Odpowiedzi:

98

To, co się działo, polegało na tym, że dołączałem odwołanie do ikony w pakiecie PendingIntent jako liczbę całkowitą, a ta liczba całkowita była później przywoływana podczas wysyłania do NotificationManager.

Pomiędzy pobraniem odwołania w postaci liczby całkowitej a wyłączeniem oczekującej intencji aplikacja została zaktualizowana, a wszystkie odniesienia do rysowania zostały zmienione. Liczba całkowita, która kiedyś odwoływała się do właściwego elementu rysunkowego, teraz odnosiła się do nieprawidłowego elementu rysunkowego lub w ogóle go nie zawiera (brak w ogóle - powodując awarię)

FishStix
źródło
8
Dziwaczny. Innymi słowy, tego nie da się naprawić, prawda? Widzę te same awarie w mojej aplikacji.
Matthias
Wydaje się, że nie da się tego naprawić. W przyszłości będę musiał wymyślić inny sposób publikowania powiadomień ze zdjęciami w przyszłości ...
FishStix
A co jeśli spróbujemy ustawić textSize zdalnego podglądu jako ret.setInt (id, "setTextSize", 20); To także ulega awarii. Wiem, że musimy też podać jednostki, ale jak to zrobić z taką sygnaturą metody. Dowolny wskaźnik?
bitsabhi
1
Czy byłoby możliwe wyczyszczenie powiadomienia i wszystkiego, co dotyczy, gdy aplikacja zostanie zabita, aby zaktualizować? (Zakładając, że dzięki temu aplikacja uniknie problemu)
NoHarmDan
3
Jeśli chcesz odwołać się do R.drawable.my_image, bezpieczniej jest zapisać go w pakiecie jako ciąg ( bundle.putString("img", "my_image")a następnie przekonwertować w razie potrzeby na rzeczywistą liczbę całkowitą @DrawableRes w następujący sposób:ctx.resources.getIdentifier(bundle.getString("img"), "drawable", ctx.packageName)
vanomart
52

VectorXmlWiadomo, że użycie wewnątrz powiadomienia powoduje ten problem. Użyj png

Bubunyo Nyavor
źródło
4
Używano tylko plików PNG.
FishStix
W moim przypadku, miałem wektor w drawablefolderze i PNG w drawable-hdpi, xhdpiitp Ale nie było dla png drawable-mdpi, i rozbił się na urządzeniu MDPI na zamieszczając powiadomienie.
Vadim Kotov
34

Nie używaj SVG na KitKat!

Miałem ten sam problem za każdym razem, gdy chciałem pokazać powiadomienie na Kitkacie. To, co spowodowało u mnie problem, to to, że zdefiniowałem każdą ikonę w xml (z svg), małą ikonę i również ikonę akcji. Po ich wymianie na png-s problem rozwiązał się po mojej stronie.

bendaf
źródło
4
Mogę potwierdzić. Elementy wektorowe w powiadomieniach powodują wyjątek RemoteServiceException w KitKat.
Khizhny Andrey
2
W przypadku KitKat problem został rozwiązany, kiedy zamieniłem XML na PNG w: new NotificationCompat.Builder (context, CHANNEL_ID) .setSmallIcon (R.drawable.my_icon)
Andrew Glukhoff
1
To zadziałało dla mnie. Uruchomiłem API 19 i użyłem pliku SVG jako ikony powiadomienia i
dawałem
10

android.app.RemoteServiceException: wysłano złe powiadomienie

Miałem ten sam problem, ale został rozwiązany. Mój problem dotyczy „pliku xml” widoku zdalnego.

W moim pliku xml zostałem dodany Viewmiędzy LinearLayoutseparatorem for.

<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:id="@+id/view"
    android:background="#000000" />

Powyższy Viewkomponent tworzy wyjątek złego powiadomienia. Ten wyjątek dotyczy tylko pliku XML Remoteviews.

Po usunięciu tego składnika View mój kod wykonywał się poprawnie, bez żadnych wyjątków. Więc czułem, że szuflada powiadomień nie akceptuje żadnych niestandardowych widoków.

Więc nie rysujesz niczego takiego jak powyższy widok w pliku .xml RemoteViewobiektu.

Kona Suresh
źródło
9

Mój problem polegał na tym, że ikona, której używałem

.setSmallIcon(R.drawable.ic_stat_push_notif)

nie został odpowiednio wygenerowany. Według oficjalnego dokumentu :

Jak opisano w sekcji Zapewnianie zestawów ikon specyficznych dla gęstości i obsługa wielu ekranów, należy utworzyć osobne ikony dla wszystkich uogólnionych gęstości ekranu, w tym ekranów o małej, średniej, dużej i bardzo dużej gęstości. Zapewnia to prawidłowe wyświetlanie ikon na różnych urządzeniach, na których można zainstalować aplikację.

Najlepszym sposobem na wypełnienie powyższego było więc skorzystanie z Generatora Powiadomień dostarczonego przez Romana Nurika na https://romannurik.github.io/AndroidAssetStudio/index.html

W ten sposób możesz użyć obrazu (biorąc pod uwagę, że musi on mieć przezroczyste tło) i pozwolić generatorowi wykonać zadanie za Ciebie, generując różne rozmiary ikon powiadomień.

Najważniejsze jest to, że jeśli generator ikon po przejrzeniu obrazu, którego zamierzasz użyć, pokazuje białe wypełnione kółko lub kwadrat, są problemy z twoim obrazem, być może dlatego, że nie ma żadnych przezroczystości, więc upewnij się, że masz to ok.

Carlos Daniel
źródło
2
W moim przypadku, miałem wektor w drawablefolderze i PNG w drawable-hdpi, xhdpiitp Ale nie było dla png drawable-mdpi, i rozbił się na urządzeniu MDPI na zamieszczając powiadomienie.
Vadim Kotov
7

W mojej aplikacji ten błąd występuje tylko podczas aktualizacji. Jeśli identyfikator zasobu zmieni się w nowszej wersji, system Android RemoteViewmoże nie znaleźć zasobu i wyrzucić plik RemoteServiceException. Jeśli opublikujesz trzecią wersję i nie zmienisz identyfikatora zasobu, błędy mogą zniknąć tylko tymczasowo .

Możliwe jest ograniczenie tego rodzaju błędów poprzez edycję res/values/public.xmli res/values/ids.xml. Kompilator wygeneruje indywidualny identyfikator zasobu, jeśli identyfikator zasobu nie znajduje się w public.xmllub ids.xml. Kiedy zmienisz nazwę zasobu lub dodasz nowe zasoby, identyfikator może się zmienić, a niektóre urządzenia mogą go nie znaleźć.

Tak więc krok jest następujący:

  1. Zdekompiluj plik apk i res/valuesznajdź public.xmliids.xml
  2. Znajdź wszystkie zasoby związane z RemoteView w swojej aplikacji i skopiuj je (ciągi znaków, wymiar, rysowanie, układ, identyfikator, kolor ...)
  3. Utwórz public.xmli ids.xmlpod res/valueskodem źródłowym i wklej skopiowane linie

Uwaga:

Gradle 1.3.0 i nowsze wersje ignorują lokalny plik public.xml . Aby to działało, musisz dodać skrypt w swoimbuild.gradle

afterEvaluate {
    for (variant in android.applicationVariants) {
        def scope = variant.getVariantData().getScope()
        String mergeTaskName = scope.getMergeResourcesTask().name
        def mergeTask = tasks.getByName(mergeTaskName)
        mergeTask.doLast {
            copy {
                int i=0
                from(android.sourceSets.main.res.srcDirs) {
                    include 'values/public.xml'
                    rename 'public.xml', (i == 0? "public.xml": "public_${i}.xml")
                    i++
                }
                into(mergeTask.outputDir)
            }
        }
    }
}

Uwaga: ten skrypt nie obsługuje projektu modułów podrzędnych. Próbuję to naprawić.

sztuczka gromu
źródło
3

Masz tę samą ikonę

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

a ty powiadomienie

 NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this, channelId)
                        .setSmallIcon(R.drawable.ic_stat_name)
                        .setContentTitle("Title")
                        .setContentText(messageBody)
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .setContentIntent(pendingIntent);
Tarun Umath
źródło
2
Przekazałem obraz wektorowy jako zasób i myślę, że spowodował awarie na urządzeniach oneplus / Android 6. Nie jestem pewien na 100%.
Alexey
3

Na wypadek, gdyby ikona nie była ważna, możesz wymienić,

R.drawable.your_icon

Do

android.R.drawable.some_standard_icon

To działa!

Ashwin Balani
źródło
2

Miałem RemoteServiceException, gdy używanie Notification w mojej klasie rozszerza się z FirebaseMessagingService. Dodałem następujący kod do AndroidManifest.xml:

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

Również zasób ic_small ustawiony w instancji klasy Notification.Builder za pomocą metody setSmallIcon (ikona int).

Вячеслав Бондаренко
źródło
te metadane należy dodać wewnątrz tagów <service </service>?
Andrey
2

W Android Studio w wersji 3.0.0 i nowszych podczas dodawania nowego obrazu do folderu drawables wybierz drawable zamiast drawable-v24.wprowadź opis obrazu tutaj

Jeśli obraz, którego używasz, jest już a (v24), po prostu skopiuj go i wklej w tym samym katalogu (np. Drawables). Tym razem zapyta Cię, który zwykły czy v24 - po prostu upewnij się, że nie jest to v24 i spróbuj ponownie, to powinno naprawić błąd.

Haider Malik
źródło
Uwaga - jeśli jesteś w widoku „Android”, przełącz go na widok „Projekt”. W widoku Androida możesz nie widzieć katalogu drawables v24
Hatzil
2

Ten sam problem wystąpił również ze mną i rozwiązałem to samo

POWÓD : Dzieje się tak, ponieważ używamy wektorów do rysowania dla RemoteViews i generowania wektorów do rysowania w czasie kompilacji. Nie jestem również pewien, dlaczego niektóre urządzenia nie są w stanie wykryć wygenerowanego identyfikatora zasobów do rysowania podczas uruchamiania aplikacji. Ale tak, to był powód.

REPRODUCE Kroki 1. Zainstaluj poprzednią kompilację. 2. Wyślij powiadomienie 3. Zaktualizuj kompilację za pomocą kodu następnej wersji 4. Po zaktualizowaniu aplikacji nie otwieraj aplikacji i nie wysyłaj powiadomienia ponownie

ROZWIĄZANIE Zastąp wektor do rysowania na normalny plik do rysowania (.png lub .jpg).

Mam nadzieję, że to rozwiązuje problem.

Gajju
źródło
1

Jeśli masz powiadomienie widoczne, gdy Twoja aplikacja jest aktualizowana, możesz się z tym spotkać. Może być konieczne utworzenie odbiornika BroadcastReceiver, który czeka na wiadomość PACKAGE_CHANGED, po czym zamkniesz wszystkie usługi, które również odrzucą powiązane z nimi powiadomienia.

 <receiver android:name=".MyBroadcastReceiver">
    <intent-filter>
        <action android:name="android.intent.action.PACKAGE_CHANGED" />
    </intent-filter>
</receiver>
Glaucus
źródło
0

Miałem ten sam problem, gdy ustawiłem powiadomienie w pakiecie. Spróbowałem tego i rozwiązało to mój problem:

builder.setLargeIcon(large_icon);
builder.setSmallIcon(R.drawable.small_icon);

Upewnij się, że metoda setLargeIcon () została wywołana przed setSmallIcon ().

Galareta
źródło
4
Dlaczego to powinno pomóc?
limitium
0

Ja też miałem ten sam problem. Problem dotyczy ikony, której używasz, używałem android.R.drawable.stat_sys_download. Przejdź do drawables.xml i wklej to.

<resources>
 <item name="ic_start_download" type="drawable">@android:drawable/stat_sys_download</item>
</resource>

a następnie w swoim kodzie

builder.setSmallIcon(R.drawable.ic_start_download);

Możesz spróbować innego obrazu zamiast tego obrazu

karthik vishnu kumar
źródło
0

Mój sposób na rozwiązanie tego problemu: miałem „złe” widoki w moim układzie (np. Pole wyboru) - więc je usunąłem.

Wydaje się, że RemoteViews obsługuje tylko obrazy i teksty (co potwierdza przeczytanie dokumentu).

Benjamin Piette
źródło
0

Miałem RemoteServiceException podczas korzystania z android.support.constraint.ConstraintLayout. Zmień to na LinearLayout lub Relative, a także android: layout_height = "wrap_content" dla kontenera

JustAndrew
źródło
0

(nie jest to rozwiązanie dla bieżącego pytania, ale pomaga komuś z podobnym podstawowym problemem). Ja też miałem ten sam problem, ale w moim przypadku użyłem uszkodzonego pliku .png, który powoduje ten sam problem. Więc usunąłem go i ponownie dołączyłem poprawny plik .png.

RameshJanagama
źródło
0

Zastąp <android.support.v7.widget.AppCompatTextViewz <TextViewniestandardowego układu powiadomień.

Ponieważ android.support.v7.widget.AppCompatTextViewlub android.support.v7.widget.AppCompatImageViewdziała tylko w czasie wykonywania.

Więc użyj TextViewlubImageView

Ahamadullah Saikat
źródło
0

Jeśli ktoś nadal boryka się z tym problemem: Dodaj plik png do folderu do rysowania o nazwie ic_stat_ic_notification (lub dowolną nazwą, którą lubisz)

aw swoim manifeście dodaj poniżej kilka wierszy

i możesz tutaj tworzyć swoje ikony -> https://romannurik.github.io/AndroidAssetStudio/icon

Jayapen Jose
źródło
0

Zsynchronizuj projekt, a następnie Wyczyść go, Plik> Synchronizuj, a następnie: Kompiluj> Wyczyść projekt

Mam nadzieję, że to wam wszystkim pomoże, to praca dla mnie

prawdziwy napster
źródło
0

Wystąpił ten błąd z powodu automatycznego łączenia i linków Opcje możliwe do kliknięcia w widoku tekstu w widoku powiadomień:

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="all"
        android:linksClickable="true"
        android:text="@string/app_name"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="@color/white" />

Bądź ostrożny!

Mistrz
źródło
-3

To zadziałało dla mnie. Skomentuj odniesienie do ikony, aby móc bez problemów korzystać z NotificationCompat.Builder.

    $msg_notificacion = [
                        'title'         => "titulonotif",
                       // "icon" : "myicon",
                        'body'          =>"cuerponotif"
                    ];
Alfonso Gutiérrez
źródło