新增:自动任务·快捷指令 —— 网络状态改变(废弃:`77777777`)

pull/408/head
pppscn 10 months ago
parent eb20d8ea05
commit 2233c0032f

@ -264,31 +264,32 @@
</intent-filter>
</receiver>
<receiver
android:name=".receiver.SmsReceiver"
android:name=".receiver.CallReceiver"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS"
tools:ignore="IntentFilterExportedReceiver">
<intent-filter android:priority="2147483647">
<!--兼容OV系手机短信广播-->
<action android:name="android.provider.OppoSpeechAssist.SMS_RECEIVED" />
<action android:name="android.provider.Telephony.SMS_DELIVER" />
<!--短信广播-->
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
<intent-filter android:priority="2147483647">
<action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
<action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
<data android:mimeType="application/vnd.wap.mms-message" />
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
<receiver
android:name=".receiver.CallReceiver"
android:name=".receiver.NetworkChangeReceiver"
android:enabled="true"
android:exported="true"
tools:ignore="IntentFilterExportedReceiver">
android:permission="android.permission.READ_PHONE_STATE">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
<action
android:name="android.net.conn.CONNECTIVITY_CHANGE"
tools:ignore="BatteryLife" />
<action
android:name="android.net.wifi.WIFI_STATE_CHANGED"
tools:ignore="BatteryLife" />
<action
android:name="android.net.wifi.STATE_CHANGE"
tools:ignore="BatteryLife" />
<!--<action
android:name="android.intent.action.DATA_CONNECTION_STATE_CHANGED"
tools:ignore="BatteryLife" />-->
</intent-filter>
</receiver>
<receiver
@ -300,6 +301,25 @@
<action android:name="android.intent.action.SIM_STATE_CHANGED" />
</intent-filter>
</receiver>
<receiver
android:name=".receiver.SmsReceiver"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS"
tools:ignore="IntentFilterExportedReceiver">
<intent-filter android:priority="2147483647">
<!--兼容OV系手机短信广播-->
<action android:name="android.provider.OppoSpeechAssist.SMS_RECEIVED" />
<action android:name="android.provider.Telephony.SMS_DELIVER" />
<!--短信广播-->
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
<intent-filter android:priority="2147483647">
<action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
<action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
<data android:mimeType="application/vnd.wap.mms-message" />
</intent-filter>
</receiver>
</application>

