新增:自动任务·快捷指令 (开发中)

This commit is contained in:
pppscn 2023-12-20 23:12:11 +08:00
parent 06ce0112a9
commit a6d1a13d44
16 changed files with 949 additions and 20 deletions

View File

@ -0,0 +1,8 @@
package com.idormy.sms.forwarder.entity.action
import java.io.Serializable
data class CleanerSetting(
var description: String = "", //描述
var days: Int = 0, //自动删除N天前的转发记录
) : Serializable

View File

@ -1,10 +1,18 @@
package com.idormy.sms.forwarder.entity.action package com.idormy.sms.forwarder.entity.action
import com.idormy.sms.forwarder.utils.HttpServerUtils
import java.io.Serializable import java.io.Serializable
data class HttpServerSetting( data class HttpServerSetting(
var description: String = "", //描述 var description: String = "", //描述
var action: String = "start", //动作: start=启动, stop=停止 var action: String = "start", //动作: start=启动, stop=停止
var startUid: String = "", //手机号码 var enableApiClone: Boolean = HttpServerUtils.enableApiClone, //是否启用一键克隆
var stopUid: String = "", //短信内容 var enableApiSmsSend: Boolean = HttpServerUtils.enableApiSmsSend, //是否启用远程发短信
var enableApiSmsQuery: Boolean = HttpServerUtils.enableApiSmsQuery, //是否启用远程查短信
var enableApiCallQuery: Boolean = HttpServerUtils.enableApiCallQuery, //是否启用远程查通话记录
var enableApiContactQuery: Boolean = HttpServerUtils.enableApiContactQuery, //是否启用远程查联系人
var enableApiContactAdd: Boolean = HttpServerUtils.enableApiContactAdd, //是否启用远程加联系人
var enableApiWol: Boolean = HttpServerUtils.enableApiWol, //是否启用远程WOL
var enableApiLocation: Boolean = HttpServerUtils.enableApiLocation, //是否启用远程找手机
var enableApiBatteryQuery: Boolean = HttpServerUtils.enableApiBatteryQuery, //是否启用远程查电量
) : Serializable ) : Serializable

View File

@ -166,12 +166,19 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
R.drawable.auto_task_icon_frpc R.drawable.auto_task_icon_frpc
), ),
PageInfo( PageInfo(
getString(R.string.task_server), getString(R.string.task_http_server),
"com.idormy.sms.forwarder.fragment.action.HttpServerFragment", "com.idormy.sms.forwarder.fragment.action.HttpServerFragment",
"{\"\":\"\"}", "{\"\":\"\"}",
CoreAnim.slide, CoreAnim.slide,
R.drawable.auto_task_icon_http_server R.drawable.auto_task_icon_http_server
), ),
PageInfo(
getString(R.string.task_cleaner),
"com.idormy.sms.forwarder.fragment.action.CleanerFragment",
"{\"\":\"\"}",
CoreAnim.slide,
R.drawable.auto_task_icon_cleaner
),
) )
override fun initArgs() { override fun initArgs() {

View File

@ -0,0 +1,144 @@
package com.idormy.sms.forwarder.fragment.action
import android.annotation.SuppressLint
import android.content.Intent
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.gson.Gson
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.databinding.FragmentTasksActionCleanerBinding
import com.idormy.sms.forwarder.entity.action.CleanerSetting
import com.idormy.sms.forwarder.utils.KEY_BACK_DATA_ACTION
import com.idormy.sms.forwarder.utils.KEY_BACK_DESCRIPTION_ACTION
import com.idormy.sms.forwarder.utils.KEY_EVENT_DATA_ACTION
import com.idormy.sms.forwarder.utils.KEY_TEST_ACTION
import com.idormy.sms.forwarder.utils.TASK_ACTION_CLEANER
import com.idormy.sms.forwarder.utils.XToastUtils
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.xui.utils.CountDownButtonHelper
import com.xuexiang.xui.widget.actionbar.TitleBar
@Page(name = "Cleaner")
@Suppress("PrivatePropertyName")
class CleanerFragment : BaseFragment<FragmentTasksActionCleanerBinding?>(), View.OnClickListener {
private val TAG: String = CleanerFragment::class.java.simpleName
private var titleBar: TitleBar? = null
private var mCountDownHelper: CountDownButtonHelper? = null
@JvmField
@AutoWired(name = KEY_EVENT_DATA_ACTION)
var eventData: String? = null
override fun initArgs() {
XRouter.getInstance().inject(this)
}
override fun viewBindingInflate(
inflater: LayoutInflater,
container: ViewGroup,
): FragmentTasksActionCleanerBinding {
return FragmentTasksActionCleanerBinding.inflate(inflater, container, false)
}
override fun initTitle(): TitleBar? {
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.task_cleaner)
return titleBar
}
/**
* 初始化控件
*/
override fun initViews() {
//测试按钮增加倒计时,避免重复点击
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, 3)
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
override fun onCountDown(time: Int) {
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
}
override fun onFinished() {
binding!!.btnTest.text = getString(R.string.test)
}
})
var settingVo = CleanerSetting(getString(R.string.task_cleaner_tips), 0)
Log.d(TAG, "initViews eventData:$eventData")
if (eventData != null) {
settingVo = Gson().fromJson(eventData, CleanerSetting::class.java)
Log.d(TAG, "initViews settingVo:$settingVo")
}
binding!!.xsbDays.setDefaultValue(settingVo.days)
}
@SuppressLint("SetTextI18n")
override fun initListeners() {
binding!!.btnTest.setOnClickListener(this)
binding!!.btnDel.setOnClickListener(this)
binding!!.btnSave.setOnClickListener(this)
LiveEventBus.get(KEY_TEST_ACTION, String::class.java).observe(this) {
mCountDownHelper?.finish()
if (it == "success") {
XToastUtils.success("测试通过", 30000)
} else {
XToastUtils.error(it, 30000)
}
}
}
@SingleClick
override fun onClick(v: View) {
try {
when (v.id) {
R.id.btn_test -> {
mCountDownHelper?.start()
Thread {
try {
val settingVo = checkSetting()
Log.d(TAG, settingVo.toString())
LiveEventBus.get(KEY_TEST_ACTION, String::class.java).post("success")
} catch (e: Exception) {
LiveEventBus.get(KEY_TEST_ACTION, String::class.java).post(e.message.toString())
e.printStackTrace()
}
}.start()
return
}
R.id.btn_del -> {
popToBack()
return
}
R.id.btn_save -> {
val settingVo = checkSetting()
val intent = Intent()
intent.putExtra(KEY_BACK_DESCRIPTION_ACTION, settingVo.description)
intent.putExtra(KEY_BACK_DATA_ACTION, Gson().toJson(settingVo))
setFragmentResult(TASK_ACTION_CLEANER, intent)
popToBack()
return
}
}
} catch (e: Exception) {
XToastUtils.error(e.message.toString(), 30000)
e.printStackTrace()
}
}
//检查设置
@SuppressLint("SetTextI18n")
private fun checkSetting(): CleanerSetting {
val days = binding!!.xsbDays.selectedNumber
val description = "自动删除${days}天前的转发记录"
return CleanerSetting(description, days)
}
}

View File

@ -9,9 +9,10 @@ import android.view.ViewGroup
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.databinding.FragmentTasksActionSendSmsBinding import com.idormy.sms.forwarder.databinding.FragmentTasksActionHttpServerBinding
import com.idormy.sms.forwarder.entity.condition.CronSetting import com.idormy.sms.forwarder.entity.action.HttpServerSetting
import com.idormy.sms.forwarder.utils.KEY_BACK_DATA_ACTION import com.idormy.sms.forwarder.utils.KEY_BACK_DATA_ACTION
import com.idormy.sms.forwarder.utils.KEY_BACK_DESCRIPTION_ACTION
import com.idormy.sms.forwarder.utils.KEY_EVENT_DATA_ACTION import com.idormy.sms.forwarder.utils.KEY_EVENT_DATA_ACTION
import com.idormy.sms.forwarder.utils.KEY_TEST_ACTION import com.idormy.sms.forwarder.utils.KEY_TEST_ACTION
import com.idormy.sms.forwarder.utils.TASK_ACTION_HTTPSERVER import com.idormy.sms.forwarder.utils.TASK_ACTION_HTTPSERVER
@ -26,7 +27,7 @@ import com.xuexiang.xui.widget.actionbar.TitleBar
@Page(name = "HttpServer") @Page(name = "HttpServer")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName")
class HttpServerFragment : BaseFragment<FragmentTasksActionSendSmsBinding?>(), View.OnClickListener { class HttpServerFragment : BaseFragment<FragmentTasksActionHttpServerBinding?>(), View.OnClickListener {
private val TAG: String = HttpServerFragment::class.java.simpleName private val TAG: String = HttpServerFragment::class.java.simpleName
private var titleBar: TitleBar? = null private var titleBar: TitleBar? = null
@ -36,9 +37,6 @@ class HttpServerFragment : BaseFragment<FragmentTasksActionSendSmsBinding?>(), V
@AutoWired(name = KEY_EVENT_DATA_ACTION) @AutoWired(name = KEY_EVENT_DATA_ACTION)
var eventData: String? = null var eventData: String? = null
private var expression = "* * * * * ? *"
private var description = "测试描述"
override fun initArgs() { override fun initArgs() {
XRouter.getInstance().inject(this) XRouter.getInstance().inject(this)
} }
@ -46,12 +44,12 @@ class HttpServerFragment : BaseFragment<FragmentTasksActionSendSmsBinding?>(), V
override fun viewBindingInflate( override fun viewBindingInflate(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup, container: ViewGroup,
): FragmentTasksActionSendSmsBinding { ): FragmentTasksActionHttpServerBinding {
return FragmentTasksActionSendSmsBinding.inflate(inflater, container, false) return FragmentTasksActionHttpServerBinding.inflate(inflater, container, false)
} }
override fun initTitle(): TitleBar? { override fun initTitle(): TitleBar? {
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.task_server) titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.task_http_server)
return titleBar return titleBar
} }
@ -72,10 +70,21 @@ class HttpServerFragment : BaseFragment<FragmentTasksActionSendSmsBinding?>(), V
}) })
Log.d(TAG, "initViews eventData:$eventData") Log.d(TAG, "initViews eventData:$eventData")
var settingVo = HttpServerSetting(getString(R.string.task_http_server_tips))
if (eventData != null) { if (eventData != null) {
val settingVo = Gson().fromJson(eventData, CronSetting::class.java) settingVo = Gson().fromJson(eventData, HttpServerSetting::class.java)
Log.d(TAG, "initViews settingVo:$settingVo") Log.d(TAG, "initViews settingVo:$settingVo")
} }
binding!!.rgHttpServerState.check(if (settingVo.action == "start") R.id.rb_start_server else R.id.rb_stop_server)
binding!!.sbApiClone.isChecked = settingVo.enableApiClone
binding!!.sbApiQuerySms.isChecked = settingVo.enableApiSmsQuery
binding!!.sbApiSendSms.isChecked = settingVo.enableApiSmsSend
binding!!.sbApiQueryCall.isChecked = settingVo.enableApiCallQuery
binding!!.sbApiQueryContacts.isChecked = settingVo.enableApiContactQuery
binding!!.sbApiAddContacts.isChecked = settingVo.enableApiContactAdd
binding!!.sbApiWol.isChecked = settingVo.enableApiWol
binding!!.sbApiLocation.isChecked = settingVo.enableApiLocation
binding!!.sbApiQueryBattery.isChecked = settingVo.enableApiBatteryQuery
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
@ -121,6 +130,7 @@ class HttpServerFragment : BaseFragment<FragmentTasksActionSendSmsBinding?>(), V
R.id.btn_save -> { R.id.btn_save -> {
val settingVo = checkSetting() val settingVo = checkSetting()
val intent = Intent() val intent = Intent()
intent.putExtra(KEY_BACK_DESCRIPTION_ACTION, settingVo.description)
intent.putExtra(KEY_BACK_DATA_ACTION, Gson().toJson(settingVo)) intent.putExtra(KEY_BACK_DATA_ACTION, Gson().toJson(settingVo))
setFragmentResult(TASK_ACTION_HTTPSERVER, intent) setFragmentResult(TASK_ACTION_HTTPSERVER, intent)
popToBack() popToBack()
@ -135,7 +145,52 @@ class HttpServerFragment : BaseFragment<FragmentTasksActionSendSmsBinding?>(), V
//检查设置 //检查设置
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
private fun checkSetting(): CronSetting { private fun checkSetting(): HttpServerSetting {
return CronSetting(description, expression) val enableList = mutableListOf<String>()
val disableList = mutableListOf<String>()
val enableApiClone = binding!!.sbApiClone.isChecked
if (enableApiClone) enableList.add(getString(R.string.api_clone)) else disableList.add(getString(R.string.api_clone))
val enableApiSmsSend = binding!!.sbApiSendSms.isChecked
if (enableApiSmsSend) enableList.add(getString(R.string.api_sms_query)) else disableList.add(getString(R.string.api_sms_query))
val enableApiSmsQuery = binding!!.sbApiQuerySms.isChecked
if (enableApiSmsQuery) enableList.add(getString(R.string.api_sms_send)) else disableList.add(getString(R.string.api_sms_send))
val enableApiCallQuery = binding!!.sbApiQueryCall.isChecked
if (enableApiCallQuery) enableList.add(getString(R.string.api_call_query)) else disableList.add(getString(R.string.api_call_query))
val enableApiContactQuery = binding!!.sbApiQueryContacts.isChecked
if (enableApiContactQuery) enableList.add(getString(R.string.api_contact_query)) else disableList.add(getString(R.string.api_contact_query))
val enableApiContactAdd = binding!!.sbApiAddContacts.isChecked
if (enableApiContactAdd) enableList.add(getString(R.string.api_contact_add)) else disableList.add(getString(R.string.api_contact_add))
val enableApiWol = binding!!.sbApiWol.isChecked
if (enableApiWol) enableList.add(getString(R.string.api_wol)) else disableList.add(getString(R.string.api_wol))
val enableApiLocation = binding!!.sbApiLocation.isChecked
if (enableApiLocation) enableList.add(getString(R.string.api_location)) else disableList.add(getString(R.string.api_location))
val enableApiBatteryQuery = binding!!.sbApiQueryBattery.isChecked
if (enableApiBatteryQuery) enableList.add(getString(R.string.api_battery_query)) else disableList.add(getString(R.string.api_battery_query))
val description = StringBuilder()
val action = if (binding!!.rgHttpServerState.checkedRadioButtonId == R.id.rb_start_server) {
description.append(getString(R.string.start_server))
if (enableList.isNotEmpty()) {
description.append(", ").append(getString(R.string.enable_function)).append(": ").append(enableList.joinToString("/"))
}
if (disableList.isNotEmpty()) {
description.append(", ").append(getString(R.string.disable_function)).append(": ").append(disableList.joinToString("/"))
}
"start"
} else {
description.append(getString(R.string.stop_server))
"stop"
}
return HttpServerSetting(description.toString(), action, enableApiClone, enableApiSmsSend, enableApiSmsQuery, enableApiCallQuery, enableApiContactQuery, enableApiContactAdd, enableApiWol, enableApiLocation, enableApiBatteryQuery)
} }
} }

View File

@ -18,6 +18,7 @@ import com.idormy.sms.forwarder.utils.SP_NETWORK_STATE
import com.idormy.sms.forwarder.utils.SP_SIM_STATE import com.idormy.sms.forwarder.utils.SP_SIM_STATE
import com.idormy.sms.forwarder.utils.SP_WIFI_SSID import com.idormy.sms.forwarder.utils.SP_WIFI_SSID
import com.idormy.sms.forwarder.utils.SharedPreference import com.idormy.sms.forwarder.utils.SharedPreference
import com.idormy.sms.forwarder.utils.TASK_ACTION_CLEANER
import com.idormy.sms.forwarder.utils.TASK_ACTION_FRPC import com.idormy.sms.forwarder.utils.TASK_ACTION_FRPC
import com.idormy.sms.forwarder.utils.TASK_ACTION_HTTPSERVER import com.idormy.sms.forwarder.utils.TASK_ACTION_HTTPSERVER
import com.idormy.sms.forwarder.utils.TASK_ACTION_NOTIFICATION import com.idormy.sms.forwarder.utils.TASK_ACTION_NOTIFICATION
@ -53,6 +54,7 @@ class TaskUtils private constructor() {
TASK_ACTION_NOTIFICATION -> R.drawable.auto_task_icon_sender TASK_ACTION_NOTIFICATION -> R.drawable.auto_task_icon_sender
TASK_ACTION_FRPC -> R.drawable.auto_task_icon_frpc TASK_ACTION_FRPC -> R.drawable.auto_task_icon_frpc
TASK_ACTION_HTTPSERVER -> R.drawable.auto_task_icon_http_server TASK_ACTION_HTTPSERVER -> R.drawable.auto_task_icon_http_server
TASK_ACTION_CLEANER -> R.drawable.auto_task_icon_cleaner
else -> R.drawable.auto_task_icon_custom_time else -> R.drawable.auto_task_icon_custom_time
} }
} }
@ -72,6 +74,7 @@ class TaskUtils private constructor() {
TASK_ACTION_NOTIFICATION -> R.drawable.auto_task_icon_sender_grey TASK_ACTION_NOTIFICATION -> R.drawable.auto_task_icon_sender_grey
TASK_ACTION_FRPC -> R.drawable.auto_task_icon_frpc_grey TASK_ACTION_FRPC -> R.drawable.auto_task_icon_frpc_grey
TASK_ACTION_HTTPSERVER -> R.drawable.auto_task_icon_http_server_grey TASK_ACTION_HTTPSERVER -> R.drawable.auto_task_icon_http_server_grey
TASK_ACTION_CLEANER -> R.drawable.auto_task_icon_cleaner_grey
else -> R.drawable.auto_task_icon_custom_time_grey else -> R.drawable.auto_task_icon_custom_time_grey
} }
} }

View File

@ -11,20 +11,26 @@ import androidx.work.WorkerParameters
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.App import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.Core
import com.idormy.sms.forwarder.database.AppDatabase import com.idormy.sms.forwarder.database.AppDatabase
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.entity.TaskSetting
import com.idormy.sms.forwarder.entity.action.CleanerSetting
import com.idormy.sms.forwarder.entity.action.FrpcSetting import com.idormy.sms.forwarder.entity.action.FrpcSetting
import com.idormy.sms.forwarder.entity.action.HttpServerSetting import com.idormy.sms.forwarder.entity.action.HttpServerSetting
import com.idormy.sms.forwarder.entity.action.SmsSetting import com.idormy.sms.forwarder.entity.action.SmsSetting
import com.idormy.sms.forwarder.service.HttpServerService import com.idormy.sms.forwarder.service.HttpServerService
import com.idormy.sms.forwarder.utils.CacheUtils
import com.idormy.sms.forwarder.utils.EVENT_TOAST_ERROR import com.idormy.sms.forwarder.utils.EVENT_TOAST_ERROR
import com.idormy.sms.forwarder.utils.EVENT_TOAST_INFO import com.idormy.sms.forwarder.utils.EVENT_TOAST_INFO
import com.idormy.sms.forwarder.utils.EVENT_TOAST_SUCCESS import com.idormy.sms.forwarder.utils.EVENT_TOAST_SUCCESS
import com.idormy.sms.forwarder.utils.EVENT_TOAST_WARNING import com.idormy.sms.forwarder.utils.EVENT_TOAST_WARNING
import com.idormy.sms.forwarder.utils.HistoryUtils
import com.idormy.sms.forwarder.utils.HttpServerUtils
import com.idormy.sms.forwarder.utils.PhoneUtils import com.idormy.sms.forwarder.utils.PhoneUtils
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.TASK_ACTION_CLEANER
import com.idormy.sms.forwarder.utils.TASK_ACTION_FRPC import com.idormy.sms.forwarder.utils.TASK_ACTION_FRPC
import com.idormy.sms.forwarder.utils.TASK_ACTION_HTTPSERVER import com.idormy.sms.forwarder.utils.TASK_ACTION_HTTPSERVER
import com.idormy.sms.forwarder.utils.TASK_ACTION_NOTIFICATION import com.idormy.sms.forwarder.utils.TASK_ACTION_NOTIFICATION
@ -35,6 +41,7 @@ import com.xuexiang.xrouter.utils.TextUtils
import com.xuexiang.xutil.file.FileUtils import com.xuexiang.xutil.file.FileUtils
import com.xuexiang.xutil.resource.ResUtils.getString import com.xuexiang.xutil.resource.ResUtils.getString
import frpclib.Frpclib import frpclib.Frpclib
import java.util.Calendar
//执行每个task具体动作任务 //执行每个task具体动作任务
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName")
@ -153,6 +160,16 @@ class ActionWorker(context: Context, params: WorkerParameters) : CoroutineWorker
writeLog("httpServerSetting is null") writeLog("httpServerSetting is null")
continue continue
} }
HttpServerUtils.enableApiClone = httpServerSetting.enableApiClone
HttpServerUtils.enableApiSmsQuery = httpServerSetting.enableApiSmsQuery
HttpServerUtils.enableApiSmsSend = httpServerSetting.enableApiSmsSend
HttpServerUtils.enableApiCallQuery = httpServerSetting.enableApiCallQuery
HttpServerUtils.enableApiContactQuery = httpServerSetting.enableApiContactQuery
HttpServerUtils.enableApiContactAdd = httpServerSetting.enableApiContactAdd
HttpServerUtils.enableApiWol = httpServerSetting.enableApiWol
HttpServerUtils.enableApiLocation = httpServerSetting.enableApiLocation
HttpServerUtils.enableApiBatteryQuery = httpServerSetting.enableApiBatteryQuery
Intent(App.context, HttpServerService::class.java).also { Intent(App.context, HttpServerService::class.java).also {
if (httpServerSetting.action == "start") { if (httpServerSetting.action == "start") {
App.context.startService(it) App.context.startService(it)
@ -165,6 +182,27 @@ class ActionWorker(context: Context, params: WorkerParameters) : CoroutineWorker
writeLog("httpServer success", "SUCCESS") writeLog("httpServer success", "SUCCESS")
} }
TASK_ACTION_CLEANER -> {
val cleanerSetting = Gson().fromJson(action.setting, CleanerSetting::class.java)
if (cleanerSetting == null) {
writeLog("cleanerSetting is null")
continue
}
if (cleanerSetting.days > 0) {
val cal = Calendar.getInstance()
cal.add(Calendar.DAY_OF_MONTH, 0 - cleanerSetting.days)
Core.msg.deleteTimeAgo(cal.timeInMillis)
} else {
Core.msg.deleteAll()
}
//清理缓存
HistoryUtils.clearPreference()
CacheUtils.clearAllCache(App.context)
successNum++
writeLog("cleaner success", "SUCCESS")
}
else -> { else -> {
writeLog("action.type is ${action.type}") writeLog("action.type is ${action.type}")
} }

View File

@ -32,7 +32,7 @@ class CronWorker(context: Context, params: WorkerParameters) : CoroutineWorker(c
} }
val task = AppDatabase.getInstance(App.context).taskDao().getOne(taskId) val task = AppDatabase.getInstance(App.context).taskDao().getOne(taskId)
if (task.status == 0) { if (task == null || task.status == 0) {
Log.d(TAG, "TASK-${task.id}task is disabled") Log.d(TAG, "TASK-${task.id}task is disabled")
return Result.success() return Result.success()
} }

View File

@ -0,0 +1,32 @@
<?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="@color/color_green_primary_default"
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" />
<group
android:scaleX="0.02"
android:scaleY="0.02"
android:translateX="2.5"
android:translateY="2.5">
<path
android:fillColor="#ffffff"
android:pathData="M710.6,398.3l-84.8,-84.8 183.9,-183.9c23.4,-23.4 61.4,-23.4 84.8,0l0,0c23.4,23.4 23.4,61.4 0,84.8L710.6,398.3z" />
<path
android:fillColor="#ffffff"
android:pathData="M711.5,571.8L451.5,311.8c62.4,-62.4 163.6,-62.4 226.1,0l33.9,33.9c62.4,62.4 62.4,163.6 0,226.1zM411.1,359.2L664.3,612.4c1.9,1.9 2.3,4.7 0.9,7 -13.7,21.9 -82.7,137.8 -101.2,291a1.8,1.8 0,0 1,-2.6 1.4l-86,-51.8c-0.8,-0.5 -1.1,-1.5 -0.7,-2.3 8.1,-16.9 85.5,-179 77.6,-171.1 -8.3,8.3 -61.9,65.2 -102,123.3l-23.1,31.8s-90.5,-60.9 -118.4,-98.8c-0.4,-0.6 -0.5,-1.1 0,-1.6 18.4,-22.3 114.1,-146.7 114.1,-146.7l-162.7,97.6c-0.8,0.4 -1.6,0.3 -2.2,-0.3 -7.9,-8.8 -62.2,-68.8 -77.9,-97 -0.3,-0.6 -0.3,-1.1 0.3,-1.6 15.5,-12.5 103.1,-86.7 103.1,-86.7l-123.3,43.7c-0.9,0.3 -1.8,-0.1 -2.2,-0.9l-45.6,-85.6c-0.6,-1 -0.2,-2.3 1,-2.5 21.7,-4.3 202.9,-42 290.8,-102.7 2.2,-1.5 5.1,-1.2 7,0.8z" />
<path
android:fillColor="#ffffff"
android:pathData="M356,248m-52,0a52,52 0,1 0,104 0,52 52,0 1,0 -104,0Z" />
<path
android:fillColor="#ffffff"
android:pathData="M680,808m-64,0a64,64 0,1 0,128 0,64 64,0 1,0 -128,0Z" />
<path
android:fillColor="#ffffff"
android:pathData="M800,736m-36,0a36,36 0,1 0,72 0,36 36,0 1,0 -72,0Z" />
</group>
</vector>

View File

@ -0,0 +1,32 @@
<?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="@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" />
<group
android:scaleX="0.02"
android:scaleY="0.02"
android:translateX="2.5"
android:translateY="2.5">
<path
android:fillColor="@color/auto_task_icon_grey"
android:pathData="M710.6,398.3l-84.8,-84.8 183.9,-183.9c23.4,-23.4 61.4,-23.4 84.8,0l0,0c23.4,23.4 23.4,61.4 0,84.8L710.6,398.3z" />
<path
android:fillColor="@color/auto_task_icon_grey"
android:pathData="M711.5,571.8L451.5,311.8c62.4,-62.4 163.6,-62.4 226.1,0l33.9,33.9c62.4,62.4 62.4,163.6 0,226.1zM411.1,359.2L664.3,612.4c1.9,1.9 2.3,4.7 0.9,7 -13.7,21.9 -82.7,137.8 -101.2,291a1.8,1.8 0,0 1,-2.6 1.4l-86,-51.8c-0.8,-0.5 -1.1,-1.5 -0.7,-2.3 8.1,-16.9 85.5,-179 77.6,-171.1 -8.3,8.3 -61.9,65.2 -102,123.3l-23.1,31.8s-90.5,-60.9 -118.4,-98.8c-0.4,-0.6 -0.5,-1.1 0,-1.6 18.4,-22.3 114.1,-146.7 114.1,-146.7l-162.7,97.6c-0.8,0.4 -1.6,0.3 -2.2,-0.3 -7.9,-8.8 -62.2,-68.8 -77.9,-97 -0.3,-0.6 -0.3,-1.1 0.3,-1.6 15.5,-12.5 103.1,-86.7 103.1,-86.7l-123.3,43.7c-0.9,0.3 -1.8,-0.1 -2.2,-0.9l-45.6,-85.6c-0.6,-1 -0.2,-2.3 1,-2.5 21.7,-4.3 202.9,-42 290.8,-102.7 2.2,-1.5 5.1,-1.2 7,0.8z" />
<path
android:fillColor="@color/auto_task_icon_grey"
android:pathData="M356,248m-52,0a52,52 0,1 0,104 0,52 52,0 1,0 -104,0Z" />
<path
android:fillColor="@color/auto_task_icon_grey"
android:pathData="M680,808m-64,0a64,64 0,1 0,128 0,64 64,0 1,0 -128,0Z" />
<path
android:fillColor="@color/auto_task_icon_grey"
android:pathData="M800,736m-36,0a36,36 0,1 0,72 0,36 36,0 1,0 -72,0Z" />
</group>
</vector>

View File

@ -0,0 +1,128 @@
<?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:layout_width="120dp"
android:layout_height="120dp"
android:layout_margin="10dp"
android:contentDescription="@string/task_cleaner"
app:srcCompat="@drawable/auto_task_icon_cleaner"
tools:ignore="ImageContrastCheck" />
<LinearLayout
style="@style/taskBarStyle"
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/task_cleaner"
android:textSize="@dimen/text_size_big"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/task_cleaner_tips"
android:textSize="@dimen/text_size_mini"
tools:ignore="SmallSp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:background="?attr/xui_config_color_separator_light" />
<LinearLayout
android:id="@+id/layout_start_server"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.xuexiang.xui.widget.picker.XSeekBar
android:id="@+id/xsb_days"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:xsb_insideRangeLineColor="#0bd97f"
app:xsb_insideRangeLineStrokeWidth="10dp"
app:xsb_isShowBubble="true"
app:xsb_isShowRuler="true"
app:xsb_max="60"
app:xsb_min="0"
app:xsb_numberTextColor="#ffffff"
app:xsb_numberTextSize="@dimen/text_size_small"
app:xsb_outsideRangeLineColor="#f0f0f0"
app:xsb_outsideRangeLineStrokeWidth="10dp"
app:xsb_rulerColor="@color/xui_config_color_gray_4"
app:xsb_rulerInterval="ten" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:text="@string/day"
android:textSize="12sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</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>

View File

@ -0,0 +1,458 @@
<?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:layout_width="120dp"
android:layout_height="120dp"
android:layout_margin="10dp"
android:contentDescription="@string/task_http_server"
app:srcCompat="@drawable/auto_task_icon_http_server"
tools:ignore="ImageContrastCheck" />
<LinearLayout
style="@style/taskBarStyle"
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/task_http_server"
android:textSize="@dimen/text_size_big"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/task_http_server_tips"
android:textSize="@dimen/text_size_mini"
tools:ignore="SmallSp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:background="?attr/xui_config_color_separator_light" />
<RadioGroup
android:id="@+id/rg_http_server_state"
style="@style/rg_style"
android:orientation="horizontal"
android:paddingBottom="@dimen/config_padding_5dp">
<RadioButton
android:id="@+id/rb_start_server"
style="@style/rg_rb_style"
android:checked="true"
android:text="@string/start_server"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton
android:id="@+id/rb_stop_server"
style="@style/rg_rb_style"
android:text="@string/stop_server"
tools:ignore="TouchTargetSizeCheck" />
</RadioGroup>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="5dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/enable_function"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="@string/enable_function_tips"
android:textSize="@dimen/text_size_mini"
tools:ignore="SmallSp" />
</LinearLayout>
<LinearLayout
style="@style/settingBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_clone"
android:textStyle="bold"
tools:ignore="RelativeOverlap" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_clone_tips"
android:textSize="@dimen/text_size_mini"
tools:ignore="SmallSp" />
</LinearLayout>
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
android:id="@+id/sb_api_clone"
style="@style/SwitchButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
style="@style/settingBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_sms_query"
android:textStyle="bold"
tools:ignore="RelativeOverlap" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_sms_query_tips"
android:textSize="@dimen/text_size_mini"
tools:ignore="SmallSp" />
</LinearLayout>
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
android:id="@+id/sb_api_query_sms"
style="@style/SwitchButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
style="@style/settingBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_sms_send"
android:textStyle="bold"
tools:ignore="RelativeOverlap" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_sms_send_tips"
android:textSize="@dimen/text_size_mini"
tools:ignore="SmallSp" />
</LinearLayout>
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
android:id="@+id/sb_api_send_sms"
style="@style/SwitchButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
style="@style/settingBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_call_query"
android:textStyle="bold"
tools:ignore="RelativeOverlap" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_call_query_tips"
android:textSize="@dimen/text_size_mini"
tools:ignore="SmallSp" />
</LinearLayout>
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
android:id="@+id/sb_api_query_call"
style="@style/SwitchButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
style="@style/settingBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_contact_query"
android:textStyle="bold"
tools:ignore="RelativeOverlap" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_contact_query_tips"
android:textSize="@dimen/text_size_mini"
tools:ignore="SmallSp" />
</LinearLayout>
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
android:id="@+id/sb_api_query_contacts"
style="@style/SwitchButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
style="@style/settingBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:ignore="TooManyViews">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_contact_add"
android:textStyle="bold"
tools:ignore="RelativeOverlap" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_contact_add_tips"
android:textSize="@dimen/text_size_mini"
tools:ignore="SmallSp" />
</LinearLayout>
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
android:id="@+id/sb_api_add_contacts"
style="@style/SwitchButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
style="@style/settingBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_wol"
android:textStyle="bold"
tools:ignore="RelativeOverlap,TooManyViews" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_wol_tips"
android:textSize="@dimen/text_size_mini"
tools:ignore="SmallSp" />
</LinearLayout>
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
android:id="@+id/sb_api_wol"
style="@style/SwitchButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
style="@style/settingBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_location"
android:textStyle="bold"
tools:ignore="RelativeOverlap,TooManyViews" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_location_tips"
android:textSize="@dimen/text_size_mini"
tools:ignore="SmallSp" />
</LinearLayout>
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
android:id="@+id/sb_api_location"
style="@style/SwitchButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
style="@style/settingBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:ignore="TooManyViews">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_battery_query"
android:textStyle="bold"
tools:ignore="RelativeOverlap" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_battery_query_tips"
android:textSize="@dimen/text_size_mini"
tools:ignore="SmallSp" />
</LinearLayout>
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
android:id="@+id/sb_api_query_battery"
style="@style/SwitchButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</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>

View File

@ -897,6 +897,7 @@
<string name="copy" tools:ignore="PrivateResource">Copy</string> <string name="copy" tools:ignore="PrivateResource">Copy</string>
<string name="random">Random</string> <string name="random">Random</string>
<string name="enable_function">Enable Function</string> <string name="enable_function">Enable Function</string>
<string name="disable_function">Disable Function</string>
<string name="enable_function_tips">Select the features you want to enable remote control as needed</string> <string name="enable_function_tips">Select the features you want to enable remote control as needed</string>
<string name="api_clone">OneKey Clone</string> <string name="api_clone">OneKey Clone</string>
<string name="api_clone_tips">One-click cloning of the general config of the machine, sender, and rules to the new machine</string> <string name="api_clone_tips">One-click cloning of the general config of the machine, sender, and rules to the new machine</string>
@ -1169,7 +1170,10 @@
<string name="task_notification">Notification</string> <string name="task_notification">Notification</string>
<string name="task_frpc">Frpc Setting</string> <string name="task_frpc">Frpc Setting</string>
<string name="task_frpc_tips">Control the start/stop of FRPC.</string> <string name="task_frpc_tips">Control the start/stop of FRPC.</string>
<string name="task_server">Server Setting</string> <string name="task_http_server">Server Setting</string>
<string name="task_http_server_tips">Manage HttpServer start/stop and enable/disable functions</string>
<string name="task_cleaner">Cleaner</string>
<string name="task_cleaner_tips">Delete FW. logs older than N days, delete cache, etc.</string>
<string name="second">Second</string> <string name="second">Second</string>
<string name="minute">Minute</string> <string name="minute">Minute</string>

View File

@ -898,6 +898,7 @@
<string name="rsa_key_tips2">已复制公钥到剪贴板</string> <string name="rsa_key_tips2">已复制公钥到剪贴板</string>
<string name="sign_key_tips">已生成密钥,并复制到剪贴板</string> <string name="sign_key_tips">已生成密钥,并复制到剪贴板</string>
<string name="enable_function">启用功能</string> <string name="enable_function">启用功能</string>
<string name="disable_function">禁用功能</string>
<string name="enable_function_tips">按需选择您要启用远程控制的功能</string> <string name="enable_function_tips">按需选择您要启用远程控制的功能</string>
<string name="api_clone">一键换新机</string> <string name="api_clone">一键换新机</string>
<string name="api_clone_tips">一键克隆本机的通用配置、发送通道、转发规则到新机器</string> <string name="api_clone_tips">一键克隆本机的通用配置、发送通道、转发规则到新机器</string>
@ -1170,7 +1171,10 @@
<string name="task_notification">通道推送</string> <string name="task_notification">通道推送</string>
<string name="task_frpc">Frpc设置</string> <string name="task_frpc">Frpc设置</string>
<string name="task_frpc_tips">控制内网穿透·FRPC的启动/停止</string> <string name="task_frpc_tips">控制内网穿透·FRPC的启动/停止</string>
<string name="task_server">HttpServer设置</string> <string name="task_http_server">HttpServer设置</string>
<string name="task_http_server_tips">控制HttpServer的启动/停止,并支持启用/禁用功能</string>
<string name="task_cleaner">清理日志</string>
<string name="task_cleaner_tips">批量删除N天前的转发记录、删除缓存等</string>
<string name="second"></string> <string name="second"></string>
<string name="minute"></string> <string name="minute"></string>

View File

@ -898,6 +898,7 @@
<string name="rsa_key_tips2">已複製公鑰到剪貼板</string> <string name="rsa_key_tips2">已複製公鑰到剪貼板</string>
<string name="sign_key_tips">已生成密鑰,並複製到剪貼板</string> <string name="sign_key_tips">已生成密鑰,並複製到剪貼板</string>
<string name="enable_function">啟用功能</string> <string name="enable_function">啟用功能</string>
<string name="disable_function">禁用功能</string>
<string name="enable_function_tips">按需選擇您要啟用遠程控制的功能</string> <string name="enable_function_tips">按需選擇您要啟用遠程控制的功能</string>
<string name="api_clone">一鍵換新機</string> <string name="api_clone">一鍵換新機</string>
<string name="api_clone_tips">一鍵克隆本機的通用配置、發送通道、轉發規則到新機器</string> <string name="api_clone_tips">一鍵克隆本機的通用配置、發送通道、轉發規則到新機器</string>
@ -1170,7 +1171,10 @@
<string name="task_notification">通道推送</string> <string name="task_notification">通道推送</string>
<string name="task_frpc">Frpc設置</string> <string name="task_frpc">Frpc設置</string>
<string name="task_frpc_tips">控制內網穿透·FRPC的啟動/停止</string> <string name="task_frpc_tips">控制內網穿透·FRPC的啟動/停止</string>
<string name="task_server">HttpServer設置</string> <string name="task_http_server">HttpServer設置</string>
<string name="task_http_server_tips">控制HttpServer的啟動/停止,並支持啟用/禁用功能</string>
<string name="task_cleaner">清理日誌</string>
<string name="task_cleaner_tips">批量刪除N天前的轉發記錄、刪除快取等</string>
<string name="second"></string> <string name="second"></string>
<string name="minute"></string> <string name="minute"></string>

View File

@ -898,6 +898,7 @@
<string name="rsa_key_tips2">已复制公钥到剪贴板</string> <string name="rsa_key_tips2">已复制公钥到剪贴板</string>
<string name="sign_key_tips">已生成密钥,并复制到剪贴板</string> <string name="sign_key_tips">已生成密钥,并复制到剪贴板</string>
<string name="enable_function">启用功能</string> <string name="enable_function">启用功能</string>
<string name="disable_function">禁用功能</string>
<string name="enable_function_tips">按需选择您要启用远程控制的功能</string> <string name="enable_function_tips">按需选择您要启用远程控制的功能</string>
<string name="api_clone">一键换新机</string> <string name="api_clone">一键换新机</string>
<string name="api_clone_tips">一键克隆本机的通用配置、发送通道、转发规则到新机器</string> <string name="api_clone_tips">一键克隆本机的通用配置、发送通道、转发规则到新机器</string>
@ -1170,7 +1171,10 @@
<string name="task_notification">通道推送</string> <string name="task_notification">通道推送</string>
<string name="task_frpc">Frpc设置</string> <string name="task_frpc">Frpc设置</string>
<string name="task_frpc_tips">控制内网穿透·FRPC的启动/停止</string> <string name="task_frpc_tips">控制内网穿透·FRPC的启动/停止</string>
<string name="task_server">HttpServer设置</string> <string name="task_http_server">HttpServer设置</string>
<string name="task_http_server_tips">控制HttpServer的启动/停止,并支持启用/禁用功能</string>
<string name="task_cleaner">清理日志</string>
<string name="task_cleaner_tips">批量删除N天前的转发记录、删除缓存等</string>
<string name="second"></string> <string name="second"></string>
<string name="minute"></string> <string name="minute"></string>