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

This commit is contained in:
pppscn 2023-12-17 23:25:02 +08:00
parent 0faa6bf26a
commit bceebbddd4
43 changed files with 451 additions and 127 deletions

View File

@ -4,23 +4,11 @@ import android.os.Bundle
import androidx.viewbinding.ViewBinding
import com.idormy.sms.forwarder.core.BaseActivity
import com.idormy.sms.forwarder.fragment.ClientFragment
import com.idormy.sms.forwarder.utils.EVENT_TOAST_ERROR
import com.idormy.sms.forwarder.utils.EVENT_TOAST_SUCCESS
import com.idormy.sms.forwarder.utils.XToastUtils
import com.jeremyliao.liveeventbus.LiveEventBus
class ClientActivity : BaseActivity<ViewBinding?>() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
openPage(ClientFragment::class.java)
//替换 Looper.loop() 后再 Toast 形式
LiveEventBus.get(EVENT_TOAST_SUCCESS, String::class.java).observe(this) { msg: String ->
XToastUtils.success(msg)
}
LiveEventBus.get(EVENT_TOAST_ERROR, String::class.java).observe(this) { msg: String ->
XToastUtils.error(msg, 15000)
}
}
}

View File

@ -264,14 +264,6 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(),
LiveEventBus.get(EVENT_UPDATE_RULE_TYPE, String::class.java).observe(this) { type: String ->
ruleType = type
}
//替换 Looper.loop() 后再 Toast 形式
LiveEventBus.get(EVENT_TOAST_SUCCESS, String::class.java).observe(this) { msg: String ->
XToastUtils.success(msg)
}
LiveEventBus.get(EVENT_TOAST_ERROR, String::class.java).observe(this) { msg: String ->
XToastUtils.error(msg, 15000)
}
}
/**

View File

@ -4,23 +4,11 @@ import android.os.Bundle
import androidx.viewbinding.ViewBinding
import com.idormy.sms.forwarder.core.BaseActivity
import com.idormy.sms.forwarder.fragment.TasksFragment
import com.idormy.sms.forwarder.utils.EVENT_TOAST_ERROR
import com.idormy.sms.forwarder.utils.EVENT_TOAST_SUCCESS
import com.idormy.sms.forwarder.utils.XToastUtils
import com.jeremyliao.liveeventbus.LiveEventBus
class TaskActivity : BaseActivity<ViewBinding?>() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
openPage(TasksFragment::class.java)
//替换 Looper.loop() 后再 Toast 形式
LiveEventBus.get(EVENT_TOAST_SUCCESS, String::class.java).observe(this) { msg: String ->
XToastUtils.success(msg)
}
LiveEventBus.get(EVENT_TOAST_ERROR, String::class.java).observe(this) { msg: String ->
XToastUtils.error(msg, 15000)
}
}
}

View File

@ -15,7 +15,7 @@ import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.adapter.TaskPagingAdapter.MyViewHolder
import com.idormy.sms.forwarder.database.entity.Task
import com.idormy.sms.forwarder.databinding.AdapterTasksCardViewListItemBinding
import com.idormy.sms.forwarder.entity.task.TaskSetting
import com.idormy.sms.forwarder.entity.TaskSetting
import com.xuexiang.xutil.data.DateUtils
class TaskPagingAdapter(private val itemClickListener: OnItemClickListener) : PagingDataAdapter<Task, MyViewHolder>(diffCallback) {

View File

@ -12,7 +12,7 @@ import android.widget.TextView
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.entity.task.TaskSetting
import com.idormy.sms.forwarder.entity.TaskSetting
class TaskSettingAdapter(
val itemList: MutableList<TaskSetting>,

View File

@ -5,6 +5,12 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import androidx.viewbinding.ViewBinding
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_SUCCESS
import com.idormy.sms.forwarder.utils.EVENT_TOAST_WARNING
import com.idormy.sms.forwarder.utils.XToastUtils
import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xpage.base.XPageActivity
import com.xuexiang.xpage.base.XPageFragment
import com.xuexiang.xpage.core.CoreSwitchBean
@ -47,6 +53,20 @@ open class BaseActivity<Binding : ViewBinding?> : XPageActivity() {
initStatusBarStyle()
super.onCreate(savedInstanceState)
registerSlideBack()
//用于接收各种事件的吐司
LiveEventBus.get(EVENT_TOAST_ERROR, String::class.java).observe(this) { msg: String ->
XToastUtils.error(msg, 15000)
}
LiveEventBus.get(EVENT_TOAST_SUCCESS, String::class.java).observe(this) { msg: String ->
XToastUtils.success(msg)
}
LiveEventBus.get(EVENT_TOAST_INFO, String::class.java).observe(this) { msg: String ->
XToastUtils.info(msg)
}
LiveEventBus.get(EVENT_TOAST_WARNING, String::class.java).observe(this) { msg: String ->
XToastUtils.warning(msg, 10000)
}
}
/**

View File

@ -1,7 +1,13 @@
package com.idormy.sms.forwarder.database.dao
import androidx.paging.PagingSource
import androidx.room.*
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.RawQuery
import androidx.room.Transaction
import androidx.room.Update
import androidx.sqlite.db.SupportSQLiteQuery
import com.idormy.sms.forwarder.database.entity.Frpc
import io.reactivex.Single
@ -31,6 +37,9 @@ interface FrpcDao {
@Query("SELECT * FROM Frpc where autorun=1")
fun getAutorun(): List<Frpc>
@Query("SELECT * FROM Frpc WHERE uid IN (:uids)")
fun getByUids(uids: List<String>): List<Frpc>
@Query("SELECT * FROM Frpc ORDER BY time DESC")
fun pagingSource(): PagingSource<Int, Frpc>

View File

@ -1,4 +1,4 @@
package com.idormy.sms.forwarder.entity.task
package com.idormy.sms.forwarder.entity
import com.idormy.sms.forwarder.utils.task.TaskUtils
import java.io.Serializable

View File

@ -0,0 +1,9 @@
package com.idormy.sms.forwarder.entity.action
import java.io.Serializable
data class FrpcSetting(
var description: String = "", //描述
var action: String = "start", //动作: start=启动, stop=停止
var uids: String = "", //指定配置UID多个以半角逗号分隔
) : Serializable

View File

@ -0,0 +1,10 @@
package com.idormy.sms.forwarder.entity.action
import java.io.Serializable
data class HttpServerSetting(
var description: String = "", //描述
var action: String = "start", //动作: start=启动, stop=停止
var startUid: String = "", //手机号码
var stopUid: String = "", //短信内容
) : Serializable

View File

@ -1,4 +1,4 @@
package com.idormy.sms.forwarder.entity.task
package com.idormy.sms.forwarder.entity.action
import java.io.Serializable

View File

@ -1,4 +1,4 @@
package com.idormy.sms.forwarder.entity.task
package com.idormy.sms.forwarder.entity.condition
import android.os.BatteryManager
import com.idormy.sms.forwarder.R

View File

@ -1,4 +1,4 @@
package com.idormy.sms.forwarder.entity.task
package com.idormy.sms.forwarder.entity.condition
import android.os.BatteryManager
import com.idormy.sms.forwarder.R

View File

@ -1,4 +1,4 @@
package com.idormy.sms.forwarder.entity.task
package com.idormy.sms.forwarder.entity.condition
import java.io.Serializable

View File

@ -1,4 +1,4 @@
package com.idormy.sms.forwarder.entity.task
package com.idormy.sms.forwarder.entity.condition
import com.idormy.sms.forwarder.R
import java.io.Serializable

View File

@ -1,4 +1,4 @@
package com.idormy.sms.forwarder.entity.task
package com.idormy.sms.forwarder.entity.condition
import android.content.Intent
import com.idormy.sms.forwarder.R

View File

@ -1,4 +1,4 @@
package com.idormy.sms.forwarder.entity.task
package com.idormy.sms.forwarder.entity.condition
import com.idormy.sms.forwarder.R
import com.xuexiang.xutil.resource.ResUtils.getString

View File

@ -1,4 +1,4 @@
package com.idormy.sms.forwarder.entity.task
package com.idormy.sms.forwarder.entity.condition
import com.idormy.sms.forwarder.R
import com.xuexiang.xutil.resource.ResUtils.getString

View File

@ -24,8 +24,8 @@ import com.idormy.sms.forwarder.database.entity.Task
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
import com.idormy.sms.forwarder.database.viewmodel.TaskViewModel
import com.idormy.sms.forwarder.databinding.FragmentTasksEditBinding
import com.idormy.sms.forwarder.entity.task.CronSetting
import com.idormy.sms.forwarder.entity.task.TaskSetting
import com.idormy.sms.forwarder.entity.TaskSetting
import com.idormy.sms.forwarder.entity.condition.CronSetting
import com.idormy.sms.forwarder.service.LocationService
import com.idormy.sms.forwarder.utils.*
import com.idormy.sms.forwarder.utils.task.CronJobScheduler

View File

@ -9,9 +9,10 @@ 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.FragmentTasksActionSendSmsBinding
import com.idormy.sms.forwarder.entity.task.CronSetting
import com.idormy.sms.forwarder.databinding.FragmentTasksActionFrpcBinding
import com.idormy.sms.forwarder.entity.action.FrpcSetting
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_FRPC
@ -26,7 +27,7 @@ import com.xuexiang.xui.widget.actionbar.TitleBar
@Page(name = "Frpc")
@Suppress("PrivatePropertyName")
class FrpcFragment : BaseFragment<FragmentTasksActionSendSmsBinding?>(), View.OnClickListener {
class FrpcFragment : BaseFragment<FragmentTasksActionFrpcBinding?>(), View.OnClickListener {
private val TAG: String = FrpcFragment::class.java.simpleName
private var titleBar: TitleBar? = null
@ -36,7 +37,6 @@ class FrpcFragment : BaseFragment<FragmentTasksActionSendSmsBinding?>(), View.On
@AutoWired(name = KEY_EVENT_DATA_ACTION)
var eventData: String? = null
private var expression = "* * * * * ? *"
private var description = "测试描述"
override fun initArgs() {
@ -46,8 +46,8 @@ class FrpcFragment : BaseFragment<FragmentTasksActionSendSmsBinding?>(), View.On
override fun viewBindingInflate(
inflater: LayoutInflater,
container: ViewGroup,
): FragmentTasksActionSendSmsBinding {
return FragmentTasksActionSendSmsBinding.inflate(inflater, container, false)
): FragmentTasksActionFrpcBinding {
return FragmentTasksActionFrpcBinding.inflate(inflater, container, false)
}
override fun initTitle(): TitleBar? {
@ -71,9 +71,26 @@ class FrpcFragment : BaseFragment<FragmentTasksActionSendSmsBinding?>(), View.On
}
})
binding!!.rgFrpcState.setOnCheckedChangeListener { _, checkedId ->
when (checkedId) {
R.id.rb_start_server -> {
binding!!.layoutStartServer.visibility = View.VISIBLE
binding!!.layoutStopServer.visibility = View.GONE
}
R.id.rb_stop_server -> {
binding!!.layoutStartServer.visibility = View.GONE
binding!!.layoutStopServer.visibility = View.VISIBLE
}
}
}
Log.d(TAG, "initViews eventData:$eventData")
if (eventData != null) {
val settingVo = Gson().fromJson(eventData, CronSetting::class.java)
val settingVo = Gson().fromJson(eventData, FrpcSetting::class.java)
binding!!.etStartUid.setText(settingVo.uids)
binding!!.etStopUid.setText(settingVo.uids)
binding!!.rgFrpcState.check(if (settingVo.action == "start") R.id.rb_start_server else R.id.rb_stop_server)
Log.d(TAG, "initViews settingVo:$settingVo")
}
}
@ -121,6 +138,7 @@ class FrpcFragment : BaseFragment<FragmentTasksActionSendSmsBinding?>(), View.On
R.id.btn_save -> {
val settingVo = checkSetting()
val intent = Intent()
intent.putExtra(KEY_BACK_DESCRIPTION_ACTION, description)
intent.putExtra(KEY_BACK_DATA_ACTION, Gson().toJson(settingVo))
setFragmentResult(TASK_ACTION_FRPC, intent)
popToBack()
@ -135,7 +153,20 @@ class FrpcFragment : BaseFragment<FragmentTasksActionSendSmsBinding?>(), View.On
//检查设置
@SuppressLint("SetTextI18n")
private fun checkSetting(): CronSetting {
return CronSetting(description, expression)
private fun checkSetting(): FrpcSetting {
val startUid = binding!!.etStartUid.text.toString().trim()
val stopUid = binding!!.etStopUid.text.toString().trim()
val action: String
val uids: String
if (binding!!.rgFrpcState.checkedRadioButtonId == R.id.rb_start_server) {
description = if (startUid == "") "启动全部自启动的Frpc" else "启动UID为${startUid}的Frpc"
action = "start"
uids = startUid
} else {
description = if (stopUid == "") "停止全部自启动的Frpc" else "停止UID为${stopUid}的Frpc"
action = "stop"
uids = stopUid
}
return FrpcSetting(description, action, uids)
}
}

View File

@ -10,7 +10,7 @@ import com.google.gson.Gson
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.databinding.FragmentTasksActionSendSmsBinding
import com.idormy.sms.forwarder.entity.task.CronSetting
import com.idormy.sms.forwarder.entity.condition.CronSetting
import com.idormy.sms.forwarder.utils.KEY_BACK_DATA_ACTION
import com.idormy.sms.forwarder.utils.KEY_EVENT_DATA_ACTION
import com.idormy.sms.forwarder.utils.KEY_TEST_ACTION

View File

@ -18,7 +18,7 @@ import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.databinding.FragmentTasksActionSendSmsBinding
import com.idormy.sms.forwarder.entity.task.SmsSetting
import com.idormy.sms.forwarder.entity.action.SmsSetting
import com.idormy.sms.forwarder.server.model.ConfigData
import com.idormy.sms.forwarder.utils.EVENT_KEY_PHONE_NUMBERS
import com.idormy.sms.forwarder.utils.EVENT_KEY_SIM_SLOT

View File

@ -11,7 +11,7 @@ import com.google.gson.Gson
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.databinding.FragmentTasksConditionBatteryBinding
import com.idormy.sms.forwarder.entity.task.BatterySetting
import com.idormy.sms.forwarder.entity.condition.BatterySetting
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

View File

@ -10,7 +10,7 @@ import com.google.gson.Gson
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.databinding.FragmentTasksConditionChargeBinding
import com.idormy.sms.forwarder.entity.task.ChargeSetting
import com.idormy.sms.forwarder.entity.condition.ChargeSetting
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

View File

@ -14,7 +14,7 @@ import com.google.gson.Gson
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.databinding.FragmentTasksConditionCronBinding
import com.idormy.sms.forwarder.entity.task.CronSetting
import com.idormy.sms.forwarder.entity.condition.CronSetting
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

View File

@ -13,7 +13,7 @@ import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.databinding.FragmentTasksConditionLeaveAddressBinding
import com.idormy.sms.forwarder.entity.task.LocationSetting
import com.idormy.sms.forwarder.entity.condition.LocationSetting
import com.idormy.sms.forwarder.service.LocationService
import com.idormy.sms.forwarder.utils.HttpServerUtils
import com.idormy.sms.forwarder.utils.KEY_BACK_DATA_CONDITION

View File

@ -10,7 +10,7 @@ import com.google.gson.Gson
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.databinding.FragmentTasksConditionLockScreenBinding
import com.idormy.sms.forwarder.entity.task.LockScreenSetting
import com.idormy.sms.forwarder.entity.condition.LockScreenSetting
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

View File

@ -12,7 +12,7 @@ import com.google.gson.Gson
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.databinding.FragmentTasksConditionNetworkBinding
import com.idormy.sms.forwarder.entity.task.NetworkSetting
import com.idormy.sms.forwarder.entity.condition.NetworkSetting
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

View File

@ -10,7 +10,7 @@ import com.google.gson.Gson
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.databinding.FragmentTasksConditionSimBinding
import com.idormy.sms.forwarder.entity.task.SimSetting
import com.idormy.sms.forwarder.entity.condition.SimSetting
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

View File

@ -13,7 +13,7 @@ import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.databinding.FragmentTasksConditionToAddressBinding
import com.idormy.sms.forwarder.entity.task.LocationSetting
import com.idormy.sms.forwarder.entity.condition.LocationSetting
import com.idormy.sms.forwarder.service.LocationService
import com.idormy.sms.forwarder.utils.HttpServerUtils
import com.idormy.sms.forwarder.utils.KEY_BACK_DATA_CONDITION

View File

@ -355,6 +355,8 @@ const val KEY_URL = "key_url"
//吐司监听
const val EVENT_TOAST_SUCCESS = "key_toast_success"
const val EVENT_TOAST_ERROR = "key_toast_error"
const val EVENT_TOAST_INFO = "key_toast_info"
const val EVENT_TOAST_WARNING = "key_toast_warning"
//主页监听时间
const val EVENT_UPDATE_LOGS_TYPE = "key_logs_type"

View File

@ -49,39 +49,20 @@ class SmsCommandUtils {
return false
}
if (TextUtils.isEmpty(param)) {
GlobalScope.async(Dispatchers.IO) {
val frpcList = AppDatabase.getInstance(App.context).frpcDao().getAutorun()
if (frpcList.isEmpty()) {
Log.d(TAG, "没有自启动的Frpc")
return@async
}
for (frpc in frpcList) {
if (action == "start") {
if (!Frpclib.isRunning(frpc.uid)) {
val error = Frpclib.runContent(frpc.uid, frpc.config)
if (!TextUtils.isEmpty(error)) {
Log.e(TAG, error)
}
}
} else if (action == "stop") {
if (Frpclib.isRunning(frpc.uid)) {
Frpclib.close(frpc.uid)
}
}
}
GlobalScope.async(Dispatchers.IO) {
val frpcList = if (param.isEmpty()) {
AppDatabase.getInstance(App.context).frpcDao().getAutorun()
} else {
val uids = param.split(",")
AppDatabase.getInstance(App.context).frpcDao().getByUids(uids)
}
} else {
GlobalScope.async(Dispatchers.IO) {
val frpc = AppDatabase.getInstance(App.context).frpcDao().getOne(param)
if (frpc.uid.isEmpty()) {
Log.d(TAG, "没有找到指定的Frpc")
return@async
}
if (frpcList.isEmpty()) {
Log.d(TAG, "没有需要操作的Frpc")
return@async
}
for (frpc in frpcList) {
if (action == "start") {
if (!Frpclib.isRunning(frpc.uid)) {
val error = Frpclib.runContent(frpc.uid, frpc.config)

View File

@ -3,14 +3,14 @@ package com.idormy.sms.forwarder.utils.task
import android.os.BatteryManager
import android.util.Log
import com.google.gson.Gson
import com.idormy.sms.forwarder.entity.task.BatterySetting
import com.idormy.sms.forwarder.entity.task.ChargeSetting
import com.idormy.sms.forwarder.entity.task.CronSetting
import com.idormy.sms.forwarder.entity.task.LocationSetting
import com.idormy.sms.forwarder.entity.task.LockScreenSetting
import com.idormy.sms.forwarder.entity.task.NetworkSetting
import com.idormy.sms.forwarder.entity.task.SimSetting
import com.idormy.sms.forwarder.entity.task.TaskSetting
import com.idormy.sms.forwarder.entity.TaskSetting
import com.idormy.sms.forwarder.entity.condition.BatterySetting
import com.idormy.sms.forwarder.entity.condition.ChargeSetting
import com.idormy.sms.forwarder.entity.condition.CronSetting
import com.idormy.sms.forwarder.entity.condition.LocationSetting
import com.idormy.sms.forwarder.entity.condition.LockScreenSetting
import com.idormy.sms.forwarder.entity.condition.NetworkSetting
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.TASK_CONDITION_BATTERY
import com.idormy.sms.forwarder.utils.TASK_CONDITION_CHARGE

View File

@ -2,6 +2,7 @@ package com.idormy.sms.forwarder.workers
import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.util.Log
import androidx.core.app.ActivityCompat
@ -10,26 +11,40 @@ import androidx.work.WorkerParameters
import com.google.gson.Gson
import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.database.entity.Rule
import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.task.SmsSetting
import com.idormy.sms.forwarder.entity.task.TaskSetting
import com.idormy.sms.forwarder.entity.TaskSetting
import com.idormy.sms.forwarder.entity.action.FrpcSetting
import com.idormy.sms.forwarder.entity.action.HttpServerSetting
import com.idormy.sms.forwarder.entity.action.SmsSetting
import com.idormy.sms.forwarder.service.HttpServerService
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_SUCCESS
import com.idormy.sms.forwarder.utils.EVENT_TOAST_WARNING
import com.idormy.sms.forwarder.utils.PhoneUtils
import com.idormy.sms.forwarder.utils.SendUtils
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_NOTIFICATION
import com.idormy.sms.forwarder.utils.TASK_ACTION_SENDSMS
import com.idormy.sms.forwarder.utils.TaskWorker
import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xrouter.utils.TextUtils
import com.xuexiang.xui.utils.ResUtils
import com.xuexiang.xutil.XUtil
import com.xuexiang.xutil.file.FileUtils
import frpclib.Frpclib
//执行每个task具体动作任务
@Suppress("PrivatePropertyName", "DEPRECATION")
class ActionWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
private val TAG: String = ActionWorker::class.java.simpleName
private var taskId = -1L
override suspend fun doWork(): Result {
val taskId = inputData.getLong(TaskWorker.taskId, -1L)
taskId = inputData.getLong(TaskWorker.taskId, -1L)
val taskActionsJson = inputData.getString(TaskWorker.taskActions)
val msgInfoJson = inputData.getString(TaskWorker.msgInfo)
Log.d(TAG, "taskId: $taskId, taskActionsJson: $taskActionsJson, msgInfoJson: $msgInfoJson")
@ -40,13 +55,13 @@ class ActionWorker(context: Context, params: WorkerParameters) : CoroutineWorker
val actionList = Gson().fromJson(taskActionsJson, Array<TaskSetting>::class.java).toMutableList()
if (actionList.isEmpty()) {
Log.d(TAG, "任务$taskIdactionList is empty")
writeLog("actionList is empty")
return Result.failure()
}
val msgInfo = Gson().fromJson(msgInfoJson, MsgInfo::class.java)
if (msgInfo == null) {
Log.d(TAG, "任务$taskIdmsgInfo is null")
writeLog("msgInfo is null")
return Result.failure()
}
@ -57,7 +72,7 @@ class ActionWorker(context: Context, params: WorkerParameters) : CoroutineWorker
TASK_ACTION_SENDSMS -> {
val smsSetting = Gson().fromJson(action.setting, SmsSetting::class.java)
if (smsSetting == null) {
Log.d(TAG, "任务$taskIdsmsSetting is null")
writeLog("smsSetting is null")
continue
}
//获取卡槽信息
@ -71,14 +86,14 @@ class ActionWorker(context: Context, params: WorkerParameters) : CoroutineWorker
//TODO取不到卡槽信息时采用默认卡槽发送
val mSubscriptionId: Int = App.SimInfoList[simSlotIndex]?.mSubscriptionId ?: -1
val msg = if (ActivityCompat.checkSelfPermission(XUtil.getContext(), Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) {
val msg = if (ActivityCompat.checkSelfPermission(App.context, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) {
ResUtils.getString(R.string.no_sms_sending_permission)
} else {
PhoneUtils.sendSms(mSubscriptionId, smsSetting.phoneNumbers, smsSetting.msgContent)
successNum++
}
Log.d(TAG, "任务$taskIdsend sms result: $msg")
writeLog("send sms result: $msg")
}
TASK_ACTION_NOTIFICATION -> {
@ -88,17 +103,107 @@ class ActionWorker(context: Context, params: WorkerParameters) : CoroutineWorker
successNum++
}
TASK_ACTION_FRPC -> {
if (!FileUtils.isFileExists(App.context.filesDir?.absolutePath + "/libs/libgojni.so")) {
writeLog("还未下载Frpc库")
continue
}
val frpcSetting = Gson().fromJson(action.setting, FrpcSetting::class.java)
if (frpcSetting == null) {
writeLog("frpcSetting is null")
continue
}
val frpcList = if (frpcSetting.uids.isEmpty()) {
AppDatabase.getInstance(App.context).frpcDao().getAutorun()
} else {
val uids = frpcSetting.uids.split(",")
AppDatabase.getInstance(App.context).frpcDao().getByUids(uids)
}
if (frpcList.isEmpty()) {
writeLog("没有需要操作的Frpc")
continue
}
for (frpc in frpcList) {
if (frpcSetting.action == "start") {
if (!Frpclib.isRunning(frpc.uid)) {
val error = Frpclib.runContent(frpc.uid, frpc.config)
if (!TextUtils.isEmpty(error)) {
Log.e(TAG, error)
}
}
} else if (frpcSetting.action == "stop") {
if (Frpclib.isRunning(frpc.uid)) {
Frpclib.close(frpc.uid)
}
}
}
}
TASK_ACTION_HTTPSERVER -> {
val httpServerSetting = Gson().fromJson(action.setting, HttpServerSetting::class.java)
if (httpServerSetting == null) {
writeLog("httpServerSetting is null")
continue
}
Intent(App.context, HttpServerService::class.java).also {
if (httpServerSetting.action == "start") {
App.context.startService(it)
} else if (httpServerSetting.action == "stop") {
App.context.stopService(it)
}
}
}
else -> {
Log.d(TAG, "任务$taskIdaction.type is ${action.type}")
writeLog("action.type is ${action.type}")
}
}
} catch (e: Exception) {
e.printStackTrace()
Log.d(TAG, "任务$taskIdaction.type is ${action.type}, exception: ${e.message}")
writeLog("action.type is ${action.type}, exception: ${e.message}")
}
}
return if (successNum == actionList.size) Result.success() else Result.failure()
}
private fun writeLog(msg: String, level: String = "DEBUG") {
val key = when (level) {
"INFO" -> {
Log.i(TAG, "TASK-$taskId$msg")
EVENT_TOAST_INFO
}
"WARN" -> {
Log.w(TAG, "TASK-$taskId$msg")
EVENT_TOAST_WARNING
}
"ERROR" -> {
Log.e(TAG, "TASK-$taskId$msg")
EVENT_TOAST_ERROR
}
"SUCCESS" -> {
Log.d(TAG, "TASK-$taskId$msg")
EVENT_TOAST_SUCCESS
}
else -> {
Log.d(TAG, "TASK-$taskId$msg")
""
}
}
if (taskId == 0L && key.isNotEmpty()) {
LiveEventBus.get(key, String::class.java).post(msg)
return
}
//TODO: 写入日志
}
}

View File

@ -11,9 +11,9 @@ import com.google.gson.Gson
import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.task.BatterySetting
import com.idormy.sms.forwarder.entity.task.ChargeSetting
import com.idormy.sms.forwarder.entity.task.TaskSetting
import com.idormy.sms.forwarder.entity.TaskSetting
import com.idormy.sms.forwarder.entity.condition.BatterySetting
import com.idormy.sms.forwarder.entity.condition.ChargeSetting
import com.idormy.sms.forwarder.utils.TASK_CONDITION_BATTERY
import com.idormy.sms.forwarder.utils.TASK_CONDITION_CHARGE
import com.idormy.sms.forwarder.utils.TaskWorker

View File

@ -11,8 +11,8 @@ import com.google.gson.Gson
import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.task.CronSetting
import com.idormy.sms.forwarder.entity.task.TaskSetting
import com.idormy.sms.forwarder.entity.TaskSetting
import com.idormy.sms.forwarder.entity.condition.CronSetting
import com.idormy.sms.forwarder.utils.TaskWorker
import com.idormy.sms.forwarder.utils.task.ConditionUtils
import com.idormy.sms.forwarder.utils.task.CronJobScheduler

View File

@ -13,8 +13,8 @@ import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.entity.LocationInfo
import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.task.LocationSetting
import com.idormy.sms.forwarder.entity.task.TaskSetting
import com.idormy.sms.forwarder.entity.TaskSetting
import com.idormy.sms.forwarder.entity.condition.LocationSetting
import com.idormy.sms.forwarder.utils.TASK_CONDITION_LEAVE_ADDRESS
import com.idormy.sms.forwarder.utils.TASK_CONDITION_TO_ADDRESS
import com.idormy.sms.forwarder.utils.TaskWorker

View File

@ -12,8 +12,8 @@ import com.google.gson.Gson
import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.task.LockScreenSetting
import com.idormy.sms.forwarder.entity.task.TaskSetting
import com.idormy.sms.forwarder.entity.TaskSetting
import com.idormy.sms.forwarder.entity.condition.LockScreenSetting
import com.idormy.sms.forwarder.utils.TaskWorker
import com.idormy.sms.forwarder.utils.task.ConditionUtils
import java.util.Date

View File

@ -12,8 +12,8 @@ import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.task.NetworkSetting
import com.idormy.sms.forwarder.entity.task.TaskSetting
import com.idormy.sms.forwarder.entity.TaskSetting
import com.idormy.sms.forwarder.entity.condition.NetworkSetting
import com.idormy.sms.forwarder.utils.PhoneUtils
import com.idormy.sms.forwarder.utils.TaskWorker
import com.idormy.sms.forwarder.utils.task.ConditionUtils

View File

@ -13,8 +13,8 @@ import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.task.SimSetting
import com.idormy.sms.forwarder.entity.task.TaskSetting
import com.idormy.sms.forwarder.entity.TaskSetting
import com.idormy.sms.forwarder.entity.condition.SimSetting
import com.idormy.sms.forwarder.utils.PhoneUtils
import com.idormy.sms.forwarder.utils.TaskWorker
import com.idormy.sms.forwarder.utils.task.ConditionUtils

View File

@ -0,0 +1,181 @@
<?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_frpc"
app:srcCompat="@drawable/auto_task_icon_frpc"
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_frpc"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/task_frpc_tips"
android:textSize="10sp"
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_frpc_state"
style="@style/rg_style"
android:orientation="vertical"
android:paddingBottom="@dimen/config_padding_5dp">
<RadioButton
android:id="@+id/rb_start_server"
style="@style/rg_rb_style_match"
android:checked="true"
android:text="@string/start_server"
tools:ignore="TouchTargetSizeCheck" />
<LinearLayout
android:id="@+id/layout_start_server"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/config_margin_10dp"
android:layout_marginEnd="@dimen/config_margin_10dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/specified_uid"
android:textStyle="bold" />
<EditText
android:id="@+id/et_start_uid"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="5dp"
android:layout_weight="1"
android:hint="@string/specified_uid_hint"
android:importantForAutofill="no"
tools:ignore="TextContrastCheck,TextFields,TouchTargetSizeCheck" />
</LinearLayout>
<RadioButton
android:id="@+id/rb_stop_server"
style="@style/rg_rb_style_match"
android:text="@string/stop_server"
tools:ignore="TouchTargetSizeCheck" />
<LinearLayout
android:id="@+id/layout_stop_server"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/config_margin_10dp"
android:layout_marginEnd="@dimen/config_margin_10dp"
android:orientation="horizontal"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/specified_uid"
android:textStyle="bold" />
<EditText
android:id="@+id/et_stop_uid"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="5dp"
android:layout_weight="1"
android:hint="@string/specified_uid_hint"
android:importantForAutofill="no"
tools:ignore="TextContrastCheck,TextFields,TouchTargetSizeCheck" />
</LinearLayout>
</RadioGroup>
</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"
android:drawableStart="@drawable/icon_delete"
android:paddingStart="15dp"
android:text="@string/discard"
android:textSize="11sp"
tools:ignore="RtlSymmetry,TextContrastCheck,TouchTargetSizeCheck" />
<com.xuexiang.xui.widget.textview.supertextview.SuperButton
android:id="@+id/btn_save"
style="@style/SuperButton.Blue.Icon"
android:layout_marginStart="10dp"
android:drawableStart="@drawable/icon_save"
android:paddingStart="15dp"
android:text="@string/submit"
android:textSize="11sp"
tools:ignore="RtlSymmetry,TextContrastCheck,TouchTargetSizeCheck" />
<com.xuexiang.xui.widget.textview.supertextview.SuperButton
android:id="@+id/btn_test"
style="@style/SuperButton.Green.Icon"
android:layout_marginStart="10dp"
android:drawableStart="@drawable/icon_test"
android:paddingStart="15dp"
android:text="@string/test"
android:textSize="11sp"
tools:ignore="RtlSymmetry,TextContrastCheck,TouchTargetSizeCheck" />
</LinearLayout>
</LinearLayout>

View File

@ -1147,6 +1147,7 @@
<string name="task_sendsms">Send Sms</string>
<string name="task_notification">Notification</string>
<string name="task_frpc">Frpc Setting</string>
<string name="task_frpc_tips">Control the start/stop of FRPC.</string>
<string name="task_server">Server Setting</string>
<string name="second">Second</string>
@ -1252,4 +1253,7 @@
<string name="current_address">Current Address: %s</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="specified_uid">Specified Uid</string>
<string name="specified_uid_hint">Enter FRPC config UIDs, separate with commas.</string>
</resources>

View File

@ -1148,6 +1148,7 @@
<string name="task_sendsms">发送短信</string>
<string name="task_notification">通道推送</string>
<string name="task_frpc">Frpc设置</string>
<string name="task_frpc_tips">控制内网穿透·FRPC的启动/停止</string>
<string name="task_server">HttpServer设置</string>
<string name="second"></string>
@ -1253,4 +1254,7 @@
<string name="current_address">当前地址:%s</string>
<string name="location_failed">定位失败,请稍后重试</string>
<string name="current_distance_from_center">, 当前距离中心%s米</string>
<string name="specified_uid">指定配置</string>
<string name="specified_uid_hint">填写frpc的uid多个以半角逗号分隔</string>
</resources>