@ -6,6 +6,8 @@ import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.ConnectivityManager
import android.net.wifi.WifiManager
import android.os.Build
import android.util.Log
import androidx.lifecycle.MutableLiveData
@ -21,6 +23,7 @@ import com.idormy.sms.forwarder.database.repository.*
import com.idormy.sms.forwarder.entity.SimInfo
import com.idormy.sms.forwarder.receiver.BatteryReceiver
import com.idormy.sms.forwarder.receiver.CactusReceiver
import com.idormy.sms.forwarder.receiver.NetworkChangeReceiver
import com.idormy.sms.forwarder.service.ForegroundService
import com.idormy.sms.forwarder.service.HttpServerService
import com.idormy.sms.forwarder.utils.*
@ -38,6 +41,7 @@ import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.TimeUnit
@Suppress("DEPRECATION")
class App : Application(), CactusCallback, Configuration.Provider by Core {
val applicationScope = CoroutineScope(SupervisorJob())
@ -128,8 +132,18 @@ class App : Application(), CactusCallback, Configuration.Provider by Core {
//监听电量&充电状态变化
val batteryReceiver = BatteryReceiver()
val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
registerReceiver(batteryReceiver, filter)
val batteryFilter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
registerReceiver(batteryReceiver, batteryFilter)
//监听网络变化
val networkReceiver = NetworkChangeReceiver()
val networkFilter = IntentFilter().apply {
addAction(ConnectivityManager.CONNECTIVITY_ACTION)
addAction(WifiManager.WIFI_STATE_CHANGED_ACTION)
addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION)
//addAction("android.intent.action.DATA_CONNECTION_STATE_CHANGED")
}
registerReceiver(networkReceiver, networkFilter)
//Cactus 集成双进程前台服务JobScheduleronePix(一像素)WorkManager无声音乐
if (SettingUtils.enableCactus) {

@ -7,9 +7,12 @@ import java.io.Serializable
data class NetworkSetting(
var description: String = "", //描述
var networkState: Int = 0, //网络状态0-没有网络1-移动网络2-WiFi3-以太网, 4-未知
var dataSimSlot: Int = 0, //数据卡槽0-不限1-卡12-卡2
var wifiSsid: String = "", //WiFi名称
) : Serializable {
constructor(networkStateCheckId: Int) : this() {
constructor(networkStateCheckId: Int, dataSimSlotCheckId: Int, ssid: String) : this() {
wifiSsid = ssid
networkState = when (networkStateCheckId) {
R.id.rb_no_network -> 0
R.id.rb_net_mobile -> 1
@ -17,6 +20,12 @@ data class NetworkSetting(
R.id.rb_net_ethernet -> 3
else -> 4
}
dataSimSlot = when (dataSimSlotCheckId) {
R.id.rb_data_sim_slot_0 -> 0
R.id.rb_data_sim_slot_1 -> 1
R.id.rb_data_sim_slot_2 -> 2
else -> 0
}
description = String.format(
getString(R.string.network_state),
when (networkState) {
@ -27,6 +36,12 @@ data class NetworkSetting(
else -> getString(R.string.net_unknown)
}
)
if (networkState == 1 && dataSimSlot != 0) {
description += ", " + getString(R.string.data_sim_index) + ": SIM-" + dataSimSlot
}
if (networkState == 2 && wifiSsid.isNotEmpty()) {
description += ", " + getString(R.string.wifi_ssid) + ": " + wifiSsid
}
}
fun getNetworkStateCheckId(): Int {
@ -38,4 +53,13 @@ data class NetworkSetting(
else -> R.id.rb_net_unknown
}
}
fun getDataSimSlotCheckId(): Int {
return when (dataSimSlot) {
0 -> R.id.rb_data_sim_slot_0
1 -> R.id.rb_data_sim_slot_1
2 -> R.id.rb_data_sim_slot_2
else -> R.id.rb_data_sim_slot_0
}
}
}

@ -118,9 +118,6 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
SettingUtils.autoCleanLogsDays = newValue
}
//监听网络状态变化
switchNetworkStateReceiver(binding!!.sbNetworkStateReceiver)
//开机启动
checkWithReboot(binding!!.sbWithReboot, binding!!.tvAutoStartup)
//忽略电池优化设置
@ -607,15 +604,6 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
}
}
//监听网络状态变化
@SuppressLint("UseSwitchCompatOrMaterialCode")
fun switchNetworkStateReceiver(sbNetworkStateReceiver: SwitchButton) {
sbNetworkStateReceiver.isChecked = SettingUtils.enableNetworkStateReceiver
sbNetworkStateReceiver.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
SettingUtils.enableNetworkStateReceiver = isChecked
}
}
//开机启动
private fun checkWithReboot(
@SuppressLint("UseSwitchCompatOrMaterialCode") sbWithReboot: SwitchButton, tvAutoStartup: TextView

@ -69,11 +69,19 @@ class NetworkFragment : BaseFragment<FragmentTasksConditionNetworkBinding?>(), V
}
})
binding!!.rgNetworkState.setOnCheckedChangeListener { _, checkedId ->
Log.d(TAG, "rgNetworkState checkedId:$checkedId")
binding!!.layoutDataSimSlot.visibility = if (checkedId == R.id.rb_net_mobile) View.VISIBLE else View.GONE
binding!!.layoutWifiSsid.visibility = if (checkedId == R.id.rb_net_wifi) View.VISIBLE else View.GONE
}
Log.d(TAG, "initViews eventData:$eventData")
if (eventData != null) {
val settingVo = Gson().fromJson(eventData, NetworkSetting::class.java)
Log.d(TAG, "initViews settingVo:$settingVo")
binding!!.rgNetworkState.check(settingVo.getNetworkStateCheckId())
binding!!.rgDataSimSlot.check(settingVo.getDataSimSlotCheckId())
binding!!.etWifiSsid.setText(settingVo.wifiSsid)
}
}
@ -136,6 +144,8 @@ class NetworkFragment : BaseFragment<FragmentTasksConditionNetworkBinding?>(), V
//检查设置
private fun checkSetting(): NetworkSetting {
val networkStateCheckId = binding!!.rgNetworkState.checkedRadioButtonId
return NetworkSetting(networkStateCheckId)
val dataSimSlotCheckId = binding!!.rgDataSimSlot.checkedRadioButtonId
val wifiSsid = binding!!.etWifiSsid.text.toString().trim()
return NetworkSetting(networkStateCheckId, dataSimSlotCheckId, wifiSsid)
}
}

