新增:通话转发规则的`匹配字段`增加`通话类型` & 自定义模板增加`{{通话类型}}`标签 #305

This commit is contained in:
pppscn 2023-07-24 23:36:01 +08:00
parent 83bca041c9
commit 00195e6c85
13 changed files with 272 additions and 103 deletions

View File

@ -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")
}
}
}
}

View File

@ -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 {

View File

@ -13,6 +13,7 @@ import java.util.*
import java.util.regex.Pattern
import java.util.regex.PatternSyntaxException
@Suppress("DEPRECATION")
@Parcelize
@Entity(
tableName = "Rule",
@ -58,11 +59,19 @@ 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) {
when (filed) {
null, FILED_TRANSPOND_ALL -> {
sb.append(getString(R.string.rule_all_fw_to))
} else {
}
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,12 +80,20 @@ 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) {
return when (filed) {
FILED_TRANSPOND_ALL -> {
simStr + getString(R.string.rule_all_fw_to)
} else {
}
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)
}
}
}
val statusChecked: Boolean
get() = status != STATUS_OFF
@ -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)

View File

@ -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)
}

View File

@ -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<FragmentRulesEditBinding?>(), View.OnClic
var titleBar: TitleBar? = null
private val viewModel by viewModels<RuleViewModel> { BaseViewModelFactory(context) }
var callType = 1
var callTypeIndex = 0
//免打扰(禁用转发)时间段
private val mTimeOption = DataProvider.timePeriodOption
private var silentPeriodStart = 0
@ -116,6 +120,7 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), 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<FragmentRulesEditBinding?>(), 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<FragmentRulesEditBinding?>(), 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<FragmentRulesEditBinding?>(), 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<FragmentRulesEditBinding?>(), 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<FragmentRulesEditBinding?>(), 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<FragmentRulesEditBinding?>(), 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<FragmentRulesEditBinding?>(), 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<FragmentRulesEditBinding?>(), View.OnClic
val etTitle = dialogTest.findViewById<EditText>(R.id.et_title)
val tvContent = dialogTest.findViewById<TextView>(R.id.tv_content)
val etContent = dialogTest.findViewById<EditText>(R.id.et_content)
//通话类型
val tvCallType = dialogTest.findViewById<TextView>(R.id.tv_call_type)
val spCallType = dialogTest.findViewById<MaterialSpinner>(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<FragmentRulesEditBinding?>(), 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<FragmentRulesEditBinding?>(), 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))
}

View File

