From f288f5a6dc0b2d3e338218d0d497f2688c4eab64 Mon Sep 17 00:00:00 2001 From: pppscn <35696959@qq.com> Date: Sat, 16 Dec 2023 13:19:05 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9A=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=C2=B7=E5=BF=AB=E6=8D=B7=E6=8C=87=E4=BB=A4=20?= =?UTF-8?q?=E2=80=94=E2=80=94=20=E5=88=B0=E8=BE=BE=E5=9C=B0=E7=82=B9&?= =?UTF-8?q?=E7=A6=BB=E5=BC=80=E5=9C=B0=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/idormy/sms/forwarder/App.kt | 1 - .../forwarder/adapter/TaskPagingAdapter.kt | 12 ++- .../sms/forwarder/entity/LocationInfo.kt | 2 +- .../forwarder/entity/task/LocationSetting.kt | 32 +++++--- .../sms/forwarder/fragment/TasksFragment.kt | 5 +- .../sms/forwarder/service/LocationService.kt | 62 ++++++++------ .../forwarder/utils/task/ConditionUtils.kt | 26 ++++++ .../forwarder/utils/task/CronJobScheduler.kt | 4 +- .../sms/forwarder/workers/BatteryWorker.kt | 16 ++-- .../sms/forwarder/workers/CronWorker.kt | 14 ++-- .../sms/forwarder/workers/LocationWorker.kt | 81 ++++++++++++++----- .../sms/forwarder/workers/LockScreenWorker.kt | 8 +- .../sms/forwarder/workers/NetworkWorker.kt | 12 +-- .../idormy/sms/forwarder/workers/SimWorker.kt | 10 +-- .../adapter_tasks_card_view_list_item.xml | 28 +++---- app/src/main/res/values-en/strings.xml | 7 +- app/src/main/res/values/strings.xml | 11 +-- 17 files changed, 215 insertions(+), 116 deletions(-) create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/task/ConditionUtils.kt diff --git a/app/src/main/java/com/idormy/sms/forwarder/App.kt b/app/src/main/java/com/idormy/sms/forwarder/App.kt index 29ffb01f..85806093 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/App.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/App.kt @@ -88,7 +88,6 @@ class App : Application(), CactusCallback, Configuration.Provider by Core { val LocationClient by lazy { LocationClient(context) } val Geocoder by lazy { Geocoder(context) } val DateFormat by lazy { SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()) } - val GeofenceStatusMap = mutableMapOf() //是否已进入/离开围栏 } override fun attachBaseContext(base: Context) { diff --git a/app/src/main/java/com/idormy/sms/forwarder/adapter/TaskPagingAdapter.kt b/app/src/main/java/com/idormy/sms/forwarder/adapter/TaskPagingAdapter.kt index c77ebe33..bb7e2f01 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/adapter/TaskPagingAdapter.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/adapter/TaskPagingAdapter.kt @@ -73,11 +73,15 @@ class TaskPagingAdapter(private val itemClickListener: OnItemClickListener) : Pa itemClickListener.onItemClicked(view, item) } - holder.binding.sbEnableTask.isChecked = item.status == 1 - holder.binding.sbEnableTask.setOnCheckedChangeListener { view: View, isChecked -> - item.status = if (isChecked) 1 else 0 + holder.binding.sbEnable.isChecked = item.status == 1 + holder.binding.sbEnable.setOnClickListener { view: View? -> itemClickListener.onItemClicked(view, item) } + //不能用 setOnCheckedChangeListener,否则会导致切换时状态错乱 + /*holder.binding.sbEnable.setOnCheckedChangeListener { view: View, isChecked -> + item.status = if (isChecked) 1 else 0 + itemClickListener.onItemClicked(view, item) + }*/ } else { holder.binding.layoutImage.visibility = View.VISIBLE holder.binding.layoutIcons.visibility = View.GONE @@ -89,7 +93,7 @@ class TaskPagingAdapter(private val itemClickListener: OnItemClickListener) : Pa holder.binding.ivStatus.setImageResource(item.statusImageId) holder.binding.ivEdit.visibility = View.GONE holder.binding.ivDelete.visibility = View.GONE - holder.binding.sbEnableTask.visibility = View.GONE + holder.binding.sbEnable.visibility = View.GONE } holder.binding.tvName.text = item.name holder.binding.tvDescription.text = item.description diff --git a/app/src/main/java/com/idormy/sms/forwarder/entity/LocationInfo.kt b/app/src/main/java/com/idormy/sms/forwarder/entity/LocationInfo.kt index b78ec280..2f998ef6 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/entity/LocationInfo.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/entity/LocationInfo.kt @@ -19,7 +19,7 @@ data class LocationInfo( if (address != "") msg += "\n" + String.format(ResUtils.getString(R.string.location_address), address) if (time != "") msg += "\n" + String.format(ResUtils.getString(R.string.location_time), time) if (provider != "") msg += "\n" + String.format(ResUtils.getString(R.string.location_provider), provider) - return msg + return msg + "\n" } } diff --git a/app/src/main/java/com/idormy/sms/forwarder/entity/task/LocationSetting.kt b/app/src/main/java/com/idormy/sms/forwarder/entity/task/LocationSetting.kt index 9b9b80d7..71f0a498 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/entity/task/LocationSetting.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/entity/task/LocationSetting.kt @@ -1,11 +1,9 @@ package com.idormy.sms.forwarder.entity.task import com.idormy.sms.forwarder.R +import com.idormy.sms.forwarder.entity.LocationInfo +import com.idormy.sms.forwarder.utils.task.ConditionUtils.Companion.calculateDistance import java.io.Serializable -import kotlin.math.atan2 -import kotlin.math.cos -import kotlin.math.sin -import kotlin.math.sqrt data class LocationSetting( var description: String = "", //描述 @@ -25,12 +23,24 @@ data class LocationSetting( } } - fun calculateDistance(lat1: Double, lon1: Double, lat2: Double, lon2: Double): Double { - val earthRadius = 6371000.0 // 地球平均半径,单位:米 - val latDistance = Math.toRadians(lat2 - lat1) - val lonDistance = Math.toRadians(lon2 - lon1) - val a = sin(latDistance / 2) * sin(latDistance / 2) + cos(Math.toRadians(lat1)) * cos(Math.toRadians(lat2)) * sin(lonDistance / 2) * sin(lonDistance / 2) - val c = 2 * atan2(sqrt(a), sqrt(1 - a)) - return earthRadius * c + //判断是否满足条件 + fun isMatchCondition(locationOld: LocationInfo, locationNew: LocationInfo): Boolean { + if (calcType == "distance") { + val distanceOld = calculateDistance(locationOld.latitude, locationOld.longitude, latitude, longitude) + val distanceNew = calculateDistance(locationNew.latitude, locationNew.longitude, latitude, longitude) + if (type == "to" && distanceOld > distance && distanceNew <= distance) { + return true + } else if (type == "leave" && distanceOld <= distance && distanceNew > distance) { + return true + } + } else if (calcType == "address") { + if (type == "to" && !locationOld.address.contains(address) && locationNew.address.contains(address)) { + return true + } else if (type == "leave" && locationOld.address.contains(address) && !locationNew.address.contains(address)) { + return true + } + } + return false } + } diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/TasksFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/TasksFragment.kt index e44a1d49..743fb7bf 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/fragment/TasksFragment.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/TasksFragment.kt @@ -1,5 +1,6 @@ package com.idormy.sms.forwarder.fragment +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -104,7 +105,9 @@ class TasksFragment : BaseFragment(), TaskPagingAdapter.O override fun onItemClicked(view: View?, item: Task) { when (view?.id) { - R.id.sb_enable_task -> { + R.id.sb_enable -> { + item.status = if (item.status == 0) 1 else 0 + Log.d(TAG, "sb_enable: ${item.id}, ${item.status}") viewModel.updateStatus(item.id, item.status) } diff --git a/app/src/main/java/com/idormy/sms/forwarder/service/LocationService.kt b/app/src/main/java/com/idormy/sms/forwarder/service/LocationService.kt index 71f01df9..318a20eb 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/service/LocationService.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/service/LocationService.kt @@ -45,7 +45,7 @@ class LocationService : Service(), Server.ServerListener { super.onCreate() if (!SettingUtils.enableLocation) return - startForegroundService() + startService() } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { @@ -53,11 +53,11 @@ class LocationService : Service(), Server.ServerListener { if (intent != null) { when (intent.action) { "START" -> { - startForegroundService() + startService() } "STOP" -> { - stopForegroundService() + stopService() } } } @@ -70,7 +70,7 @@ class LocationService : Service(), Server.ServerListener { super.onDestroy() if (!SettingUtils.enableLocation) return - stopForegroundService() + stopService() } override fun onException(e: Exception?) { @@ -85,9 +85,12 @@ class LocationService : Service(), Server.ServerListener { Log.i(TAG, "onStopped: ") } - private fun startForegroundService() { + private fun startService() { try { - //远程找手机 TODO: 判断权限 ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION + //清空缓存 + HttpServerUtils.apiLocationCache = LocationInfo() + TaskUtils.lastLocationInfo = LocationInfo() + if (SettingUtils.enableLocation && PermissionUtils.isGranted(android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION)) { //可根据具体需求设置定位配置参数(这里只列出一些主要的参数) val locationOption = App.LocationClient.getLocationOption().setAccuracy(SettingUtils.locationAccuracy)//设置位置精度:高精度 @@ -121,28 +124,15 @@ class LocationService : Service(), Server.ServerListener { //TODO: 触发自动任务 val locationInfoOld = TaskUtils.lastLocationInfo - TaskUtils.lastLocationInfo = locationInfoNew if (locationInfoOld.longitude != locationInfoNew.longitude || locationInfoOld.latitude != locationInfoNew.latitude || locationInfoOld.address != locationInfoNew.address) { Log.d(TAG, "locationInfoOld = $locationInfoOld") + TaskUtils.lastLocationInfo = locationInfoNew - val locationInfoJsonOld = Gson().toJson(locationInfoOld) - val locationInfoJsonNew = Gson().toJson(locationInfoNew) - val toAddressRequest = OneTimeWorkRequestBuilder().setInputData( - workDataOf( - TaskWorker.conditionType to TASK_CONDITION_TO_ADDRESS, - "locationInfoJsonOld" to locationInfoJsonOld, - "locationInfoJsonNew" to locationInfoJsonNew, - ) - ).build() - WorkManager.getInstance(applicationContext).enqueue(toAddressRequest) - val leaveAddressRequest = OneTimeWorkRequestBuilder().setInputData( - workDataOf( - TaskWorker.conditionType to TASK_CONDITION_LEAVE_ADDRESS, - "locationInfoJsonOld" to locationInfoJsonNew, - "locationInfoJsonNew" to locationInfoJsonOld, - ) - ).build() - WorkManager.getInstance(applicationContext).enqueue(leaveAddressRequest) + val gson = Gson() + val locationJsonOld = gson.toJson(locationInfoOld) + val locationJsonNew = gson.toJson(locationInfoNew) + enqueueLocationWorkerRequest(TASK_CONDITION_TO_ADDRESS, locationJsonOld, locationJsonNew) + enqueueLocationWorkerRequest(TASK_CONDITION_LEAVE_ADDRESS, locationJsonOld, locationJsonNew) } } @@ -185,7 +175,11 @@ class LocationService : Service(), Server.ServerListener { } } - private fun stopForegroundService() { + private fun stopService() { + //清空缓存 + HttpServerUtils.apiLocationCache = LocationInfo() + TaskUtils.lastLocationInfo = LocationInfo() + isRunning = try { //如果已经开始定位,则先停止定位 if (SettingUtils.enableLocation && App.LocationClient.isStarted()) { @@ -200,4 +194,20 @@ class LocationService : Service(), Server.ServerListener { } } + private fun enqueueLocationWorkerRequest( + conditionType: Int, + locationJsonOld: String, + locationJsonNew: String + ) { + val locationWorkerRequest = OneTimeWorkRequestBuilder().setInputData( + workDataOf( + TaskWorker.conditionType to conditionType, + "locationJsonOld" to locationJsonOld, + "locationJsonNew" to locationJsonNew + ) + ).build() + + WorkManager.getInstance(applicationContext).enqueue(locationWorkerRequest) + } + } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/task/ConditionUtils.kt b/app/src/main/java/com/idormy/sms/forwarder/utils/task/ConditionUtils.kt new file mode 100644 index 00000000..2864ec52 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/task/ConditionUtils.kt @@ -0,0 +1,26 @@ +package com.idormy.sms.forwarder.utils.task + +import kotlin.math.atan2 +import kotlin.math.cos +import kotlin.math.sin +import kotlin.math.sqrt + +/** + * 自动任务条件工具类 + */ +class ConditionUtils private constructor() { + + companion object { + + //计算两个经纬度之间的距离 + fun calculateDistance(lat1: Double, lon1: Double, lat2: Double, lon2: Double): Double { + val earthRadius = 6371000.0 // 地球平均半径,单位:米 + val latDistance = Math.toRadians(lat2 - lat1) + val lonDistance = Math.toRadians(lon2 - lon1) + val a = sin(latDistance / 2) * sin(latDistance / 2) + cos(Math.toRadians(lat1)) * cos(Math.toRadians(lat2)) * sin(lonDistance / 2) * sin(lonDistance / 2) + val c = 2 * atan2(sqrt(a), sqrt(1 - a)) + return earthRadius * c + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/task/CronJobScheduler.kt b/app/src/main/java/com/idormy/sms/forwarder/utils/task/CronJobScheduler.kt index 05aa4d0c..d27011ff 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/task/CronJobScheduler.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/task/CronJobScheduler.kt @@ -22,12 +22,12 @@ class CronJobScheduler { val delayInMillis = task.nextExecTime.time / 1000 * 1000 - currentTimeMillis val inputData = Data.Builder().putLong(TaskWorker.taskId, task.id).build() val taskRequest = if (delayInMillis <= 0L) { - Log.d(TAG, "任务${task.id}:立即执行,delayInMillis = $delayInMillis") + Log.d(TAG, "TASK-${task.id}:立即执行,delayInMillis = $delayInMillis") OneTimeWorkRequestBuilder() .setInputData(inputData) .build() } else { - Log.d(TAG, "任务${task.id}:延迟 $delayInMillis 毫秒执行") + Log.d(TAG, "TASK-${task.id}:延迟 $delayInMillis 毫秒执行") OneTimeWorkRequestBuilder() .setInitialDelay(delayInMillis, TimeUnit.MILLISECONDS) .setInputData(inputData) diff --git a/app/src/main/java/com/idormy/sms/forwarder/workers/BatteryWorker.kt b/app/src/main/java/com/idormy/sms/forwarder/workers/BatteryWorker.kt index 8fb86141..946ecd83 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/workers/BatteryWorker.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/workers/BatteryWorker.kt @@ -46,24 +46,24 @@ class BatteryWorker(context: Context, params: WorkerParameters) : CoroutineWorke // 根据任务信息执行相应操作 val conditionList = Gson().fromJson(task.conditions, Array::class.java).toMutableList() if (conditionList.isEmpty()) { - Log.d(TAG, "任务${task.id}:conditionList is empty") + Log.d(TAG, "TASK-${task.id}:conditionList is empty") continue } val firstCondition = conditionList.firstOrNull() if (firstCondition == null) { - Log.d(TAG, "任务${task.id}:firstCondition is null") + Log.d(TAG, "TASK-${task.id}:firstCondition is null") continue } val batterySetting = Gson().fromJson(firstCondition.setting, BatterySetting::class.java) if (batterySetting == null) { - Log.d(TAG, "任务${task.id}:batterySetting is null") + Log.d(TAG, "TASK-${task.id}:batterySetting is null") continue } val msg = batterySetting.getMsg(status, levelNew, levelOld, TaskUtils.batteryInfo) if (msg.isEmpty()) { - Log.d(TAG, "任务${task.id}:msg is empty, batterySetting = $batterySetting, status = $status, levelNew = $levelNew, levelOld = $levelOld") + Log.d(TAG, "TASK-${task.id}:msg is empty, batterySetting = $batterySetting, status = $status, levelNew = $levelNew, levelOld = $levelOld") continue } @@ -101,24 +101,24 @@ class BatteryWorker(context: Context, params: WorkerParameters) : CoroutineWorke // 根据任务信息执行相应操作 val conditionList = Gson().fromJson(task.conditions, Array::class.java).toMutableList() if (conditionList.isEmpty()) { - Log.d(TAG, "任务${task.id}:conditionList is empty") + Log.d(TAG, "TASK-${task.id}:conditionList is empty") continue } val firstCondition = conditionList.firstOrNull() if (firstCondition == null) { - Log.d(TAG, "任务${task.id}:firstCondition is null") + Log.d(TAG, "TASK-${task.id}:firstCondition is null") continue } val chargeSetting = Gson().fromJson(firstCondition.setting, ChargeSetting::class.java) if (chargeSetting == null) { - Log.d(TAG, "任务${task.id}:chargeSetting is null") + Log.d(TAG, "TASK-${task.id}:chargeSetting is null") continue } val msg = chargeSetting.getMsg(statusNew, statusOld, pluggedNew, pluggedOld, TaskUtils.batteryInfo) if (msg.isEmpty()) { - Log.d(TAG, "任务${task.id}:msg is empty, chargeSetting = $chargeSetting, statusNew = $statusNew, statusOld = $statusOld, pluggedNew = $pluggedNew, pluggedOld = $pluggedOld") + Log.d(TAG, "TASK-${task.id}:msg is empty, chargeSetting = $chargeSetting, statusNew = $statusNew, statusOld = $statusOld, pluggedNew = $pluggedNew, pluggedOld = $pluggedOld") continue } diff --git a/app/src/main/java/com/idormy/sms/forwarder/workers/CronWorker.kt b/app/src/main/java/com/idormy/sms/forwarder/workers/CronWorker.kt index 30e66c6f..ff50a0ae 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/workers/CronWorker.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/workers/CronWorker.kt @@ -32,30 +32,30 @@ class CronWorker(context: Context, params: WorkerParameters) : CoroutineWorker(c val task = AppDatabase.getInstance(App.context).taskDao().getOne(taskId) if (task.status == 0) { - Log.d(TAG, "任务${task.id}:task is disabled") + Log.d(TAG, "TASK-${task.id}:task is disabled") return Result.success() } // 根据任务信息执行相应操作 val conditionList = Gson().fromJson(task.conditions, Array::class.java).toMutableList() if (conditionList.isEmpty()) { - Log.d(TAG, "任务${task.id}:conditionList is empty") + Log.d(TAG, "TASK-${task.id}:conditionList is empty") return Result.failure() } val firstCondition = conditionList.firstOrNull() if (firstCondition == null) { - Log.d(TAG, "任务${task.id}:firstCondition is null") + Log.d(TAG, "TASK-${task.id}:firstCondition is null") return Result.failure() } val cronSetting = Gson().fromJson(firstCondition.setting, CronSetting::class.java) if (cronSetting == null) { - Log.d(TAG, "任务${task.id}:cronSetting is null") + Log.d(TAG, "TASK-${task.id}:cronSetting is null") return Result.failure() } // TODO: 判断其他条件是否满足 if (false) { - Log.d(TAG, "任务${task.id}:其他条件不满足") + Log.d(TAG, "TASK-${task.id}:其他条件不满足") return Result.failure() } @@ -67,7 +67,7 @@ class CronWorker(context: Context, params: WorkerParameters) : CoroutineWorker(c // 将 nextExecTime 的毫秒部分设置为 0,避免因为毫秒部分不同导致的任务重复执行 nextExecTime.time = nextExecTime.time / 1000 * 1000 task.nextExecTime = nextExecTime - Log.d(TAG, "任务${task.id}:lastExecTime = ${task.lastExecTime}, nextExecTime = ${task.nextExecTime}") + Log.d(TAG, "TASK-${task.id}:lastExecTime = ${task.lastExecTime}, nextExecTime = ${task.nextExecTime}") // 自动禁用任务 if (task.nextExecTime.time / 1000 < now.time / 1000) { @@ -78,7 +78,7 @@ class CronWorker(context: Context, params: WorkerParameters) : CoroutineWorker(c AppDatabase.getInstance(App.context).taskDao().updateExecTime(task.id, task.lastExecTime, task.nextExecTime, task.status) if (task.status == 0) { - Log.d(TAG, "任务${task.id}:task is disabled") + Log.d(TAG, "TASK-${task.id}:task is disabled") return Result.success() } diff --git a/app/src/main/java/com/idormy/sms/forwarder/workers/LocationWorker.kt b/app/src/main/java/com/idormy/sms/forwarder/workers/LocationWorker.kt index 9f205c88..ee360db7 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/workers/LocationWorker.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/workers/LocationWorker.kt @@ -9,6 +9,7 @@ import androidx.work.WorkManager 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.entity.LocationInfo import com.idormy.sms.forwarder.entity.MsgInfo @@ -17,6 +18,8 @@ import com.idormy.sms.forwarder.entity.task.TaskSetting 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 +import com.idormy.sms.forwarder.utils.task.ConditionUtils.Companion.calculateDistance +import com.xuexiang.xutil.resource.ResUtils.getString import java.util.Date @Suppress("PrivatePropertyName", "DEPRECATION") @@ -26,22 +29,24 @@ class LocationWorker(context: Context, params: WorkerParameters) : CoroutineWork override suspend fun doWork(): Result { - Log.d(TAG, "doWork") - val locationInfoJsonOld = inputData.getString("locationInfoJsonOld") - val locationInfoJsonNew = inputData.getString("locationInfoJsonNew") - if (locationInfoJsonOld == null || locationInfoJsonNew == null) { + val conditionType = inputData.getInt(TaskWorker.conditionType, -1) + val locationJsonOld = inputData.getString("locationJsonOld") + val locationJsonNew = inputData.getString("locationJsonNew") + Log.d(TAG, "conditionType = $conditionType, locationJsonOld = $locationJsonOld, locationJsonNew = $locationJsonNew") + + if (locationJsonOld == null || locationJsonNew == null) { Log.d(TAG, "locationInfoOld or locationInfoNew is null") return Result.failure() } - val locationInfoOld = Gson().fromJson(locationInfoJsonOld, LocationInfo::class.java) - val locationInfoNew = Gson().fromJson(locationInfoJsonNew, LocationInfo::class.java) - if (locationInfoOld == null || locationInfoNew == null) { + val locationOld = Gson().fromJson(locationJsonOld, LocationInfo::class.java) + val locationNew = Gson().fromJson(locationJsonNew, LocationInfo::class.java) + if (locationOld == null || locationNew == null) { Log.d(TAG, "locationInfoOld or locationInfoNew is null") return Result.failure() } - when (val conditionType = inputData.getInt(TaskWorker.conditionType, -1)) { + when (conditionType) { //到达地点 TASK_CONDITION_TO_ADDRESS -> { @@ -52,26 +57,46 @@ class LocationWorker(context: Context, params: WorkerParameters) : CoroutineWork // 根据任务信息执行相应操作 val conditionList = Gson().fromJson(task.conditions, Array::class.java).toMutableList() if (conditionList.isEmpty()) { - Log.d(TAG, "任务${task.id}:conditionList is empty") + Log.d(TAG, "TASK-${task.id}:conditionList is empty") continue } val firstCondition = conditionList.firstOrNull() if (firstCondition == null) { - Log.d(TAG, "任务${task.id}:firstCondition is null") + Log.d(TAG, "TASK-${task.id}:firstCondition is null") continue } val locationSetting = Gson().fromJson(firstCondition.setting, LocationSetting::class.java) if (locationSetting == null) { - Log.d(TAG, "任务${task.id}:locationSetting is null") + Log.d(TAG, "TASK-${task.id}:locationSetting is null") continue } //TODO:判断条件是否满足 + var description = locationSetting.description + val isMatchCondition = when (locationSetting.calcType) { + "distance" -> { + val distanceOld = calculateDistance(locationOld.latitude, locationOld.longitude, locationSetting.latitude, locationSetting.longitude) + val distanceNew = calculateDistance(locationNew.latitude, locationNew.longitude, locationSetting.latitude, locationSetting.longitude) + Log.d(TAG, "TASK-${task.id}:distanceOld = $distanceOld, distanceNew = $distanceNew") + description += String.format(getString(R.string.current_distance_from_center), String.format("%.2f", distanceNew)) + distanceOld > locationSetting.distance && distanceNew <= locationSetting.distance + } + + "address" -> { + !locationOld.address.contains(locationSetting.address) && locationNew.address.contains(locationSetting.address) + } + + else -> false + } + + if (!isMatchCondition) { + Log.d(TAG, "TASK-${task.id}:isMatchCondition = false") + continue + } //TODO: 组装消息体 && 执行具体任务 - val msg = locationInfoNew.toString() - val msgInfo = MsgInfo("task", task.name, msg, Date(), task.name) + val msgInfo = MsgInfo("task", task.name, locationNew.toString(), Date(), description) val actionData = Data.Builder().putLong(TaskWorker.taskId, task.id).putString(TaskWorker.taskActions, task.actions).putString(TaskWorker.msgInfo, Gson().toJson(msgInfo)).build() val actionRequest = OneTimeWorkRequestBuilder().setInputData(actionData).build() WorkManager.getInstance().enqueue(actionRequest) @@ -89,26 +114,46 @@ class LocationWorker(context: Context, params: WorkerParameters) : CoroutineWork // 根据任务信息执行相应操作 val conditionList = Gson().fromJson(task.conditions, Array::class.java).toMutableList() if (conditionList.isEmpty()) { - Log.d(TAG, "任务${task.id}:conditionList is empty") + Log.d(TAG, "TASK-${task.id}:conditionList is empty") continue } val firstCondition = conditionList.firstOrNull() if (firstCondition == null) { - Log.d(TAG, "任务${task.id}:firstCondition is null") + Log.d(TAG, "TASK-${task.id}:firstCondition is null") continue } val locationSetting = Gson().fromJson(firstCondition.setting, LocationSetting::class.java) if (locationSetting == null) { - Log.d(TAG, "任务${task.id}:locationSetting is null") + Log.d(TAG, "TASK-${task.id}:locationSetting is null") continue } //TODO:判断条件是否满足 + var description = locationSetting.description + val isMatchCondition = when (locationSetting.calcType) { + "distance" -> { + val distanceOld = calculateDistance(locationOld.latitude, locationOld.longitude, locationSetting.latitude, locationSetting.longitude) + val distanceNew = calculateDistance(locationNew.latitude, locationNew.longitude, locationSetting.latitude, locationSetting.longitude) + Log.d(TAG, "TASK-${task.id}:distanceOld = $distanceOld, distanceNew = $distanceNew") + description += String.format(getString(R.string.current_distance_from_center), String.format("%.2f", distanceNew)) + distanceOld <= locationSetting.distance && distanceNew > locationSetting.distance + } + + "address" -> { + locationOld.address.contains(locationSetting.address) && !locationNew.address.contains(locationSetting.address) + } + + else -> false + } + + if (!isMatchCondition) { + Log.d(TAG, "TASK-${task.id}:isMatchCondition = false") + continue + } //TODO: 组装消息体 && 执行具体任务 - val msg = locationInfoNew.toString() - val msgInfo = MsgInfo("task", task.name, msg, Date(), task.description) + val msgInfo = MsgInfo("task", task.name, locationNew.toString(), Date(), description) val actionData = Data.Builder().putLong(TaskWorker.taskId, task.id).putString(TaskWorker.taskActions, task.actions).putString(TaskWorker.msgInfo, Gson().toJson(msgInfo)).build() val actionRequest = OneTimeWorkRequestBuilder().setInputData(actionData).build() WorkManager.getInstance().enqueue(actionRequest) diff --git a/app/src/main/java/com/idormy/sms/forwarder/workers/LockScreenWorker.kt b/app/src/main/java/com/idormy/sms/forwarder/workers/LockScreenWorker.kt index a2641f3b..fdc0052f 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/workers/LockScreenWorker.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/workers/LockScreenWorker.kt @@ -35,23 +35,23 @@ class LockScreenWorker(context: Context, params: WorkerParameters) : CoroutineWo // 根据任务信息执行相应操作 val conditionList = Gson().fromJson(task.conditions, Array::class.java).toMutableList() if (conditionList.isEmpty()) { - Log.d(TAG, "任务${task.id}:conditionList is empty") + Log.d(TAG, "TASK-${task.id}:conditionList is empty") continue } val firstCondition = conditionList.firstOrNull() if (firstCondition == null) { - Log.d(TAG, "任务${task.id}:firstCondition is null") + Log.d(TAG, "TASK-${task.id}:firstCondition is null") continue } val lockScreenSetting = Gson().fromJson(firstCondition.setting, LockScreenSetting::class.java) if (lockScreenSetting == null) { - Log.d(TAG, "任务${task.id}:lockScreenSetting is null") + Log.d(TAG, "TASK-${task.id}:lockScreenSetting is null") continue } if (action != lockScreenSetting.action) { - Log.d(TAG, "任务${task.id}:action is not match, action = $action, lockScreenSetting = $lockScreenSetting") + Log.d(TAG, "TASK-${task.id}:action is not match, action = $action, lockScreenSetting = $lockScreenSetting") continue } diff --git a/app/src/main/java/com/idormy/sms/forwarder/workers/NetworkWorker.kt b/app/src/main/java/com/idormy/sms/forwarder/workers/NetworkWorker.kt index 9bb9129c..56327390 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/workers/NetworkWorker.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/workers/NetworkWorker.kt @@ -39,23 +39,23 @@ class NetworkWorker(context: Context, params: WorkerParameters) : CoroutineWorke // 根据任务信息执行相应操作 val conditionList = Gson().fromJson(task.conditions, Array::class.java).toMutableList() if (conditionList.isEmpty()) { - Log.d(TAG, "任务${task.id}:conditionList is empty") + Log.d(TAG, "TASK-${task.id}:conditionList is empty") continue } val firstCondition = conditionList.firstOrNull() if (firstCondition == null) { - Log.d(TAG, "任务${task.id}:firstCondition is null") + Log.d(TAG, "TASK-${task.id}:firstCondition is null") continue } val networkSetting = Gson().fromJson(firstCondition.setting, NetworkSetting::class.java) if (networkSetting == null) { - Log.d(TAG, "任务${task.id}:networkSetting is null") + Log.d(TAG, "TASK-${task.id}:networkSetting is null") continue } if (TaskUtils.networkState != networkSetting.networkState) { - Log.d(TAG, "任务${task.id}:networkState is not match, networkSetting = $networkSetting") + Log.d(TAG, "TASK-${task.id}:networkState is not match, networkSetting = $networkSetting") continue } @@ -70,7 +70,7 @@ class NetworkWorker(context: Context, params: WorkerParameters) : CoroutineWorke 1 -> { val dataSimSlot = TaskUtils.dataSimSlot if (networkSetting.dataSimSlot != 0 && dataSimSlot != networkSetting.dataSimSlot) { - Log.d(TAG, "任务${task.id}:dataSimSlot is not match, networkSetting = $networkSetting") + Log.d(TAG, "TASK-${task.id}:dataSimSlot is not match, networkSetting = $networkSetting") continue } msg.append(getString(R.string.net_mobile)).append("\n") @@ -93,7 +93,7 @@ class NetworkWorker(context: Context, params: WorkerParameters) : CoroutineWorke //WiFi 2 -> { if (networkSetting.wifiSsid.isNotEmpty() && TaskUtils.wifiSsid != networkSetting.wifiSsid) { - Log.d(TAG, "任务${task.id}:wifiSsid is not match, networkSetting = $networkSetting") + Log.d(TAG, "TASK-${task.id}:wifiSsid is not match, networkSetting = $networkSetting") continue } msg.append(getString(R.string.net_wifi)).append("\n") diff --git a/app/src/main/java/com/idormy/sms/forwarder/workers/SimWorker.kt b/app/src/main/java/com/idormy/sms/forwarder/workers/SimWorker.kt index 14b65c6f..5fedcc49 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/workers/SimWorker.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/workers/SimWorker.kt @@ -36,29 +36,29 @@ class SimWorker(context: Context, params: WorkerParameters) : CoroutineWorker(co // 根据任务信息执行相应操作 val conditionList = Gson().fromJson(task.conditions, Array::class.java).toMutableList() if (conditionList.isEmpty()) { - Log.d(TAG, "任务${task.id}:conditionList is empty") + Log.d(TAG, "TASK-${task.id}:conditionList is empty") continue } val firstCondition = conditionList.firstOrNull() if (firstCondition == null) { - Log.d(TAG, "任务${task.id}:firstCondition is null") + Log.d(TAG, "TASK-${task.id}:firstCondition is null") continue } val simSetting = Gson().fromJson(firstCondition.setting, SimSetting::class.java) if (simSetting == null) { - Log.d(TAG, "任务${task.id}:simSetting is null") + Log.d(TAG, "TASK-${task.id}:simSetting is null") continue } if (TaskUtils.simState != simSetting.simState) { - Log.d(TAG, "任务${task.id}:networkState is not match, simSetting = $simSetting") + Log.d(TAG, "TASK-${task.id}:networkState is not match, simSetting = $simSetting") continue } //TODO:判断其他条件是否满足,注意:SIM卡已准备就绪,延迟5秒才进入这里(给够搜索信号时间) /*if (!TaskUtils.isConditionMatch(task, msg)) { - Log.d(TAG, "任务${task.id}:condition is not match") + Log.d(TAG, "TASK-${task.id}:condition is not match") continue }*/ diff --git a/app/src/main/res/layout/adapter_tasks_card_view_list_item.xml b/app/src/main/res/layout/adapter_tasks_card_view_list_item.xml index 7870f5b6..e91e3da6 100644 --- a/app/src/main/res/layout/adapter_tasks_card_view_list_item.xml +++ b/app/src/main/res/layout/adapter_tasks_card_view_list_item.xml @@ -45,7 +45,7 @@ android:orientation="horizontal" /> + + - - diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index bae1b5ba..27904540 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -1235,13 +1235,14 @@ = leaved Latitude and longitude or distance cannot be empty. Address keyword cannot be empty. - Around longitude %s, latitude %s, within a %s-meter radius. + Entering area centered at (%s, %s) with a radius of %s-meter. GPS address contains %s means arrival. - Leave around longitude %s, latitude %s, within a %s-meter radius. + Leave area centered at (%s, %s) with a radius of %s-meter. GPS address NOT contains %s means leaved. This type of condition already exists. This type of action already exists. - Only one condition, either "To Address" or "Leave Address" can be added. + "To Address" vs "Leave Address": mutually exclusive. Current Address: %s Location failed. Please try again later. + , %s meters from the center. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index acb82698..2926b1bf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1236,13 +1236,14 @@ 则表示离开 经纬度或距离都不能为空 地址关键字不能为空 - 进入以经度:%s,维度:%s为中心,%s米半径的区域 + 进入以经纬度(%s,%s)为中心, %s米为半径的区域 进入GPS地址包含[%s]关键字区域 - 离开以经度:%s,维度:%s为中心,%s米半径的区域 + 离开以经纬度(%s,%s)为中心, %s米为半径的区域 离开GPS地址包含[%s]关键字区域 - 已经添加过该类型条件 - 已经添加过该类型动作 - 只能添加一个 进入地点 或 离开地址 类型条件 + 已添加过该类型条件 + 已添加过该类型动作 + 进入地点 与 离开地址 类型条件互斥 当前地址:%s 定位失败,请稍后重试 + , 当前距离中心%s米