You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:39:45