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
491f70e5
Commit
491f70e5
authored
Nov 19, 2025
by
zhangchengbo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:[加入黑名单]-[管理黑名单]功能
parent
87bf7fab
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
441 additions
and
77 deletions
+441
-77
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+8
-0
MainActivity.kt
...c/main/kotlin/com/secspace/sms/activities/MainActivity.kt
+4
-4
SettingsActivity.kt
...in/kotlin/com/secspace/sms/activities/SettingsActivity.kt
+27
-25
ThreadActivity.kt
...main/kotlin/com/secspace/sms/activities/ThreadActivity.kt
+8
-8
activity_settings.xml
app/src/main/res/layout/activity_settings.xml
+65
-33
menu_main.xml
app/src/main/res/menu/menu_main.xml
+0
-1
ManageBlockedNumbersActivity.kt
...etools/commons/activities/ManageBlockedNumbersActivity.kt
+322
-0
ManageBlockedNumbersScreen.kt
...ols/commons/compose/screens/ManageBlockedNumbersScreen.kt
+4
-4
Context.kt
...otlin/com/simplemobiletools/commons/extensions/Context.kt
+3
-2
No files found.
app/src/main/AndroidManifest.xml
View file @
491f70e5
...
...
@@ -135,6 +135,14 @@
android:parentActivityName=
".activities.SettingsActivity"
/>
<activity
android:name=
"com.simplemobiletools.commons.activities.ManageBlockedNumbersActivity"
android:configChanges=
"orientation"
android:exported=
"false"
android:label=
"@string/blocked_numbers"
android:parentActivityName=
".activities.SettingsActivity"
tools:replace=
"android:label"
/>
<activity
android:name=
".activities.ManageBlockedKeywordsActivity"
android:configChanges=
"orientation"
android:exported=
"false"
...
...
app/src/main/kotlin/com/secspace/sms/activities/MainActivity.kt
View file @
491f70e5
...
...
@@ -201,17 +201,17 @@ class MainActivity : SimpleActivity() {
searchTextChanged
(
text
)
}
/*
binding.mainMenu.getToolbar().setOnMenuItemClickListener { menuItem ->
binding
.
mainMenu
.
getToolbar
().
setOnMenuItemClickListener
{
menuItem
->
when
(
menuItem
.
itemId
)
{
R.id.more_apps_from_us -> launchMoreAppsFromUsIntent()
/*
R.id.more_apps_from_us -> launchMoreAppsFromUsIntent()
R.id.show_recycle_bin -> launchRecycleBin()
R.id.show_archived -> launchArchivedConversations()
R.id.about -> launchAbout()*/
R
.
id
.
settings
->
launchSettings
()
R.id.about -> launchAbout()
else
->
return
@setOnMenuItemClickListener
false
}
return
@setOnMenuItemClickListener
true
}
*/
}
}
private
fun
refreshMenuItems
()
{
...
...
app/src/main/kotlin/com/secspace/sms/activities/SettingsActivity.kt
View file @
491f70e5
...
...
@@ -13,6 +13,7 @@ import com.secspace.sms.extensions.config
import
com.secspace.sms.extensions.emptyMessagesRecycleBin
import
com.secspace.sms.extensions.messagesDB
import
com.secspace.sms.helpers.*
import
com.simplemobiletools.commons.activities.ManageBlockedNumbersActivity
import
com.simplemobiletools.commons.dialogs.*
import
com.simplemobiletools.commons.extensions.*
import
com.simplemobiletools.commons.helpers.*
...
...
@@ -48,27 +49,28 @@ class SettingsActivity : SimpleActivity() {
super
.
onResume
()
setupToolbar
(
binding
.
settingsToolbar
,
NavigationIcon
.
Arrow
)
setupPurchaseThankYou
()
setupCustomizeColors
()
//
setupPurchaseThankYou()
//
setupCustomizeColors()
// setupCustomizeNotifications()
setupUseEnglish
()
//
setupUseEnglish()
// setupLanguage()
setupManageBlockedKeywords
()
setupChangeDateTimeFormat
()
setupFontSize
()
setupShowCharacterCounter
()
setupUseSimpleCharacters
()
setupSendOnEnter
()
setupEnableDeliveryReports
()
setupSendLongMessageAsMMS
()
setupGroupMessageAsMMS
()
setupLockScreenVisibility
()
setupMMSFileSizeLimit
()
setupUseRecycleBin
()
setupEmptyRecycleBin
()
setupAppPasswordProtection
()
setupMessagesExport
()
setupMessagesImport
()
setupManageBlockedNumbers
()
// setupManageBlockedKeywords()
// setupChangeDateTimeFormat()
// setupFontSize()
// setupShowCharacterCounter()
// setupUseSimpleCharacters()
// setupSendOnEnter()
// setupEnableDeliveryReports()
// setupSendLongMessageAsMMS()
// setupGroupMessageAsMMS()
// setupLockScreenVisibility()
// setupMMSFileSizeLimit()
// setupUseRecycleBin()
// setupEmptyRecycleBin()
// setupAppPasswordProtection()
// setupMessagesExport()
// setupMessagesImport()
updateTextColors
(
binding
.
settingsNestedScrollview
)
if
(
blockedNumbersAtPause
!=
-
1
&&
blockedNumbersAtPause
!=
getBlockedNumbers
().
hashCode
())
{
...
...
@@ -185,20 +187,20 @@ class SettingsActivity : SimpleActivity() {
}
// support for device-wise blocking came on Android 7, rely only on that
/*
private fun setupManageBlockedNumbers() = binding.apply {
private
fun
setupManageBlockedNumbers
()
=
binding
.
apply
{
settingsManageBlockedNumbers
.
text
=
addLockedLabelIfNeeded
(
com
.
simplemobiletools
.
commons
.
R
.
string
.
manage_blocked_numbers
)
settingsManageBlockedNumbersHolder
.
beVisibleIf
(
isNougatPlus
())
settingsManageBlockedNumbersHolder
.
setOnClickListener
{
if (isOrWasThankYouInstalled()) {
//
if (isOrWasThankYouInstalled()) {
Intent
(
this
@SettingsActivity
,
ManageBlockedNumbersActivity
::
class
.
java
).
apply
{
startActivity
(
this
)
}
} else {
FeatureLockedDialog(this@SettingsActivity) { }
}
//
} else {
//
FeatureLockedDialog(this@SettingsActivity) { }
//
}
}
}
*/
}
private
fun
setupManageBlockedKeywords
()
=
binding
.
apply
{
settingsManageBlockedKeywords
.
text
=
addLockedLabelIfNeeded
(
R
.
string
.
manage_blocked_keywords
)
...
...
app/src/main/kotlin/com/secspace/sms/activities/ThreadActivity.kt
View file @
491f70e5
...
...
@@ -259,8 +259,8 @@ class ThreadActivity : SimpleActivity() {
findItem
(
R
.
id
.
unarchive
).
isVisible
=
/*threadItems.isNotEmpty() && conversation?.isArchived == true && !isRecycleBin && archiveAvailable*/
false
findItem
(
R
.
id
.
rename_conversation
).
isVisible
=
/*participants.size > 1 && conversation != null && !isRecycleBin*/
false
findItem
(
R
.
id
.
conversation_details
).
isVisible
=
/*conversation != null && !isRecycleBin*/
false
findItem
(
R
.
id
.
block_number
).
title
=
/*addLockedLabelIfNeeded(com.simplemobiletools.commons.R.string.block_number)*/
""
findItem
(
R
.
id
.
block_number
).
isVisible
=
/*isNougatPlus() && !isRecycleBin*/
false
findItem
(
R
.
id
.
block_number
).
title
=
addLockedLabelIfNeeded
(
com
.
simplemobiletools
.
commons
.
R
.
string
.
block_number
)
findItem
(
R
.
id
.
block_number
).
isVisible
=
isNougatPlus
()
&&
!
isRecycleBin
findItem
(
R
.
id
.
dial_number
).
isVisible
=
/*participants.size == 1 && !isSpecialNumber() && !isRecycleBin*/
false
findItem
(
R
.
id
.
manage_people
).
isVisible
=
/*!isSpecialNumber() && !isRecycleBin */
false
findItem
(
R
.
id
.
mark_as_unread
).
isVisible
=
/*threadItems.isNotEmpty() && !isRecycleBin*/
false
...
...
@@ -280,8 +280,8 @@ class ThreadActivity : SimpleActivity() {
when
(
menuItem
.
itemId
)
{
R
.
id
.
delete
->
askConfirmDelete
()
/*
R.id.block_number -> tryBlocking()
R.id.restore -> askConfirmRestoreAll()
R
.
id
.
block_number
->
tryBlocking
()
/*
R.id.restore -> askConfirmRestoreAll()
R.id.archive -> archiveConversation()
R.id.unarchive -> unarchiveConversation()
R.id.rename_conversation -> renameConversation()
...
...
@@ -945,11 +945,11 @@ class ThreadActivity : SimpleActivity() {
}
private
fun
tryBlocking
()
{
if
(
isOrWasThankYouInstalled
())
{
//
if (isOrWasThankYouInstalled()) {
blockNumber
()
}
else
{
FeatureLockedDialog
(
this
)
{
}
}
//
} else {
//
FeatureLockedDialog(this) { }
//
}
}
private
fun
blockNumber
()
{
...
...
app/src/main/res/layout/activity_settings.xml
View file @
491f70e5
...
...
@@ -33,13 +33,15 @@
style=
"@style/SettingsSectionLabelStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:text=
"@string/color_customization"
/>
android:text=
"@string/color_customization"
android:visibility=
"gone"
/>
<androidx.constraintlayout.widget.ConstraintLayout
android:id=
"@+id/settings_color_customization_holder"
style=
"@style/SettingsHolderTextViewOneLinerStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyTextView
android:id=
"@+id/settings_color_customization_label"
...
...
@@ -61,13 +63,14 @@
style=
"@style/SettingsSectionLabelStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:text=
"@string/
general_setting
s"
/>
android:text=
"@string/
blocked_number
s"
/>
<RelativeLayout
android:id=
"@+id/settings_purchase_thank_you_holder"
style=
"@style/SettingsHolderTextViewOneLinerStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyTextView
android:id=
"@+id/settings_purchase_thank_you"
...
...
@@ -82,7 +85,8 @@
android:id=
"@+id/settings_use_english_holder"
style=
"@style/SettingsHolderCheckboxStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
android:id=
"@+id/settings_use_english"
...
...
@@ -97,7 +101,8 @@
android:id=
"@+id/settings_language_holder"
style=
"@style/SettingsHolderTextViewStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyTextView
android:id=
"@+id/settings_language_label"
...
...
@@ -120,7 +125,8 @@
android:id=
"@+id/settings_change_date_time_format_holder"
style=
"@style/SettingsHolderTextViewOneLinerStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyTextView
android:id=
"@+id/settings_change_date_time_format"
...
...
@@ -150,7 +156,8 @@
android:id=
"@+id/settings_manage_blocked_keywords_holder"
style=
"@style/SettingsHolderTextViewOneLinerStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyTextView
android:id=
"@+id/settings_manage_blocked_keywords"
...
...
@@ -165,7 +172,8 @@
android:id=
"@+id/settings_font_size_holder"
style=
"@style/SettingsHolderTextViewStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyTextView
android:id=
"@+id/settings_font_size_label"
...
...
@@ -186,20 +194,23 @@
<include
android:id=
"@+id/settings_general_settings_divider"
layout=
"@layout/divider"
/>
layout=
"@layout/divider"
android:visibility=
"gone"
/>
<TextView
android:id=
"@+id/settings_notifications_label"
style=
"@style/SettingsSectionLabelStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:text=
"@string/notifications"
/>
android:text=
"@string/notifications"
android:visibility=
"gone"
/>
<RelativeLayout
android:id=
"@+id/settings_customize_notifications_holder"
style=
"@style/SettingsHolderTextViewOneLinerStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyTextView
android:id=
"@+id/settings_customize_notifications_label"
...
...
@@ -214,7 +225,8 @@
android:id=
"@+id/settings_lock_screen_visibility_holder"
style=
"@style/SettingsHolderTextViewStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyTextView
android:id=
"@+id/settings_lock_screen_visibility_label"
...
...
@@ -235,20 +247,23 @@
<include
android:id=
"@+id/settings_notifications_divider"
layout=
"@layout/divider"
/>
layout=
"@layout/divider"
android:visibility=
"gone"
/>
<TextView
android:id=
"@+id/settings_outgoing_messages_label"
style=
"@style/SettingsSectionLabelStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:text=
"@string/outgoing_messages"
/>
android:text=
"@string/outgoing_messages"
android:visibility=
"gone"
/>
<RelativeLayout
android:id=
"@+id/settings_show_character_counter_holder"
style=
"@style/SettingsHolderCheckboxStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
android:id=
"@+id/settings_show_character_counter"
...
...
@@ -263,7 +278,8 @@
android:id=
"@+id/settings_use_simple_characters_holder"
style=
"@style/SettingsHolderCheckboxStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
android:id=
"@+id/settings_use_simple_characters"
...
...
@@ -278,7 +294,8 @@
android:id=
"@+id/settings_send_on_enter_holder"
style=
"@style/SettingsHolderCheckboxStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
android:id=
"@+id/settings_send_on_enter"
...
...
@@ -293,7 +310,8 @@
android:id=
"@+id/settings_enable_delivery_reports_holder"
style=
"@style/SettingsHolderCheckboxStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
android:id=
"@+id/settings_enable_delivery_reports"
...
...
@@ -308,7 +326,8 @@
android:id=
"@+id/settings_send_long_message_mms_holder"
style=
"@style/SettingsHolderCheckboxStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
android:id=
"@+id/settings_send_long_message_mms"
...
...
@@ -323,7 +342,8 @@
android:id=
"@+id/settings_send_group_message_mms_holder"
style=
"@style/SettingsHolderCheckboxStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
android:id=
"@+id/settings_send_group_message_mms"
...
...
@@ -338,7 +358,8 @@
android:id=
"@+id/settings_mms_file_size_limit_holder"
style=
"@style/SettingsHolderTextViewStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyTextView
android:id=
"@+id/settings_mms_file_size_limit_label"
...
...
@@ -359,20 +380,23 @@
<include
android:id=
"@+id/settings_outgoing_messages_divider"
layout=
"@layout/divider"
/>
layout=
"@layout/divider"
android:visibility=
"gone"
/>
<TextView
android:id=
"@+id/settings_recycle_bin_label"
style=
"@style/SettingsSectionLabelStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:text=
"@string/recycle_bin"
/>
android:text=
"@string/recycle_bin"
android:visibility=
"gone"
/>
<RelativeLayout
android:id=
"@+id/settings_use_recycle_bin_holder"
style=
"@style/SettingsHolderCheckboxStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
android:id=
"@+id/settings_use_recycle_bin"
...
...
@@ -387,7 +411,8 @@
android:id=
"@+id/settings_empty_recycle_bin_holder"
style=
"@style/SettingsHolderTextViewStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyTextView
android:id=
"@+id/settings_empty_recycle_bin_label"
...
...
@@ -408,20 +433,23 @@
<include
android:id=
"@+id/settings_recycle_bin_divider"
layout=
"@layout/divider"
/>
layout=
"@layout/divider"
android:visibility=
"gone"
/>
<TextView
android:id=
"@+id/settings_security_label"
style=
"@style/SettingsSectionLabelStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:text=
"@string/security"
/>
android:text=
"@string/security"
android:visibility=
"gone"
/>
<RelativeLayout
android:id=
"@+id/settings_app_password_protection_holder"
style=
"@style/SettingsHolderCheckboxStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
android:id=
"@+id/settings_app_password_protection"
...
...
@@ -434,20 +462,23 @@
<include
android:id=
"@+id/settings_migrating_divider"
layout=
"@layout/divider"
/>
layout=
"@layout/divider"
android:visibility=
"gone"
/>
<TextView
android:id=
"@+id/settings_migrating_label"
style=
"@style/SettingsSectionLabelStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:text=
"@string/migrating"
/>
android:text=
"@string/migrating"
android:visibility=
"gone"
/>
<RelativeLayout
android:id=
"@+id/settings_export_messages_holder"
style=
"@style/SettingsHolderTextViewOneLinerStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyTextView
android:id=
"@+id/settings_export_messages"
...
...
@@ -462,7 +493,8 @@
android:id=
"@+id/settings_import_messages_holder"
style=
"@style/SettingsHolderTextViewOneLinerStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
android:visibility=
"gone"
>
<com.simplemobiletools.commons.views.MyTextView
android:id=
"@+id/settings_import_messages"
...
...
app/src/main/res/menu/menu_main.xml
View file @
491f70e5
...
...
@@ -17,7 +17,6 @@
android:id=
"@+id/settings"
android:icon=
"@drawable/ic_settings_cog_vector"
android:title=
"@string/settings"
android:visible=
"false"
app:showAsAction=
"always"
/>
<item
android:id=
"@+id/about"
...
...
commons/src/main/kotlin/com/simplemobiletools/commons/activities/ManageBlockedNumbersActivity.kt
0 → 100644
View file @
491f70e5
package
com.simplemobiletools.commons.activities
import
android.app.Activity
import
android.app.Application
import
android.content.ActivityNotFoundException
import
android.content.Intent
import
android.net.Uri
import
android.os.Bundle
import
android.widget.Toast
import
androidx.activity.compose.setContent
import
androidx.activity.viewModels
import
androidx.compose.runtime.*
import
androidx.compose.ui.platform.LocalContext
import
androidx.lifecycle.AndroidViewModel
import
androidx.lifecycle.compose.collectAsStateWithLifecycle
import
androidx.lifecycle.viewModelScope
import
com.simplemobiletools.commons.R
import
com.simplemobiletools.commons.compose.alert_dialog.rememberAlertDialogState
import
com.simplemobiletools.commons.compose.extensions.enableEdgeToEdgeSimple
import
com.simplemobiletools.commons.compose.extensions.onEventValue
import
com.simplemobiletools.commons.compose.screens.ManageBlockedNumbersScreen
import
com.simplemobiletools.commons.compose.theme.AppThemeSurface
import
com.simplemobiletools.commons.dialogs.AddOrEditBlockedNumberAlertDialog
import
com.simplemobiletools.commons.dialogs.ExportBlockedNumbersDialog
import
com.simplemobiletools.commons.dialogs.FilePickerDialog
import
com.simplemobiletools.commons.extensions.*
import
com.simplemobiletools.commons.helpers.*
import
com.simplemobiletools.commons.models.BlockedNumber
import
java.io.FileOutputStream
import
java.io.OutputStream
import
kotlinx.collections.immutable.ImmutableList
import
kotlinx.collections.immutable.toImmutableList
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.flow.MutableStateFlow
import
kotlinx.coroutines.flow.asStateFlow
import
kotlinx.coroutines.flow.update
import
kotlinx.coroutines.launch
import
kotlinx.coroutines.withContext
class
ManageBlockedNumbersActivity
:
BaseSimpleActivity
()
{
private
val
config
by
lazy
{
baseConfig
}
private
companion
object
{
private
const
val
PICK_IMPORT_SOURCE_INTENT
=
11
private
const
val
PICK_EXPORT_FILE_INTENT
=
21
}
override
fun
getAppIconIDs
()
=
intent
.
getIntegerArrayListExtra
(
APP_ICON_IDS
)
?:
ArrayList
()
//
override
fun
getAppLauncherName
()
=
intent
.
getStringExtra
(
APP_LAUNCHER_NAME
)
?:
""
private
val
manageBlockedNumbersViewModel
by
viewModels
<
ManageBlockedNumbersViewModel
>()
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
enableEdgeToEdgeSimple
()
setContent
{
val
context
=
LocalContext
.
current
val
blockedNumbers
by
manageBlockedNumbersViewModel
.
blockedNumbers
.
collectAsStateWithLifecycle
()
LaunchedEffect
(
blockedNumbers
)
{
if
(
blockedNumbers
?.
any
{
blockedNumber
->
blockedNumber
.
number
.
isBlockedNumberPattern
()
}
==
true
)
{
maybeSetDefaultCallerIdApp
()
}
}
val
isBlockingHiddenNumbers
by
config
.
isBlockingHiddenNumbers
.
collectAsStateWithLifecycle
(
initialValue
=
config
.
blockHiddenNumbers
)
val
isBlockingUnknownNumbers
by
config
.
isBlockingUnknownNumbers
.
collectAsStateWithLifecycle
(
initialValue
=
config
.
blockUnknownNumbers
)
val
isDialer
=
remember
{
config
.
appId
.
startsWith
(
"com.secspace.dialer"
)
}
val
isDefaultDialer
:
Boolean
=
onEventValue
{
context
.
isDefaultDialer
()
}
AppThemeSurface
{
var
clickedBlockedNumber
by
remember
{
mutableStateOf
<
BlockedNumber
?>(
null
)
}
val
addBlockedNumberDialogState
=
rememberAlertDialogState
()
addBlockedNumberDialogState
.
DialogMember
{
AddOrEditBlockedNumberAlertDialog
(
alertDialogState
=
addBlockedNumberDialogState
,
blockedNumber
=
clickedBlockedNumber
,
deleteBlockedNumber
=
{
blockedNumber
->
deleteBlockedNumber
(
blockedNumber
)
updateBlockedNumbers
()
}
)
{
blockedNumber
->
addBlockedNumber
(
blockedNumber
)
clickedBlockedNumber
=
null
updateBlockedNumbers
()
}
}
ManageBlockedNumbersScreen
(
goBack
=
::
finish
,
onAdd
=
{
clickedBlockedNumber
=
null
addBlockedNumberDialogState
.
show
()
},
onImportBlockedNumbers
=
::
tryImportBlockedNumbers
,
onExportBlockedNumbers
=
::
tryExportBlockedNumbers
,
setAsDefault
=
::
maybeSetDefaultCallerIdApp
,
isDialer
=
isDialer
,
hasGivenPermissionToBlock
=
isDefaultDialer
,
isBlockUnknownSelected
=
isBlockingUnknownNumbers
,
onBlockUnknownSelectedChange
=
{
isChecked
->
config
.
blockUnknownNumbers
=
isChecked
onCheckedSetCallerIdAsDefault
(
isChecked
)
},
isHiddenSelected
=
isBlockingHiddenNumbers
,
onHiddenSelectedChange
=
{
isChecked
->
config
.
blockHiddenNumbers
=
isChecked
onCheckedSetCallerIdAsDefault
(
isChecked
)
},
blockedNumbers
=
blockedNumbers
,
onDelete
=
{
selectedKeys
->
deleteBlockedNumbers
(
blockedNumbers
,
selectedKeys
)
},
onEdit
=
{
blockedNumber
->
clickedBlockedNumber
=
blockedNumber
addBlockedNumberDialogState
.
show
()
},
onCopy
=
{
blockedNumber
->
copyToClipboard
(
blockedNumber
.
number
)
}
)
}
}
}
private
fun
deleteBlockedNumbers
(
blockedNumbers
:
ImmutableList
<
BlockedNumber
>?,
selectedKeys
:
Set
<
Long
>
)
{
if
(
blockedNumbers
.
isNullOrEmpty
())
return
blockedNumbers
.
filter
{
blockedNumber
->
selectedKeys
.
contains
(
blockedNumber
.
id
)
}
.
forEach
{
blockedNumber
->
deleteBlockedNumber
(
blockedNumber
.
number
)
}
manageBlockedNumbersViewModel
.
updateBlockedNumbers
()
}
private
fun
tryImportBlockedNumbers
()
{
if
(
isQPlus
())
{
Intent
(
Intent
.
ACTION_GET_CONTENT
).
apply
{
addCategory
(
Intent
.
CATEGORY_OPENABLE
)
type
=
"text/plain"
try
{
startActivityForResult
(
this
,
PICK_IMPORT_SOURCE_INTENT
)
}
catch
(
e
:
ActivityNotFoundException
)
{
toast
(
R
.
string
.
system_service_disabled
,
Toast
.
LENGTH_LONG
)
}
catch
(
e
:
Exception
)
{
showErrorToast
(
e
)
}
}
}
else
{
handlePermission
(
PERMISSION_READ_STORAGE
)
{
isAllowed
->
if
(
isAllowed
)
{
pickFileToImportBlockedNumbers
()
}
}
}
}
private
fun
pickFileToImportBlockedNumbers
()
{
FilePickerDialog
(
this
)
{
importBlockedNumbers
(
it
)
}
}
private
fun
tryImportBlockedNumbersFromFile
(
uri
:
Uri
)
{
when
(
uri
.
scheme
)
{
"file"
->
importBlockedNumbers
(
uri
.
path
!!
)
"content"
->
{
val
tempFile
=
getTempFile
(
"blocked"
,
"blocked_numbers.txt"
)
if
(
tempFile
==
null
)
{
toast
(
R
.
string
.
unknown_error_occurred
)
return
}
try
{
val
inputStream
=
contentResolver
.
openInputStream
(
uri
)
val
out
=
FileOutputStream
(
tempFile
)
inputStream
!!
.
copyTo
(
out
)
importBlockedNumbers
(
tempFile
.
absolutePath
)
}
catch
(
e
:
Exception
)
{
showErrorToast
(
e
)
}
}
else
->
toast
(
R
.
string
.
invalid_file_format
)
}
}
private
fun
importBlockedNumbers
(
path
:
String
)
{
ensureBackgroundThread
{
val
result
=
BlockedNumbersImporter
(
this
).
importBlockedNumbers
(
path
)
toast
(
when
(
result
)
{
BlockedNumbersImporter
.
ImportResult
.
IMPORT_OK
->
R
.
string
.
importing_successful
BlockedNumbersImporter
.
ImportResult
.
IMPORT_FAIL
->
R
.
string
.
no_items_found
}
)
updateBlockedNumbers
()
}
}
private
fun
updateBlockedNumbers
()
{
manageBlockedNumbersViewModel
.
updateBlockedNumbers
()
}
private
fun
onCheckedSetCallerIdAsDefault
(
isChecked
:
Boolean
)
{
if
(
isChecked
)
{
maybeSetDefaultCallerIdApp
()
}
}
private
fun
maybeSetDefaultCallerIdApp
()
{
if
(
isQPlus
()
&&
baseConfig
.
appId
.
startsWith
(
"com.simplemobiletools.dialer"
))
{
setDefaultCallerIdApp
()
}
}
override
fun
onActivityResult
(
requestCode
:
Int
,
resultCode
:
Int
,
resultData
:
Intent
?)
{
super
.
onActivityResult
(
requestCode
,
resultCode
,
resultData
)
when
{
requestCode
==
REQUEST_CODE_SET_DEFAULT_DIALER
&&
isDefaultDialer
()
->
{
updateBlockedNumbers
()
}
requestCode
==
PICK_IMPORT_SOURCE_INTENT
&&
resultCode
==
Activity
.
RESULT_OK
&&
resultData
!=
null
&&
resultData
.
data
!=
null
->
{
tryImportBlockedNumbersFromFile
(
resultData
.
data
!!
)
}
requestCode
==
PICK_EXPORT_FILE_INTENT
&&
resultCode
==
Activity
.
RESULT_OK
&&
resultData
!=
null
&&
resultData
.
data
!=
null
->
{
val
outputStream
=
contentResolver
.
openOutputStream
(
resultData
.
data
!!
)
exportBlockedNumbersTo
(
outputStream
)
}
requestCode
==
REQUEST_CODE_SET_DEFAULT_CALLER_ID
&&
resultCode
!=
Activity
.
RESULT_OK
->
{
toast
(
R
.
string
.
must_make_default_caller_id_app
,
length
=
Toast
.
LENGTH_LONG
)
baseConfig
.
blockUnknownNumbers
=
false
baseConfig
.
blockHiddenNumbers
=
false
}
}
}
private
fun
exportBlockedNumbersTo
(
outputStream
:
OutputStream
?)
{
ensureBackgroundThread
{
val
blockedNumbers
=
getBlockedNumbers
()
if
(
blockedNumbers
.
isEmpty
())
{
toast
(
R
.
string
.
no_entries_for_exporting
)
}
else
{
BlockedNumbersExporter
.
exportBlockedNumbers
(
blockedNumbers
,
outputStream
)
{
toast
(
when
(
it
)
{
ExportResult
.
EXPORT_OK
->
R
.
string
.
exporting_successful
else
->
R
.
string
.
exporting_failed
}
)
}
}
}
}
private
fun
tryExportBlockedNumbers
()
{
if
(
isQPlus
())
{
ExportBlockedNumbersDialog
(
this
,
baseConfig
.
lastBlockedNumbersExportPath
,
true
)
{
file
->
Intent
(
Intent
.
ACTION_CREATE_DOCUMENT
).
apply
{
type
=
"text/plain"
putExtra
(
Intent
.
EXTRA_TITLE
,
file
.
name
)
addCategory
(
Intent
.
CATEGORY_OPENABLE
)
try
{
startActivityForResult
(
this
,
PICK_EXPORT_FILE_INTENT
)
}
catch
(
e
:
ActivityNotFoundException
)
{
toast
(
R
.
string
.
system_service_disabled
,
Toast
.
LENGTH_LONG
)
}
catch
(
e
:
Exception
)
{
showErrorToast
(
e
)
}
}
}
}
else
{
handlePermission
(
PERMISSION_WRITE_STORAGE
)
{
isAllowed
->
if
(
isAllowed
)
{
ExportBlockedNumbersDialog
(
this
,
baseConfig
.
lastBlockedNumbersExportPath
,
false
)
{
file
->
getFileOutputStream
(
file
.
toFileDirItem
(
this
),
true
)
{
out
->
exportBlockedNumbersTo
(
out
)
}
}
}
}
}
}
internal
class
ManageBlockedNumbersViewModel
(
private
val
application
:
Application
)
:
AndroidViewModel
(
application
)
{
private
val
_blockedNumbers
:
MutableStateFlow
<
ImmutableList
<
BlockedNumber
>?>
=
MutableStateFlow
(
null
)
val
blockedNumbers
=
_blockedNumbers
.
asStateFlow
()
init
{
updateBlockedNumbers
()
}
fun
updateBlockedNumbers
()
{
viewModelScope
.
launch
{
withContext
(
Dispatchers
.
IO
)
{
application
.
getBlockedNumbersWithContact
{
list
->
_blockedNumbers
.
update
{
list
.
toImmutableList
()
}
}
}
}
}
}
}
commons/src/main/kotlin/com/simplemobiletools/commons/compose/screens/ManageBlockedNumbersScreen.kt
View file @
491f70e5
...
...
@@ -141,7 +141,7 @@ internal fun ManageBlockedNumbersScreen(
}
}
SettingsCheckBoxComponent
(
/*
SettingsCheckBoxComponent(
label = if (isDialer) stringResource(id = R.string.block_not_stored_calls) else stringResource(id = R.string.block_not_stored_messages),
initialValue = isBlockUnknownSelected,
onChange = onBlockUnknownSelectedChange,
...
...
@@ -152,7 +152,7 @@ internal fun ManageBlockedNumbersScreen(
initialValue = isHiddenSelected,
onChange = onHiddenSelectedChange,
modifier = startingPadding.then(Modifier.topAppBarPaddings()),
)
)
*/
SettingsHorizontalDivider
(
modifier
=
Modifier
.
topAppBarPaddings
())
}
},
...
...
@@ -565,8 +565,8 @@ private fun NonActionModeToolbar(
val
actionMenus
=
remember
{
listOf
(
ActionItem
(
R
.
string
.
add_a_blocked_number
,
icon
=
Icons
.
Filled
.
Add
,
doAction
=
onAdd
),
ActionItem
(
R
.
string
.
import_blocked_numbers
,
doAction
=
onImportBlockedNumbers
,
overflowMode
=
OverflowMode
.
ALWAYS_OVERFLOW
),
ActionItem
(
R
.
string
.
export_blocked_numbers
,
doAction
=
onExportBlockedNumbers
,
overflowMode
=
OverflowMode
.
ALWAYS_OVERFLOW
),
/*
ActionItem(R.string.import_blocked_numbers, doAction = onImportBlockedNumbers, overflowMode = OverflowMode.ALWAYS_OVERFLOW),
ActionItem(R.string.export_blocked_numbers, doAction = onExportBlockedNumbers, overflowMode = OverflowMode.ALWAYS_OVERFLOW),
*/
).
toImmutableList
()
}
var
isMenuVisible
by
remember
{
mutableStateOf
(
false
)
}
...
...
commons/src/main/kotlin/com/simplemobiletools/commons/extensions/Context.kt
View file @
491f70e5
...
...
@@ -523,11 +523,12 @@ fun Context.getCustomizeColorsString(): String {
}
fun
Context
.
addLockedLabelIfNeeded
(
stringId
:
Int
):
String
{
return
if
(
isOrWasThankYouInstalled
())
{
/*
return if (isOrWasThankYouInstalled()) {
getString(stringId)
} else {
"${getString(stringId)} (${getString(R.string.feature_locked)})"
}
}*/
return
getString
(
stringId
)
}
fun
Context
.
isPackageInstalled
(
pkgName
:
String
):
Boolean
{
...
...
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