@ -0,0 +1,196 @@
@file:Suppress("DEPRECATION")
package com.idormy.sms.forwarder.receiver
import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.net.ConnectivityManager
import android.net.NetworkInfo
import android.net.wifi.WifiManager
import android.os.Build
import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.workDataOf
import com.idormy.sms.forwarder.utils.TASK_CONDITION_NETWORK
import com.idormy.sms.forwarder.utils.TaskWorker
import com.idormy.sms.forwarder.utils.task.TaskUtils
import com.idormy.sms.forwarder.workers.NetworkWorker
@Suppress("PrivatePropertyName", "DEPRECATION", "UNUSED_PARAMETER")
class NetworkChangeReceiver : BroadcastReceiver() {
private val TAG: String = NetworkChangeReceiver::class.java.simpleName
override fun onReceive(context: Context, intent: Intent) {
Log.d(TAG, "onReceive: ${intent.action}")
when (intent.action) {
ConnectivityManager.CONNECTIVITY_ACTION -> {
handleConnectivityChange(context)
}
WifiManager.WIFI_STATE_CHANGED_ACTION -> {
handleWifiStateChanged(context, intent)
}
WifiManager.NETWORK_STATE_CHANGED_ACTION -> {
handleNetworkStateChanged(context, intent)
}
//"android.intent.action.DATA_CONNECTION_STATE_CHANGED" -> {
// handleDataConnectionStateChanged(context, intent)
//}
}
}
private fun handleConnectivityChange(context: Context) {
val networkStateOld = TaskUtils.networkState
val dataSimSlotOld = TaskUtils.dataSimSlot
val wifiSsidOld = TaskUtils.wifiSsid
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val networkInfo = connectivityManager.activeNetworkInfo
if (networkInfo != null && networkInfo.isConnected) {
Log.d(TAG, "Network Connected")
if (networkInfo.type == ConnectivityManager.TYPE_MOBILE) {
//移动网络
TaskUtils.networkState = 1
//获取当前使用的 SIM index
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
TaskUtils.dataSimSlot = getSlotIndex(context) + 1
}
} else if (networkInfo.type == ConnectivityManager.TYPE_WIFI) {
//WiFi网络
TaskUtils.networkState = 2
//获取WiFi名称
val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
val wifiInfo = wifiManager.connectionInfo
TaskUtils.wifiSsid = wifiInfo.ssid.replace("\"", "")
}
} else {
Log.d(TAG, "Network Disconnected")
TaskUtils.networkState = 0
TaskUtils.dataSimSlot = 0
TaskUtils.wifiSsid = ""
}
//网络状态未改变,不执行任务,避免重复通知
if (networkStateOld == TaskUtils.networkState && dataSimSlotOld == TaskUtils.dataSimSlot && wifiSsidOld == TaskUtils.wifiSsid) {
Log.d(TAG, "Network State Not Changed")
return
}
//获取公网IP地址后执行任务
val request = OneTimeWorkRequestBuilder<NetworkWorker>().setInputData(
workDataOf(
TaskWorker.conditionType to TASK_CONDITION_NETWORK,
)
).build()
WorkManager.getInstance(context).enqueue(request)
}
private fun handleWifiStateChanged(context: Context, intent: Intent) {
val wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN)
Log.d(TAG, "WiFi State Changed: $wifiState")
when (wifiState) {
WifiManager.WIFI_STATE_ENABLED -> {
Log.d(TAG, "WiFi Enabled")
}
WifiManager.WIFI_STATE_DISABLED -> {
Log.d(TAG, "WiFi Disabled")
}
}
}
private fun handleNetworkStateChanged(context: Context, intent: Intent) {
val networkInfo = intent.getParcelableExtra<NetworkInfo>(WifiManager.EXTRA_NETWORK_INFO)
if (networkInfo != null && networkInfo.isConnected) {
Log.d(TAG, "Network State Changed: Connected")
} else {
Log.d(TAG, "Network State Changed: Disconnected")
}
}
//private fun handleDataConnectionStateChanged(context: Context, intent: Intent) {
// val extraData = intent.extras
// val state = extraData?.getString("state")
// val reason = extraData?.getString("reason")
//
// if (state != null && reason != null) {
// Log.d(TAG, "Data Connection State Changed: $state, Reason: $reason")
// }
//}
// 获取当前数据连接的卡槽ID不需要判断手机数据流量是否打开上层已判断
@RequiresApi(Build.VERSION_CODES.Q)
private fun getSlotIndex(context: Context): Int {
return try {
val subscriptionId = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
SubscriptionManager.getDefaultDataSubscriptionId()
} else {
getDataSubId(context)
}
SubscriptionManager.getSlotIndex(subscriptionId)
} catch (e: Exception) {
e.printStackTrace()
-1
}
}
// 获取数据连接的订阅ID
@SuppressLint("DiscouragedPrivateApi")
private fun getDataSubId(context: Context): Int {
val defaultDataSlotId = getDefaultDataSlotId(context)
return try {
val obj = Class.forName("android.telephony.SubscriptionManager")
.getDeclaredMethod("getSubId", Int::class.javaPrimitiveType)
.invoke(null, defaultDataSlotId)
obj?.let {
when (Build.VERSION.SDK_INT) {
Build.VERSION_CODES.LOLLIPOP -> (it as? LongArray)?.get(0)?.toInt()
else -> (it as? IntArray)?.get(0)
}
} ?: defaultDataSlotId
} catch (e: Exception) {
e.printStackTrace()
defaultDataSlotId
}
}
// 获取默认数据卡的卡槽ID
private fun getDefaultDataSlotId(context: Context): Int {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
val subscriptionManager = SubscriptionManager.from(context.applicationContext)
subscriptionManager?.let {
try {
val subClass = Class.forName(it.javaClass.name)
val getSubID = subClass.getMethod("getDefaultDataSubscriptionInfo")
val subInfo = getSubID.invoke(it) as? SubscriptionInfo
return subInfo?.simSlotIndex ?: -1
} catch (e: Exception) {
e.printStackTrace()
}
}
} else {
try {
val cls = Class.forName("android.telephony.SubscriptionManager")
val methodName = if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) "getSlotId" else "getSlotIndex"
val getSubId = cls.getDeclaredMethod("getDefaultDataSubId") ?: cls.getDeclaredMethod("getDefaultDataSubscriptionId")
val subId = getSubId.invoke(null) as? Int ?: return -1
val getSlotId = cls.getDeclaredMethod(methodName, Int::class.javaPrimitiveType)
return getSlotId.invoke(null, subId) as? Int ?: -1
} catch (e: Exception) {
e.printStackTrace()
}
}
return -1
}
}

