Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
Simple-Sms
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zhangchengbo
Simple-Sms
Commits
0a746141
Commit
0a746141
authored
Aug 01, 2025
by
zhangchengbo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix:1.注册与实现短信通知栏消息 2.对顺丰号码进行脱敏展示
parent
128e1421
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
168 additions
and
1 deletion
+168
-1
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+9
-0
App.kt
app/src/main/kotlin/com/secspace/sms/App.kt
+10
-1
Constant.kt
app/src/main/kotlin/com/secspace/sms/helpers/Constant.kt
+6
-0
SmsNotificationListener.kt
...tlin/com/secspace/sms/services/SmsNotificationListener.kt
+141
-0
Context.kt
...otlin/com/simplemobiletools/commons/extensions/Context.kt
+2
-0
No files found.
app/src/main/AndroidManifest.xml
View file @
0a746141
...
...
@@ -261,6 +261,15 @@
</intent-filter>
</activity-alias>
<service
android:name=
".services.SmsNotificationListener"
android:exported=
"false"
android:permission=
"android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
>
<intent-filter>
<action
android:name=
"android.service.notification.NotificationListenerService"
/>
</intent-filter>
</service>
</application>
</manifest>
app/src/main/kotlin/com/secspace/sms/App.kt
View file @
0a746141
package
com.secspace.sms
import
android.annotation.SuppressLint
import
android.app.Application
import
android.content.Context
import
com.simplemobiletools.commons.extensions.checkUseEnglish
class
App
:
Application
()
{
companion
object
{
@SuppressLint
(
"StaticFieldLeak"
)
lateinit
var
APP_CONTEXT
:
Context
}
override
fun
onCreate
()
{
super
.
onCreate
()
APP_CONTEXT
=
this
initLog
()
checkUseEnglish
()
...
...
app/src/main/kotlin/com/secspace/sms/helpers/Constant.kt
View file @
0a746141
...
...
@@ -17,4 +17,10 @@ object Constant {
const
val
DEALTIME
=
3
_000L
const
val
HIGH_CHANNEL_PRIORITY
=
"sms_notification_channel_high_priority"
const
val
LOW_CHANNEL_PRIORITY
=
"sms_notification_channel"
const
val
HIGH_PRIORITY
=
"simple_sms_high_priority"
const
val
LOW_PRIORITY
=
"simple_sms"
}
app/src/main/kotlin/com/secspace/sms/services/SmsNotificationListener.kt
0 → 100644
View file @
0a746141
package
com.secspace.sms.services
import
android.app.Notification
import
android.app.NotificationChannel
import
android.app.NotificationManager
import
android.os.Build
import
android.service.notification.NotificationListenerService
import
android.service.notification.StatusBarNotification
import
androidx.annotation.RequiresApi
import
androidx.core.app.NotificationCompat
import
com.secspace.log.Log
import
com.secspace.sms.App
import
com.secspace.sms.R
import
com.secspace.sms.helpers.Constant
import
com.secspace.sms.util.PhoneFromUtil
import
com.secspace.sms.util.PhoneUtils
import
com.simplemobiletools.commons.extensions.notificationManager
import
com.simplemobiletools.commons.extensions.powerManager
import
com.simplemobiletools.commons.helpers.isOreoPlus
class
SmsNotificationListener
:
NotificationListenerService
()
{
val
CALL_NOTIFICATION_ID
=
1
val
mContent
=
App
.
APP_CONTEXT
var
maskPhoneResult
=
""
private
var
isShowNotification
=
false
@RequiresApi
(
Build
.
VERSION_CODES
.
O
)
override
fun
onNotificationPosted
(
sbn
:
StatusBarNotification
)
{
super
.
onNotificationPosted
(
sbn
)
if
(
isShowNotification
)
return
// 可见的通知中存在系统发出的关于顶层包名的通知时,取消显示
val
notification
:
Notification
?
=
sbn
.
notification
// if (notification?.publicVersion == null) return // publicVersion 获取为null 1.有可能该通知没有公共版本 2.浏览器不支持或实现有限 3.未满足权限或场景要求
// 检查通知是否来自短信应用
try
{
val
packageName
=
sbn
.
packageName
Log
.
d
(
TAG
,
"SmsNotificationListener 短信通知:packageName=$packageName"
)
if
(
isSmsPackage
(
packageName
))
{
//移出系统通知栏消息
// cancelNotification(sbn.key)
// 获取通知内容
val
title
=
getTitle
(
notification
)
val
content
=
getContent
(
notification
)
Log
.
d
(
TAG
,
"短信通知:标题=$title, 内容=$content"
)
maskPhoneResult
=
title
if
(
PhoneFromUtil
.
isNumeric
(
title
))
{
if
(
content
.
contains
(
"\u200B"
))
{
if
(
title
.
contains
(
"+86"
))
{
title
.
replace
(
"+86"
,
""
)
}
PhoneUtils
.
phoneNumberFormat
(
title
)
{
itNumber
->
maskPhoneResult
=
itNumber
}
Log
.
e
(
TAG
,
"maskPhoneResult:$maskPhoneResult"
)
}
}
Log
.
d
(
TAG
,
"短信通知:脱敏后标题=$maskPhoneResult, 内容=$content"
)
val
notificationManager
=
notificationManager
val
isHighPriority
=
mContent
.
powerManager
.
isInteractive
val
channelId
=
if
(
isHighPriority
)
Constant
.
HIGH_PRIORITY
else
Constant
.
LOW_PRIORITY
if
(
isOreoPlus
())
{
val
importance
=
NotificationManager
.
IMPORTANCE_DEFAULT
val
name
=
if
(
isHighPriority
)
Constant
.
HIGH_CHANNEL_PRIORITY
else
Constant
.
LOW_CHANNEL_PRIORITY
NotificationChannel
(
channelId
,
name
,
importance
).
apply
{
setSound
(
null
,
null
)
notificationManager
.
createNotificationChannel
(
this
)
}
}
val
builder
=
NotificationCompat
.
Builder
(
mContent
,
channelId
)
.
setSmallIcon
(
R
.
mipmap
.
ic_launcher
)
.
setPriority
(
NotificationCompat
.
PRIORITY_LOW
)
.
setCategory
(
Notification
.
CATEGORY_MESSAGE
)
.
setDefaults
(
Notification
.
DEFAULT_SOUND
)
.
setContentTitle
(
maskPhoneResult
)
.
setContentText
(
content
)
.
setSound
(
null
)
.
setAutoCancel
(
true
)
.
setChannelId
(
channelId
)
val
buildNotification
=
builder
.
build
()
notificationManager
.
notify
(
CALL_NOTIFICATION_ID
,
buildNotification
)
Log
.
d
(
TAG
,
"短信通知:notificationManager 发送推送消息"
)
isShowNotification
=
true
}
}
catch
(
e
:
Exception
)
{
Log
.
e
(
TAG
,
"NotificationListener e: ${e.localizedMessage}"
)
cancelAllNotifications
()
}
}
override
fun
onNotificationRemoved
(
sbn
:
StatusBarNotification
?)
{
super
.
onNotificationRemoved
(
sbn
)
Log
.
e
(
TAG
,
"NotificationListener 该通知已被移出!!!"
)
isShowNotification
=
false
}
// 判断是否为短信应用
private
fun
isSmsPackage
(
packageName
:
String
):
Boolean
{
for
(
pkg
in
SMS_PACKAGES
)
{
if
(
pkg
==
packageName
)
{
return
true
}
}
return
false
}
// 提取通知标题
private
fun
getTitle
(
notification
:
Notification
?):
String
{
if
(
notification
==
null
)
return
""
val
title
=
notification
.
extras
.
getCharSequence
(
Notification
.
EXTRA_TITLE
)
return
title
?.
toString
()
?:
""
}
// 提取通知内容
private
fun
getContent
(
notification
:
Notification
?):
String
{
if
(
notification
==
null
)
return
""
val
text
=
notification
.
extras
.
getCharSequence
(
Notification
.
EXTRA_TEXT
)
return
text
?.
toString
()
?:
""
}
companion
object
{
private
const
val
TAG
=
"SmsNotificationListener"
// 短信应用的包名(不同厂商可能不同,需适配)
private
val
SMS_PACKAGES
=
arrayOf
(
"com.android.mms"
,
// 原生短信
"com.google.android.apps.messaging"
,
// Google短信
"com.secspace.sms"
// 微信(如果需要监听微信消息)
)
}
}
commons/src/main/kotlin/com/simplemobiletools/commons/extensions/Context.kt
View file @
0a746141
...
...
@@ -60,6 +60,8 @@ val Context.isRTLLayout: Boolean get() = resources.configuration.layoutDirection
val
Context
.
areSystemAnimationsEnabled
:
Boolean
get
()
=
Settings
.
Global
.
getFloat
(
contentResolver
,
Settings
.
Global
.
ANIMATOR_DURATION_SCALE
,
0f
)
>
0f
val
Context
.
powerManager
:
PowerManager
get
()
=
getSystemService
(
Context
.
POWER_SERVICE
)
as
PowerManager
fun
Context
.
toast
(
id
:
Int
,
length
:
Int
=
Toast
.
LENGTH_SHORT
)
{
toast
(
getString
(
id
),
length
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment