Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix Xiaomi specific RemoteServiceException with notification icon?

We have a lot of crashes specific to Xiaomi phones on Android 6 and 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)

I've found a lot of similar crash reports and articles on the net. Here is a few:

How to fix: android.app.RemoteServiceException: Bad notification posted from package *: Couldn't create icon: StatusBarIcon

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

But the difference is that we have these problems only on Xiaomi phones (Android 6 and 7) and probably not during updates as the same users have the crash several times in the same release version.

Interestingly I couldn't find anything on the net on this specific case and we don't have any Xiaomi phones around.

I set the notification something like this:

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

We also have Facebook notifications, which have to be set in a similar manner, but on a different Notification class. I don't know if it's relevant. Did anybody ran into this or have any recommendation how to fix this apart from wrapping the setSmallIcon and/or the setLargeIcon methods in a Manufacturer and Android version check?

EDIT: I couldn't find a solution, but here are a few new thoughts:

  • We released a new version, but excluding Xiaomi users from notification didn't help! Now I think the problem is caused by the custom code in ActivityThread.java. MIUI probably fires a notification from here on some event. There are a few dozen events in stock Android here, but none of them fires a notification. But something is wrong with our icons, so they crash.

  • But what is wrong with our icons? We have an ic_notification, which is probably not used for this. On the other hand, ic_launcher is a mipmap. Is it maybe this? But I couldn't find any problems regarding Xiaomi and mipmaps.

  • The crash report always mentions the same resource id across several app versions: 0x7f0200ad. Is this special for some reason? How can I reverse engineer our app to get the resource name for this?

EDIT 2:

  • I reverse engineered the app with apktool, but the resource id is not in public.xml, which seems to be the equivalent of R.java. Our ic_notification and ic_launcher is in the list with a different id. So is this a system resource what MIUI cannot find?

EDIT 3:

  • First evidence of others having the same problem:

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

  • Temporary solution found on a Polish forum:

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

The last comment translates to: "We have a temporary solution to the problem with Xiaomi, please try to disable notifications forced from the Elvenar application in the phone settings. After restarting the application, the error should disappear."

EDIT 4:

We are using ShortcutBadger (version 1.1.13). Here it says we should use a different method for Xiaomi badges:

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

Right after version 1.1.13 they removed default support for Xiaomi and you have to use the notification from the above link.

Does anyone else affected use this?

like image 438
Herrbert74 Avatar asked Dec 10 '18 17:12

Herrbert74


2 Answers

I have same problem as a user. I believe it's caused by following code -- decompiled from an APK I have no source code, it's from shortcutbadger

ResolveInfo.getIconResource() returned an invalid resource ID(0x7f0200ad, same across all apps and looks like it's only on MIUI10) thus the crash.

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;

As a user a simple fix is to disable notification for that app completely -- at least make it usable.

As a developer, it might be easier to just use own icon instead, or add some error handling in shortcutbadger.

builder.setSmallIcon(R.drawable.myicon);

Update:

I get what happens now...Some weird code in shortcutbadge. resolveInfo is the default home launcher(MIUI home) activity and resolveInfo.getIconResource() is the miui home's icon

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

and decompiled from miuihome.apk, here is the 0x7f0200ad.

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

So why would a 3rd party app try to set notification icon with miui home's icon? is it some hack for compatibility reason or just a bug? I write a simple app with above code snippet, test on emulator, and it fails but not crashing the app, might be the same case on old MIUI, as setSmallIcon(resID) is looking for the icon with resID from own package. The good news is, it's not a bug of MIUI10 and it should only happen on apps using above code.

like image 174
Chris.C Avatar answered Nov 15 '22 23:11

Chris.C


We bought a Redmi Note 4X. Here is what happened:

  • Device was on MIUI 8.5. Notifications working as expected. No crashes.

  • We updated to MIUI 9.5 through OTA updates. Strange notifications started to appear when we opened the app or switched between certain screens. No crashes still.

  • We updated to MIUI 10.1 through OTA updates. App crashed on startup with the previous version of the app. The crash disappeared when I updated ShortcutBadger to 1.1.22. It's clear that this happened because Xiaomi devices are not executing the applyCount() method in the new version of the library (they have to use applyNotification() instead), but I didn't dig deeper.

I keep the question and the bounty open for anyone who can explain what happened in detail. Otherwise we are happy with this result so far. For the next release I will probably try to fix badges and notifications for Xiaomi, as they are not displaying properly.

like image 37
Herrbert74 Avatar answered Nov 16 '22 00:11

Herrbert74