@ -62,8 +62,6 @@ const val SP_SILENT_PERIOD_START = "silent_period_start"
const val SP_SILENT_PERIOD_END = "silent_period_end"
const val SP_AUTO_CLEAN_LOGS_DAYS = "auto_clean_logs_days"
const val SP_NET_STATE_RECEIVER = "enable_network_state_receiver"
const val SP_ENABLE_EXCLUDE_FROM_RECENTS = "enable_exclude_from_recents"
const val SP_ENABLE_PLAY_SILENCE_MUSIC = "enable_play_silence_music"
const val SP_ENABLE_ONE_PIXEL_ACTIVITY = "enable_one_pixel_activity"
@ -577,7 +575,14 @@ var TASK_ACTION_FRAGMENT_LIST = listOf(
),
)
const val SP_BATTERY_INFO = "battery_info"
const val SP_BATTERY_STATUS = "battery_status"
const val SP_BATTERY_LEVEL = "battery_level"
const val SP_BATTERY_PCT = "battery_pct"
const val SP_BATTERY_PLUGGED = "battery_plugged"
const val SP_NETWORK_STATE = "network_state"
const val SP_DATA_SIM_SLOT = "data_sim_slot"
const val SP_WIFI_SSID = "wifi_ssid"
const val SP_IPV4 = "ipv4"
const val SP_IPV6 = "ipv6"

