Как исправить Xiaomi для RemoteServiceException со значком уведомления?

У нас много сбоев, характерных для телефонов Xiaomi на Android 6 и 7:

Fatal Exception: android.app.RemoteServiceException: Bad notification posted from package x.y.z: Couldn't create icon: StatusBarIcon(icon=Icon(typ=RESOURCE pkg=x.y.z id=0x7f0200ad) visible user=0 )
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1715)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:163)
   at android.app.ActivityThread.main(ActivityThread.java:6358)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:880)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:770)

Я нашел много подобных сообщений о сбоях и статей в сети. Вот несколько из них:

Как исправить: android.app.RemoteServiceException: плохое уведомление отправлено из пакета *: не удалось создать значок: StatusBarIcon

https://medium.com/@Miqubel/the-story-of-a-hard-to-fix-bug-ac6ed819cb49

Но разница в том, что у нас есть эти проблемы только на телефонах Xiaomi (Android 6 и 7) и, вероятно, не во время обновлений, так как одни и те же пользователи вылетали несколько раз в одной и той же версии.

Интересно, что я не смог найти ничего в сети по этому конкретному случаю, и у нас нет телефонов Xiaomi.

Я установил уведомление примерно так:

NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        int importance = NotificationManager.IMPORTANCE_HIGH;
        NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, importance);
        notificationChannel.enableLights(true);
        notificationManager.createNotificationChannel(notificationChannel);
    }
    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_notification)
            .setPriority(NotificationCompat.PRIORITY_MAX)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
            .setContentText(body == null ? "" : body)
            .setAutoCancel(true)
            .setContentIntent(PendingIntent.getActivity(
                    context,
                    0,
                    pendingIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT
            ));

У нас также есть уведомления Facebook, которые должны быть настроены аналогичным образом, но для другого класса уведомлений. Я не знаю, имеет ли это отношение. Кто-нибудь сталкивался с этим или имел какие-либо рекомендации, как это исправить, кроме оборачивания методов setSmallIcon и / или setLargeIcon в проверку версии производителя и Android?

РЕДАКТИРОВАТЬ: Я не мог найти решение, но вот несколько новых мыслей:

  • Мы выпустили новую версию, но исключение пользователей Xiaomi из уведомления не помогло! Теперь я думаю, что проблема вызвана пользовательским кодом в ActivityThread.java. MIUI, вероятно, запускает отсюда уведомление о каком-либо событии. Здесь есть несколько десятков событий на складе Android, но ни одно из них не выдает уведомления. Но что-то не так с нашими иконками, поэтому они вылетают.

  • Но что не так с нашими иконками? У нас есть ic_notification, которая, вероятно, не используется для этого. С другой стороны, ic_launcher - это мип-карта. Может быть это так? Но я не смог найти никаких проблем, касающихся Xiaomi и mipmaps.

  • В отчете о сбое всегда упоминается один и тот же идентификатор ресурса в нескольких версиях приложения: 0x7f0200ad. Это особенное по какой-то причине? Как я могу перепроектировать наше приложение, чтобы получить имя ресурса для этого?

РЕДАКТИРОВАТЬ 2:

  • Я выполнил обратное проектирование приложения с помощью apktool, но идентификатор ресурса отсутствует в public.xml, что, по-видимому, эквивалентно R.java. Наши ic_notification и ic_launcher находятся в списке с другим идентификатором. Так это системный ресурс, который MIUI не может найти?

РЕДАКТИРОВАТЬ 3:

  • Первое свидетельство того, что у других была такая же проблема:

https://xiaomi.eu/community/threads/miui-9.47247/

  • Временное решение найдено на польском форуме:

https://pl.forum.elvenar.com/index.php?threads/problem-z-uruchomieniem-23566.3348/

Последний комментарий переводится так: "У нас есть временное решение проблемы с Xiaomi, попробуйте отключить принудительные уведомления из приложения Elvenar в настройках телефона. После перезапуска приложения ошибка должна исчезнуть".

РЕДАКТИРОВАТЬ 4:

Мы используем ShortcutBadger (версия 1.1.13). Здесь говорится, что мы должны использовать другой метод для значков Xiaomi:

https://github.com/leolin310148/ShortcutBadger/wiki/Xiaomi-Device-Support

Сразу после версии 1.1.13 была удалена поддержка по умолчанию для Xiaomi, и вы должны использовать уведомление по приведенной выше ссылке.

Кто-нибудь еще пострадал использовать это?

2 ответа

Решение

У меня та же проблема, что и у пользователя. Я считаю, что это вызвано следующим кодом - декомпилирован из APK У меня нет исходного кода, это из ярлыка

ResolveInfo.getIconResource() возвратил недопустимый идентификатор ресурса (0x7f0200ad, одинаковый для всех приложений и выглядит так, как будто он только на MIUI10), поэтому произошел сбой.

iget-object v1, p0, Lme/leolin/shortcutbadger/impl/XiaomiHomeBadger;->a:Landroid/content/pm/ResolveInfo;

invoke-virtual/range {v1 .. v1}, Landroid/content/pm/ResolveInfo;->getIconResource()I

move-result v1

invoke-virtual {p1, v1}, Landroid/app/Notification$Builder;->setSmallIcon(I)Landroid/app/Notification$Builder;

Для пользователя простое решение - полностью отключить уведомление для этого приложения - по крайней мере, сделать его пригодным для использования.

Как разработчику, может быть проще использовать собственный значок или добавить некоторую обработку ошибок в ярлык быстрого доступа.

builder.setSmallIcon(R.drawable.myicon);

Обновить:

Я понимаю, что происходит сейчас... Какой-то странный код в ярлыке. resolInfo - это стандартное домашнее средство запуска (MIUI home), а resolInfo.getIconResource () - значок домашнего приложения miui.

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void tryNewMiuiBadge(Context context, int badgeCount) throws ShortcutBadgeException {
if (resolveInfo == null) {
    Intent intent = new Intent(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    resolveInfo = context.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
}

if (resolveInfo != null) {
    NotificationManager mNotificationManager = (NotificationManager) context
            .getSystemService(Context.NOTIFICATION_SERVICE);
    Notification.Builder builder = new Notification.Builder(context)
            .setContentTitle("")
            .setContentText("")
            .setSmallIcon(resolveInfo.getIconResource());
    Notification notification = builder.build();

и декомпилированный из miuihome.apk, вот 0x7f0200ad.

<public type="drawable" name="icon_launcher" id="0x7f0200ad" />

Так зачем стороннему приложению пытаться установить значок уведомления со значком miui home? это какой-то хак по причине совместимости или просто ошибка? Я пишу простое приложение с приведенным выше фрагментом кода, тестирую на эмуляторе, и оно терпит неудачу, но не приводит к сбою приложения, может быть тот же случай на старом MIUI, так как setSmallIcon(resID) ищет значок с resID из собственного пакета. Хорошей новостью является то, что это не ошибка MIUI10, и это должно происходить только в приложениях, использующих приведенный выше код.

Мы купили Redmi Note 4X. Вот что случилось:

  • Устройство было на MIUI 8.5. Уведомления работают как положено. Не вылетает.

  • Мы обновились до MIUI 9.5 через OTA обновления. Странные уведомления начали появляться, когда мы открывали приложение или переключались между определенными экранами. Нет сбоев до сих пор.

  • Мы обновились до MIUI 10.1 через OTA обновления. Сбой приложения при запуске с предыдущей версией приложения. Сбой исчез, когда я обновил ShortcutBadger до версии 1.1.22. Ясно, что это произошло из-за того, что устройства Xiaomi не выполняют метод applyCount() в новой версии библиотеки (вместо этого они должны использовать applyNotification()), но я не стал копать глубже.

Я оставляю вопрос и награду открытой для всех, кто может подробно объяснить, что произошло. В противном случае мы довольны этим результатом. В следующем выпуске я, вероятно, постараюсь исправить значки и уведомления для Xiaomi, так как они не отображаются должным образом.

Другие вопросы по тегам