新增:自动删除N天前的转发记录(0=禁用,触发机制:每次电量变化时扫描) #224

pull/231/head
pppscn 2 years ago
parent c2df047dc1
commit 66e324bbbb

@ -7,6 +7,7 @@ import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.idormy.sms.forwarder.BuildConfig
import com.idormy.sms.forwarder.database.dao.FrpcDao
import com.idormy.sms.forwarder.database.dao.LogsDao
import com.idormy.sms.forwarder.database.dao.RuleDao
@ -43,7 +44,11 @@ abstract class AppDatabase : RoomDatabase() {
}
private fun buildDatabase(context: Context): AppDatabase {
return Room.databaseBuilder(context.applicationContext, AppDatabase::class.java, DATABASE_NAME)
var builder = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
DATABASE_NAME
)
.allowMainThreadQueries() //TODO:允许主线程访问,后面再优化
.addCallback(object : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
@ -93,10 +98,14 @@ custom_domains = smsf.demo.com
MIGRATION_8_9,
MIGRATION_9_10,
)
.setQueryCallback({ sqlQuery, bindArgs ->
if (BuildConfig.DEBUG) {
builder.setQueryCallback({ sqlQuery, bindArgs ->
println("SQL_QUERY: $sqlQuery\nBIND_ARGS: $bindArgs")
}, Executors.newSingleThreadExecutor())
.build()
}
return builder.build()
}
//转发日志添加SIM卡槽信息

@ -22,6 +22,9 @@ interface LogsDao {
@Query("DELETE FROM Logs where type=:type")
fun deleteAll(type: String): Completable
@Query("DELETE FROM Logs where time<:time")
fun deleteTimeAgo(time: Long)
@Update
fun update(logs: Logs): Completable

@ -11,9 +11,15 @@ class LogsRepository(private val logsDao: LogsDao) {
logsDao.delete(id)
}
@WorkerThread
fun deleteTimeAgo(time: Long) {
logsDao.deleteTimeAgo(time)
}
@WorkerThread
suspend fun insert(logs: Logs): Long = logsDao.insert(logs)
@WorkerThread
fun updateStatus(id: Long, status: Int, response: String): Int = logsDao.updateStatus(id, status, response)
fun updateStatus(id: Long, status: Int, response: String): Int =
logsDao.updateStatus(id, status, response)
}

@ -78,18 +78,38 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
//转发短信广播
switchEnableSms(binding!!.sbEnableSms)
//转发通话记录
switchEnablePhone(binding!!.sbEnablePhone, binding!!.scbCallType1, binding!!.scbCallType2, binding!!.scbCallType3, binding!!.scbCallType4)
switchEnablePhone(
binding!!.sbEnablePhone,
binding!!.scbCallType1,
binding!!.scbCallType2,
binding!!.scbCallType3,
binding!!.scbCallType4
)
//转发应用通知
switchEnableAppNotify(binding!!.sbEnableAppNotify, binding!!.scbCancelAppNotify, binding!!.scbNotUserPresent)
switchEnableAppNotify(
binding!!.sbEnableAppNotify,
binding!!.scbCancelAppNotify,
binding!!.scbNotUserPresent
)
//启动时异步获取已安装App信息
switchEnableLoadAppList(binding!!.sbEnableLoadAppList, binding!!.scbLoadUserApp, binding!!.scbLoadSystemApp)
switchEnableLoadAppList(
binding!!.sbEnableLoadAppList,
binding!!.scbLoadUserApp,
binding!!.scbLoadSystemApp
)
//过滤多久内重复消息
binding!!.xsbDuplicateMessagesLimits.setDefaultValue(SettingUtils.duplicateMessagesLimits)
binding!!.xsbDuplicateMessagesLimits.setOnSeekBarListener { _: XSeekBar?, newValue: Int ->
SettingUtils.duplicateMessagesLimits = newValue
}
//免打扰(禁用转发)时间段
binding!!.tvSilentPeriod.text = mTimeOption[SettingUtils.silentPeriodStart] + " ~ " + mTimeOption[SettingUtils.silentPeriodEnd]
binding!!.tvSilentPeriod.text =
mTimeOption[SettingUtils.silentPeriodStart] + " ~ " + mTimeOption[SettingUtils.silentPeriodEnd]
//自动删除N天前的转发记录
binding!!.xsbAutoCleanLogs.setDefaultValue(SettingUtils.autoCleanLogsDays)
binding!!.xsbAutoCleanLogs.setOnSeekBarListener { _: XSeekBar?, newValue: Int ->
SettingUtils.autoCleanLogsDays = newValue
}
//监听电池状态变化
switchBatteryReceiver(binding!!.sbBatteryReceiver)
@ -108,7 +128,11 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
switchExcludeFromRecents(binding!!.layoutExcludeFromRecents, binding!!.sbExcludeFromRecents)
//Cactus增强保活措施
switchEnableCactus(binding!!.sbEnableCactus, binding!!.scbPlaySilenceMusic, binding!!.scbOnePixelActivity)
switchEnableCactus(
binding!!.sbEnableCactus,
binding!!.scbPlaySilenceMusic,
binding!!.scbOnePixelActivity
)
//接口请求失败重试时间间隔
editRetryDelayTime(binding!!.etRetryTimes, binding!!.etDelayTime, binding!!.etTimeout)
@ -152,14 +176,16 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
val etSmsTemplate: EditText = binding!!.etSmsTemplate
when (v.id) {
R.id.btn_silent_period -> {
OptionsPickerBuilder(context, OnOptionsSelectListener { _: View?, options1: Int, options2: Int, _: Int ->
SettingUtils.silentPeriodStart = options1
SettingUtils.silentPeriodEnd = options2
val txt = mTimeOption[options1] + " ~ " + mTimeOption[options2]
binding!!.tvSilentPeriod.text = txt
XToastUtils.toast(txt)
return@OnOptionsSelectListener false
}).setTitleText(getString(R.string.select_time_period))
OptionsPickerBuilder(
context,
OnOptionsSelectListener { _: View?, options1: Int, options2: Int, _: Int ->
SettingUtils.silentPeriodStart = options1
SettingUtils.silentPeriodEnd = options2
val txt = mTimeOption[options1] + " ~ " + mTimeOption[options2]
binding!!.tvSilentPeriod.text = txt
XToastUtils.toast(txt)
return@OnOptionsSelectListener false
}).setTitleText(getString(R.string.select_time_period))
.setSelectOptions(SettingUtils.silentPeriodStart, SettingUtils.silentPeriodEnd)
.build<Any>().also {
it.setNPicker(mTimeOption, mTimeOption)
@ -178,7 +204,12 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
}
Log.d(TAG, App.SimInfoList.toString())
if (!App.SimInfoList.containsKey(0)) {
XToastUtils.error(String.format(getString(R.string.tip_can_not_get_sim_info), 1))
XToastUtils.error(
String.format(
getString(R.string.tip_can_not_get_sim_info),
1
)
)
return
}
val simInfo: SimInfo? = App.SimInfoList[0]
@ -193,7 +224,12 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
}
Log.d(TAG, App.SimInfoList.toString())
if (!App.SimInfoList.containsKey(1)) {
XToastUtils.error(String.format(getString(R.string.tip_can_not_get_sim_info), 2))
XToastUtils.error(
String.format(
getString(R.string.tip_can_not_get_sim_info),
2
)
)
return
}
val simInfo: SimInfo? = App.SimInfoList[1]
@ -209,15 +245,24 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
return
}
R.id.bt_insert_extra -> {
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_card_slot))
CommonUtils.insertOrReplaceText2Cursor(
etSmsTemplate,
getString(R.string.tag_card_slot)
)
return
}
R.id.bt_insert_time -> {
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_receive_time))
CommonUtils.insertOrReplaceText2Cursor(
etSmsTemplate,
getString(R.string.tag_receive_time)
)
return
}
R.id.bt_insert_device_name -> {
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_device_name))
CommonUtils.insertOrReplaceText2Cursor(
etSmsTemplate,
getString(R.string.tag_device_name)
)
return
}
else -> {}
@ -266,7 +311,13 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
//转发通话
@SuppressLint("UseSwitchCompatOrMaterialCode")
fun switchEnablePhone(sbEnablePhone: SwitchButton, scbCallType1: SmoothCheckBox, scbCallType2: SmoothCheckBox, scbCallType3: SmoothCheckBox, scbCallType4: SmoothCheckBox) {
fun switchEnablePhone(
sbEnablePhone: SwitchButton,
scbCallType1: SmoothCheckBox,
scbCallType2: SmoothCheckBox,
scbCallType3: SmoothCheckBox,
scbCallType4: SmoothCheckBox
) {
sbEnablePhone.isChecked = SettingUtils.enablePhone
scbCallType1.isChecked = SettingUtils.enableCallType1
scbCallType2.isChecked = SettingUtils.enableCallType2
@ -350,7 +401,11 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
//转发应用通知
@SuppressLint("UseSwitchCompatOrMaterialCode")
fun switchEnableAppNotify(sbEnableAppNotify: SwitchButton, scbCancelAppNotify: SmoothCheckBox, scbNotUserPresent: SmoothCheckBox) {
fun switchEnableAppNotify(
sbEnableAppNotify: SwitchButton,
scbCancelAppNotify: SmoothCheckBox,
scbNotUserPresent: SmoothCheckBox
) {
val layoutOptionalAction: LinearLayout = binding!!.layoutOptionalAction
val isEnable: Boolean = SettingUtils.enableAppNotify
sbEnableAppNotify.isChecked = isEnable
@ -383,7 +438,10 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
.positiveText(R.string.lab_yes)
.negativeText(R.string.lab_no)
.onPositive { _: MaterialDialog?, _: DialogAction? ->
XXPermissions.startPermissionActivity(requireContext(), permissions)
XXPermissions.startPermissionActivity(
requireContext(),
permissions
)
}
.show()
}
@ -402,7 +460,11 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
//启动时异步获取已安装App信息 (binding!!.sbEnableLoadAppList, binding!!.scbLoadUserApp, binding!!.scbLoadSystemApp)
@SuppressLint("UseSwitchCompatOrMaterialCode")
fun switchEnableLoadAppList(sbEnableLoadAppList: SwitchButton, scbLoadUserApp: SmoothCheckBox, scbLoadSystemApp: SmoothCheckBox) {
fun switchEnableLoadAppList(
sbEnableLoadAppList: SwitchButton,
scbLoadUserApp: SmoothCheckBox,
scbLoadSystemApp: SmoothCheckBox
) {
val isEnable: Boolean = SettingUtils.enableLoadAppList
sbEnableLoadAppList.isChecked = isEnable
@ -445,8 +507,14 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
}
//设置低电量报警
private fun editBatteryLevelAlarm(xrsBatteryLevelAlarm: XRangeSlider, scbBatteryLevelAlarmOnce: SmoothCheckBox) {
xrsBatteryLevelAlarm.setStartingMinMax(SettingUtils.batteryLevelMin, SettingUtils.batteryLevelMax)
private fun editBatteryLevelAlarm(
xrsBatteryLevelAlarm: XRangeSlider,
scbBatteryLevelAlarmOnce: SmoothCheckBox
) {
xrsBatteryLevelAlarm.setStartingMinMax(
SettingUtils.batteryLevelMin,
SettingUtils.batteryLevelMax
)
xrsBatteryLevelAlarm.setOnRangeSliderListener(object : OnRangeSliderListener {
override fun onMaxChanged(slider: XRangeSlider, maxValue: Int) {
//SettingUtils.batteryLevelMin = slider.selectedMin
@ -472,7 +540,8 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
@SuppressLint("UseSwitchCompatOrMaterialCode")
fun switchBatteryCron(sbBatteryCron: SwitchButton) {
sbBatteryCron.isChecked = SettingUtils.enableBatteryCron
binding!!.layoutBatteryCron.visibility = if (SettingUtils.enableBatteryCron) View.VISIBLE else View.GONE
binding!!.layoutBatteryCron.visibility =
if (SettingUtils.enableBatteryCron) View.VISIBLE else View.GONE
sbBatteryCron.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
binding!!.layoutBatteryCron.visibility = if (isChecked) View.VISIBLE else View.GONE
SettingUtils.enableBatteryCron = isChecked
@ -482,7 +551,10 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
}
//设置推送电池状态时机
private fun editBatteryCronTiming(etBatteryCronStartTime: EditText, etBatteryCronInterval: EditText) {
private fun editBatteryCronTiming(
etBatteryCronStartTime: EditText,
etBatteryCronInterval: EditText
) {
etBatteryCronStartTime.setText(SettingUtils.batteryCronStartTime)
etBatteryCronStartTime.setOnClickListener {
val calendar = Calendar.getInstance()
@ -520,17 +592,22 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
}
//开机启动
private fun checkWithReboot(@SuppressLint("UseSwitchCompatOrMaterialCode") sbWithReboot: SwitchButton, tvAutoStartup: TextView) {
private fun checkWithReboot(
@SuppressLint("UseSwitchCompatOrMaterialCode") sbWithReboot: SwitchButton,
tvAutoStartup: TextView
) {
tvAutoStartup.text = getAutoStartTips()
//获取组件
val cm = ComponentName(getAppPackageName(), BootReceiver::class.java.name)
val pm: PackageManager = getPackageManager()
val state = pm.getComponentEnabledSetting(cm)
sbWithReboot.isChecked = (state != PackageManager.COMPONENT_ENABLED_STATE_DISABLED && state != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER)
sbWithReboot.isChecked =
(state != PackageManager.COMPONENT_ENABLED_STATE_DISABLED && state != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER)
sbWithReboot.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
try {
val newState = if (isChecked) PackageManager.COMPONENT_ENABLED_STATE_ENABLED else PackageManager.COMPONENT_ENABLED_STATE_DISABLED
val newState =
if (isChecked) PackageManager.COMPONENT_ENABLED_STATE_ENABLED else PackageManager.COMPONENT_ENABLED_STATE_DISABLED
pm.setComponentEnabledSetting(cm, newState, PackageManager.DONT_KILL_APP)
if (isChecked) startToAutoStartSetting(requireContext())
} catch (e: Exception) {
@ -550,7 +627,8 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
}
try {
val isIgnoreBatteryOptimization: Boolean = KeepAliveUtils.isIgnoreBatteryOptimization(requireActivity())
val isIgnoreBatteryOptimization: Boolean =
KeepAliveUtils.isIgnoreBatteryOptimization(requireActivity())
sbBatterySetting.isChecked = isIgnoreBatteryOptimization
sbBatterySetting.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
if (isChecked && !isIgnoreBatteryOptimization) {
@ -570,7 +648,10 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
//不在最近任务列表中显示
@SuppressLint("ObsoleteSdkInt,UseSwitchCompatOrMaterialCode")
fun switchExcludeFromRecents(layoutExcludeFromRecents: LinearLayout, sbExcludeFromRecents: SwitchButton) {
fun switchExcludeFromRecents(
layoutExcludeFromRecents: LinearLayout,
sbExcludeFromRecents: SwitchButton
) {
//安卓6.0以下没有不在最近任务列表中显示
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
layoutExcludeFromRecents.visibility = View.GONE
@ -593,7 +674,11 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
//转发应用通知
@SuppressLint("UseSwitchCompatOrMaterialCode")
fun switchEnableCactus(sbEnableCactus: SwitchButton, scbPlaySilenceMusic: SmoothCheckBox, scbOnePixelActivity: SmoothCheckBox) {
fun switchEnableCactus(
sbEnableCactus: SwitchButton,
scbPlaySilenceMusic: SmoothCheckBox,
scbOnePixelActivity: SmoothCheckBox
) {
val layoutCactusOptional: LinearLayout = binding!!.layoutCactusOptional
val isEnable: Boolean = SettingUtils.enableCactus
sbEnableCactus.isChecked = isEnable
@ -622,7 +707,11 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
}
//接口请求失败重试时间间隔
private fun editRetryDelayTime(etRetryTimes: EditText, etDelayTime: EditText, etTimeout: EditText) {
private fun editRetryDelayTime(
etRetryTimes: EditText,
etDelayTime: EditText,
etTimeout: EditText
) {
etRetryTimes.setText(java.lang.String.valueOf(SettingUtils.requestRetryTimes))
etRetryTimes.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
@ -721,7 +810,8 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun afterTextChanged(s: Editable) {
SettingUtils.notifyContent = etNotifyContent.text.toString().trim()
LiveEventBus.get(EVENT_UPDATE_NOTIFY, String::class.java).post(SettingUtils.notifyContent.toString())
LiveEventBus.get(EVENT_UPDATE_NOTIFY, String::class.java)
.post(SettingUtils.notifyContent.toString())
}
})
}
@ -971,7 +1061,8 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
} else {
//找不到? 网上的做法都是跳转到设置... 这基本上是没意义的 基本上自启动这个功能是第三方厂商自己写的安全管家类app
//所以我是直接跳转到对应的安全管家/安全中心
intent = act?.let { context.packageManager.getLaunchIntentForPackage(it) }
intent =
act?.let { context.packageManager.getLaunchIntentForPackage(it) }
}
context.startActivity(intent)
has = true

@ -13,6 +13,7 @@ import androidx.work.WorkManager
import androidx.work.workDataOf
import com.google.gson.Gson
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.Core
import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.utils.BatteryUtils
import com.idormy.sms.forwarder.utils.SettingUtils
@ -58,6 +59,13 @@ class BatteryService : Service() {
private val batteryReceiver: BroadcastReceiver = object : BroadcastReceiver() {
@SuppressLint("DefaultLocale")
override fun onReceive(context: Context, intent: Intent) {
//自动删除N天前的转发记录
if (SettingUtils.autoCleanLogsDays > 0) {
Log.d(TAG, "自动删除N天前的转发记录")
val cal = Calendar.getInstance()
cal.add(Calendar.DAY_OF_MONTH, 0 - SettingUtils.autoCleanLogsDays)
Core.logs.deleteTimeAgo(cal.timeInMillis)
}
//电量发生变化
val levelCur: Int = intent.getIntExtra("level", 0)
@ -93,7 +101,9 @@ class BatteryService : Service() {
if (status != oldStatus) {
var msg: String = BatteryUtils.getBatteryInfo(intent).toString()
SettingUtils.batteryStatus = status
msg = getString(R.string.battery_status_changed) + BatteryUtils.getStatus(oldStatus) + "" + BatteryUtils.getStatus(status) + msg
msg = getString(R.string.battery_status_changed) + BatteryUtils.getStatus(
oldStatus
) + "" + BatteryUtils.getStatus(status) + msg
sendMessage(context, msg)
}
}
@ -104,7 +114,14 @@ class BatteryService : Service() {
private fun sendMessage(context: Context, msg: String) {
Log.i(TAG, msg)
try {
val msgInfo = MsgInfo("app", "88888888", msg, Date(), getString(R.string.battery_status_monitor), -1)
val msgInfo = MsgInfo(
"app",
"88888888",
msg,
Date(),
getString(R.string.battery_status_monitor),
-1
)
val request = OneTimeWorkRequestBuilder<SendWorker>()
.setInputData(
workDataOf(

@ -42,6 +42,7 @@ const val ENABLE_LOAD_SYSTEM_APP_LIST = "enable_load_system_app_list"
const val SP_DUPLICATE_MESSAGES_LIMITS = "duplicate_messages_limits"
const val SP_SILENT_PERIOD_START = "silent_period_start"
const val SP_SILENT_PERIOD_END = "silent_period_end"
const val SP_AUTO_CLEAN_LOGS_DAYS = "auto_clean_logs_days"
const val SP_BATTERY_RECEIVER = "enable_battery_receiver"
const val SP_BATTERY_STATUS = "battery_status"
@ -164,20 +165,104 @@ const val TYPE_GOTIFY = 11
const val TYPE_DINGTALK_INNER_ROBOT = 12
const val TYPE_FEISHU_APP = 13
var SENDER_FRAGMENT_LIST = listOf(
PageInfo(getString(R.string.dingtalk_robot), "com.idormy.sms.forwarder.fragment.senders.DingtalkGroupRobotFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_dingtalk),
PageInfo(getString(R.string.email), "com.idormy.sms.forwarder.fragment.senders.EmailFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_email),
PageInfo(getString(R.string.bark), "com.idormy.sms.forwarder.fragment.senders.BarkFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_bark),
PageInfo(getString(R.string.webhook), "com.idormy.sms.forwarder.fragment.senders.WebhookFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_webhook),
PageInfo(getString(R.string.wework_robot), "com.idormy.sms.forwarder.fragment.senders.WeworkRobotFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_wework_robot),
PageInfo(getString(R.string.wework_agent), "com.idormy.sms.forwarder.fragment.senders.WeworkAgentFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_wework_agent),
PageInfo(getString(R.string.server_chan), "com.idormy.sms.forwarder.fragment.senders.ServerchanFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_serverchan),
PageInfo(getString(R.string.telegram), "com.idormy.sms.forwarder.fragment.senders.TelegramFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_telegram),
PageInfo(getString(R.string.sms_menu), "com.idormy.sms.forwarder.fragment.senders.SmsFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_sms),
PageInfo(getString(R.string.feishu), "com.idormy.sms.forwarder.fragment.senders.FeishuFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_feishu),
PageInfo(getString(R.string.pushplus), "com.idormy.sms.forwarder.fragment.senders.PushplusFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_pushplus),
PageInfo(getString(R.string.gotify), "com.idormy.sms.forwarder.fragment.senders.GotifyFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_gotify),
PageInfo(getString(R.string.dingtalk_inner_robot), "com.idormy.sms.forwarder.fragment.senders.DingtalkInnerRobotFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_dingtalk_inner),
PageInfo(getString(R.string.feishu_app), "com.idormy.sms.forwarder.fragment.senders.FeishuAppFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_feishu_app),
PageInfo(
getString(R.string.dingtalk_robot),
"com.idormy.sms.forwarder.fragment.senders.DingtalkGroupRobotFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_dingtalk
),
PageInfo(
getString(R.string.email),
"com.idormy.sms.forwarder.fragment.senders.EmailFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_email
),
PageInfo(
getString(R.string.bark),
"com.idormy.sms.forwarder.fragment.senders.BarkFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_bark
),
PageInfo(
getString(R.string.webhook),
"com.idormy.sms.forwarder.fragment.senders.WebhookFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_webhook
),
PageInfo(
getString(R.string.wework_robot),
"com.idormy.sms.forwarder.fragment.senders.WeworkRobotFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_wework_robot
),
PageInfo(
getString(R.string.wework_agent),
"com.idormy.sms.forwarder.fragment.senders.WeworkAgentFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_wework_agent
),
PageInfo(
getString(R.string.server_chan),
"com.idormy.sms.forwarder.fragment.senders.ServerchanFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_serverchan
),
PageInfo(
getString(R.string.telegram),
"com.idormy.sms.forwarder.fragment.senders.TelegramFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_telegram
),
PageInfo(
getString(R.string.sms_menu),
"com.idormy.sms.forwarder.fragment.senders.SmsFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_sms
),
PageInfo(
getString(R.string.feishu),
"com.idormy.sms.forwarder.fragment.senders.FeishuFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_feishu
),
PageInfo(
getString(R.string.pushplus),
"com.idormy.sms.forwarder.fragment.senders.PushplusFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_pushplus
),
PageInfo(
getString(R.string.gotify),
"com.idormy.sms.forwarder.fragment.senders.GotifyFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_gotify
),
PageInfo(
getString(R.string.dingtalk_inner_robot),
"com.idormy.sms.forwarder.fragment.senders.DingtalkInnerRobotFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_dingtalk_inner
),
PageInfo(
getString(R.string.feishu_app),
"com.idormy.sms.forwarder.fragment.senders.FeishuAppFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_feishu_app
),
)
//前台服务
@ -252,11 +337,53 @@ const val SP_SERVER_HISTORY = "server_history"
const val SP_SERVER_CONFIG = "server_config"
const val SP_CLIENT_SIGN_KEY = "client_sign_key"
var CLIENT_FRAGMENT_LIST = listOf(
PageInfo(getString(R.string.api_clone), "com.idormy.sms.forwarder.fragment.client.CloneFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_api_clone),
PageInfo(getString(R.string.api_sms_send), "com.idormy.sms.forwarder.fragment.client.SmsSendFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_api_sms_send),
PageInfo(getString(R.string.api_sms_query), "com.idormy.sms.forwarder.fragment.client.SmsQueryFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_api_sms_query),
PageInfo(getString(R.string.api_call_query), "com.idormy.sms.forwarder.fragment.client.CallQueryFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_api_call_query),
PageInfo(getString(R.string.api_contact_query), "com.idormy.sms.forwarder.fragment.client.ContactQueryFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_api_contact_query),
PageInfo(getString(R.string.api_battery_query), "com.idormy.sms.forwarder.fragment.client.BatteryQueryFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_api_battery_query),
PageInfo(getString(R.string.api_wol), "com.idormy.sms.forwarder.fragment.client.WolSendFragment", "{\"\":\"\"}", CoreAnim.slide, R.drawable.icon_api_wol),
PageInfo(
getString(R.string.api_clone),
"com.idormy.sms.forwarder.fragment.client.CloneFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_api_clone
),
PageInfo(
getString(R.string.api_sms_send),
"com.idormy.sms.forwarder.fragment.client.SmsSendFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_api_sms_send
),
PageInfo(
getString(R.string.api_sms_query),
"com.idormy.sms.forwarder.fragment.client.SmsQueryFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_api_sms_query
),
PageInfo(
getString(R.string.api_call_query),
"com.idormy.sms.forwarder.fragment.client.CallQueryFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_api_call_query
),
PageInfo(
getString(R.string.api_contact_query),
"com.idormy.sms.forwarder.fragment.client.ContactQueryFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_api_contact_query
),
PageInfo(
getString(R.string.api_battery_query),
"com.idormy.sms.forwarder.fragment.client.BatteryQueryFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_api_battery_query
),
PageInfo(
getString(R.string.api_wol),
"com.idormy.sms.forwarder.fragment.client.WolSendFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.icon_api_wol
),
)

@ -141,6 +141,14 @@ class SettingUtils private constructor() {
MMKVUtils.put(SP_SILENT_PERIOD_END, silentPeriodEnd)
}
//自动删除N天前的转发记录
@JvmStatic
var autoCleanLogsDays: Int
get() = MMKVUtils.getInt(SP_AUTO_CLEAN_LOGS_DAYS, 0)
set(autoCleanLogsDays) {
MMKVUtils.put(SP_AUTO_CLEAN_LOGS_DAYS, autoCleanLogsDays)
}
//是否监听电池状态变化
@JvmStatic
var enableBatteryReceiver: Boolean

@ -435,6 +435,53 @@
</LinearLayout>
<LinearLayout
style="@style/settingBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="15dp"
tools:ignore="RtlSymmetry">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/auto_clean_logs"
android:textStyle="bold"
tools:ignore="RelativeOverlap" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/auto_clean_logs_tips"
android:textSize="9sp"
tools:ignore="SmallSp" />
</LinearLayout>
<com.xuexiang.xui.widget.picker.XSeekBar
android:id="@+id/xsb_auto_clean_logs"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_weight="1"
app:xsb_max="60"
app:xsb_min="0" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:text="@string/day"
android:textSize="12sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"

@ -684,7 +684,7 @@
<string name="bark_level_active">Immediately display notifications</string>
<string name="bark_level_timeSensitive">Time-sensitive notifications that can be displayed in a focused state</string>
<string name="bark_level_passive">Only added to the notification list, no screen reminder</string>
<string name="bark_url_regex" tools:ignore="TypographyDashes" formatted="false"><![CDATA[^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]]]></string>
<string name="bark_url_regex" formatted="false" tools:ignore="TypographyDashes"><![CDATA[^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]]]></string>
<string name="bark_url_error">Url format error</string>
<string name="from_email_hint">Fill in the username before @</string>
@ -916,4 +916,7 @@
<string name="app_id">App ID</string>
<string name="app_secret">App Secret</string>
<string name="user_id">User ID</string>
<string name="auto_clean_logs">Auto delete logs N days ago</string>
<string name="auto_clean_logs_tips">0=disabled, scan when battery change</string>
<string name="day"></string>
</resources>

@ -685,7 +685,7 @@
<string name="bark_level_active">立即亮屏显示通知</string>
<string name="bark_level_timeSensitive">时效性通知,可在专注状态下显示通知</string>
<string name="bark_level_passive">仅添加到通知列表,不会亮屏提醒</string>
<string name="bark_url_regex" tools:ignore="TypographyDashes" formatted="false"><![CDATA[^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]]]></string>
<string name="bark_url_regex" formatted="false" tools:ignore="TypographyDashes"><![CDATA[^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]]]></string>
<string name="bark_url_error">Url格式错误</string>
<string name="from_email_hint">填写 @ 前面的用户名</string>
@ -917,4 +917,7 @@
<string name="app_id">App ID</string>
<string name="app_secret">App Secret</string>
<string name="user_id">User ID</string>
<string name="auto_clean_logs">自动删除N天前的转发记录</string>
<string name="auto_clean_logs_tips">0=禁用,触发机制:每次电量变化时扫描</string>
<string name="day"></string>
</resources>

Loading…
Cancel
Save