You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何获取Android通知日志中的通知数据并在应用中处理展示

如何在Android应用中访问并处理通知日志数据

嘿,我来帮你一步步搞定获取通知日志数据并展示的问题!Android系统在不同版本提供了不同的API来实现这个需求,我会分情况给你讲清楚:

1. 先搞定权限问题

权限是第一步,不同版本的要求不一样:

  • Android 11(API 30)及以上:需要READ_NOTIFICATION_HISTORY权限,这个权限没法通过常规的权限弹窗申请,得引导用户去系统设置里开启。
  • Android 10及以下:需要开启「通知监听」权限,同样得跳转到系统设置让用户手动开启。

2. 获取通知历史数据

方案一:Android 11+ 用官方API直接拿

从API 30开始,系统给了NotificationManager.getNotificationHistory()这个便捷方法,能直接获取最近的通知记录(系统限制最多500条)。

先检查权限,没有的话跳设置:

val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    if (!notificationManager.isNotificationHistoryAccessGranted) {
        // 跳转到通知历史权限设置页
        startActivity(Intent(Settings.ACTION_NOTIFICATION_HISTORY_SETTINGS))
        return
    }
}

然后就能拿到数据了,每条通知里包含你要的所有信息:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    val notificationHistory = notificationManager.notificationHistory
    notificationHistory.forEach { notification ->
        // 提取你需要的字段
        val appPackage = notification.packageName // 发送通知的应用包名
        val isOpened = notification.isNotificationOpened // 是否已被用户打开
        val postTimestamp = notification.postTime // 通知到达时间(毫秒时间戳)
        val title = notification.extras.getString(Notification.EXTRA_TITLE) // 通知标题
        val content = notification.extras.getString(Notification.EXTRA_TEXT) // 通知内容

        // 这里可以把数据存到本地数据库,或者直接用于UI展示
    }
}

方案二:Android 10及以下 用NotificationListenerService

低版本没有直接的API,得靠通知监听服务来捕获通知,同时记录状态。

第一步:注册服务

AndroidManifest.xml里添加服务声明:

<service
    android:name=".MyNotificationListener"
    android:label="我的通知日志监听"
    android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
    <intent-filter>
        <action android:name="android.service.notification.NotificationListenerService" />
    </intent-filter>
</service>

第二步:实现监听服务

创建一个继承自NotificationListenerService的类,监听通知的发布和移除事件:

class MyNotificationListener : NotificationListenerService() {

    // 新通知发布时触发,在这里记录通知基本信息
    override fun onNotificationPosted(sbn: StatusBarNotification) {
        super.onNotificationPosted(sbn)
        val appPackage = sbn.packageName
        val postTimestamp = sbn.postTime
        val title = sbn.notification.extras.getString(Notification.EXTRA_TITLE)
        val content = sbn.notification.extras.getString(Notification.EXTRA_TEXT)
        
        // 把这些信息存到本地(比如Room数据库),初始标记为未打开
    }

    // 通知被移除时触发,判断是否是用户打开导致的
    override fun onNotificationRemoved(sbn: StatusBarNotification, rankingMap: RankingMap?, reason: Int) {
        super.onNotificationRemoved(sbn, rankingMap, reason)
        if (reason == NotificationListenerService.REASON_CLICK) {
            // 通知被用户点击打开了,更新本地数据的状态为已打开
            val appPackage = sbn.packageName
            val postTimestamp = sbn.postTime
            // 这里根据包名和时间戳找到对应的记录,更新isOpened字段
        }
    }

    // 如果需要获取当前活跃的通知(历史通知的一部分),可以调用这个方法
    fun getActiveNotifications(): List<StatusBarNotification> {
        return activeNotifications.toList()
    }
}

第三步:引导用户开启权限

让用户跳转到通知监听设置页开启权限:

fun openNotificationListenerSettings() {
    startActivity(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"))
}

3. 数据处理与UI展示

拿到数据后,接下来就是处理和展示了:

  • 存储数据:推荐用Room数据库来存储通知记录,方便后续查询、排序(比如按时间倒序)。
  • 展示UI:用RecyclerView来列表展示每条通知,你还可以根据包名获取应用的图标和名称,让界面更友好:
fun getAppInfo(packageName: String): Pair<Drawable?, String> {
    val packageManager = packageManager
    return try {
        val appInfo = packageManager.getApplicationInfo(packageName, 0)
        val appIcon = packageManager.getApplicationIcon(appInfo)
        val appName = packageManager.getApplicationLabel(appInfo).toString()
        Pair(appIcon, appName)
    } catch (e: PackageManager.NameNotFoundException) {
        // 找不到应用信息时,用包名代替名称,图标用默认图
        Pair(null, packageName)
    }
}

一些关键注意事项

  • Android 11+的getNotificationHistory()只能拿到最近的500条通知,系统会自动清理旧记录,所以如果需要长期保存,得自己存到本地。
  • 通知监听服务在设备重启后会被禁用,你可以监听开机广播,然后引导用户重新开启权限。
  • 隐私合规很重要!一定要在应用里明确告知用户你为什么需要获取通知数据,符合Google Play的隐私政策,不然容易被下架。

内容的提问来源于stack exchange,提问作者Manas Kulkarni

火山引擎 最新活动