mirror of
https://github.com/pppscn/SmsForwarder
synced 2025-08-03 01:17:41 +08:00
parent
8540822b67
commit
d3899d9404
@ -89,7 +89,7 @@ data class Rule(
|
|||||||
}
|
}
|
||||||
val SIM_SLOT_MAP = object : HashMap<String, String>() {
|
val SIM_SLOT_MAP = object : HashMap<String, String>() {
|
||||||
init {
|
init {
|
||||||
put("ALL", getString(R.string.rule_all))
|
put("ALL", getString(R.string.rule_any))
|
||||||
put("SIM1", "SIM1")
|
put("SIM1", "SIM1")
|
||||||
put("SIM2", "SIM2")
|
put("SIM2", "SIM2")
|
||||||
}
|
}
|
||||||
@ -129,6 +129,23 @@ data class Rule(
|
|||||||
return sb.toString()
|
return sb.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val description: String
|
||||||
|
get() {
|
||||||
|
val card = SIM_SLOT_MAP[simSlot].toString() + getString(R.string.rule_card)
|
||||||
|
val sb = StringBuilder()
|
||||||
|
when (type) {
|
||||||
|
"app" -> sb.append(getString(R.string.task_app_when))
|
||||||
|
"call" -> sb.append(String.format(getString(R.string.task_call_when), card))
|
||||||
|
"sms" -> sb.append(String.format(getString(R.string.task_sms_when), card))
|
||||||
|
}
|
||||||
|
when (filed) {
|
||||||
|
FILED_TRANSPOND_ALL -> sb.append("")
|
||||||
|
FILED_CALL_TYPE -> sb.append(getString(R.string.rule_when) + FILED_MAP[filed] + CHECK_MAP[check] + CALL_TYPE_MAP[value])
|
||||||
|
else -> sb.append(getString(R.string.rule_when) + FILED_MAP[filed] + CHECK_MAP[check] + value)
|
||||||
|
}
|
||||||
|
return sb.toString()
|
||||||
|
}
|
||||||
|
|
||||||
val ruleMatch: String
|
val ruleMatch: String
|
||||||
get() {
|
get() {
|
||||||
val simStr = if ("app" == type) "" else SIM_SLOT_MAP[simSlot].toString() + getString(R.string.rule_card)
|
val simStr = if ("app" == type) "" else SIM_SLOT_MAP[simSlot].toString() + getString(R.string.rule_card)
|
||||||
|
@ -58,7 +58,11 @@ data class MsgInfo(
|
|||||||
var customSmsTemplate: String = getString(R.string.tag_from).toString() + "\n" +
|
var customSmsTemplate: String = getString(R.string.tag_from).toString() + "\n" +
|
||||||
getString(R.string.tag_sms) + "\n" +
|
getString(R.string.tag_sms) + "\n" +
|
||||||
getString(R.string.tag_card_slot) + "\n" +
|
getString(R.string.tag_card_slot) + "\n" +
|
||||||
(if (type == "app") "" else "SubId:${getString(R.string.tag_card_subid)}\n") +
|
when (type) {
|
||||||
|
"sms", "call" -> "SubId:${getString(R.string.tag_card_subid)}\n"
|
||||||
|
"app" -> "UID:${getString(R.string.tag_uid)}\n"
|
||||||
|
else -> ""
|
||||||
|
} +
|
||||||
getString(R.string.tag_receive_time) + "\n" +
|
getString(R.string.tag_receive_time) + "\n" +
|
||||||
getString(R.string.tag_device_name)
|
getString(R.string.tag_device_name)
|
||||||
|
|
||||||
|
@ -135,6 +135,27 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||||||
CoreAnim.slide,
|
CoreAnim.slide,
|
||||||
R.drawable.auto_task_icon_lock_screen
|
R.drawable.auto_task_icon_lock_screen
|
||||||
),
|
),
|
||||||
|
PageInfo(
|
||||||
|
getString(R.string.task_sms),
|
||||||
|
"com.idormy.sms.forwarder.fragment.condition.MsgFragment",
|
||||||
|
"sms",
|
||||||
|
CoreAnim.slide,
|
||||||
|
R.drawable.auto_task_icon_sms
|
||||||
|
),
|
||||||
|
PageInfo(
|
||||||
|
getString(R.string.task_call),
|
||||||
|
"com.idormy.sms.forwarder.fragment.condition.MsgFragment",
|
||||||
|
"call",
|
||||||
|
CoreAnim.slide,
|
||||||
|
R.drawable.auto_task_icon_incall
|
||||||
|
),
|
||||||
|
PageInfo(
|
||||||
|
getString(R.string.task_app),
|
||||||
|
"com.idormy.sms.forwarder.fragment.condition.MsgFragment",
|
||||||
|
"app",
|
||||||
|
CoreAnim.slide,
|
||||||
|
R.drawable.auto_task_icon_start_activity
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
private var TASK_ACTION_FRAGMENT_LIST = listOf(
|
private var TASK_ACTION_FRAGMENT_LIST = listOf(
|
||||||
@ -438,13 +459,20 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||||||
private fun checkForm(): Task {
|
private fun checkForm(): Task {
|
||||||
val taskName = binding!!.etName.text.toString().trim()
|
val taskName = binding!!.etName.text.toString().trim()
|
||||||
if (taskName.isEmpty()) {
|
if (taskName.isEmpty()) {
|
||||||
throw Exception("请输入任务名称")
|
throw Exception(getString(R.string.invalid_task_name))
|
||||||
}
|
}
|
||||||
if (conditionsList.size <= 0) {
|
if (conditionsList.size <= 0) {
|
||||||
throw Exception("请添加触发条件")
|
throw Exception(getString(R.string.invalid_conditions))
|
||||||
}
|
}
|
||||||
if (actionsList.size <= 0) {
|
if (actionsList.size <= 0) {
|
||||||
throw Exception("请添加执行动作")
|
throw Exception(getString(R.string.invalid_actions))
|
||||||
|
}
|
||||||
|
|
||||||
|
//短信广播/通话广播/APP通知 类型条件只能放在第一个
|
||||||
|
for (i in 1 until conditionsList.size) {
|
||||||
|
if (conditionsList[i].type == TASK_CONDITION_SMS || conditionsList[i].type == TASK_CONDITION_CALL || conditionsList[i].type == TASK_CONDITION_APP) {
|
||||||
|
throw Exception(getString(R.string.msg_condition_must_be_trigger))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val lastExecTime = Date()
|
val lastExecTime = Date()
|
||||||
@ -459,7 +487,7 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||||||
//检查定时任务的时间设置
|
//检查定时任务的时间设置
|
||||||
val cronSetting = Gson().fromJson(firstCondition.setting, CronSetting::class.java)
|
val cronSetting = Gson().fromJson(firstCondition.setting, CronSetting::class.java)
|
||||||
if (cronSetting.expression.isEmpty()) {
|
if (cronSetting.expression.isEmpty()) {
|
||||||
throw Exception("请设置定时任务的时间")
|
throw Exception(getString(R.string.invalid_cron))
|
||||||
}
|
}
|
||||||
val cronExpression = CronExpression(cronSetting.expression)
|
val cronExpression = CronExpression(cronSetting.expression)
|
||||||
nextExecTime = cronExpression.getNextValidTimeAfter(lastExecTime)
|
nextExecTime = cronExpression.getNextValidTimeAfter(lastExecTime)
|
||||||
@ -504,6 +532,11 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||||||
//判断点击的是条件还是动作
|
//判断点击的是条件还是动作
|
||||||
if (widgetInfo.classPath.contains(".condition.")) {
|
if (widgetInfo.classPath.contains(".condition.")) {
|
||||||
val typeCondition = pos + KEY_BACK_CODE_CONDITION
|
val typeCondition = pos + KEY_BACK_CODE_CONDITION
|
||||||
|
//短信广播、通话广播、APP通知 类型条件必须作为触发提交
|
||||||
|
if ((typeCondition == TASK_CONDITION_SMS || typeCondition == TASK_CONDITION_CALL || typeCondition == TASK_CONDITION_APP) && actionsList.isNotEmpty()) {
|
||||||
|
XToastUtils.error(getString(R.string.msg_condition_must_be_trigger))
|
||||||
|
return
|
||||||
|
}
|
||||||
//判断是否已经添加过该类型条件
|
//判断是否已经添加过该类型条件
|
||||||
for (item in conditionsList) {
|
for (item in conditionsList) {
|
||||||
//注意:TASK_CONDITION_XXX 枚举值 等于 TASK_CONDITION_FRAGMENT_LIST 索引加上 KEY_BACK_CODE_CONDITION,不可改变
|
//注意:TASK_CONDITION_XXX 枚举值 等于 TASK_CONDITION_FRAGMENT_LIST 索引加上 KEY_BACK_CODE_CONDITION,不可改变
|
||||||
@ -534,6 +567,12 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||||||
XToastUtils.error(getString(R.string.only_one_location_condition))
|
XToastUtils.error(getString(R.string.only_one_location_condition))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//短信广播、通话广播、APP通知 类型条件互斥
|
||||||
|
if ((typeCondition == TASK_CONDITION_SMS || typeCondition == TASK_CONDITION_CALL || typeCondition == TASK_CONDITION_APP) && (item.type == TASK_CONDITION_SMS || item.type == TASK_CONDITION_CALL || item.type == TASK_CONDITION_APP)) {
|
||||||
|
XToastUtils.error(getString(R.string.only_one_msg_condition))
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val typeAction = pos + KEY_BACK_CODE_ACTION
|
val typeAction = pos + KEY_BACK_CODE_ACTION
|
||||||
@ -546,8 +585,10 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST") PageOption.to(Class.forName(widgetInfo.classPath) as Class<XPageFragment>) //跳转的fragment
|
@Suppress("UNCHECKED_CAST") PageOption.to(Class.forName(widgetInfo.classPath) as Class<XPageFragment>) //跳转的fragment
|
||||||
.setRequestCode(0) //requestCode: 0 新增 、>0 编辑(itemListXxx 的索引加1)
|
.setRequestCode(0) //requestCode: 0 新增 、>0 编辑(itemListXxx 的索引加1)
|
||||||
|
.putString(KEY_EVENT_PARAMS_CONDITION, widgetInfo.params)
|
||||||
.open(this)
|
.open(this)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
@ -638,6 +679,7 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||||||
PageOption.to(Class.forName(widgetInfo.classPath) as Class<XPageFragment>) //跳转的fragment
|
PageOption.to(Class.forName(widgetInfo.classPath) as Class<XPageFragment>) //跳转的fragment
|
||||||
.setRequestCode(position + 1) //requestCode: 0 新增 、>0 编辑(conditionsList 的索引加1)
|
.setRequestCode(position + 1) //requestCode: 0 新增 、>0 编辑(conditionsList 的索引加1)
|
||||||
.putString(KEY_EVENT_DATA_CONDITION, condition.setting)
|
.putString(KEY_EVENT_DATA_CONDITION, condition.setting)
|
||||||
|
.putString(KEY_EVENT_PARAMS_CONDITION, widgetInfo.params)
|
||||||
.open(this)
|
.open(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,494 @@
|
|||||||
|
package com.idormy.sms.forwarder.fragment.condition
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.AdapterView
|
||||||
|
import android.widget.EditText
|
||||||
|
import android.widget.RadioGroup
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
|
import androidx.work.OneTimeWorkRequestBuilder
|
||||||
|
import androidx.work.WorkManager
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.idormy.sms.forwarder.App
|
||||||
|
import com.idormy.sms.forwarder.R
|
||||||
|
import com.idormy.sms.forwarder.adapter.spinner.AppListAdapterItem
|
||||||
|
import com.idormy.sms.forwarder.adapter.spinner.AppListSpinnerAdapter
|
||||||
|
import com.idormy.sms.forwarder.core.BaseFragment
|
||||||
|
import com.idormy.sms.forwarder.database.entity.Rule
|
||||||
|
import com.idormy.sms.forwarder.databinding.FragmentTasksConditionMsgBinding
|
||||||
|
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||||
|
import com.idormy.sms.forwarder.utils.CHECK_CONTAIN
|
||||||
|
import com.idormy.sms.forwarder.utils.CHECK_END_WITH
|
||||||
|
import com.idormy.sms.forwarder.utils.CHECK_IS
|
||||||
|
import com.idormy.sms.forwarder.utils.CHECK_NOT_CONTAIN
|
||||||
|
import com.idormy.sms.forwarder.utils.CHECK_REGEX
|
||||||
|
import com.idormy.sms.forwarder.utils.CHECK_SIM_SLOT_1
|
||||||
|
import com.idormy.sms.forwarder.utils.CHECK_SIM_SLOT_2
|
||||||
|
import com.idormy.sms.forwarder.utils.CHECK_SIM_SLOT_ALL
|
||||||
|
import com.idormy.sms.forwarder.utils.CHECK_START_WITH
|
||||||
|
import com.idormy.sms.forwarder.utils.CommonUtils
|
||||||
|
import com.idormy.sms.forwarder.utils.EVENT_LOAD_APP_LIST
|
||||||
|
import com.idormy.sms.forwarder.utils.FILED_CALL_TYPE
|
||||||
|
import com.idormy.sms.forwarder.utils.FILED_INFORM_CONTENT
|
||||||
|
import com.idormy.sms.forwarder.utils.FILED_MSG_CONTENT
|
||||||
|
import com.idormy.sms.forwarder.utils.FILED_MULTI_MATCH
|
||||||
|
import com.idormy.sms.forwarder.utils.FILED_PACKAGE_NAME
|
||||||
|
import com.idormy.sms.forwarder.utils.FILED_PHONE_NUM
|
||||||
|
import com.idormy.sms.forwarder.utils.FILED_TRANSPOND_ALL
|
||||||
|
import com.idormy.sms.forwarder.utils.FILED_UID
|
||||||
|
import com.idormy.sms.forwarder.utils.KEY_BACK_DATA_CONDITION
|
||||||
|
import com.idormy.sms.forwarder.utils.KEY_BACK_DESCRIPTION_CONDITION
|
||||||
|
import com.idormy.sms.forwarder.utils.KEY_EVENT_DATA_CONDITION
|
||||||
|
import com.idormy.sms.forwarder.utils.KEY_EVENT_PARAMS_CONDITION
|
||||||
|
import com.idormy.sms.forwarder.utils.Log
|
||||||
|
import com.idormy.sms.forwarder.utils.PhoneUtils
|
||||||
|
import com.idormy.sms.forwarder.utils.STATUS_ON
|
||||||
|
import com.idormy.sms.forwarder.utils.SettingUtils
|
||||||
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_APP
|
||||||
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_CALL
|
||||||
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_SMS
|
||||||
|
import com.idormy.sms.forwarder.utils.XToastUtils
|
||||||
|
import com.idormy.sms.forwarder.workers.LoadAppListWorker
|
||||||
|
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||||
|
import com.xuexiang.xaop.annotation.SingleClick
|
||||||
|
import com.xuexiang.xpage.annotation.Page
|
||||||
|
import com.xuexiang.xrouter.annotation.AutoWired
|
||||||
|
import com.xuexiang.xrouter.launcher.XRouter
|
||||||
|
import com.xuexiang.xrouter.utils.TextUtils
|
||||||
|
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||||
|
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||||
|
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||||
|
import com.xuexiang.xui.widget.spinner.materialspinner.MaterialSpinner
|
||||||
|
import com.xuexiang.xutil.XUtil
|
||||||
|
import com.xuexiang.xutil.resource.ResUtils.getColors
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
@Page(name = "Msg")
|
||||||
|
@Suppress("PrivatePropertyName")
|
||||||
|
class MsgFragment : BaseFragment<FragmentTasksConditionMsgBinding?>(), View.OnClickListener {
|
||||||
|
|
||||||
|
private val TAG: String = MsgFragment::class.java.simpleName
|
||||||
|
private var titleBar: TitleBar? = null
|
||||||
|
|
||||||
|
//通话类型:1.来电挂机 2.去电挂机 3.未接来电 4.来电提醒 5.来电接通 6.去电拨出
|
||||||
|
private 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),
|
||||||
|
)
|
||||||
|
|
||||||
|
private var callType = 1
|
||||||
|
private var callTypeIndex = 0
|
||||||
|
private var resultCode: Int = TASK_CONDITION_SMS
|
||||||
|
|
||||||
|
//已安装App信息列表
|
||||||
|
private val appListSpinnerList = ArrayList<AppListAdapterItem>()
|
||||||
|
private lateinit var appListSpinnerAdapter: AppListSpinnerAdapter<*>
|
||||||
|
private val appListObserver = Observer { it: String ->
|
||||||
|
Log.d(TAG, "EVENT_LOAD_APP_LIST: $it")
|
||||||
|
initAppSpinner()
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
@AutoWired(name = KEY_EVENT_PARAMS_CONDITION)
|
||||||
|
var ruleType: String = "sms"
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
@AutoWired(name = KEY_EVENT_DATA_CONDITION)
|
||||||
|
var eventData: String? = null
|
||||||
|
|
||||||
|
override fun initArgs() {
|
||||||
|
XRouter.getInstance().inject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun viewBindingInflate(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup,
|
||||||
|
): FragmentTasksConditionMsgBinding {
|
||||||
|
return FragmentTasksConditionMsgBinding.inflate(inflater, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initTitle(): TitleBar? {
|
||||||
|
titleBar = super.initTitle()!!.setImmersive(false)
|
||||||
|
return titleBar
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化控件
|
||||||
|
*/
|
||||||
|
override fun initViews() {
|
||||||
|
when (ruleType) {
|
||||||
|
"app" -> {
|
||||||
|
resultCode = TASK_CONDITION_APP
|
||||||
|
titleBar?.setTitle(R.string.task_app)
|
||||||
|
binding!!.ivTaskApp.visibility = View.VISIBLE
|
||||||
|
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)
|
||||||
|
//初始化APP下拉列表
|
||||||
|
initAppSpinner()
|
||||||
|
//监听已安装App信息列表加载完成事件
|
||||||
|
LiveEventBus.get(EVENT_LOAD_APP_LIST, String::class.java).observeStickyForever(appListObserver)
|
||||||
|
}
|
||||||
|
|
||||||
|
"call" -> {
|
||||||
|
resultCode = TASK_CONDITION_CALL
|
||||||
|
titleBar?.setTitle(R.string.task_call)
|
||||||
|
binding!!.ivTaskCall.visibility = View.VISIBLE
|
||||||
|
binding!!.rbContent.visibility = View.GONE
|
||||||
|
binding!!.rbPackageName.visibility = View.GONE
|
||||||
|
binding!!.rbUid.visibility = View.GONE
|
||||||
|
binding!!.rbInformContent.visibility = View.GONE
|
||||||
|
binding!!.tvMuRuleTips.setText(R.string.mu_rule_call_tips)
|
||||||
|
|
||||||
|
//通话类型: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.task_sms)
|
||||||
|
binding!!.ivTaskSms.visibility = View.VISIBLE
|
||||||
|
binding!!.rbCallType.visibility = View.GONE
|
||||||
|
binding!!.rbPackageName.visibility = View.GONE
|
||||||
|
binding!!.rbUid.visibility = View.GONE
|
||||||
|
binding!!.rbInformContent.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initListeners() {
|
||||||
|
binding!!.btnTest.setOnClickListener(this)
|
||||||
|
binding!!.btnDel.setOnClickListener(this)
|
||||||
|
binding!!.btnSave.setOnClickListener(this)
|
||||||
|
|
||||||
|
binding!!.rgFiled.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int ->
|
||||||
|
if (ruleType == "app" && appListSpinnerList.isNotEmpty()) {
|
||||||
|
binding!!.layoutAppList.visibility = if (checkedId == R.id.rb_inform_content) View.GONE else View.VISIBLE
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binding!!.rgCheck.setOnCheckedChangeListener { group: RadioGroup?, checkedId: Int ->
|
||||||
|
if (group != null && checkedId > 0) {
|
||||||
|
binding!!.rgCheck2.clearCheck()
|
||||||
|
group.check(checkedId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binding!!.rgCheck2.setOnCheckedChangeListener { group: RadioGroup?, checkedId: Int ->
|
||||||
|
if (group != null && checkedId > 0) {
|
||||||
|
binding!!.rgCheck.clearCheck()
|
||||||
|
group.check(checkedId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "initViews eventData:$eventData")
|
||||||
|
if (eventData != null) {
|
||||||
|
val rule = Gson().fromJson(eventData, Rule::class.java)
|
||||||
|
Log.d(TAG, rule.toString())
|
||||||
|
|
||||||
|
binding!!.rgSimSlot.check(rule.getSimSlotCheckId())
|
||||||
|
binding!!.rgFiled.check(rule.getFiledCheckId())
|
||||||
|
val checkId = rule.getCheckCheckId()
|
||||||
|
if (checkId == R.id.rb_is || checkId == R.id.rb_contain || checkId == R.id.rb_not_contain) {
|
||||||
|
binding!!.rgCheck.check(checkId)
|
||||||
|
} else {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SingleClick
|
||||||
|
override fun onClick(v: View) {
|
||||||
|
try {
|
||||||
|
when (v.id) {
|
||||||
|
R.id.btn_test -> {
|
||||||
|
val ruleNew = checkForm()
|
||||||
|
testRule(ruleNew)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
R.id.btn_del -> {
|
||||||
|
popToBack()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
R.id.btn_save -> {
|
||||||
|
val settingVo = checkForm()
|
||||||
|
val intent = Intent()
|
||||||
|
intent.putExtra(KEY_BACK_DESCRIPTION_CONDITION, settingVo.description)
|
||||||
|
intent.putExtra(KEY_BACK_DATA_CONDITION, Gson().toJson(settingVo))
|
||||||
|
setFragmentResult(resultCode, intent)
|
||||||
|
popToBack()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
XToastUtils.error(e.message.toString())
|
||||||
|
e.printStackTrace()
|
||||||
|
Log.e(TAG, e.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//初始化APP下拉列表
|
||||||
|
private fun initAppSpinner() {
|
||||||
|
if (ruleType != "app") return
|
||||||
|
|
||||||
|
//未开启异步获取已安装App信息开关时,规则编辑不显示已安装APP下拉框
|
||||||
|
if (!SettingUtils.enableLoadUserAppList && !SettingUtils.enableLoadSystemAppList) return
|
||||||
|
|
||||||
|
if (App.UserAppList.isEmpty() && App.SystemAppList.isEmpty()) {
|
||||||
|
XToastUtils.info(getString(R.string.loading_app_list))
|
||||||
|
val request = OneTimeWorkRequestBuilder<LoadAppListWorker>().build()
|
||||||
|
WorkManager.getInstance(XUtil.getContext()).enqueue(request)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
appListSpinnerList.clear()
|
||||||
|
if (SettingUtils.enableLoadUserAppList) {
|
||||||
|
for (appInfo in App.UserAppList) {
|
||||||
|
if (TextUtils.isEmpty(appInfo.packageName)) continue
|
||||||
|
appListSpinnerList.add(AppListAdapterItem(appInfo.name, appInfo.icon, appInfo.packageName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (SettingUtils.enableLoadSystemAppList) {
|
||||||
|
for (appInfo in App.SystemAppList) {
|
||||||
|
if (TextUtils.isEmpty(appInfo.packageName)) continue
|
||||||
|
appListSpinnerList.add(AppListAdapterItem(appInfo.name, appInfo.icon, appInfo.packageName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//列表为空也不显示下拉框
|
||||||
|
if (appListSpinnerList.isEmpty()) return
|
||||||
|
|
||||||
|
appListSpinnerAdapter = AppListSpinnerAdapter(appListSpinnerList).setIsFilterKey(true).setFilterColor("#EF5362").setBackgroundSelector(R.drawable.selector_custom_spinner_bg)
|
||||||
|
binding!!.spApp.setAdapter(appListSpinnerAdapter)
|
||||||
|
binding!!.spApp.setOnItemClickListener { _: AdapterView<*>, _: View, position: Int, _: Long ->
|
||||||
|
try {
|
||||||
|
val appInfo = appListSpinnerAdapter.getItemSource(position) as AppListAdapterItem
|
||||||
|
CommonUtils.insertOrReplaceText2Cursor(binding!!.etValue, appInfo.packageName.toString())
|
||||||
|
} catch (e: Exception) {
|
||||||
|
XToastUtils.error(e.message.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binding!!.layoutAppList.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//提交前检查表单
|
||||||
|
private fun checkForm(): Rule {
|
||||||
|
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_uid -> FILED_UID
|
||||||
|
R.id.rb_inform_content -> FILED_INFORM_CONTENT
|
||||||
|
R.id.rb_multi_match -> FILED_MULTI_MATCH
|
||||||
|
else -> FILED_TRANSPOND_ALL
|
||||||
|
}
|
||||||
|
val check = when (kotlin.math.max(binding!!.rgCheck.checkedRadioButtonId, binding!!.rgCheck2.checkedRadioButtonId)) {
|
||||||
|
R.id.rb_contain -> CHECK_CONTAIN
|
||||||
|
R.id.rb_not_contain -> CHECK_NOT_CONTAIN
|
||||||
|
R.id.rb_start_with -> CHECK_START_WITH
|
||||||
|
R.id.rb_end_with -> CHECK_END_WITH
|
||||||
|
R.id.rb_regex -> CHECK_REGEX
|
||||||
|
else -> CHECK_IS
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
val lineError = checkMultiMatch(value)
|
||||||
|
if (lineError > 0) {
|
||||||
|
throw Exception(String.format(getString(R.string.invalid_multi_match), lineError))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val simSlot = when (binding!!.rgSimSlot.checkedRadioButtonId) {
|
||||||
|
R.id.rb_sim_slot_1 -> CHECK_SIM_SLOT_1
|
||||||
|
R.id.rb_sim_slot_2 -> CHECK_SIM_SLOT_2
|
||||||
|
else -> CHECK_SIM_SLOT_ALL
|
||||||
|
}
|
||||||
|
|
||||||
|
return Rule(0, ruleType, filed, check, value, 0, "", "", simSlot, STATUS_ON, Date(), listOf())
|
||||||
|
}
|
||||||
|
|
||||||
|
//检查多重匹配规则是否正确
|
||||||
|
private fun checkMultiMatch(ruleStr: String?): Int {
|
||||||
|
if (TextUtils.isEmpty(ruleStr)) return 0
|
||||||
|
|
||||||
|
//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()
|
||||||
|
for (line in lineArray!!) {
|
||||||
|
Log.d(TAG, line)
|
||||||
|
if (!line.matches(regex)) return lineNum
|
||||||
|
lineNum++
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun testRule(rule: Rule) {
|
||||||
|
val dialogTest = View.inflate(requireContext(), R.layout.dialog_rule_test, null)
|
||||||
|
val tvSimSlot = dialogTest.findViewById<TextView>(R.id.tv_sim_slot)
|
||||||
|
val rgSimSlot = dialogTest.findViewById<RadioGroup>(R.id.rg_sim_slot)
|
||||||
|
val tvFrom = dialogTest.findViewById<TextView>(R.id.tv_from)
|
||||||
|
val etFrom = dialogTest.findViewById<EditText>(R.id.et_from)
|
||||||
|
val tvTitle = dialogTest.findViewById<TextView>(R.id.tv_title)
|
||||||
|
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
|
||||||
|
rgSimSlot.visibility = View.GONE
|
||||||
|
tvTitle.visibility = View.VISIBLE
|
||||||
|
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(getColors(R.color.darkGrey)).onNeutral { dialog: MaterialDialog?, _: DialogAction? ->
|
||||||
|
dialog?.dismiss()
|
||||||
|
}.positiveText(R.string.action_test).onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||||
|
try {
|
||||||
|
val simSlot = when (if (ruleType == "app") -1 else rgSimSlot.checkedRadioButtonId) {
|
||||||
|
R.id.rb_sim_slot_1 -> 0
|
||||||
|
R.id.rb_sim_slot_2 -> 1
|
||||||
|
else -> -1
|
||||||
|
}
|
||||||
|
|
||||||
|
val testSim = "SIM" + (simSlot + 1)
|
||||||
|
val ruleSim: String = rule.simSlot
|
||||||
|
if (ruleSim != "ALL" && ruleSim != testSim) {
|
||||||
|
throw Exception(getString(R.string.card_slot_does_not_match))
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取卡槽信息
|
||||||
|
val simInfo = when (simSlot) {
|
||||||
|
0 -> "SIM1_" + SettingUtils.extraSim1
|
||||||
|
1 -> "SIM2_" + SettingUtils.extraSim2
|
||||||
|
else -> etTitle.text.toString()
|
||||||
|
}
|
||||||
|
val subId = when (simSlot) {
|
||||||
|
0 -> SettingUtils.subidSim1
|
||||||
|
1 -> SettingUtils.subidSim2
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
|
||||||
|
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 getString(R.string.unknown_number)
|
||||||
|
msg.append(getString(R.string.contact)).append(contactName).append("\n")
|
||||||
|
msg.append(getString(R.string.mandatory_type))
|
||||||
|
msg.append(CALL_TYPE_MAP[callType.toString()] ?: 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))
|
||||||
|
}
|
||||||
|
|
||||||
|
XToastUtils.success(getString(R.string.matched_rule))
|
||||||
|
|
||||||
|
} catch (e: Exception) {
|
||||||
|
XToastUtils.error(e.message.toString())
|
||||||
|
}
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
}
|
@ -217,6 +217,7 @@ const val SP_CLIENT_SIGN_KEY = "client_sign_key"
|
|||||||
const val MAX_SETTING_NUM = 5 //最大条件/动作设置条数
|
const val MAX_SETTING_NUM = 5 //最大条件/动作设置条数
|
||||||
const val KEY_TEST_CONDITION = "key_test_condition"
|
const val KEY_TEST_CONDITION = "key_test_condition"
|
||||||
const val KEY_EVENT_DATA_CONDITION = "event_data_condition"
|
const val KEY_EVENT_DATA_CONDITION = "event_data_condition"
|
||||||
|
const val KEY_EVENT_PARAMS_CONDITION = "event_params_condition"
|
||||||
const val KEY_BACK_CODE_CONDITION = 1000
|
const val KEY_BACK_CODE_CONDITION = 1000
|
||||||
const val KEY_BACK_DATA_CONDITION = "back_data_condition"
|
const val KEY_BACK_DATA_CONDITION = "back_data_condition"
|
||||||
const val KEY_BACK_DESCRIPTION_CONDITION = "back_description_condition"
|
const val KEY_BACK_DESCRIPTION_CONDITION = "back_description_condition"
|
||||||
@ -235,6 +236,9 @@ const val TASK_CONDITION_SIM = 1004
|
|||||||
const val TASK_CONDITION_BATTERY = 1005
|
const val TASK_CONDITION_BATTERY = 1005
|
||||||
const val TASK_CONDITION_CHARGE = 1006
|
const val TASK_CONDITION_CHARGE = 1006
|
||||||
const val TASK_CONDITION_LOCK_SCREEN = 1007
|
const val TASK_CONDITION_LOCK_SCREEN = 1007
|
||||||
|
const val TASK_CONDITION_SMS = 1008
|
||||||
|
const val TASK_CONDITION_CALL = 1009
|
||||||
|
const val TASK_CONDITION_APP = 1010
|
||||||
|
|
||||||
//注意:TASK_ACTION_XXX 枚举值 等于 TASK_ACTION_FRAGMENT_LIST 索引加上 KEY_BACK_CODE_ACTION,不可改变
|
//注意:TASK_ACTION_XXX 枚举值 等于 TASK_ACTION_FRAGMENT_LIST 索引加上 KEY_BACK_CODE_ACTION,不可改变
|
||||||
const val TASK_ACTION_SENDSMS = 2000
|
const val TASK_ACTION_SENDSMS = 2000
|
||||||
|
@ -61,7 +61,7 @@ class DingtalkInnerRobotUtils private constructor() {
|
|||||||
Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}")
|
Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}")
|
||||||
val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost)
|
val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost)
|
||||||
if (!NetworkUtils.isIP(proxyHost)) {
|
if (!NetworkUtils.isIP(proxyHost)) {
|
||||||
throw Exception("代理服务器主机名解析失败:proxyHost=$proxyHost")
|
throw Exception(String.format(getString(R.string.invalid_proxy_host), proxyHost))
|
||||||
}
|
}
|
||||||
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890
|
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ class DingtalkInnerRobotUtils private constructor() {
|
|||||||
Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}")
|
Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}")
|
||||||
val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost)
|
val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost)
|
||||||
if (!NetworkUtils.isIP(proxyHost)) {
|
if (!NetworkUtils.isIP(proxyHost)) {
|
||||||
throw Exception("代理服务器主机名解析失败:proxyHost=$proxyHost")
|
throw Exception(String.format(getString(R.string.invalid_proxy_host), proxyHost))
|
||||||
}
|
}
|
||||||
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890
|
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package com.idormy.sms.forwarder.utils.sender
|
|||||||
|
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
|
import com.idormy.sms.forwarder.R
|
||||||
import com.idormy.sms.forwarder.database.entity.Rule
|
import com.idormy.sms.forwarder.database.entity.Rule
|
||||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||||
import com.idormy.sms.forwarder.entity.result.TelegramResult
|
import com.idormy.sms.forwarder.entity.result.TelegramResult
|
||||||
@ -13,6 +14,7 @@ import com.xuexiang.xhttp2.XHttp
|
|||||||
import com.xuexiang.xhttp2.callback.SimpleCallBack
|
import com.xuexiang.xhttp2.callback.SimpleCallBack
|
||||||
import com.xuexiang.xhttp2.exception.ApiException
|
import com.xuexiang.xhttp2.exception.ApiException
|
||||||
import com.xuexiang.xutil.net.NetworkUtils
|
import com.xuexiang.xutil.net.NetworkUtils
|
||||||
|
import com.xuexiang.xutil.resource.ResUtils.getString
|
||||||
import okhttp3.Credentials
|
import okhttp3.Credentials
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import okhttp3.Route
|
import okhttp3.Route
|
||||||
@ -76,7 +78,7 @@ class TelegramUtils private constructor() {
|
|||||||
Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}")
|
Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}")
|
||||||
val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost)
|
val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost)
|
||||||
if (!NetworkUtils.isIP(proxyHost)) {
|
if (!NetworkUtils.isIP(proxyHost)) {
|
||||||
throw Exception("代理服务器主机名解析失败:proxyHost=$proxyHost")
|
throw Exception(String.format(getString(R.string.invalid_proxy_host), proxyHost))
|
||||||
}
|
}
|
||||||
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890
|
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ class WeworkAgentUtils private constructor() {
|
|||||||
Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}")
|
Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}")
|
||||||
val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost)
|
val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost)
|
||||||
if (!NetworkUtils.isIP(proxyHost)) {
|
if (!NetworkUtils.isIP(proxyHost)) {
|
||||||
throw Exception("代理服务器主机名解析失败:proxyHost=$proxyHost")
|
throw Exception(String.format(getString(R.string.invalid_proxy_host), proxyHost))
|
||||||
}
|
}
|
||||||
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890
|
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ class WeworkAgentUtils private constructor() {
|
|||||||
Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}")
|
Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}")
|
||||||
val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost)
|
val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost)
|
||||||
if (!NetworkUtils.isIP(proxyHost)) {
|
if (!NetworkUtils.isIP(proxyHost)) {
|
||||||
throw Exception("代理服务器主机名解析失败:proxyHost=$proxyHost")
|
throw Exception(String.format(getString(R.string.invalid_proxy_host), proxyHost))
|
||||||
}
|
}
|
||||||
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890
|
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class WeworkRobotUtils private constructor() {
|
|||||||
Log.i(TAG, "requestUrl:$requestUrl")
|
Log.i(TAG, "requestUrl:$requestUrl")
|
||||||
|
|
||||||
val msgMap: MutableMap<String, Any> = mutableMapOf()
|
val msgMap: MutableMap<String, Any> = mutableMapOf()
|
||||||
msgMap["msgtype"] = setting.msgType
|
msgMap["msgtype"] = if (setting.msgType == "markdown") "markdown" else "text"
|
||||||
|
|
||||||
val contextMap = mutableMapOf<String, Any>()
|
val contextMap = mutableMapOf<String, Any>()
|
||||||
contextMap["content"] = content
|
contextMap["content"] = content
|
||||||
|
@ -2,6 +2,7 @@ package com.idormy.sms.forwarder.utils.task
|
|||||||
|
|
||||||
import android.os.BatteryManager
|
import android.os.BatteryManager
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
|
import com.idormy.sms.forwarder.database.entity.Rule
|
||||||
import com.idormy.sms.forwarder.entity.TaskSetting
|
import com.idormy.sms.forwarder.entity.TaskSetting
|
||||||
import com.idormy.sms.forwarder.entity.condition.BatterySetting
|
import com.idormy.sms.forwarder.entity.condition.BatterySetting
|
||||||
import com.idormy.sms.forwarder.entity.condition.ChargeSetting
|
import com.idormy.sms.forwarder.entity.condition.ChargeSetting
|
||||||
@ -12,13 +13,16 @@ import com.idormy.sms.forwarder.entity.condition.NetworkSetting
|
|||||||
import com.idormy.sms.forwarder.entity.condition.SimSetting
|
import com.idormy.sms.forwarder.entity.condition.SimSetting
|
||||||
import com.idormy.sms.forwarder.utils.DELAY_TIME_AFTER_SIM_READY
|
import com.idormy.sms.forwarder.utils.DELAY_TIME_AFTER_SIM_READY
|
||||||
import com.idormy.sms.forwarder.utils.Log
|
import com.idormy.sms.forwarder.utils.Log
|
||||||
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_APP
|
||||||
import com.idormy.sms.forwarder.utils.TASK_CONDITION_BATTERY
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_BATTERY
|
||||||
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_CALL
|
||||||
import com.idormy.sms.forwarder.utils.TASK_CONDITION_CHARGE
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_CHARGE
|
||||||
import com.idormy.sms.forwarder.utils.TASK_CONDITION_CRON
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_CRON
|
||||||
import com.idormy.sms.forwarder.utils.TASK_CONDITION_LEAVE_ADDRESS
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_LEAVE_ADDRESS
|
||||||
import com.idormy.sms.forwarder.utils.TASK_CONDITION_LOCK_SCREEN
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_LOCK_SCREEN
|
||||||
import com.idormy.sms.forwarder.utils.TASK_CONDITION_NETWORK
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_NETWORK
|
||||||
import com.idormy.sms.forwarder.utils.TASK_CONDITION_SIM
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_SIM
|
||||||
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_SMS
|
||||||
import com.idormy.sms.forwarder.utils.TASK_CONDITION_TO_ADDRESS
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_TO_ADDRESS
|
||||||
import gatewayapps.crondroid.CronExpression
|
import gatewayapps.crondroid.CronExpression
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
@ -214,6 +218,16 @@ class ConditionUtils private constructor() {
|
|||||||
|
|
||||||
Log.d(TAG, "TASK-$taskId:lockScreenAction is match, lockScreenSetting = $lockScreenSetting")
|
Log.d(TAG, "TASK-$taskId:lockScreenAction is match, lockScreenSetting = $lockScreenSetting")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TASK_CONDITION_SMS, TASK_CONDITION_CALL, TASK_CONDITION_APP -> {
|
||||||
|
val ruleSetting = Gson().fromJson(condition.setting, Rule::class.java)
|
||||||
|
if (ruleSetting == null) {
|
||||||
|
Log.d(TAG, "TASK-$taskId:ruleSetting is null")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
//TODO: 判断消息是否满足条件
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,13 +28,16 @@ import com.idormy.sms.forwarder.utils.TASK_ACTION_RULE
|
|||||||
import com.idormy.sms.forwarder.utils.TASK_ACTION_SENDER
|
import com.idormy.sms.forwarder.utils.TASK_ACTION_SENDER
|
||||||
import com.idormy.sms.forwarder.utils.TASK_ACTION_SENDSMS
|
import com.idormy.sms.forwarder.utils.TASK_ACTION_SENDSMS
|
||||||
import com.idormy.sms.forwarder.utils.TASK_ACTION_SETTINGS
|
import com.idormy.sms.forwarder.utils.TASK_ACTION_SETTINGS
|
||||||
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_APP
|
||||||
import com.idormy.sms.forwarder.utils.TASK_CONDITION_BATTERY
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_BATTERY
|
||||||
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_CALL
|
||||||
import com.idormy.sms.forwarder.utils.TASK_CONDITION_CHARGE
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_CHARGE
|
||||||
import com.idormy.sms.forwarder.utils.TASK_CONDITION_CRON
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_CRON
|
||||||
import com.idormy.sms.forwarder.utils.TASK_CONDITION_LEAVE_ADDRESS
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_LEAVE_ADDRESS
|
||||||
import com.idormy.sms.forwarder.utils.TASK_CONDITION_LOCK_SCREEN
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_LOCK_SCREEN
|
||||||
import com.idormy.sms.forwarder.utils.TASK_CONDITION_NETWORK
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_NETWORK
|
||||||
import com.idormy.sms.forwarder.utils.TASK_CONDITION_SIM
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_SIM
|
||||||
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_SMS
|
||||||
import com.idormy.sms.forwarder.utils.TASK_CONDITION_TO_ADDRESS
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_TO_ADDRESS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,6 +58,9 @@ class TaskUtils private constructor() {
|
|||||||
TASK_CONDITION_BATTERY -> R.drawable.auto_task_icon_battery
|
TASK_CONDITION_BATTERY -> R.drawable.auto_task_icon_battery
|
||||||
TASK_CONDITION_CHARGE -> R.drawable.auto_task_icon_charge
|
TASK_CONDITION_CHARGE -> R.drawable.auto_task_icon_charge
|
||||||
TASK_CONDITION_LOCK_SCREEN -> R.drawable.auto_task_icon_lock_screen
|
TASK_CONDITION_LOCK_SCREEN -> R.drawable.auto_task_icon_lock_screen
|
||||||
|
TASK_CONDITION_SMS -> R.drawable.auto_task_icon_sms
|
||||||
|
TASK_CONDITION_CALL -> R.drawable.auto_task_icon_incall
|
||||||
|
TASK_CONDITION_APP -> R.drawable.auto_task_icon_start_activity
|
||||||
TASK_ACTION_SENDSMS -> R.drawable.auto_task_icon_sms
|
TASK_ACTION_SENDSMS -> R.drawable.auto_task_icon_sms
|
||||||
TASK_ACTION_NOTIFICATION -> R.drawable.auto_task_icon_notification
|
TASK_ACTION_NOTIFICATION -> R.drawable.auto_task_icon_notification
|
||||||
TASK_ACTION_CLEANER -> R.drawable.auto_task_icon_cleaner
|
TASK_ACTION_CLEANER -> R.drawable.auto_task_icon_cleaner
|
||||||
@ -80,6 +86,9 @@ class TaskUtils private constructor() {
|
|||||||
TASK_CONDITION_BATTERY -> R.drawable.auto_task_icon_battery_grey
|
TASK_CONDITION_BATTERY -> R.drawable.auto_task_icon_battery_grey
|
||||||
TASK_CONDITION_CHARGE -> R.drawable.auto_task_icon_charge_grey
|
TASK_CONDITION_CHARGE -> R.drawable.auto_task_icon_charge_grey
|
||||||
TASK_CONDITION_LOCK_SCREEN -> R.drawable.auto_task_icon_lock_screen_grey
|
TASK_CONDITION_LOCK_SCREEN -> R.drawable.auto_task_icon_lock_screen_grey
|
||||||
|
TASK_CONDITION_SMS -> R.drawable.auto_task_icon_sms_grey
|
||||||
|
TASK_CONDITION_CALL -> R.drawable.auto_task_icon_incall_grey
|
||||||
|
TASK_CONDITION_APP -> R.drawable.auto_task_icon_start_activity_grey
|
||||||
TASK_ACTION_SENDSMS -> R.drawable.auto_task_icon_sms_grey
|
TASK_ACTION_SENDSMS -> R.drawable.auto_task_icon_sms_grey
|
||||||
TASK_ACTION_NOTIFICATION -> R.drawable.auto_task_icon_notification_grey
|
TASK_ACTION_NOTIFICATION -> R.drawable.auto_task_icon_notification_grey
|
||||||
TASK_ACTION_CLEANER -> R.drawable.auto_task_icon_cleaner_grey
|
TASK_ACTION_CLEANER -> R.drawable.auto_task_icon_cleaner_grey
|
||||||
|
@ -139,6 +139,9 @@ class ActionWorker(context: Context, params: WorkerParameters) : CoroutineWorker
|
|||||||
|
|
||||||
TASK_ACTION_NOTIFICATION -> {
|
TASK_ACTION_NOTIFICATION -> {
|
||||||
val ruleSetting = Gson().fromJson(action.setting, Rule::class.java)
|
val ruleSetting = Gson().fromJson(action.setting, Rule::class.java)
|
||||||
|
//重新查询发送通道最新设置
|
||||||
|
val ids = ruleSetting.senderList.joinToString(",") { it.id.toString() }
|
||||||
|
ruleSetting.senderList = Core.sender.getByIds(ids.split(",").map { it.trim().toLong() }, ids)
|
||||||
//自动任务的不需要吐司或者更新日志,特殊处理 logId = -1,msgId = -1
|
//自动任务的不需要吐司或者更新日志,特殊处理 logId = -1,msgId = -1
|
||||||
SendUtils.sendMsgSender(msgInfo, ruleSetting, 0, -1L, -1L)
|
SendUtils.sendMsgSender(msgInfo, ruleSetting, 0, -1L, -1L)
|
||||||
|
|
||||||
|
@ -68,6 +68,10 @@ class BatteryWorker(context: Context, params: WorkerParameters) : CoroutineWorke
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO:判断其他条件是否满足
|
//TODO:判断其他条件是否满足
|
||||||
|
if (!ConditionUtils.checkCondition(task.id, conditionList)) {
|
||||||
|
Log.d(TAG, "TASK-${task.id}:other condition is not satisfied")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: 组装消息体 && 执行具体任务
|
//TODO: 组装消息体 && 执行具体任务
|
||||||
val msgInfo = MsgInfo("task", task.name, msg, Date(), task.name)
|
val msgInfo = MsgInfo("task", task.name, msg, Date(), task.name)
|
||||||
|
@ -12,10 +12,7 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@Suppress("PrivatePropertyName")
|
@Suppress("PrivatePropertyName")
|
||||||
class LoadAppListWorker(
|
class LoadAppListWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
|
||||||
context: Context,
|
|
||||||
workerParams: WorkerParameters,
|
|
||||||
) : CoroutineWorker(context, workerParams) {
|
|
||||||
|
|
||||||
private val TAG: String = LoadAppListWorker::class.java.simpleName
|
private val TAG: String = LoadAppListWorker::class.java.simpleName
|
||||||
|
|
||||||
|
@ -14,10 +14,8 @@ import com.idormy.sms.forwarder.utils.Worker
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
class SendLogicWorker(
|
class SendLogicWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
|
||||||
context: Context,
|
|
||||||
workerParams: WorkerParameters,
|
|
||||||
) : CoroutineWorker(context, workerParams) {
|
|
||||||
override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
|
override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
|
||||||
|
|
||||||
val msgInfoJson = inputData.getString(Worker.SEND_MSG_INFO)
|
val msgInfoJson = inputData.getString(Worker.SEND_MSG_INFO)
|
||||||
|
@ -3,6 +3,9 @@ package com.idormy.sms.forwarder.workers
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.work.CoroutineWorker
|
import androidx.work.CoroutineWorker
|
||||||
|
import androidx.work.Data
|
||||||
|
import androidx.work.OneTimeWorkRequestBuilder
|
||||||
|
import androidx.work.WorkManager
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import androidx.work.workDataOf
|
import androidx.work.workDataOf
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
@ -12,12 +15,19 @@ import com.idormy.sms.forwarder.database.entity.Logs
|
|||||||
import com.idormy.sms.forwarder.database.entity.Msg
|
import com.idormy.sms.forwarder.database.entity.Msg
|
||||||
import com.idormy.sms.forwarder.database.entity.Rule
|
import com.idormy.sms.forwarder.database.entity.Rule
|
||||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||||
|
import com.idormy.sms.forwarder.entity.TaskSetting
|
||||||
|
import com.idormy.sms.forwarder.utils.CHECK_SIM_SLOT_ALL
|
||||||
import com.idormy.sms.forwarder.utils.DataProvider
|
import com.idormy.sms.forwarder.utils.DataProvider
|
||||||
import com.idormy.sms.forwarder.utils.HistoryUtils
|
import com.idormy.sms.forwarder.utils.HistoryUtils
|
||||||
import com.idormy.sms.forwarder.utils.Log
|
import com.idormy.sms.forwarder.utils.Log
|
||||||
import com.idormy.sms.forwarder.utils.SendUtils
|
import com.idormy.sms.forwarder.utils.SendUtils
|
||||||
import com.idormy.sms.forwarder.utils.SettingUtils
|
import com.idormy.sms.forwarder.utils.SettingUtils
|
||||||
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_APP
|
||||||
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_CALL
|
||||||
|
import com.idormy.sms.forwarder.utils.TASK_CONDITION_SMS
|
||||||
|
import com.idormy.sms.forwarder.utils.TaskWorker
|
||||||
import com.idormy.sms.forwarder.utils.Worker
|
import com.idormy.sms.forwarder.utils.Worker
|
||||||
|
import com.idormy.sms.forwarder.utils.task.ConditionUtils
|
||||||
import com.xuexiang.xutil.resource.ResUtils
|
import com.xuexiang.xutil.resource.ResUtils
|
||||||
import com.xuexiang.xutil.security.CipherUtils
|
import com.xuexiang.xutil.security.CipherUtils
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -27,16 +37,28 @@ import java.text.SimpleDateFormat
|
|||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
class SendWorker(
|
@Suppress("PrivatePropertyName", "DEPRECATION")
|
||||||
context: Context,
|
class SendWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
|
||||||
workerParams: WorkerParameters,
|
|
||||||
) : CoroutineWorker(context, workerParams) {
|
private val TAG: String = SendWorker::class.java.simpleName
|
||||||
|
|
||||||
@SuppressLint("SimpleDateFormat")
|
@SuppressLint("SimpleDateFormat")
|
||||||
override suspend fun doWork(): Result {
|
override suspend fun doWork(): Result {
|
||||||
|
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
|
val msgInfoJson = inputData.getString(Worker.SEND_MSG_INFO)
|
||||||
|
if (msgInfoJson.isNullOrBlank()) {
|
||||||
|
return@withContext Result.failure(workDataOf("send" to "msgInfoJson is null"))
|
||||||
|
}
|
||||||
|
|
||||||
|
val msgInfo = Gson().fromJson(msgInfoJson, MsgInfo::class.java)
|
||||||
|
//【注意】卡槽id:-1=获取失败、0=卡槽1、1=卡槽2,但是 Rule 表里存的是 SIM1/SIM2
|
||||||
|
val simSlot = "SIM" + (msgInfo.simSlot + 1)
|
||||||
|
|
||||||
|
//自动任务处理逻辑
|
||||||
|
autoTaskProcess(msgInfo, msgInfoJson, simSlot)
|
||||||
|
|
||||||
// 免打扰(禁用转发)时间段
|
// 免打扰(禁用转发)时间段
|
||||||
var isSilentPeriod = false
|
var isSilentPeriod = false
|
||||||
if (SettingUtils.silentPeriodStart != SettingUtils.silentPeriodEnd) {
|
if (SettingUtils.silentPeriodStart != SettingUtils.silentPeriodEnd) {
|
||||||
@ -70,9 +92,6 @@ class SendWorker(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val msgInfoJson = inputData.getString(Worker.SEND_MSG_INFO)
|
|
||||||
val msgInfo = Gson().fromJson(msgInfoJson, MsgInfo::class.java)
|
|
||||||
|
|
||||||
// 过滤重复消息机制
|
// 过滤重复消息机制
|
||||||
val duplicateMessagesLimits = SettingUtils.duplicateMessagesLimits * 1000L
|
val duplicateMessagesLimits = SettingUtils.duplicateMessagesLimits * 1000L
|
||||||
if (duplicateMessagesLimits > 0L) {
|
if (duplicateMessagesLimits > 0L) {
|
||||||
@ -88,8 +107,6 @@ class SendWorker(
|
|||||||
timestampPrev = timestamp
|
timestampPrev = timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
//【注意】卡槽id:-1=获取失败、0=卡槽1、1=卡槽2,但是 Rule 表里存的是 SIM1/SIM2
|
|
||||||
val simSlot = "SIM" + (msgInfo.simSlot + 1)
|
|
||||||
val ruleList: List<Rule> = Core.rule.getRuleList(msgInfo.type, 1, simSlot)
|
val ruleList: List<Rule> = Core.rule.getRuleList(msgInfo.type, 1, simSlot)
|
||||||
if (ruleList.isEmpty()) {
|
if (ruleList.isEmpty()) {
|
||||||
return@withContext Result.failure(workDataOf("send" to "failed"))
|
return@withContext Result.failure(workDataOf("send" to "failed"))
|
||||||
@ -128,4 +145,60 @@ class SendWorker(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun autoTaskProcess(msgInfo: MsgInfo, msgInfoJson: String, simSlot: String) {
|
||||||
|
val conditionType = when (msgInfo.type) {
|
||||||
|
"app" -> TASK_CONDITION_APP
|
||||||
|
"call" -> TASK_CONDITION_CALL
|
||||||
|
else -> TASK_CONDITION_SMS
|
||||||
|
}
|
||||||
|
|
||||||
|
val taskList = Core.task.getByType(conditionType)
|
||||||
|
for (task in taskList) {
|
||||||
|
Log.d(TAG, "task = $task")
|
||||||
|
|
||||||
|
// 根据任务信息执行相应操作
|
||||||
|
val conditionList = Gson().fromJson(task.conditions, Array<TaskSetting>::class.java).toMutableList()
|
||||||
|
if (conditionList.isEmpty()) {
|
||||||
|
Log.d(TAG, "TASK-${task.id}:conditionList is empty")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val firstCondition = conditionList.firstOrNull()
|
||||||
|
if (firstCondition == null) {
|
||||||
|
Log.d(TAG, "TASK-${task.id}:firstCondition is null")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
val ruleSetting = Gson().fromJson(firstCondition.setting, Rule::class.java)
|
||||||
|
if (ruleSetting == null) {
|
||||||
|
Log.d(TAG, "TASK-${task.id}:ruleSetting is null")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ruleSetting.simSlot != CHECK_SIM_SLOT_ALL && simSlot != ruleSetting.simSlot) {
|
||||||
|
Log.d(TAG, "TASK-${task.id}:simSlot is not matched, simSlot = $simSlot, ruleSetting = $ruleSetting")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ruleSetting.checkMsg(msgInfo)) {
|
||||||
|
Log.d(TAG, "TASK-${task.id}:ruleSetting is not matched, msgInfo = $msgInfo, ruleSetting = $ruleSetting")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO:判断其他条件是否满足
|
||||||
|
if (!ConditionUtils.checkCondition(task.id, conditionList)) {
|
||||||
|
Log.d(TAG, "TASK-${task.id}:other condition is not satisfied")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: 组装消息体 && 执行具体任务
|
||||||
|
val actionData = Data.Builder()
|
||||||
|
.putLong(TaskWorker.TASK_ID, task.id)
|
||||||
|
.putString(TaskWorker.TASK_ACTIONS, task.actions)
|
||||||
|
.putString(TaskWorker.MSG_INFO, msgInfoJson)
|
||||||
|
.build()
|
||||||
|
val actionRequest = OneTimeWorkRequestBuilder<ActionWorker>().setInputData(actionData).build()
|
||||||
|
WorkManager.getInstance().enqueue(actionRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -14,10 +14,8 @@ import kotlinx.coroutines.withContext
|
|||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
class UpdateLogsWorker(
|
class UpdateLogsWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
|
||||||
context: Context,
|
|
||||||
workerParams: WorkerParameters,
|
|
||||||
) : CoroutineWorker(context, workerParams) {
|
|
||||||
override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
|
override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val sendResponseJson = inputData.getString(Worker.UPDATE_LOGS)
|
val sendResponseJson = inputData.getString(Worker.UPDATE_LOGS)
|
||||||
|
6
app/src/main/res/drawable/auto_task_icon_incall_grey.xml
Normal file
6
app/src/main/res/drawable/auto_task_icon_incall_grey.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector android:height="25.0dip" android:width="25.0dip" android:autoMirrored="true" android:viewportWidth="25.0" android:viewportHeight="25.0"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@color/auto_task_icon_grey_bg" android:pathData="M6.66,0.66L18.66,0.66A6,6 0,0 1,24.66 6.66L24.66,18.66A6,6 0,0 1,18.66 24.66L6.66,24.66A6,6 0,0 1,0.66 18.66L0.66,6.66A6,6 0,0 1,6.66 0.66z" />
|
||||||
|
<path android:fillColor="@color/auto_task_icon_grey" android:pathData="M9.372,6.643C9.337,6.583 9.292,6.531 9.238,6.488C9.078,6.322 8.846,6.252 8.622,6.298L8.486,6.314C8.453,6.313 8.427,6.318 8.412,6.321C8.375,6.328 8.344,6.34 8.326,6.348C8.285,6.365 8.24,6.388 8.197,6.412C8.107,6.462 7.991,6.534 7.864,6.615C7.609,6.779 7.295,6.995 7.034,7.186L7.029,7.19L7.025,7.193C6.433,7.657 6.249,8.29 6.29,8.968C6.327,9.585 6.549,10.26 6.823,10.93L6.81,10.951L6.872,11.093C7.346,12.181 8.27,13.582 9.741,15.108L9.738,15.112L9.926,15.3L9.993,15.366L10.009,15.381L10.02,15.392L10.113,15.299L10.114,15.3L10.021,15.394C11.622,16.972 13.094,17.953 14.226,18.447L14.368,18.509L14.389,18.496C15.058,18.77 15.734,18.992 16.351,19.029C17.028,19.07 17.662,18.886 18.126,18.294L18.129,18.29L18.132,18.285C18.323,18.024 18.539,17.71 18.703,17.455C18.785,17.328 18.857,17.212 18.906,17.122C18.931,17.079 18.954,17.034 18.971,16.993C18.979,16.975 18.991,16.944 18.998,16.907C19.001,16.892 19.006,16.866 19.005,16.833L19.02,16.697C19.066,16.473 18.996,16.241 18.831,16.081C18.788,16.028 18.736,15.982 18.676,15.948L18.64,15.92L15.363,14.127L13.785,15.497C13.005,15.085 12.239,14.414 11.574,13.762C10.916,13.093 10.237,12.321 9.822,11.533L11.192,9.955L9.399,6.679L9.372,6.643ZM10.039,15.186L10.039,15.185L10.048,15.176L10.049,15.177C10.059,15.207 10.073,15.237 10.091,15.267L10.09,15.268C10.071,15.244 10.053,15.217 10.039,15.186ZM10.005,14.98L10.02,14.991C10.021,14.98 10.022,14.971 10.024,14.965C10.023,14.965 10.023,14.964 10.022,14.963C10.017,14.968 10.011,14.974 10.005,14.98ZM10.091,15.269L10.092,15.268L10.101,15.281L10.091,15.269ZM10.116,15.298L10.115,15.297L10.234,15.178L10.116,15.298ZM10.431,15.407L10.441,15.398L10.44,15.4L10.431,15.407ZM10.425,15.413L10.428,15.41L10.427,15.411L10.425,15.413ZM10.394,15.435L10.391,15.436L10.403,15.429L10.394,15.435ZM10.408,15.426L10.407,15.427L10.41,15.424L10.408,15.426Z" android:fillType="evenOdd" />
|
||||||
|
</vector>
|
@ -6,7 +6,7 @@
|
|||||||
android:viewportWidth="25.0"
|
android:viewportWidth="25.0"
|
||||||
android:viewportHeight="25.0">
|
android:viewportHeight="25.0">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#ff2eafff"
|
android:fillColor="#ff8482ff"
|
||||||
android:pathData="M6.66,0.66L18.66,0.66A6,6 0,0 1,24.66 6.66L24.66,18.66A6,6 0,0 1,18.66 24.66L6.66,24.66A6,6 0,0 1,0.66 18.66L0.66,6.66A6,6 0,0 1,6.66 0.66z" />
|
android:pathData="M6.66,0.66L18.66,0.66A6,6 0,0 1,24.66 6.66L24.66,18.66A6,6 0,0 1,18.66 24.66L6.66,24.66A6,6 0,0 1,0.66 18.66L0.66,6.66A6,6 0,0 1,6.66 0.66z" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#ffffffff"
|
android:fillColor="#ffffffff"
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="25.0dip"
|
||||||
|
android:height="25.0dip"
|
||||||
|
android:autoMirrored="true"
|
||||||
|
android:viewportWidth="25.0"
|
||||||
|
android:viewportHeight="25.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#ffe6e6e6"
|
||||||
|
android:pathData="M6.66,0.66L18.66,0.66A6,6 0,0 1,24.66 6.66L24.66,18.66A6,6 0,0 1,18.66 24.66L6.66,24.66A6,6 0,0 1,0.66 18.66L0.66,6.66A6,6 0,0 1,6.66 0.66z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#ffffffff"
|
||||||
|
android:fillType="evenOdd"
|
||||||
|
android:pathData="M7.984,5.837C8.418,5.586 8.974,5.735 9.224,6.169L9.779,7.13C10.518,6.712 11.372,6.473 12.282,6.473C13.199,6.473 14.06,6.715 14.803,7.14L15.342,6.207C15.592,5.772 16.148,5.623 16.582,5.874C17.017,6.125 17.165,6.68 16.915,7.115L16.212,8.331C16.862,9.121 17.278,10.11 17.355,11.194H7.21C7.287,10.103 7.708,9.107 8.366,8.314L7.651,7.077C7.401,6.643 7.55,6.087 7.984,5.837ZM17.368,12.647H7.198V17.732C7.198,18.535 7.848,19.185 8.651,19.185H15.915C16.718,19.185 17.368,18.535 17.368,17.732V12.647Z" />
|
||||||
|
</vector>
|
@ -131,17 +131,17 @@
|
|||||||
android:id="@+id/rb_sim_slot_all"
|
android:id="@+id/rb_sim_slot_all"
|
||||||
style="@style/rg_rb_style"
|
style="@style/rg_rb_style"
|
||||||
android:checked="true"
|
android:checked="true"
|
||||||
android:text="@string/all" />
|
android:text="@string/sim_any" />
|
||||||
|
|
||||||
<RadioButton
|
<RadioButton
|
||||||
android:id="@+id/rb_sim_slot_1"
|
android:id="@+id/rb_sim_slot_1"
|
||||||
style="@style/rg_rb_style"
|
style="@style/rg_rb_style"
|
||||||
android:text="@string/sim1" />
|
android:text="@string/sim_1" />
|
||||||
|
|
||||||
<RadioButton
|
<RadioButton
|
||||||
android:id="@+id/rb_sim_slot_2"
|
android:id="@+id/rb_sim_slot_2"
|
||||||
style="@style/rg_rb_style"
|
style="@style/rg_rb_style"
|
||||||
android:text="@string/sim2" />
|
android:text="@string/sim_2" />
|
||||||
|
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
|
|
||||||
|
312
app/src/main/res/layout/fragment_tasks_condition_msg.xml
Normal file
312
app/src/main/res/layout/fragment_tasks_condition_msg.xml
Normal file
@ -0,0 +1,312 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/xui_config_color_background"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:overScrollMode="never">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="5dp"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/iv_task_sms"
|
||||||
|
android:layout_width="120dp"
|
||||||
|
android:layout_height="120dp"
|
||||||
|
android:layout_margin="10dp"
|
||||||
|
android:contentDescription="@string/task_sms"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:srcCompat="@drawable/auto_task_icon_sms"
|
||||||
|
tools:ignore="ImageContrastCheck" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/iv_task_call"
|
||||||
|
android:layout_width="120dp"
|
||||||
|
android:layout_height="120dp"
|
||||||
|
android:layout_margin="10dp"
|
||||||
|
android:contentDescription="@string/task_call"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:srcCompat="@drawable/auto_task_icon_incall"
|
||||||
|
tools:ignore="ImageContrastCheck" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/iv_task_app"
|
||||||
|
android:layout_width="120dp"
|
||||||
|
android:layout_height="120dp"
|
||||||
|
android:layout_margin="10dp"
|
||||||
|
android:contentDescription="@string/task_app"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:srcCompat="@drawable/auto_task_icon_start_activity"
|
||||||
|
tools:ignore="ImageContrastCheck" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layout_sim_slot"
|
||||||
|
style="@style/BarStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/match_sim_slot"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<RadioGroup
|
||||||
|
android:id="@+id/rg_sim_slot"
|
||||||
|
style="@style/rg_style"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_sim_slot_all"
|
||||||
|
style="@style/rg_rb_style"
|
||||||
|
android:checked="true"
|
||||||
|
android:text="@string/sim_any" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_sim_slot_1"
|
||||||
|
style="@style/rg_rb_style"
|
||||||
|
android:text="@string/sim_1" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_sim_slot_2"
|
||||||
|
style="@style/rg_rb_style"
|
||||||
|
android:text="@string/sim_2" />
|
||||||
|
|
||||||
|
</RadioGroup>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
style="@style/BarStyle.Switch"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/match_field"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<RadioGroup
|
||||||
|
android:id="@+id/rg_filed"
|
||||||
|
style="@style/rg_style"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_transpond_all"
|
||||||
|
style="@style/rg_rb_style_wrap"
|
||||||
|
android:checked="true"
|
||||||
|
android:text="@string/all" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_phone"
|
||||||
|
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"
|
||||||
|
android:text="@string/sms_content" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_package_name"
|
||||||
|
style="@style/rg_rb_style_wrap"
|
||||||
|
android:text="@string/package_name" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_uid"
|
||||||
|
style="@style/rg_rb_style_wrap"
|
||||||
|
android:text="@string/uid" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_inform_content"
|
||||||
|
style="@style/rg_rb_style_wrap"
|
||||||
|
android:text="@string/inform_content" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_multi_match"
|
||||||
|
style="@style/rg_rb_style_wrap"
|
||||||
|
android:text="@string/multiple_matches" />
|
||||||
|
|
||||||
|
</RadioGroup>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layout_match_type"
|
||||||
|
style="@style/BarStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:text="@string/match_type"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<RadioGroup
|
||||||
|
android:id="@+id/rg_check"
|
||||||
|
style="@style/rg_style"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_is"
|
||||||
|
style="@style/rg_rb_style"
|
||||||
|
android:checked="true"
|
||||||
|
android:text="@string/btn_is" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_contain"
|
||||||
|
style="@style/rg_rb_style"
|
||||||
|
android:text="@string/btn_contain" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_not_contain"
|
||||||
|
style="@style/rg_rb_style"
|
||||||
|
android:text="@string/btn_not_contain" />
|
||||||
|
</RadioGroup>
|
||||||
|
|
||||||
|
<RadioGroup
|
||||||
|
android:id="@+id/rg_check2"
|
||||||
|
style="@style/rg_style"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_start_with"
|
||||||
|
style="@style/rg_rb_style"
|
||||||
|
android:text="@string/btn_start_with" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_end_with"
|
||||||
|
style="@style/rg_rb_style"
|
||||||
|
android:text="@string/btn_end_with" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_regex"
|
||||||
|
style="@style/rg_rb_style"
|
||||||
|
android:text="@string/btn_regex" />
|
||||||
|
|
||||||
|
</RadioGroup>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layout_match_value"
|
||||||
|
style="@style/BarStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/match_value"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
|
||||||
|
android:id="@+id/et_value"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/match_value_tips"
|
||||||
|
android:inputType="textMultiLine"
|
||||||
|
app:met_clearButton="true" />
|
||||||
|
|
||||||
|
<com.xuexiang.xui.widget.spinner.materialspinner.MaterialSpinner
|
||||||
|
android:id="@+id/sp_call_type"
|
||||||
|
style="@style/Material.SpinnerStyle"
|
||||||
|
android:layout_marginTop="@dimen/config_margin_4dp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layout_app_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/choose_app"
|
||||||
|
android:textSize="@dimen/text_size_small"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<com.xuexiang.xui.widget.spinner.editspinner.EditSpinner
|
||||||
|
android:id="@+id/sp_app"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
app:es_hint="@string/choose_app_hint"
|
||||||
|
app:es_maxLength="20"
|
||||||
|
app:es_maxLine="1" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_mu_rule_tips"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/mu_rule_sms_tips"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="10dp">
|
||||||
|
|
||||||
|
<com.xuexiang.xui.widget.textview.supertextview.SuperButton
|
||||||
|
android:id="@+id/btn_del"
|
||||||
|
style="@style/SuperButton.Gray.Icon.Spacing"
|
||||||
|
android:drawableStart="@drawable/ic_delete"
|
||||||
|
android:text="@string/discard"
|
||||||
|
tools:ignore="RtlSymmetry,TextContrastCheck,TouchTargetSizeCheck" />
|
||||||
|
|
||||||
|
<com.xuexiang.xui.widget.textview.supertextview.SuperButton
|
||||||
|
android:id="@+id/btn_save"
|
||||||
|
style="@style/SuperButton.Blue.Icon.Spacing"
|
||||||
|
android:drawableStart="@drawable/ic_save"
|
||||||
|
android:text="@string/submit"
|
||||||
|
tools:ignore="RtlSymmetry,TextContrastCheck,TouchTargetSizeCheck" />
|
||||||
|
|
||||||
|
<com.xuexiang.xui.widget.textview.supertextview.SuperButton
|
||||||
|
android:id="@+id/btn_test"
|
||||||
|
style="@style/SuperButton.Green.Icon.Spacing"
|
||||||
|
android:drawableStart="@drawable/ic_test"
|
||||||
|
android:text="@string/test"
|
||||||
|
tools:ignore="RtlSymmetry,TextContrastCheck,TouchTargetSizeCheck" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -169,6 +169,7 @@
|
|||||||
<string name="test">Test</string>
|
<string name="test">Test</string>
|
||||||
<string name="confirm">Confirm</string>
|
<string name="confirm">Confirm</string>
|
||||||
<string name="all">All</string>
|
<string name="all">All</string>
|
||||||
|
<string name="any">Any</string>
|
||||||
<string name="select">Select</string>
|
<string name="select">Select</string>
|
||||||
<string name="clone">Clone</string>
|
<string name="clone">Clone</string>
|
||||||
<string name="setting">Setting</string>
|
<string name="setting">Setting</string>
|
||||||
@ -640,6 +641,7 @@
|
|||||||
<string name="rule_call">CALL</string>
|
<string name="rule_call">CALL</string>
|
||||||
<string name="rule_app">APP</string>
|
<string name="rule_app">APP</string>
|
||||||
<string name="rule_all">ALL</string>
|
<string name="rule_all">ALL</string>
|
||||||
|
<string name="rule_any">ANY</string>
|
||||||
<string name="rule_transpond_all">Transpond All</string>
|
<string name="rule_transpond_all">Transpond All</string>
|
||||||
<string name="rule_phone_num">Phone Num</string>
|
<string name="rule_phone_num">Phone Num</string>
|
||||||
<string name="rule_msg_content">Msg Content</string>
|
<string name="rule_msg_content">Msg Content</string>
|
||||||
@ -997,6 +999,7 @@
|
|||||||
<string name="contact_info" formatted="false">Name:%s\nPhone:%s</string>
|
<string name="contact_info" formatted="false">Name:%s\nPhone:%s</string>
|
||||||
<string name="card_slot_does_not_match">Card slot does not match the rule</string>
|
<string name="card_slot_does_not_match">Card slot does not match the rule</string>
|
||||||
<string name="unmatched_rule">Unmatched rule</string>
|
<string name="unmatched_rule">Unmatched rule</string>
|
||||||
|
<string name="matched_rule">Matched rule</string>
|
||||||
<string name="copied_to_clipboard">Copied to clipboard:\n%s</string>
|
<string name="copied_to_clipboard">Copied to clipboard:\n%s</string>
|
||||||
<string name="search_keyword">Search Keyword: %s</string>
|
<string name="search_keyword">Search Keyword: %s</string>
|
||||||
<string name="export_succeeded">Export configuration succeeded!</string>
|
<string name="export_succeeded">Export configuration succeeded!</string>
|
||||||
@ -1194,6 +1197,15 @@
|
|||||||
<string name="task_charge_tips">Trigger when charge status meets condition.</string>
|
<string name="task_charge_tips">Trigger when charge status meets condition.</string>
|
||||||
<string name="task_lock_screen">Screen Off/On</string>
|
<string name="task_lock_screen">Screen Off/On</string>
|
||||||
<string name="task_lock_screen_tips">Trigger upon screen lock/unlock instantly or after a set time.</string>
|
<string name="task_lock_screen_tips">Trigger upon screen lock/unlock instantly or after a set time.</string>
|
||||||
|
<string name="task_sms">SMS</string>
|
||||||
|
<string name="task_sms_tips">Triggered upon receiving SMS broadcast</string>
|
||||||
|
<string name="task_sms_when">received SMS broadcast from %s</string>
|
||||||
|
<string name="task_call">Call</string>
|
||||||
|
<string name="task_call_tips">Triggered upon receiving call broadcast</string>
|
||||||
|
<string name="task_call_when">received call broadcast from %s</string>
|
||||||
|
<string name="task_app">Notification</string>
|
||||||
|
<string name="task_app_tips">Triggered upon receiving app notification</string>
|
||||||
|
<string name="task_app_when">received app notification</string>
|
||||||
<string name="task_sendsms">Send Sms</string>
|
<string name="task_sendsms">Send Sms</string>
|
||||||
<string name="task_notification">Notify</string>
|
<string name="task_notification">Notify</string>
|
||||||
<string name="task_frpc">Frpc On/Off</string>
|
<string name="task_frpc">Frpc On/Off</string>
|
||||||
@ -1322,6 +1334,8 @@
|
|||||||
<string name="condition_already_exists">This type of condition already exists.</string>
|
<string name="condition_already_exists">This type of condition already exists.</string>
|
||||||
<string name="action_already_exists">This type of action already exists.</string>
|
<string name="action_already_exists">This type of action already exists.</string>
|
||||||
<string name="only_one_location_condition">"To Address" vs "Leave Address": mutually exclusive.</string>
|
<string name="only_one_location_condition">"To Address" vs "Leave Address": mutually exclusive.</string>
|
||||||
|
<string name="only_one_msg_condition">SMS/CALL/APP: mutually exclusive.</string>
|
||||||
|
<string name="msg_condition_must_be_trigger">SMS/CALL/APP: must be used as trigger.</string>
|
||||||
<string name="current_address">Current Address: %s</string>
|
<string name="current_address">Current Address: %s</string>
|
||||||
<string name="location_failed">Location failed. Please try again later.</string>
|
<string name="location_failed">Location failed. Please try again later.</string>
|
||||||
<string name="current_distance_from_center">, %s meters from the center.</string>
|
<string name="current_distance_from_center">, %s meters from the center.</string>
|
||||||
@ -1385,4 +1399,9 @@
|
|||||||
<string name="alarm_play_times">Play Times(0=Infinite)</string>
|
<string name="alarm_play_times">Play Times(0=Infinite)</string>
|
||||||
|
|
||||||
<string name="invalid_tag">%s tag is invalid: %s</string>
|
<string name="invalid_tag">%s tag is invalid: %s</string>
|
||||||
|
<string name="invalid_task_name">Please input task name.</string>
|
||||||
|
<string name="invalid_conditions">Please add trigger conditions.</string>
|
||||||
|
<string name="invalid_actions">Please add execution actions.</string>
|
||||||
|
<string name="invalid_cron">Please set the time for the scheduled task</string>
|
||||||
|
<string name="invalid_proxy_host">Proxy server hostname resolution failed: proxyHost=%s</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -170,6 +170,7 @@
|
|||||||
<string name="test">测试</string>
|
<string name="test">测试</string>
|
||||||
<string name="confirm">确认</string>
|
<string name="confirm">确认</string>
|
||||||
<string name="all">全部</string>
|
<string name="all">全部</string>
|
||||||
|
<string name="any">任意</string>
|
||||||
<string name="select">选择</string>
|
<string name="select">选择</string>
|
||||||
<string name="clone">一键克隆</string>
|
<string name="clone">一键克隆</string>
|
||||||
<string name="setting">通用设置</string>
|
<string name="setting">通用设置</string>
|
||||||
@ -235,7 +236,7 @@
|
|||||||
<string name="add_frpc_first">请先去设置FRPC页面添加</string>
|
<string name="add_frpc_first">请先去设置FRPC页面添加</string>
|
||||||
<string name="add_task_first">请先去设置自动任务页面添加</string>
|
<string name="add_task_first">请先去设置自动任务页面添加</string>
|
||||||
<string name="select_sender">发送通道</string>
|
<string name="select_sender">发送通道</string>
|
||||||
<string name="rule_tester">转发规则测试</string>
|
<string name="rule_tester">规则匹配测试</string>
|
||||||
<string name="test_sim_slot">测试模拟的接收卡槽</string>
|
<string name="test_sim_slot">测试模拟的接收卡槽</string>
|
||||||
<string name="test_phone_number">测试模拟的来源号码</string>
|
<string name="test_phone_number">测试模拟的来源号码</string>
|
||||||
<string name="test_msg_content">测试模拟的短信内容</string>
|
<string name="test_msg_content">测试模拟的短信内容</string>
|
||||||
@ -641,6 +642,7 @@
|
|||||||
<string name="rule_call">来电</string>
|
<string name="rule_call">来电</string>
|
||||||
<string name="rule_app">应用</string>
|
<string name="rule_app">应用</string>
|
||||||
<string name="rule_all">全部</string>
|
<string name="rule_all">全部</string>
|
||||||
|
<string name="rule_any">任意</string>
|
||||||
<string name="rule_transpond_all">全部转发</string>
|
<string name="rule_transpond_all">全部转发</string>
|
||||||
<string name="rule_phone_num">手机号</string>
|
<string name="rule_phone_num">手机号</string>
|
||||||
<string name="rule_msg_content">内容</string>
|
<string name="rule_msg_content">内容</string>
|
||||||
@ -998,6 +1000,7 @@
|
|||||||
<string name="contact_info" formatted="false">姓名:%s\n号码:%s</string>
|
<string name="contact_info" formatted="false">姓名:%s\n号码:%s</string>
|
||||||
<string name="card_slot_does_not_match">卡槽未匹配中规则</string>
|
<string name="card_slot_does_not_match">卡槽未匹配中规则</string>
|
||||||
<string name="unmatched_rule">未匹配中规则</string>
|
<string name="unmatched_rule">未匹配中规则</string>
|
||||||
|
<string name="matched_rule">匹配中规则</string>
|
||||||
<string name="copied_to_clipboard">已复制到剪贴板:\n%s</string>
|
<string name="copied_to_clipboard">已复制到剪贴板:\n%s</string>
|
||||||
<string name="search_keyword">搜索关键字: %s</string>
|
<string name="search_keyword">搜索关键字: %s</string>
|
||||||
<string name="export_succeeded">导出配置成功!</string>
|
<string name="export_succeeded">导出配置成功!</string>
|
||||||
@ -1045,7 +1048,7 @@
|
|||||||
<string name="enable_cactus">启用 Cactus 增强保活措施(会增加耗电)</string>
|
<string name="enable_cactus">启用 Cactus 增强保活措施(会增加耗电)</string>
|
||||||
<string name="enabe_cactus_tips">双进程前台服务/JobScheduler/WorkManager/1像素/无声音乐</string>
|
<string name="enabe_cactus_tips">双进程前台服务/JobScheduler/WorkManager/1像素/无声音乐</string>
|
||||||
<string name="load_app_list">启动时异步获取已安装App列表</string>
|
<string name="load_app_list">启动时异步获取已安装App列表</string>
|
||||||
<string name="load_app_list_tips">用于加速进入应用列表/编辑转发规则下拉选择/替换{{APP名称}}</string>
|
<string name="load_app_list_tips">用于加速进入应用列表/编辑转发规则下拉选择/替换{{APP_NAME}}</string>
|
||||||
<string name="load_app_list_toast">开启异步获取已安装App列表时必选一个类型</string>
|
<string name="load_app_list_toast">开启异步获取已安装App列表时必选一个类型</string>
|
||||||
<string name="no_server_history">暂无历史记录,接口测试通过后自动加入</string>
|
<string name="no_server_history">暂无历史记录,接口测试通过后自动加入</string>
|
||||||
<string name="select_time_period">时间段选择</string>
|
<string name="select_time_period">时间段选择</string>
|
||||||
@ -1195,6 +1198,15 @@
|
|||||||
<string name="task_charge_tips">当充电状态满足条件时触发</string>
|
<string name="task_charge_tips">当充电状态满足条件时触发</string>
|
||||||
<string name="task_lock_screen">锁屏解锁</string>
|
<string name="task_lock_screen">锁屏解锁</string>
|
||||||
<string name="task_lock_screen_tips">在屏幕锁定或解锁后立即或指定时间触发</string>
|
<string name="task_lock_screen_tips">在屏幕锁定或解锁后立即或指定时间触发</string>
|
||||||
|
<string name="task_sms">短信广播</string>
|
||||||
|
<string name="task_sms_tips">在接收到短信广播时触发</string>
|
||||||
|
<string name="task_sms_when">接收到%s短信广播</string>
|
||||||
|
<string name="task_call">通话广播</string>
|
||||||
|
<string name="task_call_tips">在接收到通话广播时触发</string>
|
||||||
|
<string name="task_call_when">接收到%s通话广播</string>
|
||||||
|
<string name="task_app">APP通知</string>
|
||||||
|
<string name="task_app_tips">在接收到APP通知时触发</string>
|
||||||
|
<string name="task_app_when">接收到APP通知</string>
|
||||||
<string name="task_sendsms">发送短信</string>
|
<string name="task_sendsms">发送短信</string>
|
||||||
<string name="task_notification">推送通知</string>
|
<string name="task_notification">推送通知</string>
|
||||||
<string name="task_frpc">启停Frpc</string>
|
<string name="task_frpc">启停Frpc</string>
|
||||||
@ -1323,6 +1335,8 @@
|
|||||||
<string name="condition_already_exists">已添加过该类型条件</string>
|
<string name="condition_already_exists">已添加过该类型条件</string>
|
||||||
<string name="action_already_exists">已添加过该类型动作</string>
|
<string name="action_already_exists">已添加过该类型动作</string>
|
||||||
<string name="only_one_location_condition">进入地点 与 离开地点 类型条件互斥</string>
|
<string name="only_one_location_condition">进入地点 与 离开地点 类型条件互斥</string>
|
||||||
|
<string name="only_one_msg_condition">短信广播/通话广播/APP通知 类型条件互斥</string>
|
||||||
|
<string name="msg_condition_must_be_trigger">短信广播/通话广播/APP通知 类型条件只能作为触发条件</string>
|
||||||
<string name="current_address">当前地址:%s</string>
|
<string name="current_address">当前地址:%s</string>
|
||||||
<string name="location_failed">定位失败,请稍后重试</string>
|
<string name="location_failed">定位失败,请稍后重试</string>
|
||||||
<string name="current_distance_from_center">, 当前距离中心%s米</string>
|
<string name="current_distance_from_center">, 当前距离中心%s米</string>
|
||||||
@ -1386,4 +1400,9 @@
|
|||||||
<string name="alarm_play_times">播放次数(0=无限)</string>
|
<string name="alarm_play_times">播放次数(0=无限)</string>
|
||||||
|
|
||||||
<string name="invalid_tag">%s 标签无效:%s</string>
|
<string name="invalid_tag">%s 标签无效:%s</string>
|
||||||
|
<string name="invalid_task_name">请输入任务名称</string>
|
||||||
|
<string name="invalid_conditions">请添加触发条件</string>
|
||||||
|
<string name="invalid_actions">请添加执行动作</string>
|
||||||
|
<string name="invalid_cron">请设置定时任务的时间</string>
|
||||||
|
<string name="invalid_proxy_host">代理服务器主机名解析失败:proxyHost=%s</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -170,6 +170,7 @@
|
|||||||
<string name="test">測試</string>
|
<string name="test">測試</string>
|
||||||
<string name="confirm">確認</string>
|
<string name="confirm">確認</string>
|
||||||
<string name="all">全部</string>
|
<string name="all">全部</string>
|
||||||
|
<string name="any">任意</string>
|
||||||
<string name="select">選擇</string>
|
<string name="select">選擇</string>
|
||||||
<string name="clone">一鍵克隆</string>
|
<string name="clone">一鍵克隆</string>
|
||||||
<string name="setting">通用設置</string>
|
<string name="setting">通用設置</string>
|
||||||
@ -235,7 +236,7 @@
|
|||||||
<string name="add_frpc_first">請先去設置FRPC頁面添加</string>
|
<string name="add_frpc_first">請先去設置FRPC頁面添加</string>
|
||||||
<string name="add_task_first">請先去設置自動任務頁面添加</string>
|
<string name="add_task_first">請先去設置自動任務頁面添加</string>
|
||||||
<string name="select_sender">發送通道</string>
|
<string name="select_sender">發送通道</string>
|
||||||
<string name="rule_tester">轉發規則測試</string>
|
<string name="rule_tester">規則匹配測試</string>
|
||||||
<string name="test_sim_slot">測試模擬的接收卡槽</string>
|
<string name="test_sim_slot">測試模擬的接收卡槽</string>
|
||||||
<string name="test_phone_number">測試模擬的來源號碼</string>
|
<string name="test_phone_number">測試模擬的來源號碼</string>
|
||||||
<string name="test_msg_content">測試模擬的簡訊內容</string>
|
<string name="test_msg_content">測試模擬的簡訊內容</string>
|
||||||
@ -641,6 +642,7 @@
|
|||||||
<string name="rule_call">來電</string>
|
<string name="rule_call">來電</string>
|
||||||
<string name="rule_app">應用</string>
|
<string name="rule_app">應用</string>
|
||||||
<string name="rule_all">全部</string>
|
<string name="rule_all">全部</string>
|
||||||
|
<string name="rule_any">任意</string>
|
||||||
<string name="rule_transpond_all">全部轉發</string>
|
<string name="rule_transpond_all">全部轉發</string>
|
||||||
<string name="rule_phone_num">手機號</string>
|
<string name="rule_phone_num">手機號</string>
|
||||||
<string name="rule_msg_content">內容</string>
|
<string name="rule_msg_content">內容</string>
|
||||||
@ -998,6 +1000,7 @@
|
|||||||
<string name="contact_info" formatted="false">姓名:%s\n號碼:%s</string>
|
<string name="contact_info" formatted="false">姓名:%s\n號碼:%s</string>
|
||||||
<string name="card_slot_does_not_match">卡槽未匹配中規則</string>
|
<string name="card_slot_does_not_match">卡槽未匹配中規則</string>
|
||||||
<string name="unmatched_rule">未匹配中規則</string>
|
<string name="unmatched_rule">未匹配中規則</string>
|
||||||
|
<string name="matched_rule">匹配中規則</string>
|
||||||
<string name="copied_to_clipboard">已複製到剪貼板:\n%s</string>
|
<string name="copied_to_clipboard">已複製到剪貼板:\n%s</string>
|
||||||
<string name="search_keyword">搜索關鍵字: %s</string>
|
<string name="search_keyword">搜索關鍵字: %s</string>
|
||||||
<string name="export_succeeded">導出配置成功!</string>
|
<string name="export_succeeded">導出配置成功!</string>
|
||||||
@ -1045,7 +1048,7 @@
|
|||||||
<string name="enable_cactus">啟用 Cactus 增強保活措施(會增加耗電)</string>
|
<string name="enable_cactus">啟用 Cactus 增強保活措施(會增加耗電)</string>
|
||||||
<string name="enabe_cactus_tips">雙進程前台服務/JobScheduler/WorkManager/1像素/無聲音樂</string>
|
<string name="enabe_cactus_tips">雙進程前台服務/JobScheduler/WorkManager/1像素/無聲音樂</string>
|
||||||
<string name="load_app_list">啟動時異步獲取已安裝App列表</string>
|
<string name="load_app_list">啟動時異步獲取已安裝App列表</string>
|
||||||
<string name="load_app_list_tips">用於加速進入應用列表/編輯轉發規則下拉選擇/替換{{APP名稱}}</string>
|
<string name="load_app_list_tips">用於加速進入應用列表/編輯轉發規則下拉選擇/替換{{APP_NAME}}</string>
|
||||||
<string name="load_app_list_toast">開啟異步獲取已安裝App列表時必選一個類型</string>
|
<string name="load_app_list_toast">開啟異步獲取已安裝App列表時必選一個類型</string>
|
||||||
<string name="no_server_history">暫無歷史記錄,接口測試通過後自動加入</string>
|
<string name="no_server_history">暫無歷史記錄,接口測試通過後自動加入</string>
|
||||||
<string name="select_time_period">時間段選擇</string>
|
<string name="select_time_period">時間段選擇</string>
|
||||||
@ -1195,6 +1198,15 @@
|
|||||||
<string name="task_charge_tips">當充電狀態滿足條件時觸發</string>
|
<string name="task_charge_tips">當充電狀態滿足條件時觸發</string>
|
||||||
<string name="task_lock_screen">鎖屏解鎖</string>
|
<string name="task_lock_screen">鎖屏解鎖</string>
|
||||||
<string name="task_lock_screen_tips">在屏幕鎖定或解鎖後立即或指定時間觸發</string>
|
<string name="task_lock_screen_tips">在屏幕鎖定或解鎖後立即或指定時間觸發</string>
|
||||||
|
<string name="task_sms">簡訊廣播</string>
|
||||||
|
<string name="task_sms_tips">在接收到簡訊廣播時觸發</string>
|
||||||
|
<string name="task_sms_when">接收到%s簡訊廣播</string>
|
||||||
|
<string name="task_call">通話廣播</string>
|
||||||
|
<string name="task_call_tips">在接收到通話廣播時觸發</string>
|
||||||
|
<string name="task_call_when">接收到%s通話廣播</string>
|
||||||
|
<string name="task_app">APP通知</string>
|
||||||
|
<string name="task_app_tips">在接收到APP通知時觸發</string>
|
||||||
|
<string name="task_app_when">接收到APP通知</string>
|
||||||
<string name="task_sendsms">發送簡訊</string>
|
<string name="task_sendsms">發送簡訊</string>
|
||||||
<string name="task_notification">推送通知</string>
|
<string name="task_notification">推送通知</string>
|
||||||
<string name="task_frpc">啟停Frpc</string>
|
<string name="task_frpc">啟停Frpc</string>
|
||||||
@ -1322,7 +1334,9 @@
|
|||||||
<string name="leave_address_keyword_description">離開GPS地址包含[%s]關鍵字區域</string>
|
<string name="leave_address_keyword_description">離開GPS地址包含[%s]關鍵字區域</string>
|
||||||
<string name="condition_already_exists">已添加過該類型條件</string>
|
<string name="condition_already_exists">已添加過該類型條件</string>
|
||||||
<string name="action_already_exists">已添加過該類型動作</string>
|
<string name="action_already_exists">已添加過該類型動作</string>
|
||||||
<string name="only_one_location_condition">進入地點與離開地點類型條件互斥</string>
|
<string name="only_one_location_condition">進入地點 與 離開地點 類型條件互斥</string>
|
||||||
|
<string name="only_one_msg_condition">簡訊廣播/通話廣播/APP通知 類型條件互斥</string>
|
||||||
|
<string name="msg_condition_must_be_trigger">簡訊廣播/通話廣播/APP通知 類型條件只能作為觸發條件</string>
|
||||||
<string name="current_address">當前地址:%s</string>
|
<string name="current_address">當前地址:%s</string>
|
||||||
<string name="location_failed">定位失敗,請稍後重試</string>
|
<string name="location_failed">定位失敗,請稍後重試</string>
|
||||||
<string name="current_distance_from_center">, 當前距離中心%s米</string>
|
<string name="current_distance_from_center">, 當前距離中心%s米</string>
|
||||||
@ -1386,4 +1400,9 @@
|
|||||||
<string name="alarm_play_times">播放次數(0=無限)</string>
|
<string name="alarm_play_times">播放次數(0=無限)</string>
|
||||||
|
|
||||||
<string name="invalid_tag">%s 標籤無效:%s</string>
|
<string name="invalid_tag">%s 標籤無效:%s</string>
|
||||||
|
<string name="invalid_task_name">請輸入任務名稱</string>
|
||||||
|
<string name="invalid_conditions">請添加觸發條件</string>
|
||||||
|
<string name="invalid_actions">請添加執行動作</string>
|
||||||
|
<string name="invalid_cron">請設置定時任務的時間</string>
|
||||||
|
<string name="invalid_proxy_host">代理伺服器主機名解析失敗:proxyHost=%s</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -170,6 +170,7 @@
|
|||||||
<string name="test">测试</string>
|
<string name="test">测试</string>
|
||||||
<string name="confirm">确认</string>
|
<string name="confirm">确认</string>
|
||||||
<string name="all">全部</string>
|
<string name="all">全部</string>
|
||||||
|
<string name="any">任意</string>
|
||||||
<string name="select">选择</string>
|
<string name="select">选择</string>
|
||||||
<string name="clone">一键克隆</string>
|
<string name="clone">一键克隆</string>
|
||||||
<string name="setting">通用设置</string>
|
<string name="setting">通用设置</string>
|
||||||
@ -235,7 +236,7 @@
|
|||||||
<string name="add_frpc_first">请先去设置Frpc页面添加</string>
|
<string name="add_frpc_first">请先去设置Frpc页面添加</string>
|
||||||
<string name="add_task_first">请先去设置自动任务页面添加</string>
|
<string name="add_task_first">请先去设置自动任务页面添加</string>
|
||||||
<string name="select_sender">发送通道</string>
|
<string name="select_sender">发送通道</string>
|
||||||
<string name="rule_tester">转发规则测试</string>
|
<string name="rule_tester">规则匹配测试</string>
|
||||||
<string name="test_sim_slot">测试模拟的接收卡槽</string>
|
<string name="test_sim_slot">测试模拟的接收卡槽</string>
|
||||||
<string name="test_phone_number">测试模拟的来源号码</string>
|
<string name="test_phone_number">测试模拟的来源号码</string>
|
||||||
<string name="test_msg_content">测试模拟的短信内容</string>
|
<string name="test_msg_content">测试模拟的短信内容</string>
|
||||||
@ -641,6 +642,7 @@
|
|||||||
<string name="rule_call">来电</string>
|
<string name="rule_call">来电</string>
|
||||||
<string name="rule_app">应用</string>
|
<string name="rule_app">应用</string>
|
||||||
<string name="rule_all">全部</string>
|
<string name="rule_all">全部</string>
|
||||||
|
<string name="rule_any">任意</string>
|
||||||
<string name="rule_transpond_all">全部转发</string>
|
<string name="rule_transpond_all">全部转发</string>
|
||||||
<string name="rule_phone_num">手机号</string>
|
<string name="rule_phone_num">手机号</string>
|
||||||
<string name="rule_msg_content">内容</string>
|
<string name="rule_msg_content">内容</string>
|
||||||
@ -998,6 +1000,7 @@
|
|||||||
<string name="contact_info" formatted="false">姓名:%s\n号码:%s</string>
|
<string name="contact_info" formatted="false">姓名:%s\n号码:%s</string>
|
||||||
<string name="card_slot_does_not_match">卡槽未匹配中规则</string>
|
<string name="card_slot_does_not_match">卡槽未匹配中规则</string>
|
||||||
<string name="unmatched_rule">未匹配中规则</string>
|
<string name="unmatched_rule">未匹配中规则</string>
|
||||||
|
<string name="matched_rule">匹配中规则</string>
|
||||||
<string name="copied_to_clipboard">已复制到剪贴板:\n%s</string>
|
<string name="copied_to_clipboard">已复制到剪贴板:\n%s</string>
|
||||||
<string name="search_keyword">搜索关键字: %s</string>
|
<string name="search_keyword">搜索关键字: %s</string>
|
||||||
<string name="export_succeeded">导出配置成功!</string>
|
<string name="export_succeeded">导出配置成功!</string>
|
||||||
@ -1045,7 +1048,7 @@
|
|||||||
<string name="enable_cactus">启用 Cactus 增强保活措施(会增加耗电)</string>
|
<string name="enable_cactus">启用 Cactus 增强保活措施(会增加耗电)</string>
|
||||||
<string name="enabe_cactus_tips">双进程前台服务/JobScheduler/WorkManager/1像素/无声音乐</string>
|
<string name="enabe_cactus_tips">双进程前台服务/JobScheduler/WorkManager/1像素/无声音乐</string>
|
||||||
<string name="load_app_list">启动时异步获取已安装App列表</string>
|
<string name="load_app_list">启动时异步获取已安装App列表</string>
|
||||||
<string name="load_app_list_tips">用于加速进入应用列表/编辑转发规则下拉选择/替换{{APP名称}}</string>
|
<string name="load_app_list_tips">用于加速进入应用列表/编辑转发规则下拉选择/替换{{APP_NAME}}</string>
|
||||||
<string name="load_app_list_toast">开启异步获取已安装App列表时必选一个类型</string>
|
<string name="load_app_list_toast">开启异步获取已安装App列表时必选一个类型</string>
|
||||||
<string name="no_server_history">暂无历史记录,接口测试通过后自动加入</string>
|
<string name="no_server_history">暂无历史记录,接口测试通过后自动加入</string>
|
||||||
<string name="select_time_period">时间段选择</string>
|
<string name="select_time_period">时间段选择</string>
|
||||||
@ -1195,6 +1198,15 @@
|
|||||||
<string name="task_charge_tips">当充电状态满足条件时触发</string>
|
<string name="task_charge_tips">当充电状态满足条件时触发</string>
|
||||||
<string name="task_lock_screen">锁屏解锁</string>
|
<string name="task_lock_screen">锁屏解锁</string>
|
||||||
<string name="task_lock_screen_tips">在屏幕锁定或解锁后立即或指定时间触发</string>
|
<string name="task_lock_screen_tips">在屏幕锁定或解锁后立即或指定时间触发</string>
|
||||||
|
<string name="task_sms">短信广播</string>
|
||||||
|
<string name="task_sms_tips">在接收到短信广播时触发</string>
|
||||||
|
<string name="task_sms_when">接收到%s短信广播</string>
|
||||||
|
<string name="task_call">通话广播</string>
|
||||||
|
<string name="task_call_tips">在接收到通话广播时触发</string>
|
||||||
|
<string name="task_call_when">接收到%s通话广播</string>
|
||||||
|
<string name="task_app">APP通知</string>
|
||||||
|
<string name="task_app_tips">在接收到APP通知时触发</string>
|
||||||
|
<string name="task_app_when">接收到APP通知</string>
|
||||||
<string name="task_sendsms">发送短信</string>
|
<string name="task_sendsms">发送短信</string>
|
||||||
<string name="task_notification">推送通知</string>
|
<string name="task_notification">推送通知</string>
|
||||||
<string name="task_frpc">启停Frpc</string>
|
<string name="task_frpc">启停Frpc</string>
|
||||||
@ -1323,6 +1335,8 @@
|
|||||||
<string name="condition_already_exists">已添加过该类型条件</string>
|
<string name="condition_already_exists">已添加过该类型条件</string>
|
||||||
<string name="action_already_exists">已添加过该类型动作</string>
|
<string name="action_already_exists">已添加过该类型动作</string>
|
||||||
<string name="only_one_location_condition">进入地点 与 离开地点 类型条件互斥</string>
|
<string name="only_one_location_condition">进入地点 与 离开地点 类型条件互斥</string>
|
||||||
|
<string name="only_one_msg_condition">短信广播/通话广播/APP通知 类型条件互斥</string>
|
||||||
|
<string name="msg_condition_must_be_trigger">短信广播/通话广播/APP通知 类型条件只能作为触发条件</string>
|
||||||
<string name="current_address">当前地址:%s</string>
|
<string name="current_address">当前地址:%s</string>
|
||||||
<string name="location_failed">定位失败,请稍后重试</string>
|
<string name="location_failed">定位失败,请稍后重试</string>
|
||||||
<string name="current_distance_from_center">, 当前距离中心%s米</string>
|
<string name="current_distance_from_center">, 当前距离中心%s米</string>
|
||||||
@ -1386,4 +1400,9 @@
|
|||||||
<string name="alarm_play_times">播放次数(0=无限)</string>
|
<string name="alarm_play_times">播放次数(0=无限)</string>
|
||||||
|
|
||||||
<string name="invalid_tag">%s 标签无效:%s</string>
|
<string name="invalid_tag">%s 标签无效:%s</string>
|
||||||
|
<string name="invalid_task_name">请输入任务名称</string>
|
||||||
|
<string name="invalid_conditions">请添加触发条件</string>
|
||||||
|
<string name="invalid_actions">请添加执行动作</string>
|
||||||
|
<string name="invalid_cron">请设置定时任务的时间</string>
|
||||||
|
<string name="invalid_proxy_host">代理服务器主机名解析失败:proxyHost=%s</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user