From 00195e6c85be3f0dc92e72864b45f48a218fad12 Mon Sep 17 00:00:00 2001 From: pppscn <35696959@qq.com> Date: Mon, 24 Jul 2023 23:36:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9A=E9=80=9A=E8=AF=9D?= =?UTF-8?q?=E8=BD=AC=E5=8F=91=E8=A7=84=E5=88=99=E7=9A=84`=E5=8C=B9?= =?UTF-8?q?=E9=85=8D=E5=AD=97=E6=AE=B5`=E5=A2=9E=E5=8A=A0`=E9=80=9A?= =?UTF-8?q?=E8=AF=9D=E7=B1=BB=E5=9E=8B`=20&=20=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E5=A2=9E=E5=8A=A0`{{=E9=80=9A=E8=AF=9D?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B}}`=E6=A0=87=E7=AD=BE=20#305?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sms/forwarder/database/AppDatabase.kt | 10 +- .../sms/forwarder/database/entity/Msg.kt | 2 + .../sms/forwarder/database/entity/Rule.kt | 40 ++++- .../idormy/sms/forwarder/entity/MsgInfo.kt | 6 +- .../forwarder/fragment/RulesEditFragment.kt | 94 ++++++++++- .../sms/forwarder/receiver/CallReceiver.kt | 15 +- .../idormy/sms/forwarder/utils/Constants.kt | 12 ++ .../idormy/sms/forwarder/utils/RuleLine.kt | 5 +- .../sms/forwarder/workers/SendWorker.kt | 2 +- app/src/main/res/layout/dialog_rule_test.xml | 158 ++++++++++-------- .../main/res/layout/fragment_rules_edit.xml | 11 ++ app/src/main/res/values-en/strings.xml | 10 +- app/src/main/res/values/strings.xml | 10 +- 13 files changed, 272 insertions(+), 103 deletions(-) diff --git a/app/src/main/java/com/idormy/sms/forwarder/database/AppDatabase.kt b/app/src/main/java/com/idormy/sms/forwarder/database/AppDatabase.kt index 67a66a38..790c0dd6 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/database/AppDatabase.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/database/AppDatabase.kt @@ -15,7 +15,7 @@ import com.idormy.sms.forwarder.utils.DATABASE_NAME @Database( entities = [Frpc::class, Msg::class, Logs::class, Rule::class, Sender::class], views = [LogsDetail::class], - version = 16, + version = 17, exportSchema = false ) @TypeConverters(ConvertersDate::class) @@ -97,6 +97,7 @@ custom_domains = smsf.demo.com MIGRATION_13_14, MIGRATION_14_15, MIGRATION_15_16, + MIGRATION_16_17, ) /*if (BuildConfig.DEBUG) { @@ -373,6 +374,13 @@ CREATE TABLE "Logs" ( } } + //通话类型:1.来电挂机 2.去电挂机 3.未接来电 4.来电提醒 5.来电接通 6.去电拨出 + private val MIGRATION_16_17 = object : Migration(16, 17) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("Alter table Msg add column call_type INTEGER NOT NULL DEFAULT 0") + } + } + } } diff --git a/app/src/main/java/com/idormy/sms/forwarder/database/entity/Msg.kt b/app/src/main/java/com/idormy/sms/forwarder/database/entity/Msg.kt index 7074d871..3fa694ec 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/database/entity/Msg.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/database/entity/Msg.kt @@ -25,6 +25,8 @@ data class Msg( @ColumnInfo(name = "sim_slot", defaultValue = "-1") var simSlot: Int = -1, //卡槽id:-1=获取失败、0=卡槽1、1=卡槽2 @ColumnInfo(name = "sim_info", defaultValue = "") var simInfo: String = "", @ColumnInfo(name = "sub_id", defaultValue = "0") var subId: Int = 0, + //通话类型:1.来电挂机 2.去电挂机 3.未接来电 4.来电提醒 5.来电接通 6.去电拨出 + @ColumnInfo(name = "call_type", defaultValue = "0") var callType: Int = 0, @ColumnInfo(name = "time") var time: Date = Date(), ) : Parcelable { diff --git a/app/src/main/java/com/idormy/sms/forwarder/database/entity/Rule.kt b/app/src/main/java/com/idormy/sms/forwarder/database/entity/Rule.kt index 4f64941b..a6d45e7a 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/database/entity/Rule.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/database/entity/Rule.kt @@ -13,6 +13,7 @@ import java.util.* import java.util.regex.Pattern import java.util.regex.PatternSyntaxException +@Suppress("DEPRECATION") @Parcelize @Entity( tableName = "Rule", @@ -58,10 +59,18 @@ data class Rule( fun getRuleMatch(filed: String?, check: String?, value: String?, simSlot: String?): Any { val sb = StringBuilder() sb.append(SIM_SLOT_MAP[simSlot]).append(getString(R.string.rule_card)) - if (filed == null || filed == FILED_TRANSPOND_ALL) { - sb.append(getString(R.string.rule_all_fw_to)) - } else { - sb.append(getString(R.string.rule_when)).append(FILED_MAP[filed]).append(CHECK_MAP[check]).append(value).append(getString(R.string.rule_fw_to)) + when (filed) { + null, FILED_TRANSPOND_ALL -> { + sb.append(getString(R.string.rule_all_fw_to)) + } + + FILED_CALL_TYPE -> { + sb.append(getString(R.string.rule_when)).append(FILED_MAP[filed]).append(CHECK_MAP[check]).append(CALL_TYPE_MAP[value]).append(getString(R.string.rule_fw_to)) + } + + else -> { + sb.append(getString(R.string.rule_when)).append(FILED_MAP[filed]).append(CHECK_MAP[check]).append(value).append(getString(R.string.rule_fw_to)) + } } return sb.toString() } @@ -71,10 +80,18 @@ data class Rule( val ruleMatch: String get() { val simStr = if ("app" == type) "" else SIM_SLOT_MAP[simSlot].toString() + getString(R.string.rule_card) - return if (filed == FILED_TRANSPOND_ALL) { - simStr + getString(R.string.rule_all_fw_to) - } else { - simStr + getString(R.string.rule_when) + FILED_MAP[filed] + CHECK_MAP[check] + value + getString(R.string.rule_fw_to) + return when (filed) { + FILED_TRANSPOND_ALL -> { + simStr + getString(R.string.rule_all_fw_to) + } + + FILED_CALL_TYPE -> { + simStr + getString(R.string.rule_when) + FILED_MAP[filed] + CHECK_MAP[check] + CALL_TYPE_MAP[value] + getString(R.string.rule_fw_to) + } + + else -> { + simStr + getString(R.string.rule_when) + FILED_MAP[filed] + CHECK_MAP[check] + value + getString(R.string.rule_fw_to) + } } } @@ -115,6 +132,7 @@ data class Rule( return when (filed) { FILED_MSG_CONTENT -> R.id.rb_content FILED_PHONE_NUM -> R.id.rb_phone + FILED_CALL_TYPE -> R.id.rb_call_type FILED_PACKAGE_NAME -> R.id.rb_package_name FILED_INFORM_CONTENT -> R.id.rb_inform_content FILED_MULTI_MATCH -> R.id.rb_multi_match @@ -144,6 +162,7 @@ data class Rule( when (this.filed) { FILED_TRANSPOND_ALL -> mixChecked = true FILED_PHONE_NUM, FILED_PACKAGE_NAME -> mixChecked = checkValue(msg.from) + FILED_CALL_TYPE -> mixChecked = checkValue(msg.callType.toString()) FILED_MSG_CONTENT, FILED_INFORM_CONTENT -> mixChecked = checkValue(msg.content) FILED_MULTI_MATCH -> mixChecked = RuleLineUtils.checkRuleLines(msg, this.value) else -> {} @@ -162,15 +181,19 @@ data class Rule( CHECK_CONTAIN -> if (msgValue != null) { checked = msgValue.contains(this.value) } + CHECK_NOT_CONTAIN -> if (msgValue != null) { checked = !msgValue.contains(this.value) } + CHECK_START_WITH -> if (msgValue != null) { checked = msgValue.startsWith(this.value) } + CHECK_END_WITH -> if (msgValue != null) { checked = msgValue.endsWith(this.value) } + CHECK_REGEX -> if (msgValue != null) { try { //checked = Pattern.matches(this.value, msgValue); @@ -188,6 +211,7 @@ data class Rule( Log.d(TAG, "Pattern: " + e.pattern) } } + else -> {} } Log.i(TAG, "checkValue " + msgValue + " " + this.check + " " + this.value + " checked:" + checked) diff --git a/app/src/main/java/com/idormy/sms/forwarder/entity/MsgInfo.kt b/app/src/main/java/com/idormy/sms/forwarder/entity/MsgInfo.kt index 570f96df..83166789 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/entity/MsgInfo.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/entity/MsgInfo.kt @@ -5,6 +5,7 @@ import android.text.TextUtils import android.util.Log import com.idormy.sms.forwarder.App import com.idormy.sms.forwarder.R +import com.idormy.sms.forwarder.utils.CALL_TYPE_MAP import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils.Companion.enableSmsTemplate import com.idormy.sms.forwarder.utils.SettingUtils.Companion.extraDeviceMark @@ -15,7 +16,7 @@ import java.io.Serializable import java.text.SimpleDateFormat import java.util.* -@Suppress("unused") +@Suppress("unused", "DEPRECATION") data class MsgInfo( var type: String = "sms", var from: String, @@ -24,6 +25,7 @@ data class MsgInfo( var simInfo: String, var simSlot: Int = -1, //卡槽id:-1=获取失败、0=卡槽1、1=卡槽2 var subId: Int = 0, //卡槽主键 + var callType: Int = 0, //通话类型:1.来电挂机 2.去电挂机 3.未接来电 4.来电提醒 5.来电接通 6.去电拨出 ) : Serializable { val titleForSend: String @@ -54,6 +56,7 @@ data class MsgInfo( .replace(getString(R.string.tag_current_time), SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())) .replace(getString(R.string.tag_device_name), deviceMark) .replace(getString(R.string.tag_app_version), versionName) + .replace(getString(R.string.tag_call_type), CALL_TYPE_MAP[callType.toString()] ?: getString(R.string.unknown_call)) .trim() return replaceAppName(regexReplace(titleForSend, regexReplace), from) } @@ -101,6 +104,7 @@ data class MsgInfo( .replace(getString(R.string.tag_current_time), SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())) .replace(getString(R.string.tag_device_name), deviceMark) .replace(getString(R.string.tag_app_version), versionName) + .replace(getString(R.string.tag_call_type), CALL_TYPE_MAP[callType.toString()] ?: getString(R.string.unknown_call)) .trim() return replaceAppName(regexReplace(smsVoForSend, regexReplace), from) } diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/RulesEditFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/RulesEditFragment.kt index e3e87d0f..a4a9d591 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/fragment/RulesEditFragment.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/RulesEditFragment.kt @@ -39,6 +39,7 @@ import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog import com.xuexiang.xui.widget.picker.widget.builder.OptionsPickerBuilder import com.xuexiang.xui.widget.picker.widget.listener.OnOptionsSelectListener +import com.xuexiang.xui.widget.spinner.materialspinner.MaterialSpinner import com.xuexiang.xutil.XUtil import io.reactivex.SingleObserver import io.reactivex.android.schedulers.AndroidSchedulers @@ -55,6 +56,9 @@ class RulesEditFragment : BaseFragment(), View.OnClic var titleBar: TitleBar? = null private val viewModel by viewModels { BaseViewModelFactory(context) } + var callType = 1 + var callTypeIndex = 0 + //免打扰(禁用转发)时间段 private val mTimeOption = DataProvider.timePeriodOption private var silentPeriodStart = 0 @@ -116,6 +120,7 @@ class RulesEditFragment : BaseFragment(), View.OnClic titleBar?.setTitle(R.string.app_rule) binding!!.layoutSimSlot.visibility = View.GONE binding!!.rbPhone.visibility = View.GONE + binding!!.rbCallType.visibility = View.GONE binding!!.rbContent.visibility = View.GONE binding!!.tvMuRuleTips.setText(R.string.mu_rule_app_tips) binding!!.btInsertExtra.visibility = View.GONE @@ -132,15 +137,31 @@ class RulesEditFragment : BaseFragment(), View.OnClic binding!!.rbContent.visibility = View.GONE binding!!.rbPackageName.visibility = View.GONE binding!!.rbInformContent.visibility = View.GONE - binding!!.rbMultiMatch.visibility = View.GONE + //binding!!.rbMultiMatch.visibility = View.GONE + binding!!.tvMuRuleTips.setText(R.string.mu_rule_call_tips) binding!!.btInsertContent.visibility = View.GONE binding!!.btInsertSenderApp.visibility = View.GONE binding!!.btInsertTitleApp.visibility = View.GONE binding!!.btInsertContentApp.visibility = View.GONE + + //通话类型:1.来电挂机 2.去电挂机 3.未接来电 4.来电提醒 5.来电接通 6.去电拨出 + binding!!.spCallType.setItems(CALL_TYPE_MAP.values.toList()) + binding!!.spCallType.setOnItemSelectedListener { _: MaterialSpinner?, _: Int, _: Long, item: Any -> + CALL_TYPE_MAP.forEach { + if (it.value == item) callType = it.key.toInt() + } + } + binding!!.spCallType.setOnNothingSelectedListener { + callType = 1 + callTypeIndex = 0 + binding!!.spCallType.selectedIndex = callTypeIndex + } + binding!!.spCallType.selectedIndex = callTypeIndex } else -> { titleBar?.setTitle(R.string.sms_rule) + binding!!.rbCallType.visibility = View.GONE binding!!.rbPackageName.visibility = View.GONE binding!!.rbInformContent.visibility = View.GONE binding!!.btInsertSenderApp.visibility = View.GONE @@ -185,6 +206,7 @@ class RulesEditFragment : BaseFragment(), View.OnClic when (checkedId) { R.id.rb_transpond_all -> { binding!!.rgCheck.check(R.id.rb_is) + binding!!.spCallType.visibility = View.GONE binding!!.tvMuRuleTips.visibility = View.GONE binding!!.layoutMatchType.visibility = View.GONE binding!!.layoutMatchValue.visibility = View.GONE @@ -192,15 +214,28 @@ class RulesEditFragment : BaseFragment(), View.OnClic R.id.rb_multi_match -> { binding!!.rgCheck.check(R.id.rb_is) + binding!!.spCallType.visibility = View.GONE binding!!.tvMuRuleTips.visibility = View.VISIBLE binding!!.layoutMatchType.visibility = View.GONE binding!!.layoutMatchValue.visibility = View.VISIBLE + binding!!.etValue.visibility = View.VISIBLE + } + + R.id.rb_call_type -> { + binding!!.rgCheck.check(R.id.rb_is) + binding!!.tvMuRuleTips.visibility = View.GONE + binding!!.layoutMatchType.visibility = View.GONE + binding!!.layoutMatchValue.visibility = View.VISIBLE + binding!!.etValue.visibility = View.GONE + binding!!.spCallType.visibility = View.VISIBLE } else -> { + binding!!.spCallType.visibility = View.GONE binding!!.tvMuRuleTips.visibility = View.GONE binding!!.layoutMatchType.visibility = View.VISIBLE binding!!.layoutMatchValue.visibility = View.VISIBLE + binding!!.etValue.visibility = View.VISIBLE } } } @@ -545,6 +580,11 @@ class RulesEditFragment : BaseFragment(), View.OnClic binding!!.rgCheck2.check(checkId) } binding!!.etValue.setText(rule.value) + if (ruleType == "call" && rule.filed == FILED_CALL_TYPE) { + callType = rule.value.toInt() + callTypeIndex = callType - 1 + binding!!.spCallType.selectedIndex = callTypeIndex + } binding!!.sbSmsTemplate.isChecked = !TextUtils.isEmpty(rule.smsTemplate.trim()) binding!!.etSmsTemplate.setText(rule.smsTemplate.trim()) binding!!.sbRegexReplace.isChecked = !TextUtils.isEmpty(rule.regexReplace.trim()) @@ -567,6 +607,7 @@ class RulesEditFragment : BaseFragment(), View.OnClic val filed = when (binding!!.rgFiled.checkedRadioButtonId) { R.id.rb_content -> FILED_MSG_CONTENT R.id.rb_phone -> FILED_PHONE_NUM + R.id.rb_call_type -> FILED_CALL_TYPE R.id.rb_package_name -> FILED_PACKAGE_NAME R.id.rb_inform_content -> FILED_INFORM_CONTENT R.id.rb_multi_match -> FILED_MULTI_MATCH @@ -580,8 +621,13 @@ class RulesEditFragment : BaseFragment(), View.OnClic R.id.rb_regex -> CHECK_REGEX else -> CHECK_IS } - val value = binding!!.etValue.text.toString().trim() - if (FILED_TRANSPOND_ALL != filed && TextUtils.isEmpty(value)) { + var value = binding!!.etValue.text.toString().trim() + if (FILED_CALL_TYPE == filed) { + value = callType.toString() + if (callType !in 1..6) { + throw Exception(getString(R.string.invalid_call_type)) + } + } else if (FILED_TRANSPOND_ALL != filed && TextUtils.isEmpty(value)) { throw Exception(getString(R.string.invalid_match_value)) } if (FILED_MULTI_MATCH == filed) { @@ -621,7 +667,7 @@ class RulesEditFragment : BaseFragment(), View.OnClic private fun checkMultiMatch(ruleStr: String?): Int { if (TextUtils.isEmpty(ruleStr)) return 0 - Log.d(TAG, getString(R.string.regex_multi_match)) + //Log.d(TAG, getString(R.string.regex_multi_match)) val regex = Regex(pattern = getString(R.string.regex_multi_match)) var lineNum = 1 val lineArray = ruleStr?.split("\\n".toRegex())?.toTypedArray() @@ -658,6 +704,11 @@ class RulesEditFragment : BaseFragment(), View.OnClic val etTitle = dialogTest.findViewById(R.id.et_title) val tvContent = dialogTest.findViewById(R.id.tv_content) val etContent = dialogTest.findViewById(R.id.et_content) + //通话类型 + val tvCallType = dialogTest.findViewById(R.id.tv_call_type) + val spCallType = dialogTest.findViewById(R.id.sp_call_type) + var callTypeTest = callType + var callTypeIndexTest = callTypeIndex if ("app" == ruleType) { tvSimSlot.visibility = View.GONE @@ -666,9 +717,25 @@ class RulesEditFragment : BaseFragment(), View.OnClic etTitle.visibility = View.VISIBLE tvFrom.setText(R.string.test_package_name) tvContent.setText(R.string.test_inform_content) + tvCallType.visibility = View.GONE + spCallType.visibility = View.GONE } else if ("call" == ruleType) { tvContent.visibility = View.GONE etContent.visibility = View.GONE + tvCallType.visibility = View.VISIBLE + spCallType.visibility = View.VISIBLE + spCallType.setItems(CALL_TYPE_MAP.values.toList()) + spCallType.setOnItemSelectedListener { _: MaterialSpinner?, _: Int, _: Long, item: Any -> + CALL_TYPE_MAP.forEach { + if (it.value == item) callTypeTest = it.key.toInt() + } + } + spCallType.setOnNothingSelectedListener { + callTypeTest = callType + callTypeIndexTest = callTypeIndex + spCallType.selectedIndex = callTypeIndexTest + } + spCallType.selectedIndex = callTypeIndexTest } MaterialDialog.Builder(requireContext()).iconRes(android.R.drawable.ic_dialog_email).title(R.string.rule_tester).customView(dialogTest, true).cancelable(false).autoDismiss(false).neutralText(R.string.action_back).neutralColor(ResUtils.getColors(R.color.darkGrey)).onNeutral { dialog: MaterialDialog?, _: DialogAction? -> @@ -693,8 +760,25 @@ class RulesEditFragment : BaseFragment(), View.OnClic 1 -> "SIM2_" + SettingUtils.extraSim2 else -> etTitle.text.toString() } + val subId = when (simSlot) { + 0 -> SettingUtils.subidSim1 + 1 -> SettingUtils.subidSim2 + else -> 0 + } - val msgInfo = MsgInfo(ruleType, etFrom.text.toString(), etContent.text.toString(), Date(), simInfo, simSlot) + val msg = StringBuilder() + if (ruleType == "call") { + val phoneNumber = etFrom.text.toString() + val contacts = PhoneUtils.getContactByNumber(phoneNumber) + val contactName = if (contacts.isNotEmpty()) contacts[0].name else ResUtils.getString(R.string.unknown_number) + msg.append(ResUtils.getString(R.string.linkman)).append(contactName).append("\n") + msg.append(ResUtils.getString(R.string.mandatory_type)) + msg.append(CALL_TYPE_MAP[callType.toString()] ?: ResUtils.getString(R.string.unknown_call)) + } else { + msg.append(etContent.text.toString()) + } + + val msgInfo = MsgInfo(ruleType, etFrom.text.toString(), msg.toString(), Date(), simInfo, simSlot, subId, callTypeTest) if (!rule.checkMsg(msgInfo)) { throw Exception(getString(R.string.unmatched_rule)) } diff --git a/app/src/main/java/com/idormy/sms/forwarder/receiver/CallReceiver.kt b/app/src/main/java/com/idormy/sms/forwarder/receiver/CallReceiver.kt index c80f7a98..b3b211fb 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/receiver/CallReceiver.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/receiver/CallReceiver.kt @@ -9,6 +9,7 @@ import com.google.gson.Gson import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.entity.CallInfo import com.idormy.sms.forwarder.entity.MsgInfo +import com.idormy.sms.forwarder.utils.CALL_TYPE_MAP import com.idormy.sms.forwarder.utils.PhoneUtils import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.Worker @@ -18,6 +19,7 @@ import com.xuexiang.xui.utils.ResUtils.getString import com.xuexiang.xutil.resource.ResUtils import java.util.* +@Suppress("DEPRECATION") open class CallReceiver : PhoneStateReceiver() { companion object { @@ -80,18 +82,9 @@ open class CallReceiver : PhoneStateReceiver() { val msg = StringBuilder() msg.append(getString(R.string.linkman)).append(contactName).append("\n") msg.append(getString(R.string.mandatory_type)) - //通话类型:1.来电挂机 2.去电挂机 3.未接来电 4.来电提醒 5.来电接通 6.去电拨出 - when (callType) { - 1 -> msg.append(ResUtils.getString(R.string.incoming_call_ended)) - 2 -> msg.append(ResUtils.getString(R.string.outgoing_call_ended)) - 3 -> msg.append(ResUtils.getString(R.string.missed_call)) - 4 -> msg.append(ResUtils.getString(R.string.incoming_call_received)) - 5 -> msg.append(ResUtils.getString(R.string.incoming_call_answered)) - 6 -> msg.append(ResUtils.getString(R.string.outgoing_call_started)) - else -> msg.append(ResUtils.getString(R.string.unknown_call)) - } + msg.append(CALL_TYPE_MAP[callType.toString()] ?: getString(R.string.unknown_call)) - val msgInfo = MsgInfo("call", phoneNumber.toString(), msg.toString(), Date(), "") + val msgInfo = MsgInfo("call", phoneNumber.toString(), msg.toString(), Date(), "", -1, 0, callType) val request = OneTimeWorkRequestBuilder().setInputData( workDataOf( Worker.sendMsgInfo to Gson().toJson(msgInfo) diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/Constants.kt b/app/src/main/java/com/idormy/sms/forwarder/utils/Constants.kt index 7ebb7f6b..3d4ffd6b 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/Constants.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/Constants.kt @@ -100,6 +100,7 @@ const val STATUS_ON = 1 const val STATUS_OFF = 0 const val FILED_TRANSPOND_ALL = "transpond_all" const val FILED_PHONE_NUM = "phone_num" +const val FILED_CALL_TYPE = "call_type" const val FILED_PACKAGE_NAME = "package_name" const val FILED_MSG_CONTENT = "msg_content" const val FILED_INFORM_CONTENT = "inform_content" @@ -135,6 +136,7 @@ val FILED_MAP = object : HashMap() { put("multi_match", getString(R.string.rule_multi_match)) put("package_name", getString(R.string.rule_package_name)) put("inform_content", getString(R.string.rule_inform_content)) + put("call_type", getString(R.string.rule_call_type)) } } val CHECK_MAP = object : HashMap() { @@ -176,6 +178,16 @@ val BARK_ENCRYPTION_ALGORITHM_MAP = mapOf( "AES256/CBC/PKCS7Padding" to "AES256/CBC/PKCS7Padding", "AES256/ECB/PKCS7Padding" to "AES256/ECB/PKCS7Padding", ) +//通话类型:1.来电挂机 2.去电挂机 3.未接来电 4.来电提醒 5.来电接通 6.去电拨出 +val CALL_TYPE_MAP = mapOf( + //"0" to getString(R.string.unknown_call), + "1" to getString(R.string.incoming_call_ended), + "2" to getString(R.string.outgoing_call_ended), + "3" to getString(R.string.missed_call), + "4" to getString(R.string.incoming_call_received), + "5" to getString(R.string.incoming_call_answered), + "6" to getString(R.string.outgoing_call_started), +) //发送通道 const val TYPE_DINGTALK_GROUP_ROBOT = 0 diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/RuleLine.kt b/app/src/main/java/com/idormy/sms/forwarder/utils/RuleLine.kt index 92a9f70e..3a183d72 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/RuleLine.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/RuleLine.kt @@ -7,7 +7,7 @@ import com.xuexiang.xui.utils.ResUtils.getString import java.util.regex.Pattern import java.util.regex.PatternSyntaxException -@Suppress("unused") +@Suppress("unused", "DEPRECATION") class RuleLine(line: String, lineNum: Int, beforeRuleLine: RuleLine?) { companion object { val CONJUNCTION_AND: String = getString(R.string.CONJUNCTION_AND) @@ -18,6 +18,7 @@ class RuleLine(line: String, lineNum: Int, beforeRuleLine: RuleLine?) { val FILED_INFORM_TITLE: String = getString(R.string.FILED_INFORM_TITLE) val FILED_INFORM_CONTENT: String = getString(R.string.FILED_INFORM_CONTENT) val FILED_SIM_SLOT_INFO: String = getString(R.string.FILED_SIM_SLOT_INFO) + val FILED_CALL_TYPE: String = getString(R.string.FILED_CALL_TYPE) val SURE_YES: String = getString(R.string.SURE_YES) val SURE_NOT: String = getString(R.string.SURE_NOT) val CHECK_EQUALS: String = getString(R.string.CHECK_EQUALS) @@ -57,6 +58,7 @@ class RuleLine(line: String, lineNum: Int, beforeRuleLine: RuleLine?) { FILED_LIST.add(FILED_INFORM_CONTENT) FILED_LIST.add(FILED_INFORM_TITLE) FILED_LIST.add(FILED_SIM_SLOT_INFO) + FILED_LIST.add(FILED_CALL_TYPE) } init { @@ -99,6 +101,7 @@ class RuleLine(line: String, lineNum: Int, beforeRuleLine: RuleLine?) { var mixChecked = false when (field) { FILED_PHONE_NUM, FILED_PACKAGE_NAME -> mixChecked = checkValue(msg.from) + FILED_CALL_TYPE -> mixChecked = checkValue(msg.callType.toString()) FILED_MSG_CONTENT, FILED_INFORM_CONTENT -> mixChecked = checkValue(msg.content) FILED_INFORM_TITLE, FILED_SIM_SLOT_INFO -> mixChecked = checkValue(msg.simInfo) else -> {} diff --git a/app/src/main/java/com/idormy/sms/forwarder/workers/SendWorker.kt b/app/src/main/java/com/idormy/sms/forwarder/workers/SendWorker.kt index cbd4ead8..5594729d 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/workers/SendWorker.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/workers/SendWorker.kt @@ -94,7 +94,7 @@ class SendWorker( return@withContext Result.failure(workDataOf("send" to "failed")) } - val msg = Msg(0, msgInfo.type, msgInfo.from, msgInfo.content, msgInfo.simSlot, msgInfo.simInfo, msgInfo.subId) + val msg = Msg(0, msgInfo.type, msgInfo.from, msgInfo.content, msgInfo.simSlot, msgInfo.simInfo, msgInfo.subId, msgInfo.callType) val msgId = Core.msg.insert(msg) for (rule in ruleListMatched) { val sender = rule.senderList[0] diff --git a/app/src/main/res/layout/dialog_rule_test.xml b/app/src/main/res/layout/dialog_rule_test.xml index c27c0d58..59258664 100644 --- a/app/src/main/res/layout/dialog_rule_test.xml +++ b/app/src/main/res/layout/dialog_rule_test.xml @@ -1,74 +1,86 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_rules_edit.xml b/app/src/main/res/layout/fragment_rules_edit.xml index 44b1a51a..21dc1e81 100644 --- a/app/src/main/res/layout/fragment_rules_edit.xml +++ b/app/src/main/res/layout/fragment_rules_edit.xml @@ -172,6 +172,11 @@ style="@style/rg_rb_style_wrap" android:text="@string/phone_number" /> + + + + Test Phone Number Test Msg Content Test PackageName + Test Call Type Test Notify Title Test Notify Content Run Logic @@ -229,6 +230,7 @@ SIM Slot Field Phone No. + Call Type PkgName SMS Notice @@ -245,6 +247,7 @@ Enable This Forwarding Rule The forwarding rule is disabled The matched value cannot be null + The call type is incorrect, you can only enter any number from 1 to 6. Invalid sender, abort! Delete confirmation @@ -398,6 +401,8 @@ SIM1 SIM2 Example of multiple matching rules: (see wiki for syntax)\n\nAND IS PHONE_NUM EQUALS 10086\n[space]OR IS PHONE_NUM EQUALS 10011\nAND IS MSG_CONTENT CONTAIN arrears\n\nThe above rule means: receive a text message, and (the mobile phone number is 10086 or the mobile phone number is 10010), and the content of the text message includes arrears When forwarding the text message\n\nNote: The space at the beginning of each line represents the level, too complex multiple rules may lead to a large memory usage! + Example of multiple matching rules: (see wiki for syntax)\n\nAND IS PHONE_NUM EQUALS 10086\n[space]OR IS PHONE_NUM EQUALS 10011\nAND IS CALL_TYPE IS 3\n\nThe above rule means: receive a call, and (the mobile phone number is 10086 or 10010), and the call type is Missed When forwarding the call\n\nNote: The space at the beginning of each line represents the level, too complex multiple rules may lead to a large memory usage!\n\nCall types: 1.Incoming Ended 2.Outgoing Ended 3.Missed 4.Incoming Received 5.Incoming Answered 6.Outgoing Started + Enter any number from 1 to 6.\n\nCall types: 1.Incoming Ended 2.Outgoing Ended 3.Missed 4.Incoming Received 5.Incoming Answered 6.Outgoing Started Example of multiple matching rules: (see wiki for syntax)\n\nAND IS PACKAGE_NAME EQUALS com.tencent.mm\n[space]OR IS PACKAGE_NAME EQUALS com.tencent.mobileqq\nAND IS INFORM_CONTENT CONTAIN arrears\n\nThe above rules mean: Receive an APP notification, and (the APP package name is com.tencent.mm or the APP package name is com.tencent.mobileqq), and the content of the notification includes forwarding the notification when the payment is in arrears\n\nNote: The space at the beginning of each line represents the level, too complex multiple rules may lead to a large memory usage! POST GET @@ -595,6 +600,7 @@ {{APP_VERSION}} {{TITLE}} {{SCHEME}} + {{CALL_TYPE}} SMS CALL APP @@ -605,6 +611,7 @@ Multi Match Package Name Inform Content + Call Type Card When Fw. @@ -786,7 +793,7 @@ Extra Apps One package name per line\nEnable async loading of the App list for selection. Drop-down selection to get package name, keyword fuzzy matching APP name - ^\\s*(AND|OR)\\s(IS|NOTIS)\\s(PHONE_NUM|PACKAGE_NAME|MSG_CONTENT|INFORM_CONTENT|INFORM_TITLE|CARD_SLOT)\\s(EQUALS|CONTAIN|NOTCONTAIN|STARTWITH|ENDWITH|REGEX)\\s(.*)$ + ^\\s*(AND|OR)\\s(IS|NOTIS)\\s(PHONE_NUM|PACKAGE_NAME|MSG_CONTENT|INFORM_CONTENT|INFORM_TITLE|CARD_SLOT|CALL_TYPE)\\s(EQUALS|CONTAIN|NOTCONTAIN|STARTWITH|ENDWITH|REGEX)\\s(.*)$ Welcome to We understand the importance of personal information to you and thank you for your trust in us.\n In order to better protect your rights and comply with relevant regulatory requirements, we will pass " @@ -823,6 +830,7 @@ INFORM_TITLE INFORM_CONTENT CARD_SLOT + CALL_TYPE IS NOTIS EQUALS diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2cc614db..119f905a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -221,6 +221,7 @@ 测试模拟的来源号码 测试模拟的短信内容 测试模拟的APP包名 + 测试模拟的通话类型 测试模拟的通知标题 测试模拟的通知内容 执行逻辑 @@ -230,6 +231,7 @@ 匹配卡槽 匹配字段 手机号 + 通话类型 APP包名 短信内容 通知内容 @@ -246,6 +248,7 @@ 启用该条转发规则 该条转发规则已禁用 匹配的值不可为空 + 通话类型不正确,只能填写1到6的任意一个数字 异常的发送通道类型,自动删除! 发送通道操作确认 @@ -399,6 +402,8 @@ SIM1 SIM2 多重匹配规则示例:(语法参见wiki)\n\n并且 是 手机号 相等 10086\n[空格]或者 是 手机号 相等 10011\n并且 是 短信内容 包含 欠费\n\n以上规则表示:收到短信,并且(手机号是10086 或者 手机号是10010),并且 短信内容 包含 欠费 时转发短信\n\n注意:每行开始的空格代表层级,太过复杂的多重规则可能导致内存占用很大! + 多重匹配规则示例:(语法参见wiki)\n\n并且 是 手机号 相等 10086\n[空格]或者 是 手机号 相等 10011\n并且 是 通话类型 相等 3\n\n以上规则表示:收到来电,并且(手机号是10086 或者 手机号是10010),并且 通话类型 是 未接来电 时转发提醒\n\n注意:每行开始的空格代表层级,太过复杂的多重规则可能导致内存占用很大!\n\n通话类型:1.来电挂机 2.去电挂机 3.未接来电 4.来电提醒 5.来电接通 6.去电拨出 + 填写数字:1到6的任意一个\n\n通话类型:1.来电挂机 2.去电挂机 3.未接来电 4.来电提醒 5.来电接通 6.去电拨出 多重匹配规则示例:(语法参见wiki)\n\n并且 是 APP包名 相等 com.tencent.mm\n[空格]或者 是 APP包名 相等 com.tencent.mobileqq\n并且 是 通知内容 包含 欠费\n\n以上规则表示:收到APP通知,并且(APP包名是com.tencent.mm 或者 APP包名是com.tencent.mobileqq),并且 通知内容 包含 欠费 时转发通知\n\n注意:每行开始的空格代表层级,太过复杂的多重规则可能导致内存占用很大! POST GET @@ -596,6 +601,7 @@ {{当前应用版本号}} {{通知标题}} {{通知Scheme}} + {{通话类型}} 短信 来电 应用 @@ -606,6 +612,7 @@ 多重匹配 APP包名 通知内容 + 通话类型 转发到 @@ -787,7 +794,7 @@ 额外消除应用通知 一行一个包名\n开启异步加载App列表以便选择 下拉选择获取包名,关键字模糊匹配APP名称 - ^\\s*(并且|或者)\\s(是|不是)\\s(手机号|APP包名|短信内容|通知内容|通知标题|卡槽信息)\\s(相等|包含|不包含|开头|结尾|正则匹配)\\s(.*)$ + ^\\s*(并且|或者)\\s(是|不是)\\s(手机号|APP包名|短信内容|通知内容|通知标题|卡槽信息|通话类型)\\s(相等|包含|不包含|开头|结尾|正则匹配)\\s(.*)$ 欢迎使用 我们深知个人信息对你的重要性,也感谢你对我们的信任。\n 为了更好地保护你的权益,同时遵守相关监管的要求,我们将通过 @@ -824,6 +831,7 @@ 通知标题 通知内容 卡槽信息 + 通话类型 不是 相等