@ -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<SendWorker>().setInputData(
workDataOf(
Worker.sendMsgInfo to Gson().toJson(msgInfo)

View File

@ -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<String, String>() {
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<String, String>() {
@ -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

View File

@ -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 -> {}

View File

@ -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]

View File

@ -43,6 +43,18 @@
android:inputType="textMultiLine"
app:met_clearButton="true" />
<TextView
android:id="@+id/tv_call_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/test_call_type"
android:visibility="gone" />
<com.xuexiang.xui.widget.spinner.materialspinner.MaterialSpinner
android:id="@+id/sp_call_type"
android:layout_marginTop="@dimen/config_margin_4dp"
style="@style/Material.SpinnerStyle" />
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"

View File

@ -172,6 +172,11 @@
style="@style/rg_rb_style_wrap"
android:text="@string/phone_number" />
<RadioButton
android:id="@+id/rb_call_type"
style="@style/rg_rb_style_wrap"
android:text="@string/call_type" />
<RadioButton
android:id="@+id/rb_content"
style="@style/rg_rb_style_wrap"
@ -280,6 +285,12 @@
android:inputType="textMultiLine"
app:met_clearButton="true" />
<com.xuexiang.xui.widget.spinner.materialspinner.MaterialSpinner
android:id="@+id/sp_call_type"
android:layout_marginTop="@dimen/config_margin_4dp"
style="@style/Material.SpinnerStyle"
android:visibility="gone" />
<LinearLayout
android:id="@+id/layout_app_list"
android:layout_width="match_parent"

View File

@ -220,6 +220,7 @@
<string name="test_phone_number">Test Phone Number</string>
<string name="test_msg_content">Test Msg Content</string>
<string name="test_package_name">Test PackageName</string>
<string name="test_call_type">Test Call Type</string>
<string name="test_inform_title">Test Notify Title</string>
<string name="test_inform_content">Test Notify Content</string>
<string name="sender_logic">Run Logic</string>
@ -229,6 +230,7 @@
<string name="match_sim_slot">SIM Slot</string>
<string name="match_field">Field</string>
<string name="phone_number">Phone No.</string>
<string name="call_type">Call Type</string>
<string name="package_name">PkgName</string>
<string name="sms_content">SMS</string>
<string name="inform_content">Notice</string>
@ -245,6 +247,7 @@
<string name="switch_rule_status">Enable This Forwarding Rule</string>
<string name="invalid_rule_status">The forwarding rule is disabled</string>
<string name="invalid_match_value">The matched value cannot be null</string>
<string name="invalid_call_type">The call type is incorrect, you can only enter any number from 1 to 6.</string>
<!--SenderActivity-->
<string name="invalid_sender">Invalid sender, abort!</string>
<string name="delete_sender_title">Delete confirmation</string>
@ -398,6 +401,8 @@
<string name="sim1" tools:ignore="Typos">SIM1</string>
<string name="sim2" tools:ignore="Typos">SIM2</string>
<string name="mu_rule_sms_tips">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!</string>
<string name="mu_rule_call_tips">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</string>
<string name="call_type_tips">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</string>
<string name="mu_rule_app_tips">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!</string>
<string name="post">POST</string>
<string name="get">GET</string>
@ -595,6 +600,7 @@
<string name="tag_app_version">{{APP_VERSION}}</string>
<string name="tag_title">{{TITLE}}</string>
<string name="tag_scheme">{{SCHEME}}</string>
<string name="tag_call_type">{{CALL_TYPE}}</string>
<string name="rule_sms">SMS</string>
<string name="rule_call">CALL</string>
<string name="rule_app">APP</string>
@ -605,6 +611,7 @@
<string name="rule_multi_match">Multi Match</string>
<string name="rule_package_name">Package Name</string>
<string name="rule_inform_content">Inform Content</string>
<string name="rule_call_type">Call Type</string>
<string name="rule_card">Card</string>
<string name="rule_when">When</string>
<string name="rule_fw_to">Fw.</string>
@ -786,7 +793,7 @@
<string name="extra_app">Extra Apps</string>
<string name="extra_app_hint">One package name per line\nEnable async loading of the App list for selection.</string>
<string name="choose_app_hint">Drop-down selection to get package name, keyword fuzzy matching APP name</string>
<string name="regex_multi_match" tools:ignore="TypographyDashes">^\\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(.*)$</string>
<string name="regex_multi_match" tools:ignore="TypographyDashes">^\\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(.*)$</string>
<string name="privacy_content_1">Welcome to</string>
<string name="privacy_content_2">We understand the importance of personal information to you and thank you for your trust in us.\n</string>
<string name="privacy_content_3">In order to better protect your rights and comply with relevant regulatory requirements, we will pass "</string>
@ -823,6 +830,7 @@
<string name="FILED_INFORM_TITLE">INFORM_TITLE</string>
<string name="FILED_INFORM_CONTENT">INFORM_CONTENT</string>
<string name="FILED_SIM_SLOT_INFO">CARD_SLOT</string>
<string name="FILED_CALL_TYPE">CALL_TYPE</string>
<string name="SURE_YES">IS</string>
<string name="SURE_NOT">NOTIS</string>
<string name="CHECK_EQUALS">EQUALS</string>

View File

@ -221,6 +221,7 @@
<string name="test_phone_number">测试模拟的来源号码</string>
<string name="test_msg_content">测试模拟的短信内容</string>
<string name="test_package_name">测试模拟的APP包名</string>
<string name="test_call_type">测试模拟的通话类型</string>
<string name="test_inform_title">测试模拟的通知标题</string>
<string name="test_inform_content">测试模拟的通知内容</string>
<string name="sender_logic">执行逻辑</string>
@ -230,6 +231,7 @@
<string name="match_sim_slot">匹配卡槽</string>
<string name="match_field">匹配字段</string>
<string name="phone_number">手机号</string>
<string name="call_type">通话类型</string>
<string name="package_name">APP包名</string>
<string name="sms_content">短信内容</string>
<string name="inform_content">通知内容</string>
@ -246,6 +248,7 @@
<string name="switch_rule_status">启用该条转发规则</string>
<string name="invalid_rule_status">该条转发规则已禁用</string>
<string name="invalid_match_value">匹配的值不可为空</string>
<string name="invalid_call_type">通话类型不正确只能填写1到6的任意一个数字</string>
<!--SenderActivity-->
<string name="invalid_sender">异常的发送通道类型,自动删除!</string>
<string name="delete_sender_title">发送通道操作确认</string>
@ -399,6 +402,8 @@
<string name="sim1" tools:ignore="Typos">SIM1</string>
<string name="sim2" tools:ignore="Typos">SIM2</string>
<string name="mu_rule_sms_tips">多重匹配规则示例语法参见wiki\n\n并且 是 手机号 相等 10086\n[空格]或者 是 手机号 相等 10011\n并且 是 短信内容 包含 欠费\n\n以上规则表示收到短信并且手机号是10086 或者 手机号是10010并且 短信内容 包含 欠费 时转发短信\n\n注意每行开始的空格代表层级太过复杂的多重规则可能导致内存占用很大</string>
<string name="mu_rule_call_tips">多重匹配规则示例语法参见wiki\n\n并且 是 手机号 相等 10086\n[空格]或者 是 手机号 相等 10011\n并且 是 通话类型 相等 3\n\n以上规则表示收到来电并且手机号是10086 或者 手机号是10010并且 通话类型 是 未接来电 时转发提醒\n\n注意每行开始的空格代表层级太过复杂的多重规则可能导致内存占用很大\n\n通话类型1.来电挂机 2.去电挂机 3.未接来电 4.来电提醒 5.来电接通 6.去电拨出</string>
<string name="call_type_tips">填写数字1到6的任意一个\n\n通话类型1.来电挂机 2.去电挂机 3.未接来电 4.来电提醒 5.来电接通 6.去电拨出</string>
<string name="mu_rule_app_tips">多重匹配规则示例语法参见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注意每行开始的空格代表层级太过复杂的多重规则可能导致内存占用很大</string>
<string name="post">POST</string>
<string name="get">GET</string>
@ -596,6 +601,7 @@
<string name="tag_app_version">{{当前应用版本号}}</string>
<string name="tag_title">{{通知标题}}</string>
<string name="tag_scheme">{{通知Scheme}}</string>
<string name="tag_call_type">{{通话类型}}</string>
<string name="rule_sms">短信</string>
<string name="rule_call">来电</string>
<string name="rule_app">应用</string>
@ -606,6 +612,7 @@
<string name="rule_multi_match">多重匹配</string>
<string name="rule_package_name">APP包名</string>
<string name="rule_inform_content">通知内容</string>
<string name="rule_call_type">通话类型</string>
<string name="rule_card"></string>
<string name="rule_when"></string>
<string name="rule_fw_to">转发到</string>
@ -787,7 +794,7 @@
<string name="extra_app">额外消除应用通知</string>
<string name="extra_app_hint">一行一个包名\n开启异步加载App列表以便选择</string>
<string name="choose_app_hint">下拉选择获取包名关键字模糊匹配APP名称</string>
<string name="regex_multi_match" tools:ignore="TypographyDashes">^\\s*(并且|或者)\\s(是|不是)\\s(手机号|APP包名|短信内容|通知内容|通知标题|卡槽信息)\\s(相等|包含|不包含|开头|结尾|正则匹配)\\s(.*)$</string>
<string name="regex_multi_match" tools:ignore="TypographyDashes">^\\s*(并且|或者)\\s(是|不是)\\s(手机号|APP包名|短信内容|通知内容|通知标题|卡槽信息|通话类型)\\s(相等|包含|不包含|开头|结尾|正则匹配)\\s(.*)$</string>
<string name="privacy_content_1">欢迎使用</string>
<string name="privacy_content_2">我们深知个人信息对你的重要性,也感谢你对我们的信任。\n</string>
<string name="privacy_content_3">为了更好地保护你的权益,同时遵守相关监管的要求,我们将通过 </string>
@ -824,6 +831,7 @@
<string name="FILED_INFORM_TITLE">通知标题</string>
<string name="FILED_INFORM_CONTENT">通知内容</string>
<string name="FILED_SIM_SLOT_INFO">卡槽信息</string>
<string name="FILED_CALL_TYPE">通话类型</string>
<string name="SURE_YES"></string>
<string name="SURE_NOT">不是</string>
<string name="CHECK_EQUALS">相等</string>