diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 07ba3c2a..139ec21c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -264,6 +264,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/SettingsFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/SettingsFragment.kt
index 22533b97..dae7cc98 100644
--- a/app/src/main/java/com/idormy/sms/forwarder/fragment/SettingsFragment.kt
+++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/SettingsFragment.kt
@@ -157,6 +157,8 @@ class SettingsFragment : BaseFragment(), View.OnClickL
editAddExtraSim1(binding!!.etExtraSim1)
//SIM2备注
editAddExtraSim2(binding!!.etExtraSim2)
+ //SIM卡槽状态监控
+ switchSimStateReceiver(binding!!.sbSimStateReceiver)
//通知内容
editNotifyContent(binding!!.etNotifyContent)
@@ -212,10 +214,12 @@ class SettingsFragment : BaseFragment(), View.OnClickL
it.show()
}
}
+
R.id.btn_extra_device_mark -> {
binding!!.etExtraDeviceMark.setText(PhoneUtils.getDeviceName())
return
}
+
R.id.btn_extra_sim1 -> {
App.SimInfoList = PhoneUtils.getSimMultiInfo()
if (App.SimInfoList.isEmpty()) {
@@ -239,6 +243,7 @@ class SettingsFragment : BaseFragment(), View.OnClickL
binding!!.etExtraSim1.setText(simInfo?.mCarrierName.toString() + "_" + simInfo?.mNumber.toString())
return
}
+
R.id.btn_extra_sim2 -> {
App.SimInfoList = PhoneUtils.getSimMultiInfo()
if (App.SimInfoList.isEmpty()) {
@@ -262,32 +267,38 @@ class SettingsFragment : BaseFragment(), View.OnClickL
binding!!.etExtraSim2.setText(simInfo?.mCarrierName.toString() + "_" + simInfo?.mNumber.toString())
return
}
+
R.id.bt_insert_sender -> {
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_from))
return
}
+
R.id.bt_insert_content -> {
CommonUtils.insertOrReplaceText2Cursor(etSmsTemplate, getString(R.string.tag_sms))
return
}
+
R.id.bt_insert_extra -> {
CommonUtils.insertOrReplaceText2Cursor(
etSmsTemplate, getString(R.string.tag_card_slot)
)
return
}
+
R.id.bt_insert_time -> {
CommonUtils.insertOrReplaceText2Cursor(
etSmsTemplate, getString(R.string.tag_receive_time)
)
return
}
+
R.id.bt_insert_device_name -> {
CommonUtils.insertOrReplaceText2Cursor(
etSmsTemplate, getString(R.string.tag_device_name)
)
return
}
+
else -> {}
}
}
@@ -881,6 +892,25 @@ class SettingsFragment : BaseFragment(), View.OnClickL
})
}
+ //SIM卡槽状态监控
+ @SuppressLint("UseSwitchCompatOrMaterialCode")
+ fun switchSimStateReceiver(sbSimStateReceiver: SwitchButton) {
+ sbSimStateReceiver.isChecked = SettingUtils.enableSimStateReceiver
+ sbSimStateReceiver.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
+ App.SimInfoList = PhoneUtils.getSimMultiInfo()
+ if (isChecked && App.SimInfoList.isEmpty()) {
+ XToastUtils.error(R.string.tip_can_not_get_sim_infos)
+ XXPermissions.startPermissionActivity(
+ requireContext(), "android.permission.READ_PHONE_STATE"
+ )
+ SettingUtils.enableSimStateReceiver = false
+ sbSimStateReceiver.isChecked = false
+ return@setOnCheckedChangeListener
+ }
+ SettingUtils.enableSimStateReceiver = isChecked
+ }
+ }
+
//设置通知内容
private fun editNotifyContent(etNotifyContent: EditText) {
etNotifyContent.setText(SettingUtils.notifyContent)
diff --git a/app/src/main/java/com/idormy/sms/forwarder/receiver/BootReceiver.kt b/app/src/main/java/com/idormy/sms/forwarder/receiver/BootReceiver.kt
index 8e0e3533..842e522b 100644
--- a/app/src/main/java/com/idormy/sms/forwarder/receiver/BootReceiver.kt
+++ b/app/src/main/java/com/idormy/sms/forwarder/receiver/BootReceiver.kt
@@ -14,7 +14,7 @@ class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
val receiveAction: String? = intent?.action
Log.d(TAG, "onReceive intent $receiveAction")
- if (receiveAction == "android.intent.action.BOOT_COMPLETED" || receiveAction == "android.intent.action.LOCKED_BOOT_COMPLETED") {
+ if (receiveAction == Intent.ACTION_BOOT_COMPLETED || receiveAction == Intent.ACTION_LOCKED_BOOT_COMPLETED) {
try {
Log.d(TAG, "强制重启APP一次")
val intent1 = Intent(context, SplashActivity::class.java)
diff --git a/app/src/main/java/com/idormy/sms/forwarder/receiver/SimStateReceiver.kt b/app/src/main/java/com/idormy/sms/forwarder/receiver/SimStateReceiver.kt
index bf0943f6..b23d0ccb 100644
--- a/app/src/main/java/com/idormy/sms/forwarder/receiver/SimStateReceiver.kt
+++ b/app/src/main/java/com/idormy/sms/forwarder/receiver/SimStateReceiver.kt
@@ -3,35 +3,128 @@ package com.idormy.sms.forwarder.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
+import android.telephony.TelephonyManager
import android.util.Log
-import com.idormy.sms.forwarder.App
+import androidx.work.OneTimeWorkRequestBuilder
+import androidx.work.WorkManager
+import androidx.work.workDataOf
+import com.google.gson.Gson
+import com.idormy.sms.forwarder.R
+import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.utils.PhoneUtils
+import com.idormy.sms.forwarder.utils.Worker
+import com.idormy.sms.forwarder.workers.SendWorker
+import com.xuexiang.xutil.resource.ResUtils.getString
+import java.util.Date
+import com.idormy.sms.forwarder.App
+import android.os.Handler
+import com.idormy.sms.forwarder.utils.SettingUtils
+@Suppress("PrivatePropertyName")
class SimStateReceiver : BroadcastReceiver() {
- /**
- * 更换SIM卡,如果不杀后台并重启,则发送出的「卡槽信息」仍然是刚启动应用时读取的SIM卡
- * 增加这个Receiver,接收SIM卡插拔状态广播,自动更新缓存
- */
+
+ private var TAG = "SimStateReceiver"
+
override fun onReceive(context: Context, intent: Intent) {
- val receiveAction = intent.action
- Log.d(TAG, "onReceive intent $receiveAction")
- if (ACTION_SIM_STATE_CHANGED == receiveAction) {
- //SIM状态的额外信息
- val state = intent.extras!!.getString(EXTRA_SIM_STATE)
- Log.d(TAG, state!!)
- //只需要最后一个SIM加载完毕的 LOADED 状态
- if (SIM_STATE_LOADED == state) {
- //刷新SimInfoList
- App.SimInfoList = PhoneUtils.getSimMultiInfo()
- Log.d(TAG, App.SimInfoList.toString())
+ //纯客户端模式
+ if (SettingUtils.enablePureClientMode) return
+
+ //SIM卡槽状态监控开关
+ if (!SettingUtils.enableSimStateReceiver) return
+
+ val action = intent.action
+ if (action == Intent.ACTION_BOOT_COMPLETED) {
+ // 在这里处理开机启动时的逻辑
+ // 例如:注册监听 SIM 变化
+ registerSimStateListener(context)
+ } else if (action == "android.intent.action.SIM_STATE_CHANGED") {
+ // 处理 SIM 卡状态变化的逻辑
+ val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
+
+ // 获取当前 SIM 卡状态
+ when (telephonyManager.simState) {
+ TelephonyManager.SIM_STATE_ABSENT -> {
+ Log.d(TAG, "SIM 卡被移除")
+ // 处理 SIM 卡被移除的情况
+ }
+
+ TelephonyManager.SIM_STATE_READY -> {
+ Log.d(TAG, "SIM 卡已准备就绪,延迟2秒再获取信息")
+
+ val handler = Handler()
+ handler.postDelayed({
+ // 获取 SIM 卡信息
+ App.SimInfoList = PhoneUtils.getSimMultiInfo()
+ Log.d(TAG, App.SimInfoList.toString())
+
+ val msg = StringBuilder()
+ App.SimInfoList.forEach {
+ msg.append("[SIM-").append(it.key + 1).append("]\n")
+ msg.append(getString(R.string.carrier_name)).append(": ").append(it.value.mCarrierName).append("\n")
+ //msg.append(getString(R.string.icc_id)).append(": ").append(it.value.mIccId).append("\n")
+ msg.append(getString(R.string.sim_slot_index)).append(": ").append(it.value.mSimSlotIndex).append("\n")
+ msg.append(getString(R.string.number)).append(": ").append(it.value.mNumber).append("\n")
+ msg.append(getString(R.string.country_iso)).append(": ").append(it.value.mCountryIso).append("\n")
+ msg.append(getString(R.string.subscription_id)).append(": ").append(it.value.mSubscriptionId).append("\n")
+ }
+
+ sendMessage(context, msg.toString().trimEnd())
+ }, 2000)
+ }
+
+ TelephonyManager.SIM_STATE_CARD_IO_ERROR -> {
+ Log.d(TAG, "SIM 卡读取失败")
+ }
+
+ TelephonyManager.SIM_STATE_CARD_RESTRICTED -> {
+ Log.d(TAG, "SIM 卡受限")
+ }
+
+ TelephonyManager.SIM_STATE_NETWORK_LOCKED -> {
+ Log.d(TAG, "SIM 卡网络锁定")
+ }
+
+ TelephonyManager.SIM_STATE_NOT_READY -> {
+ Log.d(TAG, "SIM 卡未准备好")
+ }
+
+ TelephonyManager.SIM_STATE_PERM_DISABLED -> {
+ Log.d(TAG, "SIM 卡被禁用")
+ }
+
+ TelephonyManager.SIM_STATE_PIN_REQUIRED -> {
+ Log.d(TAG, "SIM 卡需要 PIN 解锁")
+ }
+
+ TelephonyManager.SIM_STATE_PUK_REQUIRED -> {
+ Log.d(TAG, "SIM 卡需要 PUK 解锁")
+ }
+
+ TelephonyManager.SIM_STATE_UNKNOWN -> {
+ Log.d(TAG, "SIM 卡状态未知")
+ }
}
}
}
- companion object {
- private const val TAG = "SimStateReceiver"
- const val ACTION_SIM_STATE_CHANGED = "android.intent.action.SIM_STATE_CHANGED"
- private const val EXTRA_SIM_STATE = "ss"
- private const val SIM_STATE_LOADED = "LOADED"
+ private fun registerSimStateListener(context: Context) {
+ // 在此处注册 SIM 变化监听器
+ // 可以使用 TelephonyManager 或 SubscriptionManager 进行注册监听
+ }
+
+ //发送信息
+ private fun sendMessage(context: Context, msg: String) {
+ Log.i(TAG, msg)
+ try {
+ val msgInfo = MsgInfo("app", "66666666", msg, Date(), getString(R.string.sim_state_monitor), -1)
+ val request = OneTimeWorkRequestBuilder().setInputData(
+ workDataOf(
+ Worker.sendMsgInfo to Gson().toJson(msgInfo),
+ )
+ ).build()
+ WorkManager.getInstance(context).enqueue(request)
+ } catch (e: Exception) {
+ Log.e(TAG, "getLog e:" + e.message)
+ }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/Constants.kt b/app/src/main/java/com/idormy/sms/forwarder/utils/Constants.kt
index 3d4ffd6b..1b987b9e 100644
--- a/app/src/main/java/com/idormy/sms/forwarder/utils/Constants.kt
+++ b/app/src/main/java/com/idormy/sms/forwarder/utils/Constants.kt
@@ -80,6 +80,7 @@ const val SP_SUBID_SIM1 = "subid_sim1"
const val SP_SUBID_SIM2 = "subid_sim2"
const val SP_EXTRA_SIM1 = "extra_sim1"
const val SP_EXTRA_SIM2 = "extra_sim2"
+const val SP_SIM_STATE_RECEIVER = "enable_sim_state_receiver"
const val SP_ENABLE_SMS_TEMPLATE = "enable_sms_template"
const val SP_SMS_TEMPLATE = "sms_template"
diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtils.kt b/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtils.kt
index c9e2f4b5..c87f226d 100644
--- a/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtils.kt
+++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtils.kt
@@ -130,18 +130,21 @@ class SettingUtils private constructor() {
//设备名称
var extraDeviceMark: String by SharedPreference(SP_EXTRA_DEVICE_MARK, "")
- //SM1主键
+ //SIM1主键
var subidSim1: Int by SharedPreference(SP_SUBID_SIM1, 0)
- //SM2主键
+ //SIM2主键
var subidSim2: Int by SharedPreference(SP_SUBID_SIM2, 0)
- //SM1备注
+ //SIM1备注
var extraSim1: String by SharedPreference(SP_EXTRA_SIM1, "")
- //SM2备注
+ //SIM2备注
var extraSim2: String by SharedPreference(SP_EXTRA_SIM2, "")
+ //SIM卡槽状态监控
+ var enableSimStateReceiver: Boolean by SharedPreference(SP_SIM_STATE_RECEIVER, false)
+
//是否启用自定义模板
var enableSmsTemplate: Boolean by SharedPreference(SP_ENABLE_SMS_TEMPLATE, false)
diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml
index 83d30657..2474d27f 100644
--- a/app/src/main/res/layout/fragment_settings.xml
+++ b/app/src/main/res/layout/fragment_settings.xml
@@ -1475,6 +1475,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
Obtain instructions through passive reception or active polling to operate the machine
Local HttpServer
Available under WiFi network, after startup, other machines in the LAN can directly call the local interface
+ SIM State Monitor
+ [Note] You need to manually create APP forwarding rules, package name: 66666666
Network State Monitor
[Note] You need to manually create APP forwarding rules, package name: 77777777
Network State Change Remind
@@ -1048,4 +1050,11 @@
Operator Name
Host Address
Loading app list async...
+
+ Carrier Name
+ ICC ID
+ Sim Slot Index
+ Number
+ Country
+ Subscription ID
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index fc661c91..cd53dd57 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -559,6 +559,8 @@
通过 被动接收 或者 主动轮询 获取指令,从而操作本机
被动接收本地 HttpServer
WiFi网络下可用,启动后局域网内其他机器可直接调用本机接口
+ SIM卡槽状态监控
+ 需要手动创建APP转发规则,包名:66666666
网络状态监控
需要手动创建APP转发规则,包名:77777777
网络状态改变提醒
@@ -703,7 +705,7 @@
No
---
刷新
- 请确认应用权限【获取手机信息】为【始终允许】或手动填写
+ 无法获取卡槽信息,请确认应用权限【获取手机信息】为【始终允许】
未获取到卡槽%s中的SIM卡信息
添加
检查更新
@@ -1049,4 +1051,11 @@
运营商
本地IP
正在异步加载应用列表...
+
+ 运营商名
+ ICC ID
+ 卡槽索引
+ 手机号码
+ 国家代码
+ 订阅标识