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
ed54f8b4
Commit
ed54f8b4
authored
Dec 03, 2025
by
zhangchengbo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:1.添加彩信手机号掩码功能
2.添加彩信PopWindow悬浮窗通知功能 3.添加彩信Notify通知栏推送功能 4.PopWindow短信悬浮窗推送与通知栏推送展示(通讯录如果有备注则优先展示备注名称,其次手机号)
parent
6bfbf2fd
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
169 additions
and
5 deletions
+169
-5
MmsReceiver.kt
...src/main/kotlin/com/secspace/sms/receivers/MmsReceiver.kt
+169
-5
No files found.
app/src/main/kotlin/com/secspace/sms/receivers/MmsReceiver.kt
View file @
ed54f8b4
...
...
@@ -2,30 +2,52 @@ package com.secspace.sms.receivers
import
android.content.Context
import
android.net.Uri
import
android.os.Handler
import
android.os.Looper
import
com.bumptech.glide.Glide
import
com.google.gson.Gson
import
com.klinker.android.send_message.MmsReceivedReceiver
import
com.secspace.log.Log
import
com.secspace.sms.R
import
com.secspace.sms.extensions.*
import
com.secspace.sms.helpers.Config
import
com.secspace.sms.helpers.RecentsHelper
import
com.secspace.sms.helpers.refreshMessages
import
com.secspace.sms.models.Message
import
com.secspace.sms.models.RecentCall
import
com.secspace.sms.popup.MyPushWindow
import
com.secspace.sms.util.AES
import
com.secspace.sms.util.PhoneFromUtil
import
com.secspace.sms.util.PhoneUtils
import
com.secspace.sms.util.SmsCountUtil
import
com.simplemobiletools.commons.extensions.hasPermission
import
com.simplemobiletools.commons.extensions.isNumberBlocked
import
com.simplemobiletools.commons.extensions.normalizePhoneNumber
import
com.simplemobiletools.commons.extensions.showErrorToast
import
com.simplemobiletools.commons.helpers.PERMISSION_READ_CALL_LOG
import
com.simplemobiletools.commons.helpers.ensureBackgroundThread
import
com.simplemobiletools.commons.util.GsonUtil
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.launch
// more info at https://github.com/klinker41/android-smsmms
class
MmsReceiver
:
MmsReceivedReceiver
()
{
private
val
TAG
=
"MmsReceiver"
override
fun
isAddressBlocked
(
context
:
Context
,
address
:
String
):
Boolean
{
val
normalizedAddress
=
address
.
normalizePhoneNumber
()
return
context
.
isNumberBlocked
(
normalizedAddress
)
}
override
fun
onMessageReceived
(
context
:
Context
,
messageUri
:
Uri
)
{
val
mms
=
context
.
getLatestMMS
()
?:
return
//手机号
val
address
=
mms
.
getSender
()
?.
phoneNumbers
?.
first
()
?.
normalizedNumber
?:
""
Log
.
d
(
TAG
,
"onMessageReceived: mms = ${Gson().toJson(mms)}"
)
Log
.
d
(
TAG
,
"onMessageReceived: address = $address"
)
val
size
=
context
.
resources
.
getDimension
(
R
.
dimen
.
notification_large_icon_size
).
toInt
()
ensureBackgroundThread
{
val
glideBitmap
=
try
{
...
...
@@ -39,16 +61,158 @@ class MmsReceiver : MmsReceivedReceiver() {
null
}
Handler
(
Looper
.
getMainLooper
()).
post
{
context
.
showReceivedMessageNotification
(
mms
.
id
,
address
,
mms
.
body
,
mms
.
threadId
,
glideBitmap
)
val
conversation
=
context
.
getConversations
(
mms
.
threadId
).
firstOrNull
()
?:
return
@post
CoroutineScope
(
Dispatchers
.
Main
).
launch
{
var
listContains
=
listOf
<
String
>()
var
encryptNumberResult
=
""
var
notificationUserName
=
""
//通讯录如果有备注则优先展示备注,其次手机号
val
conversation
=
context
.
getConversations
(
mms
.
threadId
).
firstOrNull
()
?:
return
@launch
Log
.
d
(
TAG
,
"onMessageReceived: conversation = ${Gson().toJson(conversation)}"
)
if
(!
PhoneFromUtil
.
isNumeric
(
conversation
.
userName
))
{
notificationUserName
=
conversation
.
userName
}
//切子线程
ensureBackgroundThread
{
encryptNumberResult
=
findConversationWithPhoneNumber
(
context
,
address
,
mms
.
body
,
mms
.
threadId
)
Log
.
d
(
TAG
,
"onMessageReceived: encryptNumberResult = $encryptNumberResult"
)
val
messages
=
context
.
getMessages
(
mms
.
threadId
,
true
)
Log
.
d
(
TAG
,
"onMessageReceived: messages 是否为空 = ${messages.isNotEmpty()}"
)
if
(
messages
.
isNotEmpty
())
{
listContains
=
messages
.
map
{
it
.
body
}.
filter
{
it
.
contains
(
"\u200B"
)
}
}
if
(!
PhoneFromUtil
.
isNumeric
(
encryptNumberResult
)
||
mms
.
body
.
contains
(
"\u200B"
)
||
listContains
.
isNotEmpty
())
{
conversation
.
title
=
encryptNumberResult
conversation
.
isSFNumber
=
true
Log
.
d
(
TAG
,
"onMessageReceived: 满足号码脱敏条件 更改顺丰标识为true "
)
}
context
.
insertOrUpdateConversation
(
conversation
)
badgeTotalNumber
(
context
)
refreshMessages
()
Log
.
d
(
TAG
,
"onMessageReceived: 子线程 currentThread = ${Thread.currentThread()}"
)
Log
.
d
(
TAG
,
"handleMessage: notificationUserName = $notificationUserName encryptNumberResult = $encryptNumberResult address = $address"
)
if
(
notificationUserName
.
isNotBlank
()){
context
.
showReceivedMessageNotification
(
mms
.
id
,
notificationUserName
,
mms
.
body
,
mms
.
threadId
,
glideBitmap
)
}
else
if
(
encryptNumberResult
.
isNotBlank
())
{
context
.
showReceivedMessageNotification
(
mms
.
id
,
encryptNumberResult
,
mms
.
body
,
mms
.
threadId
,
glideBitmap
)
}
else
{
context
.
showReceivedMessageNotification
(
mms
.
id
,
address
,
mms
.
body
,
mms
.
threadId
,
glideBitmap
)
}
}
Log
.
d
(
TAG
,
"onMessageReceived: UI程 currentThread = ${Thread.currentThread()}"
)
Log
.
d
(
TAG
,
"SmsReceiver: notificationUserName = $notificationUserName encryptNumberResult = $encryptNumberResult address = $address"
)
if
(
notificationUserName
.
isNotBlank
())
{
val
tipPopup
=
MyPushWindow
(
context
,
notificationUserName
,
mms
.
body
)
tipPopup
.
show
()
}
else
if
(
encryptNumberResult
.
isNotBlank
())
{
val
tipPopup
=
MyPushWindow
(
context
,
encryptNumberResult
,
mms
.
body
)
tipPopup
.
show
()
}
else
{
Log
.
d
(
TAG
,
"SmsReceiver 短信内容 = ${mms.body} address = $address "
)
if
(
mms
.
body
.
contains
(
"\u200B"
))
{
if
(
address
.
contains
(
"+86"
))
{
address
.
replace
(
"+86"
,
""
)
}
PhoneUtils
.
phoneNumberFormat
(
address
)
{
itNumber
->
val
tipPopup
=
MyPushWindow
(
context
,
itNumber
,
mms
.
body
)
tipPopup
.
show
()
}
}
else
{
val
tipPopup
=
MyPushWindow
(
context
,
address
,
mms
.
body
)
tipPopup
.
show
()
}
}
}
}
}
override
fun
onError
(
context
:
Context
,
error
:
String
)
=
context
.
showErrorToast
(
context
.
getString
(
R
.
string
.
couldnt_download_mms
))
/**
* 1.先从短信DB库查找
* 2.未找到再从 通话记录中查找
*/
private
fun
findConversationWithPhoneNumber
(
context
:
Context
,
phoneNumber
:
String
,
body
:
String
,
threadId
:
Long
):
String
{
var
lastNumber
=
""
Log
.
d
(
TAG
,
"SmsReceiver phoneNumber:${phoneNumber} body = $body threadId = $threadId"
)
val
hasPerMissionResult
=
context
.
hasPermission
(
PERMISSION_READ_CALL_LOG
)
if
(
hasPerMissionResult
)
{
//1
val
listMessageData
=
context
.
getMessages
(
threadId
,
false
)
if
(
listMessageData
.
isNotEmpty
())
{
val
listContains
:
List
<
Message
>
=
listMessageData
.
filter
{
msg
->
msg
.
body
.
contains
(
"\u200B"
)
}
if
(
listContains
.
isNotEmpty
())
{
PhoneUtils
.
phoneNumberFormat
(
phoneNumber
)
{
itNumber
->
lastNumber
=
itNumber
}
}
}
//2
if
(
lastNumber
.
isEmpty
())
{
RecentsHelper
(
context
=
context
).
getRecentCalls
(
false
,
Int
.
MAX_VALUE
)
{
recents
:
List
<
RecentCall
>
->
val
listCallRecent
:
List
<
RecentCall
>
=
recents
.
distinctBy
{
it
.
phoneNumber
}
Log
.
d
(
TAG
,
"SmsReceiver最近通话 recents:${GsonUtil.parseListToJson(listCallRecent)}"
)
val
findResult
=
listCallRecent
.
filter
{
it
.
isShunFeng
}.
count
{
Log
.
d
(
TAG
,
"SmsReceiver findResult isNumber = ${PhoneFromUtil.isNumeric(it.phoneNumber)}"
)
if
(
PhoneFromUtil
.
isNumeric
(
it
.
phoneNumber
))
{
if
(
phoneNumber
.
contains
(
"+86"
))
{
it
.
phoneNumber
==
phoneNumber
.
replace
(
"+86"
,
""
)
}
else
{
it
.
phoneNumber
==
phoneNumber
}
}
else
{
if
(
phoneNumber
.
contains
(
"+86"
))
{
AES
.
decrypt
(
it
.
phoneNumber
)
==
phoneNumber
.
replace
(
"+86"
,
""
)
}
else
{
AES
.
decrypt
(
it
.
phoneNumber
)
==
phoneNumber
}
}
}
Log
.
d
(
TAG
,
"SmsReceiverFindResult:${findResult} phoneNumber = ${phoneNumber.trim()}"
)
//从最近通话记录中找到了号码 进行掩码操作
if
(
findResult
>
0
)
{
PhoneUtils
.
phoneNumberFormat
(
phoneNumber
)
{
itNumber
->
lastNumber
=
itNumber
}
}
}
}
Log
.
d
(
TAG
,
"SmsReceiver lastNumber = $lastNumber"
)
}
return
lastNumber
.
ifBlank
{
phoneNumber
}
}
/**
* 统计未读消息数量
*
* 存储值在 Mainactivity.kt 完成
* 此处只做获取数值操作
* 1.未获取到值则表明没有未读短信,直接+1显示
* 2.获取到值也要数量+1 显示
*/
private
fun
badgeTotalNumber
(
context
:
Context
)
{
val
readTotalResult
:
Int
=
Config
.
newInstance
(
context
).
badgeTotalNumber
val
totalResult
=
readTotalResult
+
1
SmsCountUtil
.
setBadgeNum
(
context
,
totalResult
)
Config
.
newInstance
(
context
).
badgeTotalNumber
=
totalResult
Log
.
d
(
TAG
,
"badgeTotalNumber readTotalResult = $totalResult "
)
}
}
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