新增:自动任务·快捷指令 —— 执行动作:启停任务 #389
This commit is contained in:
parent
2b091bbefe
commit
65ea7bcf0c
|
@ -0,0 +1,104 @@
|
|||
package com.idormy.sms.forwarder.adapter
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
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.adapter.base.ItemMoveCallback
|
||||
import com.idormy.sms.forwarder.database.entity.Task
|
||||
import java.util.Collections
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
class TaskRecyclerAdapter(
|
||||
var itemList: MutableList<Task>,
|
||||
private var removeClickListener: ((Int) -> Unit)? = null,
|
||||
private var editClickListener: ((Int) -> Unit)? = null,
|
||||
) : RecyclerView.Adapter<TaskRecyclerAdapter.ViewHolder>(), ItemMoveCallback.Listener {
|
||||
|
||||
private lateinit var touchHelper: ItemTouchHelper
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(R.layout.adapter_task_list_item, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val item = itemList[position]
|
||||
holder.bind(item)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = itemList.size
|
||||
|
||||
fun setTouchHelper(touchHelper: ItemTouchHelper) {
|
||||
this@TaskRecyclerAdapter.touchHelper = touchHelper
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
|
||||
private val image: ImageView = itemView.findViewById(R.id.iv_image)
|
||||
private val status: ImageView = itemView.findViewById(R.id.iv_status)
|
||||
private val title: TextView = itemView.findViewById(R.id.tv_title)
|
||||
private val editIcon: ImageView = itemView.findViewById(R.id.iv_edit)
|
||||
private val removeIcon: ImageView = itemView.findViewById(R.id.iv_remove)
|
||||
private val dragIcon: ImageView = itemView.findViewById(R.id.iv_drag)
|
||||
|
||||
init {
|
||||
if (removeClickListener == null) {
|
||||
removeIcon.visibility = View.GONE
|
||||
} else {
|
||||
removeIcon.setOnClickListener(this)
|
||||
}
|
||||
|
||||
if (editClickListener == null) {
|
||||
editIcon.visibility = View.GONE
|
||||
} else {
|
||||
editIcon.setOnClickListener(this)
|
||||
}
|
||||
|
||||
dragIcon.setOnTouchListener { _, event ->
|
||||
if (event.actionMasked == MotionEvent.ACTION_DOWN) {
|
||||
touchHelper.startDrag(this)
|
||||
}
|
||||
return@setOnTouchListener false
|
||||
}
|
||||
}
|
||||
|
||||
fun bind(task: Task) {
|
||||
image.setImageResource(task.imageId)
|
||||
status.setImageResource(task.statusImageId)
|
||||
title.text = task.name
|
||||
}
|
||||
|
||||
override fun onClick(v: View?) {
|
||||
val position = adapterPosition
|
||||
if (position != RecyclerView.NO_POSITION) {
|
||||
when (v?.id) {
|
||||
R.id.iv_edit -> editClickListener?.let { it(position) }
|
||||
R.id.iv_remove -> removeClickListener?.let { it(position) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemMove(fromPosition: Int, toPosition: Int) {
|
||||
if (fromPosition < toPosition) {
|
||||
for (i in fromPosition until toPosition) {
|
||||
Collections.swap(itemList, i, i + 1)
|
||||
}
|
||||
} else {
|
||||
for (i in fromPosition downTo toPosition + 1) {
|
||||
Collections.swap(itemList, i, i - 1)
|
||||
}
|
||||
}
|
||||
notifyItemMoved(fromPosition, toPosition)
|
||||
}
|
||||
|
||||
override fun onDragFinished() {}
|
||||
}
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
package com.idormy.sms.forwarder.adapter.spinner
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Build
|
||||
import android.text.Html
|
||||
import android.text.TextUtils
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.DrawableRes
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.utils.Log
|
||||
import com.idormy.sms.forwarder.utils.STATUS_OFF
|
||||
import com.xuexiang.xui.utils.CollectionUtils
|
||||
import com.xuexiang.xui.widget.spinner.editspinner.BaseEditSpinnerAdapter
|
||||
import com.xuexiang.xui.widget.spinner.editspinner.EditSpinnerFilter
|
||||
import com.xuexiang.xutil.resource.ResUtils.getDrawable
|
||||
|
||||
@Suppress("unused", "NAME_SHADOWING", "DEPRECATION")
|
||||
class TaskSpinnerAdapter<T> : BaseEditSpinnerAdapter<T>, EditSpinnerFilter {
|
||||
/**
|
||||
* 选项的文字颜色
|
||||
*/
|
||||
private var mTextColor = 0
|
||||
|
||||
/**
|
||||
* 选项的文字大小
|
||||
*/
|
||||
private var mTextSize = 0f
|
||||
|
||||
/**
|
||||
* 背景颜色
|
||||
*/
|
||||
private var mBackgroundSelector = 0
|
||||
|
||||
/**
|
||||
* 过滤关键词的选中颜色
|
||||
*/
|
||||
private var mFilterColor = "#F15C58"
|
||||
private var mIsFilterKey = false
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
*
|
||||
* @param data 选项数据
|
||||
*/
|
||||
constructor(data: List<T>?) : super(data)
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
*
|
||||
* @param data 选项数据
|
||||
*/
|
||||
constructor(data: Array<T>?) : super(data)
|
||||
|
||||
override fun getEditSpinnerFilter(): EditSpinnerFilter {
|
||||
return this
|
||||
}
|
||||
|
||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View? {
|
||||
var convertView = convertView
|
||||
val holder: ViewHolder
|
||||
if (convertView == null) {
|
||||
convertView = LayoutInflater.from(parent.context).inflate(R.layout.item_spinner_with_icon, parent, false)
|
||||
holder = ViewHolder(convertView, mTextColor, mTextSize, mBackgroundSelector)
|
||||
convertView.tag = holder
|
||||
} else {
|
||||
holder = convertView.tag as ViewHolder
|
||||
}
|
||||
val item = CollectionUtils.getListItem(mDataSource, mIndexs[position]) as TaskSpinnerItem
|
||||
holder.iconView.setImageDrawable(item.icon)
|
||||
holder.statusView.setImageDrawable(
|
||||
getDrawable(
|
||||
when (item.status) {
|
||||
STATUS_OFF -> R.drawable.ic_stop
|
||||
else -> R.drawable.ic_start
|
||||
}
|
||||
)
|
||||
)
|
||||
//holder.titleView.text = Html.fromHtml(item.toString())
|
||||
holder.titleView.text = Html.fromHtml(getItem(position))
|
||||
return convertView
|
||||
}
|
||||
|
||||
override fun onFilter(keyword: String): Boolean {
|
||||
mDisplayData.clear()
|
||||
Log.d("TaskSpinnerAdapter", "keyword = $keyword")
|
||||
Log.d("TaskSpinnerAdapter", "mIndexs.indices = ${mIndexs.indices}")
|
||||
if (TextUtils.isEmpty(keyword)) {
|
||||
initDisplayData(mDataSource)
|
||||
for (i in mIndexs.indices) {
|
||||
mIndexs[i] = i
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
for (i in mDataSource.indices) {
|
||||
if (getDataSourceString(i).contains(keyword, ignoreCase = true)) {
|
||||
mIndexs[mDisplayData.size] = i
|
||||
if (mIsFilterKey) {
|
||||
mDisplayData.add(getDataSourceString(i).replaceFirst(keyword.toRegex(), "<font color=\"$mFilterColor\">$keyword</font>"))
|
||||
} else {
|
||||
mDisplayData.add(getDataSourceString(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
Log.e("TaskSpinnerAdapter", "onFilter error: ${e.message}")
|
||||
}
|
||||
}
|
||||
Log.d("TaskSpinnerAdapter", "mDisplayData = $mDisplayData")
|
||||
notifyDataSetChanged()
|
||||
return mDisplayData.size > 0
|
||||
}
|
||||
|
||||
fun setTextColor(@ColorInt textColor: Int): TaskSpinnerAdapter<*> {
|
||||
mTextColor = textColor
|
||||
return this
|
||||
}
|
||||
|
||||
fun setTextSize(textSize: Float): TaskSpinnerAdapter<*> {
|
||||
mTextSize = textSize
|
||||
return this
|
||||
}
|
||||
|
||||
fun setBackgroundSelector(@DrawableRes backgroundSelector: Int): TaskSpinnerAdapter<*> {
|
||||
mBackgroundSelector = backgroundSelector
|
||||
return this
|
||||
}
|
||||
|
||||
fun setFilterColor(filterColor: String): TaskSpinnerAdapter<*> {
|
||||
mFilterColor = filterColor
|
||||
return this
|
||||
}
|
||||
|
||||
fun setIsFilterKey(isFilterKey: Boolean): TaskSpinnerAdapter<*> {
|
||||
mIsFilterKey = isFilterKey
|
||||
return this
|
||||
}
|
||||
|
||||
@SuppressLint("ObsoleteSdkInt")
|
||||
private class ViewHolder(convertView: View, @ColorInt textColor: Int, textSize: Float, @DrawableRes backgroundSelector: Int) {
|
||||
val iconView: ImageView = convertView.findViewById(R.id.iv_icon)
|
||||
val statusView: ImageView = convertView.findViewById(R.id.iv_status)
|
||||
val titleView: TextView = convertView.findViewById(R.id.tv_title)
|
||||
|
||||
init {
|
||||
if (textColor > 0) titleView.setTextColor(textColor)
|
||||
if (textSize > 0F) titleView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
|
||||
if (backgroundSelector != 0) titleView.setBackgroundResource(backgroundSelector)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
val config = convertView.resources.configuration
|
||||
if (config.layoutDirection == View.LAYOUT_DIRECTION_RTL) {
|
||||
titleView.textDirection = View.TEXT_DIRECTION_RTL
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getItemSource(position: Int): T {
|
||||
return mDataSource[mIndexs[position]]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.idormy.sms.forwarder.adapter.spinner
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
|
||||
@Suppress("unused")
|
||||
class TaskSpinnerItem(
|
||||
var title: CharSequence,
|
||||
var icon: Drawable? = null,
|
||||
var id: Long? = 0L,
|
||||
var status: Int? = 1
|
||||
) {
|
||||
|
||||
fun setTitle(title: CharSequence): TaskSpinnerItem {
|
||||
this.title = title
|
||||
return this
|
||||
}
|
||||
|
||||
fun setIcon(icon: Drawable?): TaskSpinnerItem {
|
||||
this.icon = icon
|
||||
return this
|
||||
}
|
||||
|
||||
fun setId(id: Long): TaskSpinnerItem {
|
||||
this.id = id
|
||||
return this
|
||||
}
|
||||
|
||||
fun setStatus(status: Int): TaskSpinnerItem {
|
||||
this.status = status
|
||||
return this
|
||||
}
|
||||
|
||||
// 注意:自定义实体需要重写对象的 toString 方法
|
||||
override fun toString(): String {
|
||||
return title.toString()
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun of(title: CharSequence): TaskSpinnerItem {
|
||||
return TaskSpinnerItem(title)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun arrayOf(vararg titles: CharSequence): Array<TaskSpinnerItem> {
|
||||
return titles.map { TaskSpinnerItem(it) }.toTypedArray()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -34,6 +34,9 @@ interface TaskDao {
|
|||
@Query("UPDATE Task SET status = :status WHERE id = :id")
|
||||
fun updateStatus(id: Long, status: Int)
|
||||
|
||||
@Query("UPDATE Task SET status=:status WHERE id IN (:ids)")
|
||||
fun updateStatusByIds(ids: List<Long>, status: Int)
|
||||
|
||||
@Query("SELECT * FROM Task where id=:id")
|
||||
fun get(id: Long): Single<Task>
|
||||
|
||||
|
@ -46,6 +49,9 @@ interface TaskDao {
|
|||
@Query("SELECT * FROM Task where type >= 1000 ORDER BY id DESC")
|
||||
fun pagingSourceMine(): PagingSource<Int, Task>
|
||||
|
||||
@Query("SELECT * FROM Task ORDER BY id DESC")
|
||||
fun getAll(): Single<List<Task>>
|
||||
|
||||
@Transaction
|
||||
@RawQuery(observedEntities = [Task::class])
|
||||
fun getAllRaw(query: SupportSQLiteQuery): List<Task>
|
||||
|
|
|
@ -4,6 +4,7 @@ import androidx.annotation.WorkerThread
|
|||
import androidx.sqlite.db.SimpleSQLiteQuery
|
||||
import com.idormy.sms.forwarder.database.dao.TaskDao
|
||||
import com.idormy.sms.forwarder.database.entity.Task
|
||||
import io.reactivex.Single
|
||||
import java.util.Date
|
||||
|
||||
class TaskRepository(private val taskDao: TaskDao) {
|
||||
|
@ -20,10 +21,14 @@ class TaskRepository(private val taskDao: TaskDao) {
|
|||
|
||||
fun updateExecTime(taskId: Long, lastExecTime: Date, nextExecTime: Date, status: Int) = taskDao.updateExecTime(taskId, lastExecTime, nextExecTime, status)
|
||||
|
||||
fun updateStatusByIds(ids: List<Long>, status: Int) = taskDao.updateStatusByIds(ids, status)
|
||||
|
||||
fun get(id: Long) = taskDao.get(id)
|
||||
|
||||
suspend fun getOne(id: Long) = taskDao.getOne(id)
|
||||
|
||||
fun getAll(): Single<List<Task>> = taskDao.getAll()
|
||||
|
||||
fun getAllNonCache(): List<Task> {
|
||||
val query = SimpleSQLiteQuery("SELECT * FROM Task ORDER BY id ASC")
|
||||
return taskDao.getAllRaw(query)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package com.idormy.sms.forwarder.entity.action
|
||||
|
||||
import com.idormy.sms.forwarder.database.entity.Task
|
||||
import java.io.Serializable
|
||||
|
||||
data class TaskActionSetting(
|
||||
var description: String = "", //描述
|
||||
var status: Int = 1, //状态:0-禁用;1-启用
|
||||
var taskList: List<Task>, //自动任务列表
|
||||
) : Serializable
|
|
@ -208,6 +208,13 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||
CoreAnim.slide,
|
||||
R.drawable.auto_task_icon_resend
|
||||
),
|
||||
PageInfo(
|
||||
getString(R.string.task_task),
|
||||
"com.idormy.sms.forwarder.fragment.action.TaskActionFragment",
|
||||
"{\"\":\"\"}",
|
||||
CoreAnim.slide,
|
||||
R.drawable.auto_task_icon_task
|
||||
),
|
||||
)
|
||||
|
||||
override fun initArgs() {
|
||||
|
|
|
@ -0,0 +1,303 @@
|
|||
package com.idormy.sms.forwarder.fragment.action
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.work.Data
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.adapter.TaskRecyclerAdapter
|
||||
import com.idormy.sms.forwarder.adapter.base.ItemMoveCallback
|
||||
import com.idormy.sms.forwarder.adapter.spinner.TaskSpinnerAdapter
|
||||
import com.idormy.sms.forwarder.adapter.spinner.TaskSpinnerItem
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.core.Core
|
||||
import com.idormy.sms.forwarder.database.entity.Task
|
||||
import com.idormy.sms.forwarder.databinding.FragmentTasksActionTaskBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.TaskSetting
|
||||
import com.idormy.sms.forwarder.entity.action.TaskActionSetting
|
||||
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.Log
|
||||
import com.idormy.sms.forwarder.utils.STATUS_OFF
|
||||
import com.idormy.sms.forwarder.utils.TASK_ACTION_TASK
|
||||
import com.idormy.sms.forwarder.utils.TaskWorker
|
||||
import com.idormy.sms.forwarder.utils.XToastUtils
|
||||
import com.idormy.sms.forwarder.workers.ActionWorker
|
||||
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
|
||||
import com.xuexiang.xutil.resource.ResUtils.getDrawable
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.Date
|
||||
|
||||
@Page(name = "Task")
|
||||
@Suppress("PrivatePropertyName", "DEPRECATION")
|
||||
class TaskActionFragment : BaseFragment<FragmentTasksActionTaskBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = TaskActionFragment::class.java.simpleName
|
||||
private var titleBar: TitleBar? = null
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
//所有自动任务下拉框
|
||||
private var taskListAll = mutableListOf<Task>()
|
||||
private val taskSpinnerList = mutableListOf<TaskSpinnerItem>()
|
||||
private lateinit var taskSpinnerAdapter: TaskSpinnerAdapter<*>
|
||||
|
||||
//已选自动任务列表
|
||||
private var taskId = 0L
|
||||
private var taskListSelected = mutableListOf<Task>()
|
||||
private lateinit var taskRecyclerView: RecyclerView
|
||||
private lateinit var taskRecyclerAdapter: TaskRecyclerAdapter
|
||||
|
||||
@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,
|
||||
): FragmentTasksActionTaskBinding {
|
||||
return FragmentTasksActionTaskBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.task_task)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, 1)
|
||||
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)
|
||||
//获取自动任务列表
|
||||
getTaskList()
|
||||
}
|
||||
})
|
||||
|
||||
Log.d(TAG, "initViews eventData:$eventData")
|
||||
if (eventData != null) {
|
||||
val settingVo = Gson().fromJson(eventData, TaskActionSetting::class.java)
|
||||
binding!!.rgStatus.check(if (settingVo.status == 1) R.id.rb_status_enable else R.id.rb_status_disable)
|
||||
Log.d(TAG, settingVo.taskList.toString())
|
||||
settingVo.taskList.forEach {
|
||||
taskId = it.id
|
||||
taskListSelected.add(it)
|
||||
}
|
||||
Log.d(TAG, "initViews settingVo:$settingVo")
|
||||
}
|
||||
|
||||
//初始化自动任务下拉框
|
||||
initTask()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun initListeners() {
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
when (v.id) {
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val taskAction = TaskSetting(TASK_ACTION_TASK, getString(R.string.task_task), settingVo.description, Gson().toJson(settingVo), requestCode)
|
||||
val taskActionsJson = Gson().toJson(arrayListOf(taskAction))
|
||||
val msgInfo = MsgInfo("task", getString(R.string.task_task), settingVo.description, Date(), getString(R.string.task_task))
|
||||
val actionData = Data.Builder().putLong(TaskWorker.taskId, 0).putString(TaskWorker.taskActions, taskActionsJson).putString(TaskWorker.msgInfo, Gson().toJson(msgInfo)).build()
|
||||
val actionRequest = OneTimeWorkRequestBuilder<ActionWorker>().setInputData(actionData).build()
|
||||
WorkManager.getInstance().enqueue(actionRequest)
|
||||
} catch (e: Exception) {
|
||||
mCountDownHelper?.finish()
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "onClick error: ${e.message}")
|
||||
XToastUtils.error(e.message.toString(), 30000)
|
||||
}
|
||||
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_TASK, intent)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString(), 30000)
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "onClick error: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
//初始化自动任务
|
||||
@SuppressLint("SetTextI18n", "NotifyDataSetChanged")
|
||||
private fun initTask() {
|
||||
//初始化自动任务下拉框
|
||||
binding!!.spTask.setOnItemClickListener { _: AdapterView<*>, _: View, position: Int, _: Long ->
|
||||
try {
|
||||
val item = taskSpinnerAdapter.getItemSource(position) as TaskSpinnerItem
|
||||
taskId = item.id!!
|
||||
if (taskId > 0L) {
|
||||
taskListSelected.forEach {
|
||||
if (taskId == it.id) {
|
||||
XToastUtils.warning(getString(R.string.task_contains_tips))
|
||||
return@setOnItemClickListener
|
||||
}
|
||||
}
|
||||
taskListAll.forEach {
|
||||
if (taskId == it.id) {
|
||||
taskListSelected.add(it)
|
||||
}
|
||||
}
|
||||
taskRecyclerAdapter.notifyDataSetChanged()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化已选自动任务列表 RecyclerView 和 Adapter
|
||||
taskRecyclerView = binding!!.recyclerTasks
|
||||
taskRecyclerAdapter = TaskRecyclerAdapter(taskListSelected, { position ->
|
||||
taskListSelected.removeAt(position)
|
||||
taskRecyclerAdapter.notifyItemRemoved(position)
|
||||
taskRecyclerAdapter.notifyItemRangeChanged(position, taskListSelected.size) // 更新索引
|
||||
})
|
||||
taskRecyclerView.apply {
|
||||
layoutManager = LinearLayoutManager(requireContext())
|
||||
adapter = taskRecyclerAdapter
|
||||
}
|
||||
val taskMoveCallback = ItemMoveCallback(object : ItemMoveCallback.Listener {
|
||||
override fun onItemMove(fromPosition: Int, toPosition: Int) {
|
||||
Log.d(TAG, "onItemMove: $fromPosition $toPosition")
|
||||
taskRecyclerAdapter.onItemMove(fromPosition, toPosition)
|
||||
taskListSelected = taskRecyclerAdapter.itemList
|
||||
}
|
||||
|
||||
override fun onDragFinished() {
|
||||
taskListSelected = taskRecyclerAdapter.itemList
|
||||
//taskRecyclerAdapter.notifyDataSetChanged()
|
||||
Log.d(TAG, "onDragFinished: $taskListSelected")
|
||||
}
|
||||
})
|
||||
val taskTouchHelper = ItemTouchHelper(taskMoveCallback)
|
||||
taskTouchHelper.attachToRecyclerView(taskRecyclerView)
|
||||
taskRecyclerAdapter.setTouchHelper(taskTouchHelper)
|
||||
|
||||
//获取自动任务列表
|
||||
getTaskList()
|
||||
}
|
||||
|
||||
//获取自动任务列表
|
||||
private fun getTaskList() {
|
||||
Core.task.getAll().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(object : SingleObserver<List<Task>> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "getTaskList error: ${e.message}")
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun onSuccess(taskList: List<Task>) {
|
||||
if (taskList.isEmpty()) {
|
||||
XToastUtils.error(R.string.add_task_first)
|
||||
return
|
||||
}
|
||||
|
||||
taskSpinnerList.clear()
|
||||
taskListAll = taskList as MutableList<Task>
|
||||
for (task in taskList) {
|
||||
val name = if (task.name.length > 20) task.name.substring(0, 19) else task.name
|
||||
taskSpinnerList.add(TaskSpinnerItem(name, getDrawable(if (STATUS_OFF == task.status) task.greyImageId else task.imageId), task.id, task.status))
|
||||
}
|
||||
taskSpinnerAdapter = TaskSpinnerAdapter(taskSpinnerList).setIsFilterKey(true).setFilterColor("#EF5362").setBackgroundSelector(R.drawable.selector_custom_spinner_bg)
|
||||
binding!!.spTask.setAdapter(taskSpinnerAdapter)
|
||||
//taskSpinnerAdapter.notifyDataSetChanged()
|
||||
|
||||
//更新taskListSelected的状态与名称
|
||||
taskListSelected.forEach {
|
||||
taskListAll.forEach { task ->
|
||||
if (it.id == task.id) {
|
||||
//it.name = task.name
|
||||
it.status = task.status
|
||||
}
|
||||
}
|
||||
}
|
||||
taskRecyclerAdapter.notifyDataSetChanged()
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//检查设置
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun checkSetting(): TaskActionSetting {
|
||||
if (taskListSelected.isEmpty() || taskId == 0L) {
|
||||
throw Exception(getString(R.string.new_task_first))
|
||||
}
|
||||
|
||||
val description = StringBuilder()
|
||||
val status: Int
|
||||
if (binding!!.rgStatus.checkedRadioButtonId == R.id.rb_status_enable) {
|
||||
status = 1
|
||||
description.append(getString(R.string.enable))
|
||||
} else {
|
||||
status = 0
|
||||
description.append(getString(R.string.disable))
|
||||
}
|
||||
description.append(getString(R.string.menu_tasks)).append(", ").append(getString(R.string.specified_task)).append(": ")
|
||||
description.append(taskListSelected.joinToString(",") { "[${it.id}]${it.name}" })
|
||||
|
||||
return TaskActionSetting(description.toString(), status, taskListSelected)
|
||||
}
|
||||
}
|
|
@ -248,6 +248,7 @@ const val TASK_ACTION_RULE = 2006
|
|||
const val TASK_ACTION_SENDER = 2007
|
||||
const val TASK_ACTION_ALARM = 2008
|
||||
const val TASK_ACTION_RESEND = 2009
|
||||
const val TASK_ACTION_TASK = 2010
|
||||
|
||||
const val SP_BATTERY_INFO = "battery_info"
|
||||
const val SP_BATTERY_STATUS = "battery_status"
|
||||
|
@ -269,7 +270,7 @@ const val SP_LOCK_SCREEN_ACTION = "lock_screen_action"
|
|||
const val DELAY_TIME_AFTER_SIM_READY = 5000L
|
||||
|
||||
//切换语言需要替换的自定义模板标签列表
|
||||
val TAG_LANG = arrayOf("zh_CN", "zh_TW", "en")
|
||||
//val TAG_LANG = arrayOf("zh_CN", "zh_TW", "en")
|
||||
val TAG_LIST = arrayOf(
|
||||
mapOf("zh_CN" to "{{来源号码}}", "zh_TW" to "{{來源號碼}}", "en" to "{{FROM}}"),
|
||||
mapOf("zh_CN" to "{{短信内容}}", "zh_TW" to "{{簡訊內容}}", "en" to "{{SMS}}"),
|
||||
|
|
|
@ -25,6 +25,7 @@ import com.idormy.sms.forwarder.entity.action.RuleSetting
|
|||
import com.idormy.sms.forwarder.entity.action.SenderSetting
|
||||
import com.idormy.sms.forwarder.entity.action.SettingsSetting
|
||||
import com.idormy.sms.forwarder.entity.action.SmsSetting
|
||||
import com.idormy.sms.forwarder.entity.action.TaskActionSetting
|
||||
import com.idormy.sms.forwarder.service.HttpServerService
|
||||
import com.idormy.sms.forwarder.service.LocationService
|
||||
import com.idormy.sms.forwarder.utils.CacheUtils
|
||||
|
@ -49,6 +50,7 @@ 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_SENDSMS
|
||||
import com.idormy.sms.forwarder.utils.TASK_ACTION_SETTINGS
|
||||
import com.idormy.sms.forwarder.utils.TASK_ACTION_TASK
|
||||
import com.idormy.sms.forwarder.utils.TaskWorker
|
||||
import com.idormy.sms.forwarder.utils.task.ConditionUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
|
@ -310,6 +312,22 @@ class ActionWorker(context: Context, params: WorkerParameters) : CoroutineWorker
|
|||
writeLog(String.format(getString(R.string.successful_execution), senderSetting.description), "SUCCESS")
|
||||
}
|
||||
|
||||
TASK_ACTION_TASK -> {
|
||||
val taskActionSetting = Gson().fromJson(action.setting, TaskActionSetting::class.java)
|
||||
if (taskActionSetting == null) {
|
||||
writeLog("taskActionSetting is null")
|
||||
continue
|
||||
}
|
||||
|
||||
val ids = taskActionSetting.taskList.map { it.id }
|
||||
if (ids.isNotEmpty()) {
|
||||
Core.task.updateStatusByIds(ids, taskActionSetting.status)
|
||||
}
|
||||
|
||||
successNum++
|
||||
writeLog(String.format(getString(R.string.successful_execution), taskActionSetting.description), "SUCCESS")
|
||||
}
|
||||
|
||||
TASK_ACTION_ALARM -> {
|
||||
val alarmSetting = Gson().fromJson(action.setting, AlarmSetting::class.java)
|
||||
if (alarmSetting == null) {
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<?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="#ff3482ff"
|
||||
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.017"
|
||||
android:scaleY="0.017"
|
||||
android:translateX="4.6"
|
||||
android:translateY="4.0">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M920.2,668.1c0,33.3 -14.8,64.6 -40.7,85.6l-290.7,236.2c-54.4,45.4 -139.1,45.4 -193.6,0l-290.7,-236.2c-54,-42.2 -54,-129 0,-171.3L191.2,512 104.5,441.6c-54,-42.2 -54,-129.1 0,-171.3L395.2,34.1c54.4,-45.4 139.1,-45.4 193.6,0l290.7,236.2c54,42.2 54,129 0,171.3 -42.6,31.8 -90.4,-27.1 -50.5,-62.1a30.3,30.3 0,0 0,0 -47l-290.6,-236.2a73.8,73.8 0,0 0,-92.7 0l-290.6,236.2a30.3,30.3 0,0 0,0 47l290.6,236.2c26.9,21.8 65.9,21.8 92.7,0l0.4,-0.4 46.5,-36.5a40,40 0,0 1,49.5 62.8l-46.3,36.5c-54.4,45.3 -139,45.2 -193.3,-0.3L254.7,563.6 155,644.5a30.3,30.3 0,0 0,0 47l290.6,236.2c26.9,21.8 65.9,21.8 92.7,0l290.6,-236.2a30.3,30.3 0,0 0,0 -47l-290.6,-236.2a73.8,73.8 0,0 0,-92.7 0l-0.4,0.4 -46.5,36.6a40,40 0,0 1,-49.5 -62.8l46.2,-36.5C450,300.8 534.5,300.8 588.9,346.4l290.7,236.2c25.9,21 40.7,52.2 40.7,85.6z" />
|
||||
</group>
|
||||
</vector>
|
|
@ -0,0 +1,20 @@
|
|||
<?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" />
|
||||
<group
|
||||
android:scaleX="0.017"
|
||||
android:scaleY="0.017"
|
||||
android:translateX="4.6"
|
||||
android:translateY="4.0">
|
||||
<path
|
||||
android:fillColor="#ffffffff"
|
||||
android:pathData="M920.2,668.1c0,33.3 -14.8,64.6 -40.7,85.6l-290.7,236.2c-54.4,45.4 -139.1,45.4 -193.6,0l-290.7,-236.2c-54,-42.2 -54,-129 0,-171.3L191.2,512 104.5,441.6c-54,-42.2 -54,-129.1 0,-171.3L395.2,34.1c54.4,-45.4 139.1,-45.4 193.6,0l290.7,236.2c54,42.2 54,129 0,171.3 -42.6,31.8 -90.4,-27.1 -50.5,-62.1a30.3,30.3 0,0 0,0 -47l-290.6,-236.2a73.8,73.8 0,0 0,-92.7 0l-290.6,236.2a30.3,30.3 0,0 0,0 47l290.6,236.2c26.9,21.8 65.9,21.8 92.7,0l0.4,-0.4 46.5,-36.5a40,40 0,0 1,49.5 62.8l-46.3,36.5c-54.4,45.3 -139,45.2 -193.3,-0.3L254.7,563.6 155,644.5a30.3,30.3 0,0 0,0 47l290.6,236.2c26.9,21.8 65.9,21.8 92.7,0l290.6,-236.2a30.3,30.3 0,0 0,0 -47l-290.6,-236.2a73.8,73.8 0,0 0,-92.7 0l-0.4,0.4 -46.5,36.6a40,40 0,0 1,-49.5 -62.8l46.2,-36.5C450,300.8 534.5,300.8 588.9,346.4l290.7,236.2c25.9,21 40.7,52.2 40.7,85.6z" />
|
||||
</group>
|
||||
</vector>
|
|
@ -3,7 +3,13 @@
|
|||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<group
|
||||
android:scaleX="0.021"
|
||||
android:scaleY="0.021"
|
||||
android:translateX="1.7"
|
||||
android:translateY="1.2">
|
||||
<path
|
||||
android:fillColor="#BEC2C7"
|
||||
android:pathData="M14,2H6C4.9,2 4.01,2.9 4.01,4L4,20c0,1.1 0.89,2 1.99,2H18c1.1,0 2,-0.9 2,-2V8L14,2zM10.94,18L7.4,14.46l1.41,-1.41l2.12,2.12l4.24,-4.24l1.41,1.41L10.94,18zM13,9V3.5L18.5,9H13z" />
|
||||
android:pathData="M920.2,668.1c0,33.3 -14.8,64.6 -40.7,85.6l-290.7,236.2c-54.4,45.4 -139.1,45.4 -193.6,0l-290.7,-236.2c-54,-42.2 -54,-129 0,-171.3L191.2,512 104.5,441.6c-54,-42.2 -54,-129.1 0,-171.3L395.2,34.1c54.4,-45.4 139.1,-45.4 193.6,0l290.7,236.2c54,42.2 54,129 0,171.3 -42.6,31.8 -90.4,-27.1 -50.5,-62.1a30.3,30.3 0,0 0,0 -47l-290.6,-236.2a73.8,73.8 0,0 0,-92.7 0l-290.6,236.2a30.3,30.3 0,0 0,0 47l290.6,236.2c26.9,21.8 65.9,21.8 92.7,0l0.4,-0.4 46.5,-36.5a40,40 0,0 1,49.5 62.8l-46.3,36.5c-54.4,45.3 -139,45.2 -193.3,-0.3L254.7,563.6 155,644.5a30.3,30.3 0,0 0,0 47l290.6,236.2c26.9,21.8 65.9,21.8 92.7,0l290.6,-236.2a30.3,30.3 0,0 0,0 -47l-290.6,-236.2a73.8,73.8 0,0 0,-92.7 0l-0.4,0.4 -46.5,36.6a40,40 0,0 1,-49.5 -62.8l46.2,-36.5C450,300.8 534.5,300.8 588.9,346.4l290.7,236.2c25.9,21 40.7,52.2 40.7,85.6z" />
|
||||
</group>
|
||||
</vector>
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
<?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="wrap_content"
|
||||
android:background="@color/xui_config_color_white"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/xui_config_color_separator_light" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="@dimen/config_padding_5dp"
|
||||
android:paddingBottom="@dimen/config_padding_5dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_image"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@drawable/icon_dingtalk"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_status"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"
|
||||
android:layout_marginStart="14dp"
|
||||
android:layout_marginTop="-10dp"
|
||||
android:src="@drawable/ic_stop"
|
||||
tools:ignore="ContentDescription,VisualLintBounds" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/dingtalk_robot"
|
||||
android:textSize="@dimen/text_size_small"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_edit"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:src="@drawable/ic_edit"
|
||||
app:tint="@color/toast_info_color"
|
||||
tools:ignore="ContentDescription,PrivateResource,ImageContrastCheck" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_remove"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:src="@drawable/ic_delete"
|
||||
app:tint="@color/toast_error_color"
|
||||
tools:ignore="ContentDescription,PrivateResource" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_drag"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:src="@drawable/ic_drag"
|
||||
app:tint="@color/colorStart"
|
||||
tools:ignore="ContentDescription,ImageContrastCheck" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,148 @@
|
|||
<?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_task"
|
||||
app:srcCompat="@drawable/auto_task_icon_task"
|
||||
tools:ignore="ImageContrastCheck" />
|
||||
|
||||
<LinearLayout
|
||||
style="@style/BarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="10dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/task_task"
|
||||
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_task_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_status"
|
||||
style="@style/rg_style"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="@dimen/config_padding_5dp">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rb_status_enable"
|
||||
style="@style/rg_rb_style"
|
||||
android:checked="true"
|
||||
android:text="@string/enable"
|
||||
tools:ignore="TouchTargetSizeCheck" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rb_status_disable"
|
||||
style="@style/rg_rb_style"
|
||||
android:text="@string/disable"
|
||||
tools:ignore="TouchTargetSizeCheck" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/specified_task"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.xuexiang.xui.widget.spinner.editspinner.EditSpinner
|
||||
android:id="@+id/sp_task"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
app:es_hint="@string/choose_task"
|
||||
app:es_maxLength="20"
|
||||
app:es_maxLine="1" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_tasks"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/config_margin_5dp" />
|
||||
|
||||
</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>
|
|
@ -227,9 +227,11 @@
|
|||
<string name="new_sender_first">Please add a new sender and then choose it.</string>
|
||||
<string name="new_rule_first">Please add a new rule and then choose it.</string>
|
||||
<string name="new_frpc_first">Please add a new frpc and then choose it.</string>
|
||||
<string name="new_task_first">Please add a new task and then choose it.</string>
|
||||
<string name="add_sender_first">Please add a sender first.</string>
|
||||
<string name="add_rule_first">Please add a rule first.</string>
|
||||
<string name="add_frpc_first">Please add a frpc first.</string>
|
||||
<string name="add_task_first">Please add a task first.</string>
|
||||
<string name="select_sender">Select Sender</string>
|
||||
<string name="rule_tester">Rule tester:</string>
|
||||
<string name="test_sim_slot">Test SIM Slot</string>
|
||||
|
@ -830,6 +832,7 @@
|
|||
<string name="choose_rule">Drop-down selection, keyword fuzzy match</string>
|
||||
<string name="choose_sender">Drop-down selection, keyword fuzzy match</string>
|
||||
<string name="choose_frpc">Drop-down selection, keyword fuzzy match</string>
|
||||
<string name="choose_task">Drop-down selection, keyword fuzzy match</string>
|
||||
<string name="choose_app">Installed Apps</string>
|
||||
<string name="extra_app">Extra Apps</string>
|
||||
<string name="extra_app_hint">One package name per line\nEnable async loading of the App list for selection.</string>
|
||||
|
@ -982,6 +985,7 @@
|
|||
<string name="sender_contains_tips">[Note] The sender is already in the list, no need to add it again!</string>
|
||||
<string name="rule_contains_tips">[Note] The rule is already in the list, no need to add it again!</string>
|
||||
<string name="frpc_contains_tips">[Note] The frpc is already in the list, no need to add it again!</string>
|
||||
<string name="task_contains_tips">[Note] The task is already in the list, no need to add it again!</string>
|
||||
<string name="local_call">Local Call:</string>
|
||||
<string name="remote_sms">Remote SMS:</string>
|
||||
<string name="clear">Clear</string>
|
||||
|
@ -1199,15 +1203,17 @@
|
|||
<string name="task_settings">Settings</string>
|
||||
<string name="task_settings_tips">Control the configuration switch of "Settings".</string>
|
||||
<string name="task_rule">Rules On/Off</string>
|
||||
<string name="task_rule_tips">Control enabling/disabling of "Rules"</string>
|
||||
<string name="task_rule_tips">Control the enable/disable of "Rules"</string>
|
||||
<string name="task_sender">Channels On/Off</string>
|
||||
<string name="task_sender_tips">Control enabling/disabling of "Senders"</string>
|
||||
<string name="task_sender_tips">Control the enable/disable of "Senders"</string>
|
||||
<string name="task_alarm">Alarm</string>
|
||||
<string name="task_alarm_tips">Alarm</string>
|
||||
<string name="task_resend">Resend Message</string>
|
||||
<string name="task_resend_tips">Resend forwarded records since N hours ago, 0=ALL</string>
|
||||
<string name="task_resend_desc" formatted="false">Resend forwarding records since %s hours ago for %s</string>
|
||||
<string name="task_resend_error">At least one "Original Result" must be selected</string>
|
||||
<string name="task_task">Tasks On/Off</string>
|
||||
<string name="task_task_tips">Control the enable/disable of the "Auto Task"</string>
|
||||
|
||||
<string name="second">Second</string>
|
||||
<string name="minute">Minute</string>
|
||||
|
@ -1323,6 +1329,8 @@
|
|||
<string name="specified_rule_hint">Enter Rule IDs (comma-separated)</string>
|
||||
<string name="specified_sender">Specified Sender</string>
|
||||
<string name="specified_sender_hint">Enter Sender IDs (comma-separated)</string>
|
||||
<string name="specified_task">Specified Task</string>
|
||||
<string name="specified_task_hint">Enter Task IDs (comma-separated)</string>
|
||||
|
||||
<string name="current_language">English</string>
|
||||
<string name="current_activity_language">Current Activity language: </string>
|
||||
|
|
|
@ -228,9 +228,11 @@
|
|||
<string name="new_sender_first">请选择发送通道(若无,请先添加)</string>
|
||||
<string name="new_rule_first">请选择发送通道(若无,请先添加)</string>
|
||||
<string name="new_frpc_first">请选择发送通道(若无,请先添加)</string>
|
||||
<string name="new_task_first">请选择自动任务(若无,请先添加)</string>
|
||||
<string name="add_sender_first">请先去设置发送通道页面添加</string>
|
||||
<string name="add_rule_first">请先去设置转发规则页面添加</string>
|
||||
<string name="add_frpc_first">请先去设置FRPC页面添加</string>
|
||||
<string name="add_task_first">请先去设置自动任务页面添加</string>
|
||||
<string name="select_sender">发送通道</string>
|
||||
<string name="rule_tester">转发规则测试</string>
|
||||
<string name="test_sim_slot">测试模拟的接收卡槽</string>
|
||||
|
@ -831,6 +833,7 @@
|
|||
<string name="choose_rule">下拉选择,关键字模糊匹配</string>
|
||||
<string name="choose_sender">下拉选择,关键字模糊匹配</string>
|
||||
<string name="choose_frpc">下拉选择,关键字模糊匹配</string>
|
||||
<string name="choose_task">下拉选择,关键字模糊匹配</string>
|
||||
<string name="choose_app">已装APP列表</string>
|
||||
<string name="extra_app">额外消除应用通知</string>
|
||||
<string name="extra_app_hint">一行一个包名\n开启异步加载App列表以便选择</string>
|
||||
|
@ -983,6 +986,7 @@
|
|||
<string name="sender_contains_tips">【注意】该发送通道已经在列表中,无需重复添加!</string>
|
||||
<string name="rule_contains_tips">【注意】该转发规则已经在列表中,无需重复添加!</string>
|
||||
<string name="frpc_contains_tips">【注意】该Frpc已经在列表中,无需重复添加!</string>
|
||||
<string name="task_contains_tips">【注意】该自动任务已经在列表中,无需重复添加!</string>
|
||||
<string name="local_call">本地呼叫:</string>
|
||||
<string name="remote_sms">远程发短信:</string>
|
||||
<string name="clear">清除</string>
|
||||
|
@ -1209,6 +1213,8 @@
|
|||
<string name="task_resend_tips">自动重发N小时以来的转发记录,0=全部</string>
|
||||
<string name="task_resend_desc" formatted="false">自动重发%s小时以来%s的转发记录</string>
|
||||
<string name="task_resend_error">必须至少选择一个【原转发状态】</string>
|
||||
<string name="task_task">启停任务</string>
|
||||
<string name="task_task_tips">控制【自动任务】的启用/禁用</string>
|
||||
|
||||
<string name="second">秒</string>
|
||||
<string name="minute">分</string>
|
||||
|
@ -1324,6 +1330,8 @@
|
|||
<string name="specified_rule_hint">填写转发规则的id,多个以半角逗号分隔</string>
|
||||
<string name="specified_sender">指定通道</string>
|
||||
<string name="specified_sender_hint">填写发送通道的id,多个以半角逗号分隔</string>
|
||||
<string name="specified_task">指定任务</string>
|
||||
<string name="specified_task_hint">填写自动任务的id,多个以半角逗号分隔</string>
|
||||
|
||||
<string name="current_language">简体中文</string>
|
||||
<string name="current_activity_language">当前 Activity 语种:</string>
|
||||
|
|
|
@ -228,9 +228,11 @@
|
|||
<string name="new_sender_first">請選擇發送通道(若無,請先添加)</string>
|
||||
<string name="new_rule_first">請選擇轉發規則(若無,請先添加)</string>
|
||||
<string name="new_frpc_first">請選擇FRPC(若無,請先添加)</string>
|
||||
<string name="new_task_first">請選擇自動任務(若無,請先添加)</string>
|
||||
<string name="add_sender_first">請先去設置發送通道頁面添加</string>
|
||||
<string name="add_rule_first">請先去設置轉發規則頁面添加</string>
|
||||
<string name="add_frpc_first">請先去設置FRPC頁面添加</string>
|
||||
<string name="add_task_first">請先去設置自動任務頁面添加</string>
|
||||
<string name="select_sender">發送通道</string>
|
||||
<string name="rule_tester">轉發規則測試</string>
|
||||
<string name="test_sim_slot">測試模擬的接收卡槽</string>
|
||||
|
@ -831,6 +833,7 @@
|
|||
<string name="choose_rule">下拉選擇,關鍵字模糊匹配</string>
|
||||
<string name="choose_sender">下拉選擇,關鍵字模糊匹配</string>
|
||||
<string name="choose_frpc">下拉選擇,關鍵字模糊匹配</string>
|
||||
<string name="choose_task">下拉選擇,關鍵字模糊匹配</string>
|
||||
<string name="choose_app">已裝APP列表</string>
|
||||
<string name="extra_app">額外消除應用通知</string>
|
||||
<string name="extra_app_hint">一行一個包名\n開啟異步加載App列表以便選擇</string>
|
||||
|
@ -983,6 +986,7 @@
|
|||
<string name="sender_contains_tips">【注意】該發送通道已經在列表中,無需重複添加!</string>
|
||||
<string name="rule_contains_tips">【注意】該轉發規則已經在列表中,無需重複添加!</string>
|
||||
<string name="frpc_contains_tips">【注意】該Frpc已經在列表中,無需重複添加!</string>
|
||||
<string name="task_contains_tips">【注意】該自動任務已經在列表中,無需重複添加!</string>
|
||||
<string name="local_call">本地呼叫:</string>
|
||||
<string name="remote_sms">遠程發簡訊:</string>
|
||||
<string name="clear">清除</string>
|
||||
|
@ -1209,6 +1213,8 @@
|
|||
<string name="task_resend_tips">自動重發N小時以來的轉發記錄,0=全部</string>
|
||||
<string name="task_resend_desc" formatted="false">自動重發%s小時以來%s的轉發記錄</string>
|
||||
<string name="task_resend_error">必须至少选择一個「原轉發狀態」</string>
|
||||
<string name="task_task">啟停任務</string>
|
||||
<string name="task_task_tips">控制【自動任務】的啟用/禁用</string>
|
||||
|
||||
<string name="second">秒</string>
|
||||
<string name="minute">分</string>
|
||||
|
@ -1324,7 +1330,8 @@
|
|||
<string name="specified_rule_hint">填寫轉發規則的ID,多個以半角逗號分隔</string>
|
||||
<string name="specified_sender">指定通道</string>
|
||||
<string name="specified_sender_hint">填寫發送通道的ID,多個以半角逗號分隔</string>
|
||||
|
||||
<string name="specified_task">指定任務</string>
|
||||
<string name="specified_task_hint">填寫自動任務的ID,多個以半角逗號分隔</string>
|
||||
|
||||
<string name="current_language">繁體中文</string>
|
||||
<string name="current_activity_language">當前 Activity 語種:</string>
|
||||
|
|
|
@ -228,9 +228,11 @@
|
|||
<string name="new_sender_first">请选择发送通道(若无,请先添加)</string>
|
||||
<string name="new_rule_first">请选择转发规则(若无,请先添加)</string>
|
||||
<string name="new_frpc_first">请选择Frpc(若无,请先添加)</string>
|
||||
<string name="new_task_first">请选择自动任务(若无,请先添加)</string>
|
||||
<string name="add_sender_first">请先去设置发送通道页面添加</string>
|
||||
<string name="add_rule_first">请先去设置转发规则页面添加</string>
|
||||
<string name="add_frpc_first">请先去设置Frpc页面添加</string>
|
||||
<string name="add_task_first">请先去设置自动任务页面添加</string>
|
||||
<string name="select_sender">发送通道</string>
|
||||
<string name="rule_tester">转发规则测试</string>
|
||||
<string name="test_sim_slot">测试模拟的接收卡槽</string>
|
||||
|
@ -831,6 +833,7 @@
|
|||
<string name="choose_rule">下拉选择,关键字模糊匹配</string>
|
||||
<string name="choose_sender">下拉选择,关键字模糊匹配</string>
|
||||
<string name="choose_frpc">下拉选择,关键字模糊匹配</string>
|
||||
<string name="choose_task">下拉选择,关键字模糊匹配</string>
|
||||
<string name="choose_app">已装APP列表</string>
|
||||
<string name="extra_app">额外消除应用通知</string>
|
||||
<string name="extra_app_hint">一行一个包名\n开启异步加载App列表以便选择</string>
|
||||
|
@ -983,6 +986,7 @@
|
|||
<string name="sender_contains_tips">【注意】该发送通道已经在列表中,无需重复添加!</string>
|
||||
<string name="rule_contains_tips">【注意】该转发规则已经在列表中,无需重复添加!</string>
|
||||
<string name="frpc_contains_tips">【注意】该Frpc已经在列表中,无需重复添加!</string>
|
||||
<string name="task_contains_tips">【注意】该自动任务已经在列表中,无需重复添加!</string>
|
||||
<string name="local_call">本地呼叫:</string>
|
||||
<string name="remote_sms">远程发短信:</string>
|
||||
<string name="clear">清除</string>
|
||||
|
@ -1209,6 +1213,8 @@
|
|||
<string name="task_resend_tips">自动重发N小时以来的转发记录,0=全部</string>
|
||||
<string name="task_resend_desc" formatted="false">自动重发%s小时以来%s的转发记录</string>
|
||||
<string name="task_resend_error">必须至少选择一个【原转发状态】</string>
|
||||
<string name="task_task">启停任务</string>
|
||||
<string name="task_task_tips">控制【自动任务】的启用/禁用</string>
|
||||
|
||||
<string name="second">秒</string>
|
||||
<string name="minute">分</string>
|
||||
|
@ -1324,6 +1330,8 @@
|
|||
<string name="specified_rule_hint">填写转发规则的id,多个以半角逗号分隔</string>
|
||||
<string name="specified_sender">指定通道</string>
|
||||
<string name="specified_sender_hint">填写发送通道的id,多个以半角逗号分隔</string>
|
||||
<string name="specified_task">指定任务</string>
|
||||
<string name="specified_task_hint">填写发送通道的id,多个以半角逗号分隔</string>
|
||||
|
||||
<string name="current_language">跟随系统</string>
|
||||
<string name="current_activity_language">当前 Activity 语种:</string>
|
||||
|
|
Loading…
Reference in New Issue