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

Android中如何检测应用通知开关状态的变化?

检测应用通知权限开关状态变化的问题解决

问题描述

我正在寻找一种检测用户开启/关闭我的应用通知的方法。尝试了以下代码,但监听器并未触发,尽管OP值确实发生了变化:

val appOpsManager: AppOpsManager = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
appOpsManager.startWatchingMode("android:post_notification", context.packageName) { op, _ -> 
    Log.d("foo", "$op value changed")
}

原因分析及解决方案

1. 优先使用NotificationManager的官方监听方案

从Android 10(API 29)开始,AppOpsManager.startWatchingMode针对通知权限的监听触发逻辑被限制,推荐使用NotificationManager提供的专用监听接口,兼容性和可靠性更强:

val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val permissionChangeListener = object : NotificationManager.OnNotificationPolicyChangedListener {
    override fun onNotificationPolicyChanged() {
        val isEnabled = notificationManager.areNotificationsEnabled()
        Log.d("foo", "通知权限状态变化:${if (isEnabled) "已开启" else "已关闭"}")
    }
}
// 注册监听
notificationManager.addOnNotificationPolicyChangedListener(permissionChangeListener)
// 注意:在页面销毁或不再需要监听时,务必移除监听
// notificationManager.removeOnNotificationPolicyChangedListener(permissionChangeListener)

2. 修复AppOpsManager监听的问题

如果坚持使用AppOpsManager,需要注意几个关键点:

  • 使用官方常量替代硬编码字符串,避免拼写错误:AppOpsManager.OP_POST_NOTIFICATION
  • 部分系统版本需要声明android.permission.OBSERVE_APP_OPS权限
  • 部分厂商定制系统可能拦截AppOps监听事件,需做好兼容
    修改后的代码:
val appOpsManager: AppOpsManager = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
appOpsManager.startWatchingMode(AppOpsManager.OP_POST_NOTIFICATION, context.packageName) { _, _ ->
    val mode = appOpsManager.checkOpNoThrow(AppOpsManager.OP_POST_NOTIFICATION, android.os.Process.myUid(), context.packageName)
    val isEnabled = mode == AppOpsManager.MODE_ALLOWED
    Log.d("foo", "通知权限变化:$isEnabled")
}

3. Android 12+ 可用的广播监听方案

Android 12(API 31)及以上系统支持通过动态注册广播监听通知设置变化:

val settingChangeReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        if (Intent.ACTION_APP_NOTIFICATION_SETTINGS_CHANGED == intent?.action) {
            val targetPackage = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME)
            if (targetPackage == context?.packageName) {
                val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                val isEnabled = notificationManager.areNotificationsEnabled()
                Log.d("foo", "通知权限状态更新:${if (isEnabled) "开启" else "关闭"}")
            }
        }
    }
}
// 动态注册广播(静态注册无效)
context.registerReceiver(settingChangeReceiver, IntentFilter(Intent.ACTION_APP_NOTIFICATION_SETTINGS_CHANGED))
// 记得在合适时机注销广播
// context.unregisterReceiver(settingChangeReceiver)

内容的提问来源于stack exchange,提问作者Marek Teuchner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 14:54:15