新增:APP通知关键词黑名单,命中关键词后不转发通知 #736

This commit is contained in:
pppscn
2026-07-14 22:13:32 +08:00
parent 3945b9058c
commit 1a9520f082
9 changed files with 89 additions and 7 deletions

View File

@@ -28,12 +28,6 @@ import androidx.core.content.ContextCompat
import androidx.lifecycle.Observer
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import com.hjq.language.LocaleContract
import com.hjq.language.MultiLanguages
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.XXPermissions
import com.hjq.permissions.permission.PermissionLists
import com.hjq.permissions.permission.base.IPermission
import cn.ppps.forwarder.App
import cn.ppps.forwarder.R
import cn.ppps.forwarder.activity.MainActivity
@@ -68,6 +62,12 @@ import cn.ppps.forwarder.utils.SettingUtils
import cn.ppps.forwarder.utils.XToastUtils
import cn.ppps.forwarder.widget.GuideTipsDialog
import cn.ppps.forwarder.workers.LoadAppListWorker
import com.hjq.language.LocaleContract
import com.hjq.language.MultiLanguages
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.XXPermissions
import com.hjq.permissions.permission.PermissionLists
import com.hjq.permissions.permission.base.IPermission
import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xpage.annotation.Page
@@ -158,6 +158,8 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
switchEnableLoadAppList(binding!!.sbEnableLoadAppList, binding!!.scbLoadUserApp, binding!!.scbLoadSystemApp)
//设置自动消除额外APP通知
editExtraAppList(binding!!.etAppList)
//设置APP通知关键词黑名单
editAppNotifyBlacklist(binding!!.etAppNotifyBlacklist)
//自动过滤多久内重复消息
binding!!.xsbDuplicateMessagesLimits.setDefaultValue(SettingUtils.duplicateMessagesLimits)
binding!!.xsbDuplicateMessagesLimits.setOnSeekBarListener { _: XSeekBar?, newValue: Int ->
@@ -792,7 +794,19 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun afterTextChanged(s: Editable) {
SettingUtils.cancelExtraAppNotify = textAppList.text.toString().trim().removeSuffix("\n")
SettingUtils.cancelExtraAppNotify = textAppList.text.toString().trim().replace("\r", "").replace("\n+", "\n").removeSuffix("\n")
}
})
}
//设置APP通知关键词黑名单
private fun editAppNotifyBlacklist(textBlacklist: EditText) {
textBlacklist.setText(SettingUtils.appNotifyBlacklist)
textBlacklist.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun afterTextChanged(s: Editable) {
SettingUtils.appNotifyBlacklist = textBlacklist.text.toString().trim().replace("\r", "").replace("\n+", "\n").removeSuffix("\n")
}
})
}

View File

