如何解决Android 4.4及更低版本使用XML状态栏图标崩溃问题?
解决Android 4.4及以下版本使用XML矢量图作为通知图标崩溃的问题
这个坑我之前踩过!你遇到的崩溃本质是Android 5.0(API 21)以下的系统完全不支持直接将XML矢量图(VectorDrawable)作为状态栏通知图标,系统的通知管理器无法解析矢量图资源,就会抛出你看到的RemoteServiceException。
先贴一下你提到的报错信息:
03-22 19:21:39.441 2221-2221/org.odk.collect.android E/AndroidRuntime: FATAL EXCEPTION: main Process: org.odk.collect.android, PID: 2221 android.app.RemoteServiceException: Bad notification posted from package org.odk.collect.android: Couldn't create icon: StatusBarIcon(pkg=org.odk.collect.androiduser=...
下面给你两个亲测有效的解决方案:
方案一:为低版本系统提供位图图标(最推荐)
Android的资源系统本身就支持版本/密度适配,你只需要:
- 把你的矢量图标转换成对应分辨率的PNG位图(需要覆盖mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi这几个密度)
- 将这些PNG文件放到
res/drawable-xxxdpi对应的目录中,并且和你的XML矢量图标同名 - 代码里还是正常调用
setSmallIcon(R.drawable.your_icon_name),系统会自动在5.0+设备加载矢量图,低版本设备加载对应的PNG位图
方案二:代码层面做版本判断(更稳妥的兜底)
如果担心资源系统的适配逻辑出问题,可以在构建通知时手动判断系统版本:
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context); // 根据系统版本选择不同的图标资源 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { // 低版本用位图图标 notificationBuilder.setSmallIcon(R.drawable.ic_notification_bitmap); } else { // 5.0+用矢量图标 notificationBuilder.setSmallIcon(R.drawable.ic_notification_vector); } // 其他通知配置... NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build());
额外注意事项
- 状态栏通知图标必须是单色带alpha通道的,不管是位图还是矢量图,低版本系统对图标的颜色和透明度要求更严格,别用多色图标
- 不要试图用
VectorDrawableCompat来兼容,因为系统通知管理器的图标加载逻辑不兼容这个库的处理方式,照样会崩溃
内容的提问来源于stack exchange,提问作者Lekker
相关产品推荐
相关产品推荐