@ -74,9 +74,6 @@ class SettingUtils private constructor() {
//自动删除N天前的转发记录
var autoCleanLogsDays: Int by SharedPreference(SP_AUTO_CLEAN_LOGS_DAYS, 0)
//是否监听网络状态变化
var enableNetworkStateReceiver: Boolean by SharedPreference(SP_NET_STATE_RECEIVER, false)
//是否不在最近任务列表中显示
var enableExcludeFromRecents: Boolean by SharedPreference(SP_ENABLE_EXCLUDE_FROM_RECENTS, false)

@ -1,10 +1,16 @@
package com.idormy.sms.forwarder.utils.task
import android.os.BatteryManager
import com.idormy.sms.forwarder.utils.SP_BATTERY_INFO
import com.idormy.sms.forwarder.utils.SP_BATTERY_LEVEL
import com.idormy.sms.forwarder.utils.SP_BATTERY_PCT
import com.idormy.sms.forwarder.utils.SP_BATTERY_PLUGGED
import com.idormy.sms.forwarder.utils.SP_BATTERY_STATUS
import com.idormy.sms.forwarder.utils.SP_DATA_SIM_SLOT
import com.idormy.sms.forwarder.utils.SP_IPV4
import com.idormy.sms.forwarder.utils.SP_IPV6
import com.idormy.sms.forwarder.utils.SP_NETWORK_STATE
import com.idormy.sms.forwarder.utils.SP_WIFI_SSID
import com.idormy.sms.forwarder.utils.SharedPreference
/**
@ -15,7 +21,7 @@ class TaskUtils private constructor() {
companion object {
//电池信息
var batteryInfo: String by SharedPreference("batteryInfo", "")
var batteryInfo: String by SharedPreference(SP_BATTERY_INFO, "")
//当前电量
var batteryLevel: Int by SharedPreference(SP_BATTERY_LEVEL, 0)
@ -28,5 +34,20 @@ class TaskUtils private constructor() {
//充电方式
var batteryPlugged: Int by SharedPreference(SP_BATTERY_PLUGGED, BatteryManager.BATTERY_PLUGGED_AC)
//网络状态0-没有网络1-移动网络2-WiFi3-以太网, 4-未知
var networkState: Int by SharedPreference(SP_NETWORK_STATE, 0)
//数据卡槽0-未知1-卡12-卡2
var dataSimSlot: Int by SharedPreference(SP_DATA_SIM_SLOT, 0)
//WiFi名称
var wifiSsid: String by SharedPreference(SP_WIFI_SSID, "")
//IPv4地址
var ipv4: String by SharedPreference(SP_IPV4, "")
//IPv6地址
var ipv6: String by SharedPreference(SP_IPV6, "")
}
}

@ -52,6 +52,7 @@ class ActionWorker(context: Context, params: WorkerParameters) : CoroutineWorker
var successNum = 0
for (action in actionList) {
try {
when (action.type) {
TASK_ACTION_SENDSMS -> {
val smsSetting = Gson().fromJson(action.setting, SmsSetting::class.java)
@ -78,26 +79,23 @@ class ActionWorker(context: Context, params: WorkerParameters) : CoroutineWorker
}
Log.d(TAG, "任务$taskIdsend sms result: $msg")
continue
}
TASK_ACTION_NOTIFICATION -> {
try {
val settingVo = Gson().fromJson(action.setting, Rule::class.java)
//自动任务的不需要吐司或者更新日志,特殊处理 logId = -1msgId = -1
SendUtils.sendMsgSender(msgInfo, settingVo, 0, -1L, -1L)
successNum++
} catch (e: Exception) {
e.printStackTrace()
}
continue
}
else -> {
Log.d(TAG, "任务$taskIdaction.type is ${action.type}")
continue
}
}
} catch (e: Exception) {
e.printStackTrace()
Log.d(TAG, "任务$taskIdaction.type is ${action.type}, exception: ${e.message}")
}
}
return if (successNum == actionList.size) Result.success() else Result.failure()

@ -39,7 +39,7 @@ class BatteryWorker(context: Context, params: WorkerParameters) : CoroutineWorke
return Result.failure()
}
val taskList = AppDatabase.getInstance(App.context).taskDao().getByType(TASK_CONDITION_BATTERY)
val taskList = AppDatabase.getInstance(App.context).taskDao().getByType(conditionType)
for (task in taskList) {
Log.d(TAG, "task = $task")
@ -94,7 +94,7 @@ class BatteryWorker(context: Context, params: WorkerParameters) : CoroutineWorke
return Result.failure()
}
val taskList = AppDatabase.getInstance(App.context).taskDao().getByType(TASK_CONDITION_CHARGE)
val taskList = AppDatabase.getInstance(App.context).taskDao().getByType(conditionType)
for (task in taskList) {
Log.d(TAG, "task = $task")
@ -125,7 +125,7 @@ class BatteryWorker(context: Context, params: WorkerParameters) : CoroutineWorke
//TODO判断其他条件是否满足
//TODO: 组装消息体 && 执行具体任务
val msgInfo = MsgInfo("task", task.name, msg, Date(), task.name)
val msgInfo = MsgInfo("task", task.name, msg, Date(), task.description)
val actionData = Data.Builder()
.putLong(TaskWorker.taskId, task.id)
.putString(TaskWorker.taskActions, task.actions)

@ -0,0 +1,153 @@
package com.idormy.sms.forwarder.workers
import android.content.Context
import android.util.Log
import androidx.work.CoroutineWorker
import androidx.work.Data
import androidx.work.OneTimeWorkRequestBuilder
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.MsgInfo
import com.idormy.sms.forwarder.entity.task.NetworkSetting
import com.idormy.sms.forwarder.entity.task.TaskSetting
import com.idormy.sms.forwarder.utils.PhoneUtils
import com.idormy.sms.forwarder.utils.TaskWorker
import com.idormy.sms.forwarder.utils.task.TaskUtils
import com.xuexiang.xutil.app.ServiceUtils
import com.xuexiang.xutil.resource.ResUtils.getString
import java.net.HttpURLConnection
import java.net.URL
import java.util.Date
@Suppress("PrivatePropertyName", "DEPRECATION")
class NetworkWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
private val TAG: String = NetworkWorker::class.java.simpleName
private val ipv4Pattern = Regex("^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$")
private val ipv6Pattern = Regex("^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$")
override suspend fun doWork(): Result {
val conditionType = inputData.getInt(TaskWorker.conditionType, -1)
val taskList = AppDatabase.getInstance(App.context).taskDao().getByType(conditionType)
for (task in taskList) {
Log.d(TAG, "task = $task")
// 根据任务信息执行相应操作
val conditionList = Gson().fromJson(task.conditions, Array<TaskSetting>::class.java).toMutableList()
if (conditionList.isEmpty()) {
Log.d(TAG, "任务${task.id}conditionList is empty")
continue
}
val firstCondition = conditionList.firstOrNull()
if (firstCondition == null) {
Log.d(TAG, "任务${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")
continue
}
if (TaskUtils.networkState != networkSetting.networkState) {
Log.d(TAG, "任务${task.id}networkState is not match, networkSetting = $networkSetting")
continue
}
//TODO判断其他条件是否满足
var ipv4 = ""
var ipv6 = ""
val msg = StringBuilder()
msg.append(getString(R.string.network_type)).append(": ")
when (networkSetting.networkState) {
//移动网络
1 -> {
val dataSimSlot = TaskUtils.dataSimSlot
if (networkSetting.dataSimSlot != 0 && dataSimSlot != networkSetting.dataSimSlot) {
Log.d(TAG, "任务${task.id}dataSimSlot is not match, networkSetting = $networkSetting")
continue
}
msg.append(getString(R.string.net_mobile)).append("\n")
if (dataSimSlot != 0) {
msg.append(getString(R.string.data_sim_index)).append(": SIM-").append(dataSimSlot).append("\n")
// 获取 SIM 卡信息
val simIndex = dataSimSlot - 1
App.SimInfoList = PhoneUtils.getSimMultiInfo()
if (App.SimInfoList[simIndex]?.mCarrierName != null) {
//获取网络运营商名称:中国移动、中国联通、中国电信
msg.append(getString(R.string.carrier_name)).append(": ").append(App.SimInfoList[simIndex]?.mCarrierName).append("\n")
}
}
ipv4 = getPublicIP(false)
ipv6 = getPublicIP(true)
}
//WiFi
2 -> {
if (networkSetting.wifiSsid.isNotEmpty() && TaskUtils.wifiSsid != networkSetting.wifiSsid) {
Log.d(TAG, "任务${task.id}wifiSsid is not match, networkSetting = $networkSetting")
continue
}
msg.append(getString(R.string.net_wifi)).append("\n")
msg.append(getString(R.string.wifi_ssid)).append(": ").append(TaskUtils.wifiSsid).append("\n")
ipv4 = getPublicIP(false)
ipv6 = getPublicIP(true)
}
//未知 && 没有网络
else -> {
msg.append(getString(R.string.no_network)).append("\n")
}
}
val isHttpServerRunning = ServiceUtils.isServiceRunning("com.idormy.sms.forwarder.service.HttpServerService")
if (ipv4Pattern.matches(ipv4)) {
msg.append(getString(R.string.ipv4)).append(": ").append(ipv4).append("\n")
TaskUtils.ipv4 = ipv4
if (isHttpServerRunning) {
msg.append(getString(R.string.http_server)).append(": ").append("http://${ipv4}:5000").append("\n")
}
} else {
TaskUtils.ipv4 = ""
}
if (ipv6Pattern.matches(ipv6)) {
msg.append(getString(R.string.ipv6)).append(": ").append(ipv6).append("\n")
TaskUtils.ipv6 = ipv6
if (isHttpServerRunning) {
msg.append(getString(R.string.http_server)).append(": ").append("http://[${ipv6}]:5000").append("\n")
}
} else {
TaskUtils.ipv6 = ""
}
//TODO: 组装消息体 && 执行具体任务
val msgInfo = MsgInfo("task", task.name, msg.toString().trimEnd(), Date(), task.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<ActionWorker>().setInputData(actionData).build()
WorkManager.getInstance().enqueue(actionRequest)
}
return Result.success()
}
//获取公网IP地址
private fun getPublicIP(ipv6: Boolean = false): String {
val url = if (ipv6) URL("https://api6.ipify.org/") else URL("https://api.ipify.org/")
val urlConnection = url.openConnection() as HttpURLConnection
urlConnection.requestMethod = "GET"
val inputStream = urlConnection.inputStream
return inputStream.bufferedReader().use { it.readText() }
}
}

@ -357,6 +357,7 @@
<RadioButton
android:id="@+id/rb_uriType_tcp"
style="@style/rg_rb_style"
android:checked="true"
android:text="@string/tcp" />
<RadioButton

@ -700,64 +700,6 @@
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="5dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/network_state_monitor"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="@string/network_state_monitor_tips"
android:textSize="10sp"
tools:ignore="SmallSp" />
</LinearLayout>
<LinearLayout
style="@style/settingBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/network_state_change_remind"
android:textStyle="bold"
tools:ignore="RelativeOverlap" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/network_state_change_remind_tips"
android:textSize="9sp"
tools:ignore="SmallSp" />
</LinearLayout>
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
android:id="@+id/sb_network_state_receiver"
style="@style/SwitchButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"

@ -56,22 +56,102 @@
android:text="@string/net_mobile"
tools:ignore="TouchTargetSizeCheck" />
<LinearLayout
android:id="@+id/layout_data_sim_slot"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
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="30dp"
android:gravity="center_vertical"
android:text="@string/data_sim_index"
android:textStyle="bold" />
<RadioGroup
android:id="@+id/rg_data_sim_slot"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="5dp"
android:layout_weight="1"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rb_data_sim_slot_0"
style="@style/rg_rb_style_wrap"
android:checked="true"
android:text="@string/sim_any"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton
android:id="@+id/rb_data_sim_slot_1"
style="@style/rg_rb_style_wrap"
android:text="@string/sim_1"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton
android:id="@+id/rb_data_sim_slot_2"
style="@style/rg_rb_style_wrap"
android:text="@string/sim_2"
tools:ignore="TouchTargetSizeCheck" />
</RadioGroup>
</LinearLayout>
<RadioButton
android:id="@+id/rb_net_wifi"
style="@style/rg_rb_style_match"
android:text="@string/net_wifi"
tools:ignore="TouchTargetSizeCheck" />
<LinearLayout
android:id="@+id/layout_wifi_ssid"
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/wifi_ssid"
android:textStyle="bold" />
<EditText
android:id="@+id/et_wifi_ssid"
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/wifi_ssid_hint"
android:importantForAutofill="no"
tools:ignore="TextContrastCheck,TextFields,TouchTargetSizeCheck" />
</LinearLayout>
<RadioButton
android:id="@+id/rb_net_ethernet"
style="@style/rg_rb_style_match"
android:text="@string/net_ethernet"
android:visibility="gone"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton
android:id="@+id/rb_net_unknown"
style="@style/rg_rb_style_match"
android:text="@string/net_unknown"
android:visibility="gone"
tools:ignore="TouchTargetSizeCheck,DuplicateSpeakableTextCheck" />
</RadioGroup>

@ -557,9 +557,7 @@
<string name="sim_state_monitor">SIM State Monitor</string>
<string name="sim_state_monitor_tips">[Note] You need to manually create APP forwarding rules, package name: 66666666</string>
<string name="network_state_monitor">Network State Monitor</string>
<string name="network_state_monitor_tips">[Note] You need to manually create APP forwarding rules, package name: 77777777</string>
<string name="network_state_change_remind">Network State Change Remind</string>
<string name="network_state_change_remind_tips">Send a notification when the network status changes (connection mode/IP change)</string>
<string name="keep_alive">Keep Alive</string>
<string name="keep_alive_tips">It is recommended to open the first three switch, do not disable the notification bar, to avoid APP being killed</string>
<string name="custom_settings">Custom Settings</string>
@ -1083,6 +1081,9 @@
<string name="net_unknown">Unknown</string>
<string name="network_state">Network State: %s</string>
<string name="wifi_ssid">WiFi SSID</string>
<string name="wifi_ssid_hint">If left blank, it won\'t check the connected WiFi SSID.</string>
<string name="ipv4">IPv4</string>
<string name="ipv6">IPv6</string>
<string name="enable_location_tag">Enable {{LOCATION}} Tag</string>
<string name="enable_location_tag_tips">Insert location info into forwarded msg.</string>
@ -1191,4 +1192,8 @@
<string name="sim_state_absent">Absent</string>
<string name="sim_state_ready">Ready</string>
<string name="sim_state_unknown">Unknown</string>
<string name="sim_any">Any SIM</string>
<string name="sim_1">SIM-1</string>
<string name="sim_2">SIM-2</string>
</resources>

@ -558,9 +558,7 @@
<string name="sim_state_monitor">SIM卡槽状态监控</string>
<string name="sim_state_monitor_tips">需要手动创建APP转发规则包名66666666</string>
<string name="network_state_monitor">网络状态监控</string>
<string name="network_state_monitor_tips">需要手动创建APP转发规则包名77777777</string>
<string name="network_state_change_remind">网络状态改变提醒</string>
<string name="network_state_change_remind_tips">网络状态改变(连接方式/IP变化)时发出通知</string>
<string name="keep_alive">保活措施</string>
<string name="keep_alive_tips">建议开启前三项授权或设置不要禁用通知栏避免APP被杀</string>
<string name="custom_settings">个性设置</string>
@ -1084,6 +1082,9 @@
<string name="net_unknown">未知网络</string>
<string name="network_state">网络状态:%s</string>
<string name="wifi_ssid">WiFi名称</string>
<string name="wifi_ssid_hint">留空则不判断连接的WiFi-SSID</string>
<string name="ipv4">IPv4</string>
<string name="ipv6">IPv6</string>
<string name="enable_location_tag">启用 {{定位信息}} 标签</string>
<string name="enable_location_tag_tips">在转发信息中插入手机的当前定位信息</string>
@ -1192,4 +1193,8 @@
<string name="sim_state_absent">被移除</string>
<string name="sim_state_ready">已就绪</string>
<string name="sim_state_unknown">未知</string>
<string name="sim_any">不限卡槽</string>
<string name="sim_1">SIM-1</string>
<string name="sim_2">SIM-2</string>
</resources>

Loading…
Cancel
Save