@@ -98,6 +98,12 @@ class NotificationService : NotificationListenerService() {
//不处理空消息(标题跟内容都为空)
if (TextUtils.isEmpty(title) && TextUtils.isEmpty(text)) return
//关键词黑名单:一行一个,支持正则,命中标题或内容则不转发
if (isInBlacklist(title, text)) {
Log.d(TAG, "命中APP通知关键词黑名单跳过转发。title=$title, text=$text")
return
}
val msgInfo = MsgInfo("app", from, text, Date(), title, -1)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
Log.d(TAG, "消息的UID====>" + sbn.uid)
@@ -132,6 +138,30 @@ class NotificationService : NotificationListenerService() {
}
//关键词黑名单匹配:一行一个关键词,支持正则表达式,命中通知标题或内容任意一项即返回 true
private fun isInBlacklist(title: String, text: String): Boolean {
val blacklist = SettingUtils.appNotifyBlacklist
if (TextUtils.isEmpty(blacklist)) return false
for (line in blacklist.split("\n")) {
val keyword = line.trim()
if (keyword.isEmpty()) continue
try {
val regex = Regex(keyword)
if (regex.containsMatchIn(title) || regex.containsMatchIn(text)) {
return true
}
} catch (e: Exception) {
//正则表达式非法时,降级为普通包含匹配
Log.w(TAG, "黑名单关键词正则非法,降级为包含匹配:$keyword, ${e.message}")
if (title.contains(keyword) || text.contains(keyword)) {
return true
}
}
}
return false
}
override fun onNotificationRemoved(sbn: StatusBarNotification?) {
Log.d(TAG, "Removed Package Name : ${sbn?.packageName}")
}

View File

@@ -50,6 +50,7 @@ const val SP_ENABLE_CALL_TYPE_6 = "enable_call_type_6"
const val SP_ENABLE_APP_NOTIFY = "enable_app_notify"
const val SP_ENABLE_CANCEL_APP_NOTIFY = "enable_cancel_app_notify"
const val SP_CANCEL_EXTRA_APP_NOTIFY = "cancel_extra_app_notify_list"
const val SP_APP_NOTIFY_BLACKLIST = "app_notify_blacklist"
const val SP_ENABLE_NOT_USER_PRESENT = "enable_not_user_present"
const val SP_ENABLE_SMS_COMMAND = "enable_sms_command"

View File

@@ -56,6 +56,9 @@ class SettingUtils private constructor() {
//是否转发应用通知——自动消除额外APP通知
var cancelExtraAppNotify: String by SharedPreference(SP_CANCEL_EXTRA_APP_NOTIFY, "")
//是否转发应用通知——关键词黑名单(一行一个,支持正则,命中标题或内容则不转发)
var appNotifyBlacklist: String by SharedPreference(SP_APP_NOTIFY_BLACKLIST, "")
//是否转发应用通知——仅锁屏状态
var enableNotUserPresent: Boolean by SharedPreference(SP_ENABLE_NOT_USER_PRESENT, false)

View File

@@ -916,6 +916,32 @@
</LinearLayout>
<LinearLayout
android:id="@+id/layout_app_notify_blacklist"
style="@style/BarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/app_notify_blacklist"
android:textStyle="bold"
tools:ignore="RelativeOverlap" />
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
android:id="@+id/et_app_notify_blacklist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/app_notify_blacklist_hint"
android:inputType="textMultiLine"
app:met_clearButton="true"
tools:ignore="TextContrastCheck" />
</LinearLayout>
<LinearLayout
style="@style/BarStyle"
android:layout_width="match_parent"

View File

@@ -661,6 +661,8 @@
<string name="choose_app">Installed Apps</string>
<string name="extra_app">Extra Apps</string>
<string name="extra_app_hint">One package name per line\nEnable async loading of the App list for selection.</string>
<string name="app_notify_blacklist">App Notification Keyword Blacklist</string>
<string name="app_notify_blacklist_hint">One keyword per line, regex supported\nSkip forwarding if the title or content matches any keyword.</string>
<string name="choose_app_hint">Drop-down selection to get package name, keyword fuzzy matching APP name</string>
<string name="regex_multi_match" tools:ignore="TypographyDashes">^\\s*(AND|OR)\\s(IS|NOTIS)\\s(PHONE_NUM|PACKAGE_NAME|MSG_CONTENT|INFORM_CONTENT|INFORM_TITLE|CARD_SLOT|CALL_TYPE|UID)\\s(EQUALS|CONTAIN|NOTCONTAIN|STARTWITH|ENDWITH|REGEX)\\s(.*)$</string>
<string name="privacy_content_1">Welcome to</string>

View File

@@ -662,6 +662,8 @@
<string name="choose_app">已装APP列表</string>
<string name="extra_app">额外消除应用通知</string>
<string name="extra_app_hint">一行一个包名\n开启异步加载App列表以便选择</string>
<string name="app_notify_blacklist">APP通知关键词黑名单</string>
<string name="app_notify_blacklist_hint">一行一个关键词,支持正则表达式\n通知标题或内容命中任一关键词则不转发</string>
<string name="choose_app_hint">下拉选择获取包名关键字模糊匹配APP名称</string>
<string name="regex_multi_match" tools:ignore="TypographyDashes">^\\s*(并且|或者)\\s(是|不是)\\s(手机号|APP包名|短信内容|通知内容|通知标题|卡槽信息|通话类型|UID)\\s(相等|包含|不包含|开头|结尾|正则匹配)\\s(.*)$</string>
<string name="privacy_content_1">欢迎使用</string>

View File

@@ -662,6 +662,8 @@
<string name="choose_app">已裝APP列表</string>
<string name="extra_app">額外消除應用通知</string>
<string name="extra_app_hint">一行一個包名\n開啟異步加載App列表以便選擇</string>
<string name="app_notify_blacklist">APP通知關鍵詞黑名單</string>
<string name="app_notify_blacklist_hint">一行一個關鍵詞,支持正則表達式\n通知標題或內容命中任一關鍵詞則不轉發</string>
<string name="choose_app_hint">下拉選擇獲取包名關鍵字模糊匹配APP名稱</string>
<string name="regex_multi_match" tools:ignore="TypographyDashes">^\\s*(並且|或者)\\s(是|不是)\\s(手機號|APP包名|簡訊內容|通知內容|通知標題|卡槽信息|通話類型|UID)\\s(相等|包含|不包含|開頭|結尾|正則匹配)\\s(.*)$</string>
<string name="privacy_content_1">歡迎使用</string>

View File

@@ -691,6 +691,8 @@
<string name="choose_app">已装APP列表</string>
<string name="extra_app">额外消除应用通知</string>
<string name="extra_app_hint">一行一个包名\n开启异步加载App列表以便选择</string>
<string name="app_notify_blacklist">APP通知关键词黑名单</string>
<string name="app_notify_blacklist_hint">一行一个关键词,支持正则表达式\n通知标题或内容命中任一关键词则不转发</string>
<string name="choose_app_hint">下拉选择获取包名关键字模糊匹配APP名称</string>
<string name="regex_multi_match" tools:ignore="TypographyDashes">^\\s*(并且|或者)\\s(是|不是)\\s(手机号|APP包名|短信内容|通知内容|通知标题|卡槽信息|通话类型|UID)\\s(相等|包含|不包含|开头|结尾|正则匹配)\\s(.*)$</string>
<string name="privacy_content_1">欢迎使用</string>