Skip to content

Commit 66d29c7

Browse files
author
Chenhe
committed
新增添加特别关心通知前缀选项
1 parent e972832 commit 66d29c7

File tree

5 files changed

+172
-66
lines changed

5 files changed

+172
-66
lines changed

app/src/main/java/cc/chenhe/qqnotifyevo/core/NotificationProcessor.kt

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ abstract class NotificationProcessor(context: Context) {
5656
// 群聊消息
5757
// title: 群名 | 群名 (x条新消息)
5858
// ticker: 昵称(群名):消息内容
59-
// text: 昵称: 消息内容
59+
// text: 昵称: 消息内容 //特别关注前缀:[有关注的内容]
6060

6161
/**
6262
* 匹配群聊消息 Ticker.
@@ -68,6 +68,14 @@ abstract class NotificationProcessor(context: Context) {
6868
@VisibleForTesting
6969
val groupMsgPattern: Pattern = Pattern.compile("^(.+?)\\((.+)\\):([\\s\\S]+)$")
7070

71+
/**
72+
* 匹配群聊消息 Content.
73+
*
74+
* Group: 1[有关注的内容
75+
*/
76+
@VisibleForTesting
77+
val groupMsgContentPattern: Pattern = Pattern.compile("^(\\[有关注的内容])?[\\s\\S]+")
78+
7179
// 私聊消息
7280
// title: 昵称 | 昵称 (x条新消息) //特别关心前缀:[特别关心]
7381
// ticker: 昵称: 消息内容
@@ -250,7 +258,7 @@ abstract class NotificationProcessor(context: Context) {
250258
getNotifyLargeIcon(context, original))
251259
conversation = addMessage(tag, qzoneSpecialTitle, content, null,
252260
avatarManager.getAvatar(CONVERSATION_NAME_QZONE_SPECIAL.hashCode()), original.contentIntent,
253-
original.deleteIntent)
261+
original.deleteIntent, false)
254262
// 由于特别关心动态推送的通知没有显示未读消息个数,所以这里无法提取并删除多余的历史消息。
255263
// Workaround: 在通知删除回调下来匹配并清空特别关心动态历史记录。
256264
Timber.tag(TAG).d("[QZoneSpecial] Ticker: $ticker")
@@ -259,7 +267,7 @@ abstract class NotificationProcessor(context: Context) {
259267
avatarManager.saveAvatar(CONVERSATION_NAME_QZONE.hashCode(), getNotifyLargeIcon(context, original))
260268
conversation = addMessage(tag, qzoneSpecialTitle, content, null,
261269
avatarManager.getAvatar(CONVERSATION_NAME_QZONE.hashCode()), original.contentIntent,
262-
original.deleteIntent)
270+
original.deleteIntent, false)
263271
deleteOldMessage(conversation, num)
264272
Timber.tag(TAG).d("[QZone] Ticker: $ticker")
265273
}
@@ -277,12 +285,16 @@ abstract class NotificationProcessor(context: Context) {
277285
val name = matcher.group(1) ?: return null
278286
val groupName = matcher.group(2) ?: return null
279287
val text = matcher.group(3) ?: return null
288+
289+
val contentMatcher = groupMsgContentPattern.matcher(content!!)
290+
val special = contentMatcher.matches() && contentMatcher.group(1) != null
291+
280292
if (!isMulti)
281293
avatarManager.saveAvatar(groupName.hashCode(), getNotifyLargeIcon(context, original))
282-
val conversation = addMessage(tag, name, text, groupName,
283-
avatarManager.getAvatar(name.hashCode()), original.contentIntent, original.deleteIntent)
294+
val conversation = addMessage(tag, name, text, groupName, avatarManager.getAvatar(name.hashCode()),
295+
original.contentIntent, original.deleteIntent, special)
284296
deleteOldMessage(conversation, if (isMulti) 0 else matchMessageNum(title))
285-
Timber.tag(TAG).d("[Group] Name: $name; Group: $groupName; Text: $text")
297+
Timber.tag(TAG).d("[${if (special) "GroupS" else "Group"}] Name: $name; Group: $groupName; Text: $text")
286298
return renewConversionNotification(context, tag, NotifyChannel.GROUP, conversation, sbn, original)
287299
}
288300
}
@@ -297,10 +309,10 @@ abstract class NotificationProcessor(context: Context) {
297309
if (!isMulti)
298310
avatarManager.saveAvatar(name.hashCode(), getNotifyLargeIcon(context, original))
299311
val conversation = addMessage(tag, name, text, null, avatarManager.getAvatar(name.hashCode()),
300-
original.contentIntent, original.deleteIntent)
312+
original.contentIntent, original.deleteIntent, special)
301313
deleteOldMessage(conversation, if (isMulti) 0 else matchMessageNum(titleMatcher))
302314
return if (special) {
303-
Timber.tag(TAG).d("[Special] Name: $name; Text: $text")
315+
Timber.tag(TAG).d("[FriendS] Name: $name; Text: $text")
304316
renewConversionNotification(context, tag, NotifyChannel.FRIEND_SPECIAL, conversation, sbn, original)
305317
} else {
306318
Timber.tag(TAG).d("[Friend] Name: $name; Text: $text")
@@ -422,7 +434,7 @@ abstract class NotificationProcessor(context: Context) {
422434
val style = NotificationCompat.MessagingStyle(Person.Builder()
423435
.setName(context.getString(R.string.notify_qzone_title)).build())
424436
conversation.messages.forEach { msg ->
425-
style.addMessage(msg.content, msg.time, msg.person)
437+
style.addMessage(msg)
426438
}
427439
val num = conversation.messages.size
428440
val subtext = if (num > 1) context.getString(R.string.notify_subtext_qzone_num, num) else null
@@ -446,7 +458,7 @@ abstract class NotificationProcessor(context: Context) {
446458
style.isGroupConversation = true
447459
}
448460
conversation.messages.forEach { msg ->
449-
style.addMessage(msg.content, msg.time, msg.person)
461+
style.addMessage(msg)
450462
}
451463
val num = conversation.messages.size
452464
val subtext = if (num > 1) context.getString(R.string.notify_subtext_message_num, num) else null
@@ -455,6 +467,34 @@ abstract class NotificationProcessor(context: Context) {
455467
avatarManager.getAvatar(conversation.name.hashCode()), original, subtext)
456468
}
457469

470+
private fun NotificationCompat.MessagingStyle.addMessage(message: Message) {
471+
var name = message.person.name
472+
if (message.special && showSpecialPrefix(ctx)) {
473+
// 添加特别关心或关注前缀
474+
name = if (isGroupConversation)
475+
ctx.getString(R.string.special_group_prefix) + name
476+
else
477+
ctx.getString(R.string.special_prefix) + name
478+
}
479+
480+
val person = if (name == message.person.name) {
481+
message.person
482+
} else {
483+
message.person.clone(name)
484+
}
485+
addMessage(message.content, message.time, person)
486+
}
487+
488+
private fun Person.clone(newName: CharSequence? = null): Person {
489+
return Person.Builder()
490+
.setBot(this.isBot)
491+
.setIcon(this.icon)
492+
.setImportant(this.isImportant)
493+
.setKey(this.key)
494+
.setName(newName ?: this.name)
495+
.setUri(this.uri)
496+
.build()
497+
}
458498

459499
private fun setIcon(context: Context, builder: NotificationCompat.Builder, tag: Int, isQzone: Boolean) {
460500
if (isQzone) {
@@ -488,9 +528,14 @@ abstract class NotificationProcessor(context: Context) {
488528

489529
/**
490530
* 加入历史消息记录。
531+
*
532+
* @param name 发送者昵称。
533+
* @param content 消息内容。
534+
* @param group 群组名。`null` 表示非群组消息。
535+
* @param special 是否来自特别关心或特别关注。
491536
*/
492537
private fun addMessage(@SourceTag tag: Int, name: String, content: String, group: String?, icon: Bitmap?,
493-
contentIntent: PendingIntent, deleteIntent: PendingIntent): Conversation {
538+
contentIntent: PendingIntent, deleteIntent: PendingIntent, special: Boolean): Conversation {
494539
var conversation: Conversation? = null
495540
// 以会话名为标准寻找已存在的会话
496541
for (item in getHistoryMessage(tag)) {
@@ -511,7 +556,7 @@ abstract class NotificationProcessor(context: Context) {
511556
conversation = Conversation(group != null, group ?: name, contentIntent, deleteIntent)
512557
getHistoryMessage(tag).add(conversation)
513558
}
514-
conversation.messages.add(Message(name, icon, content))
559+
conversation.messages.add(Message(name, icon, content, special))
515560
return conversation
516561
}
517562

@@ -544,8 +589,9 @@ abstract class NotificationProcessor(context: Context) {
544589
* @param name 发送者昵称。
545590
* @param icon 头像。
546591
* @param content 消息内容。
592+
* @param special 是否来自特别关心或特别关注。仅在聊天消息中有效。
547593
*/
548-
protected data class Message(val name: String, val icon: Bitmap?, val content: String) {
594+
protected data class Message(val name: String, val icon: Bitmap?, val content: String, val special: Boolean) {
549595
val person: Person = Person.Builder()
550596
.setIcon(icon?.let { IconCompat.createWithBitmap(it) })
551597
.setName(name)

app/src/main/java/cc/chenhe/qqnotifyevo/utils/PreferencesUtils.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ fun getIconMode(context: Context): Int {
8484
}
8585
}
8686

87+
fun showSpecialPrefix(context: Context): Boolean = PreferenceManager.getDefaultSharedPreferences(context)
88+
.getBoolean("show_special_prefix", false)
89+
8790
fun getAvatarCachePeriod(context: Context): Long {
8891
val s = PreferenceManager.getDefaultSharedPreferences(context).getString("avatar_cache_period", "0") ?: "0"
8992
return s.toLong()

app/src/main/res/values/strings.xml

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
<string name="tip">提示</string>
77
<string name="dont_show">不再提示</string>
88
<string name="learn_more">了解详情</string>
9+
<string name="special_prefix">[特别关心]</string>
10+
<string name="special_group_prefix">[特别关注]</string>
911

1012
<string name="day">天</string>
1113
<string name="hour">小时</string>
@@ -28,7 +30,11 @@
2830
<string name="multi_msg_dialog_positive">使用传统模式</string>
2931
<string name="multi_msg_dialog_neutral">下次再说</string>
3032

31-
<!--通知-->
33+
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
34+
~ 通知渠道
35+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
36+
37+
<!-- 转发 QQ 的通知 -->
3238
<string name="notify_group_base">仅传统模式有效,Nevo 模式请前往 Nevo 应用设置</string>
3339
<string name="notify_nevo_prefix">Q进化-</string>
3440
<string name="notify_friend_channel_name">联系人消息</string>
@@ -39,9 +45,14 @@
3945
<string name="notify_group_channel_des">QQ 群消息通知</string>
4046
<string name="notify_qzone_channel_name">空间动态</string>
4147
<string name="notify_qzone_channel_des">QQ 空间动态通知</string>
42-
<!-- 自身通知的渠道 -->
48+
<!-- 自身通知 -->
4349
<string name="notify_self_tips_channel_name">使用提示</string>
4450

51+
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
52+
~ 通知内容
53+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
54+
55+
<!-- 转发 QQ 的通知 -->
4556
<string name="notify_qzone_title">空间动态</string>
4657
<string name="notify_qzone_special_title">特别关心动态</string>
4758
<string name="notify_subtext_message_num">%1$d条新消息</string>
@@ -52,7 +63,11 @@
5263
<string name="warning_monitor_service">通知监听服务未运行</string>
5364
<string name="warning_monitor_service_summary">请到「必要权限」里授予通知访问权,并确认已允许本应用自启动/后台运行。</string>
5465

55-
<!--设置页-->
66+
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
67+
~ 首选项:首页
68+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
69+
70+
<!-- 基础 -->
5671
<string name="pref_cate_base">基础</string>
5772
<string name="pref_mode">工作模式</string>
5873
<string-array name="pref_mode_entries">
@@ -63,7 +78,6 @@
6378
<item>1</item>
6479
<item>2</item>
6580
</string-array>
66-
6781
<!-- 必要权限 -->
6882
<string name="pref_cate_permit">必要权限</string>
6983
<string name="pref_notf_permit">通知访问权</string>
@@ -76,7 +90,6 @@
7690
<string name="pref_disable_permit">已禁用</string>
7791
<string name="pref_battery_optimize_disable">已停用</string>
7892
<string name="pref_battery_optimize_enable">未停用</string>
79-
8093
<!-- 通知 -->
8194
<string name="pref_cate_notify">通知</string>
8295
<string name="pref_notify_system">系统设置</string>
@@ -94,9 +107,41 @@
94107
<item>1</item>
95108
<item>2</item>
96109
</string-array>
110+
<!-- 关于 -->
111+
<string name="pref_cate_about">关于</string>
112+
<string name="about_manual">使用手册</string>
113+
<string name="about_manual_summary">模式选择 · 双重通知 · 最佳实践</string>
114+
<string name="pref_donate">捐助</string>
115+
<string name="pref_donate_message">请选择扶贫方式</string>
116+
<string-array name="pref_donate_options">
117+
<item>支付宝</item>
118+
</string-array>
119+
<string name="pref_donate_alipay_error">打开支付宝失败</string>
120+
<string name="pref_osc">开放源代码</string>
121+
<string name="pref_version_code">版本号:%1$s</string>
122+
<string name="about_dialog_title">关于</string>
123+
<string name="about_dialog_message">
124+
<![CDATA[
125+
1. 本应用完全免费开源\n
126+
严禁用于商用/出售/引流\n\n
127+
2. 支持 Nevo 插件与独立运行\n
128+
请参考使用手册选择合适的模式\n\n
129+
3. 唯一发布地址为 GitHub\n戳下面按钮直达
130+
]]>
131+
</string>
132+
<string name="about_dialog_github">GitHub 发布页</string>
133+
134+
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
135+
~ 首选项:高级
136+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
97137

98-
<!-- 高级 -->
99138
<string name="pref_cate_advanced">高级选项</string>
139+
<!-- 通知 -->
140+
<string name="pref_cate_advanced_notify">通知</string>
141+
<string name="pref_advanced_show_special_prefix">显示特别关心前缀</string>
142+
<string name="pref_advanced_show_special_prefix_summary">添加[特别关心]或群聊中[特别关注]前缀</string>
143+
<!-- 其他 -->
144+
<string name="pref_cate_advanced_other">其他</string>
100145
<string name="pref_avatar_cache_period">头像缓存刷新间隔</string>
101146
<string-array name="pref_avatar_cache_period_entries">
102147
<item>10分钟</item>
@@ -117,34 +162,11 @@
117162
<item>便于锁定最近任务以免被杀</item> <!-- checked -->
118163
<item>按返回键退出后将从最近任务界面隐藏</item> <!-- non-checked -->
119164
</string-array>
165+
<!-- 调试 -->
120166
<string name="pref_cat_debug">调试</string>
121167
<string name="pref_log">记录日志</string>
122168
<string name="pref_log_dialog_message">开启后将记录应用日志并明文保存在本地,其中包含您的通知详情,请注意隐私安全。\n请不要从应用外部删除日志文件以免影响完整性。</string>
123169
<string name="pref_delete_log">删除日志</string>
124170
<string name="pref_delete_log_summary">%1$d个日志 总大小%2$s</string>
125171
<string name="pref_delete_log_dialog_message">删除所有日志?</string>
126-
127-
<!--关于页-->
128-
<string name="pref_cate_about">关于</string>
129-
<string name="about_manual">使用手册</string>
130-
<string name="about_manual_summary">模式选择 · 双重通知 · 最佳实践</string>
131-
<string name="pref_donate">捐助</string>
132-
<string name="pref_donate_message">请选择扶贫方式</string>
133-
<string-array name="pref_donate_options">
134-
<item>支付宝</item>
135-
</string-array>
136-
<string name="pref_donate_alipay_error">打开支付宝失败</string>
137-
<string name="pref_osc">开放源代码</string>
138-
<string name="pref_version_code">版本号:%1$s</string>
139-
<string name="about_dialog_title">关于</string>
140-
<string name="about_dialog_message">
141-
<![CDATA[
142-
1. 本应用完全免费开源\n
143-
严禁用于商用/出售/引流\n\n
144-
2. 支持 Nevo 插件与独立运行\n
145-
请参考使用手册选择合适的模式\n\n
146-
3. 唯一发布地址为 GitHub\n戳下面按钮直达
147-
]]>
148-
</string>
149-
<string name="about_dialog_github">GitHub 发布页</string>
150172
</resources>

app/src/main/res/xml/pref_advanced.xml

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,41 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
33

4-
<ListPreference
5-
app:defaultValue="86400000"
6-
app:entries="@array/pref_avatar_cache_period_entries"
7-
app:entryValues="@array/pref_avatar_cache_period_values"
8-
app:key="avatar_cache_period"
9-
app:title="@string/pref_avatar_cache_period" />
10-
11-
<Preference
12-
app:key="delete_avatar_cache"
13-
app:title="@string/pref_delete_avatar_cache" />
14-
15-
<Preference
16-
app:key="delete_nevo_channel"
17-
app:title="@string/pref_delete_nevo_channel" />
18-
19-
<Preference
20-
app:key="reset_tips"
21-
app:title="@string/pref_reset_tips" />
22-
23-
<SwitchPreferenceCompat
24-
app:defaultValue="true"
25-
app:key="show_in_recent"
26-
app:title="@string/pref_show_in_recent" />
4+
<PreferenceCategory app:title="@string/pref_cate_advanced_notify">
5+
6+
<SwitchPreferenceCompat
7+
app:defaultValue="false"
8+
app:key="show_special_prefix"
9+
app:summary="@string/pref_advanced_show_special_prefix_summary"
10+
app:title="@string/pref_advanced_show_special_prefix" />
11+
</PreferenceCategory>
12+
13+
<PreferenceCategory app:title="@string/pref_cate_advanced_other">
14+
15+
<ListPreference
16+
app:defaultValue="86400000"
17+
app:entries="@array/pref_avatar_cache_period_entries"
18+
app:entryValues="@array/pref_avatar_cache_period_values"
19+
app:key="avatar_cache_period"
20+
app:title="@string/pref_avatar_cache_period" />
21+
22+
<Preference
23+
app:key="delete_avatar_cache"
24+
app:title="@string/pref_delete_avatar_cache" />
25+
26+
<Preference
27+
app:key="delete_nevo_channel"
28+
app:title="@string/pref_delete_nevo_channel" />
29+
30+
<Preference
31+
app:key="reset_tips"
32+
app:title="@string/pref_reset_tips" />
33+
34+
<SwitchPreferenceCompat
35+
app:defaultValue="true"
36+
app:key="show_in_recent"
37+
app:title="@string/pref_show_in_recent" />
38+
</PreferenceCategory>
2739

2840
<PreferenceCategory app:title="@string/pref_cat_debug">
2941

0 commit comments

Comments
 (0)