Android 8获取通知大图标抛IllegalStateException,Android 7.1正常求助
解决Android 8.0中BitmapFactory.decodeResource返回null的问题
嘿,我之前也踩过类似的坑!这个问题其实和Android 8.0(API 26)开始的系统规则变化直接相关,结合你用Kotlin的情况,咱们一步步来理清楚:
为什么Android 7.1正常,Android 8.0就崩了?
- Android 8.0引入了通知渠道机制,同时对通知图标的资源加载逻辑做了调整:
mipmap目录的资源原本是给应用启动器专用的,系统在8.0+版本中对这类资源用于通知图标的兼容性下降,导致BitmapFactory.decodeResource无法正确解码,返回了null。 - 而Kotlin默认会对非空类型做严格检查,你这段代码里
bm被推断为非空Bitmap类型,一旦返回null就直接抛出IllegalStateException: bm must not be null。
具体解决方案
1. 把通知图标移到drawable目录
通知图标建议放在drawable(按密度分drawable-mdpi/drawable-hdpi等)目录下,而非mipmap。系统对drawable资源的加载兼容性更好,而且这也是官方推荐的做法:
// 假设你把图标复制到drawable目录,命名为ic_notification val bm = BitmapFactory.decodeResource(this.resources, R.drawable.ic_notification)
记得要保证各个密度的drawable子目录都有对应尺寸的图标,避免因资源缺失导致解码失败。
2. 添加空值兜底处理
即使调整了资源目录,也建议加个空值判断,防止极端情况下资源找不到的问题,避免直接崩溃:
val bm = BitmapFactory.decodeResource(this.resources, R.mipmap.ic_launcher) ?: run { // 返回一个默认的占位图标,或者做自定义错误处理 BitmapFactory.decodeResource(this.resources, R.drawable.default_notification_icon) }
3. 别忘了适配Android 8.0+的通知渠道
虽然这不是导致bm为空的直接原因,但Android 8.0+必须创建通知渠道才能显示通知,顺便补上这个必要的适配:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( "your_channel_id", "你的通知渠道名称", NotificationManager.IMPORTANCE_DEFAULT ) val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(channel) }
内容的提问来源于stack exchange,提问作者fr3ak
相关产品推荐
相关产品推荐

