mirror of
https://github.com/pppscn/SmsForwarder
synced 2025-08-03 17:37:40 +08:00
优化:短信/通话转发获取卡槽信息机制(自行备注卡槽SubId对应)#228 #235
This commit is contained in:
parent
442c29fd3d
commit
65e861ba62
@ -144,8 +144,8 @@ class App : Application(), CactusCallback, Configuration.Provider by Core {
|
|||||||
runCatching {
|
runCatching {
|
||||||
get.await()
|
get.await()
|
||||||
Log.d("GlobalScope", "AppUtils.getAppsInfo() Done")
|
Log.d("GlobalScope", "AppUtils.getAppsInfo() Done")
|
||||||
Log.d("GlobalScope", "UserAppList = $UserAppList")
|
//Log.d("GlobalScope", "UserAppList = $UserAppList")
|
||||||
Log.d("GlobalScope", "SystemAppList = $SystemAppList")
|
//Log.d("GlobalScope", "SystemAppList = $SystemAppList")
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
//Log.e("GlobalScope", it.message.toString())
|
//Log.e("GlobalScope", it.message.toString())
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ import com.idormy.sms.forwarder.utils.DATABASE_NAME
|
|||||||
|
|
||||||
@Database(
|
@Database(
|
||||||
entities = [Frpc::class, Logs::class, Rule::class, Sender::class],
|
entities = [Frpc::class, Logs::class, Rule::class, Sender::class],
|
||||||
version = 10,
|
version = 11,
|
||||||
exportSchema = false
|
exportSchema = false
|
||||||
)
|
)
|
||||||
@TypeConverters(Converters::class)
|
@TypeConverters(Converters::class)
|
||||||
@ -95,6 +95,7 @@ custom_domains = smsf.demo.com
|
|||||||
MIGRATION_7_8,
|
MIGRATION_7_8,
|
||||||
MIGRATION_8_9,
|
MIGRATION_8_9,
|
||||||
MIGRATION_9_10,
|
MIGRATION_9_10,
|
||||||
|
MIGRATION_10_11,
|
||||||
)
|
)
|
||||||
|
|
||||||
/*if (BuildConfig.DEBUG) {
|
/*if (BuildConfig.DEBUG) {
|
||||||
@ -277,6 +278,12 @@ CREATE TABLE "Sender" (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//转发日志添加SIM卡槽ID
|
||||||
|
private val MIGRATION_10_11 = object : Migration(10, 11) {
|
||||||
|
override fun migrate(database: SupportSQLiteDatabase) {
|
||||||
|
database.execSQL("Alter table Logs add column sub_id INTEGER NOT NULL DEFAULT 0 ")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ data class Logs(
|
|||||||
@ColumnInfo(name = "content", defaultValue = "") var content: String,
|
@ColumnInfo(name = "content", defaultValue = "") var content: String,
|
||||||
@ColumnInfo(name = "rule_id", defaultValue = "0") var ruleId: Long = 0,
|
@ColumnInfo(name = "rule_id", defaultValue = "0") var ruleId: Long = 0,
|
||||||
@ColumnInfo(name = "sim_info", defaultValue = "") var simInfo: String = "",
|
@ColumnInfo(name = "sim_info", defaultValue = "") var simInfo: String = "",
|
||||||
|
@ColumnInfo(name = "sub_id", defaultValue = "0") var subId: Int = 0,
|
||||||
@ColumnInfo(name = "forward_status", defaultValue = "1") var forwardStatus: Int = 1,
|
@ColumnInfo(name = "forward_status", defaultValue = "1") var forwardStatus: Int = 1,
|
||||||
@ColumnInfo(name = "forward_response", defaultValue = "") var forwardResponse: String = "",
|
@ColumnInfo(name = "forward_response", defaultValue = "") var forwardResponse: String = "",
|
||||||
@ColumnInfo(name = "time") var time: Date = Date(),
|
@ColumnInfo(name = "time") var time: Date = Date(),
|
||||||
|
@ -21,6 +21,9 @@ data class CallInfo(
|
|||||||
//卡槽ID: 0=Sim1, 1=Sim2, -1=获取失败
|
//卡槽ID: 0=Sim1, 1=Sim2, -1=获取失败
|
||||||
@SerializedName("sim_id")
|
@SerializedName("sim_id")
|
||||||
var simId: Int = -1,
|
var simId: Int = -1,
|
||||||
|
//卡槽主键
|
||||||
|
@SerializedName("sub_id")
|
||||||
|
var subId: Int = 0,
|
||||||
) : Serializable {
|
) : Serializable {
|
||||||
|
|
||||||
val typeImageId: Int
|
val typeImageId: Int
|
||||||
|
@ -23,6 +23,7 @@ data class MsgInfo(
|
|||||||
var date: Date,
|
var date: Date,
|
||||||
var simInfo: String,
|
var simInfo: String,
|
||||||
var simSlot: Int = -1, //卡槽id:-1=获取失败、0=卡槽1、1=卡槽2
|
var simSlot: Int = -1, //卡槽id:-1=获取失败、0=卡槽1、1=卡槽2
|
||||||
|
var subId: Int = 0, //卡槽主键
|
||||||
) : Serializable {
|
) : Serializable {
|
||||||
|
|
||||||
val titleForSend: String
|
val titleForSend: String
|
||||||
@ -36,13 +37,14 @@ data class MsgInfo(
|
|||||||
fun getTitleForSend(titleTemplate: String, regexReplace: String): String {
|
fun getTitleForSend(titleTemplate: String, regexReplace: String): String {
|
||||||
var template = titleTemplate.replace("null", "")
|
var template = titleTemplate.replace("null", "")
|
||||||
if (TextUtils.isEmpty(template)) template = getString(R.string.tag_from)
|
if (TextUtils.isEmpty(template)) template = getString(R.string.tag_from)
|
||||||
val deviceMark = extraDeviceMark!!.trim()
|
val deviceMark = extraDeviceMark.trim()
|
||||||
val versionName = AppUtils.getAppVersionName()
|
val versionName = AppUtils.getAppVersionName()
|
||||||
val titleForSend: String = template.replace(getString(R.string.tag_from), from)
|
val titleForSend: String = template.replace(getString(R.string.tag_from), from)
|
||||||
.replace(getString(R.string.tag_package_name), from)
|
.replace(getString(R.string.tag_package_name), from)
|
||||||
.replace(getString(R.string.tag_sms), content)
|
.replace(getString(R.string.tag_sms), content)
|
||||||
.replace(getString(R.string.tag_msg), content)
|
.replace(getString(R.string.tag_msg), content)
|
||||||
.replace(getString(R.string.tag_card_slot), simInfo)
|
.replace(getString(R.string.tag_card_slot), simInfo)
|
||||||
|
.replace(getString(R.string.tag_card_subid), subId.toString())
|
||||||
.replace(getString(R.string.tag_title), simInfo)
|
.replace(getString(R.string.tag_title), simInfo)
|
||||||
.replace(getString(R.string.tag_receive_time), SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date))
|
.replace(getString(R.string.tag_receive_time), SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date))
|
||||||
.replace(getString(R.string.tag_device_name), deviceMark)
|
.replace(getString(R.string.tag_device_name), deviceMark)
|
||||||
@ -60,10 +62,11 @@ data class MsgInfo(
|
|||||||
|
|
||||||
@SuppressLint("SimpleDateFormat")
|
@SuppressLint("SimpleDateFormat")
|
||||||
fun getContentForSend(ruleSmsTemplate: String, regexReplace: String): String {
|
fun getContentForSend(ruleSmsTemplate: String, regexReplace: String): String {
|
||||||
val deviceMark = extraDeviceMark!!.trim()
|
val deviceMark = extraDeviceMark.trim()
|
||||||
var customSmsTemplate: String = getString(R.string.tag_from).toString() + "\n" +
|
var customSmsTemplate: String = getString(R.string.tag_from).toString() + "\n" +
|
||||||
getString(R.string.tag_sms) + "\n" +
|
getString(R.string.tag_sms) + "\n" +
|
||||||
getString(R.string.tag_card_slot) + "\n" +
|
getString(R.string.tag_card_slot) + "\n" +
|
||||||
|
"SubId:" + getString(R.string.tag_card_subid) + "\n" +
|
||||||
getString(R.string.tag_receive_time) + "\n" +
|
getString(R.string.tag_receive_time) + "\n" +
|
||||||
getString(R.string.tag_device_name)
|
getString(R.string.tag_device_name)
|
||||||
|
|
||||||
@ -72,7 +75,7 @@ data class MsgInfo(
|
|||||||
customSmsTemplate = ruleSmsTemplate.replace("null", "")
|
customSmsTemplate = ruleSmsTemplate.replace("null", "")
|
||||||
} else {
|
} else {
|
||||||
val switchSmsTemplate = enableSmsTemplate
|
val switchSmsTemplate = enableSmsTemplate
|
||||||
val smsTemplate = smsTemplate.toString().trim()
|
val smsTemplate = smsTemplate.trim()
|
||||||
if (switchSmsTemplate && smsTemplate.isNotEmpty()) {
|
if (switchSmsTemplate && smsTemplate.isNotEmpty()) {
|
||||||
customSmsTemplate = smsTemplate.replace("null", "")
|
customSmsTemplate = smsTemplate.replace("null", "")
|
||||||
}
|
}
|
||||||
@ -83,6 +86,7 @@ data class MsgInfo(
|
|||||||
.replace(getString(R.string.tag_sms), content)
|
.replace(getString(R.string.tag_sms), content)
|
||||||
.replace(getString(R.string.tag_msg), content)
|
.replace(getString(R.string.tag_msg), content)
|
||||||
.replace(getString(R.string.tag_card_slot), simInfo)
|
.replace(getString(R.string.tag_card_slot), simInfo)
|
||||||
|
.replace(getString(R.string.tag_card_subid), subId.toString())
|
||||||
.replace(getString(R.string.tag_title), simInfo)
|
.replace(getString(R.string.tag_title), simInfo)
|
||||||
.replace(getString(R.string.tag_receive_time), SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date))
|
.replace(getString(R.string.tag_receive_time), SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date))
|
||||||
.replace(getString(R.string.tag_device_name), deviceMark)
|
.replace(getString(R.string.tag_device_name), deviceMark)
|
||||||
|
@ -18,6 +18,9 @@ data class SmsInfo(
|
|||||||
// 卡槽ID: 0=Sim1, 1=Sim2, -1=获取失败
|
// 卡槽ID: 0=Sim1, 1=Sim2, -1=获取失败
|
||||||
@SerializedName("sim_id")
|
@SerializedName("sim_id")
|
||||||
var simId: Int = -1,
|
var simId: Int = -1,
|
||||||
|
// 卡槽主键
|
||||||
|
@SerializedName("sub_id")
|
||||||
|
var subId: Int = 0,
|
||||||
) : Serializable {
|
) : Serializable {
|
||||||
|
|
||||||
val typeImageId: Int = R.drawable.ic_sms
|
val typeImageId: Int = R.drawable.ic_sms
|
||||||
|
@ -10,6 +10,7 @@ import android.net.Uri
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
|
import android.text.TextUtils
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@ -128,6 +129,10 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
|||||||
|
|
||||||
//设备备注
|
//设备备注
|
||||||
editAddExtraDeviceMark(binding!!.etExtraDeviceMark)
|
editAddExtraDeviceMark(binding!!.etExtraDeviceMark)
|
||||||
|
//SIM1主键
|
||||||
|
editAddSubidSim1(binding!!.etSubidSim1)
|
||||||
|
//SIM2主键
|
||||||
|
editAddSubidSim2(binding!!.etSubidSim2)
|
||||||
//SIM1备注
|
//SIM1备注
|
||||||
editAddExtraSim1(binding!!.etExtraSim1)
|
editAddExtraSim1(binding!!.etExtraSim1)
|
||||||
//SIM2备注
|
//SIM2备注
|
||||||
@ -200,6 +205,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
val simInfo: SimInfo? = App.SimInfoList[0]
|
val simInfo: SimInfo? = App.SimInfoList[0]
|
||||||
|
binding!!.etSubidSim1.setText(simInfo?.mSubscriptionId.toString())
|
||||||
binding!!.etExtraSim1.setText(simInfo?.mCarrierName.toString() + "_" + simInfo?.mNumber.toString())
|
binding!!.etExtraSim1.setText(simInfo?.mCarrierName.toString() + "_" + simInfo?.mNumber.toString())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -222,6 +228,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
val simInfo: SimInfo? = App.SimInfoList[1]
|
val simInfo: SimInfo? = App.SimInfoList[1]
|
||||||
|
binding!!.etSubidSim2.setText(simInfo?.mSubscriptionId.toString())
|
||||||
binding!!.etExtraSim2.setText(simInfo?.mCarrierName.toString() + "_" + simInfo?.mNumber.toString())
|
binding!!.etExtraSim2.setText(simInfo?.mCarrierName.toString() + "_" + simInfo?.mNumber.toString())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -729,6 +736,40 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//设置SIM1主键
|
||||||
|
private fun editAddSubidSim1(etSubidSim1: EditText) {
|
||||||
|
etSubidSim1.setText(SettingUtils.subidSim1.toString())
|
||||||
|
etSubidSim1.addTextChangedListener(object : TextWatcher {
|
||||||
|
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||||
|
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
|
||||||
|
override fun afterTextChanged(s: Editable) {
|
||||||
|
val v = etSubidSim1.text.toString()
|
||||||
|
SettingUtils.subidSim1 = if (!TextUtils.isEmpty(v)) {
|
||||||
|
v.toInt()
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置SIM2主键
|
||||||
|
private fun editAddSubidSim2(etSubidSim2: EditText) {
|
||||||
|
etSubidSim2.setText(SettingUtils.subidSim2.toString())
|
||||||
|
etSubidSim2.addTextChangedListener(object : TextWatcher {
|
||||||
|
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||||
|
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
|
||||||
|
override fun afterTextChanged(s: Editable) {
|
||||||
|
val v = etSubidSim2.text.toString()
|
||||||
|
SettingUtils.subidSim2 = if (!TextUtils.isEmpty(v)) {
|
||||||
|
v.toInt()
|
||||||
|
} else {
|
||||||
|
2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
//设置SIM1备注
|
//设置SIM1备注
|
||||||
private fun editAddExtraSim1(etExtraSim1: EditText) {
|
private fun editAddExtraSim1(etExtraSim1: EditText) {
|
||||||
etExtraSim1.setText(SettingUtils.extraSim1)
|
etExtraSim1.setText(SettingUtils.extraSim1)
|
||||||
@ -783,6 +824,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
|||||||
${getString(R.string.tag_from)}
|
${getString(R.string.tag_from)}
|
||||||
${getString(R.string.tag_sms)}
|
${getString(R.string.tag_sms)}
|
||||||
${getString(R.string.tag_card_slot)}
|
${getString(R.string.tag_card_slot)}
|
||||||
|
SubId:${getString(R.string.tag_card_subid)}
|
||||||
${getString(R.string.tag_receive_time)}
|
${getString(R.string.tag_receive_time)}
|
||||||
${getString(R.string.tag_device_name)}
|
${getString(R.string.tag_device_name)}
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
@ -51,31 +51,26 @@ class PhoneStateReceiver : BroadcastReceiver() {
|
|||||||
TelephonyManager.EXTRA_STATE_RINGING -> state = TelephonyManager.CALL_STATE_RINGING
|
TelephonyManager.EXTRA_STATE_RINGING -> state = TelephonyManager.CALL_STATE_RINGING
|
||||||
}
|
}
|
||||||
Log.d(TAG, "state=$state, number=$number")
|
Log.d(TAG, "state=$state, number=$number")
|
||||||
|
var callSavedNumber: String by SharedPreference("CALL_SAVED_NUMBER", "")
|
||||||
onCallStateChanged(context, state, number)
|
if (!TextUtils.isEmpty(number)) callSavedNumber = number.toString()
|
||||||
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.e(TAG, e.message.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Incoming call- goes from IDLE to RINGING when it rings, to OFFHOOK when it's answered, to IDLE when its hung up
|
//Incoming call- goes from IDLE to RINGING when it rings, to OFFHOOK when it's answered, to IDLE when its hung up
|
||||||
//Outgoing call- goes from IDLE to OFFHOOK when it dials out, to IDLE when hung up
|
//Outgoing call- goes from IDLE to OFFHOOK when it dials out, to IDLE when hung up
|
||||||
private fun onCallStateChanged(context: Context, state: Int, number: String?) {
|
|
||||||
var lastState: Int by SharedPreference("CALL_LAST_STATE", TelephonyManager.CALL_STATE_IDLE)
|
var lastState: Int by SharedPreference("CALL_LAST_STATE", TelephonyManager.CALL_STATE_IDLE)
|
||||||
if (lastState == state || (state == TelephonyManager.CALL_STATE_RINGING && number == null)) {
|
if (lastState == state || (state == TelephonyManager.CALL_STATE_RINGING && number == null)) {
|
||||||
//No change, debounce extras
|
//No change, debounce extras
|
||||||
|
Log.d(TAG, "状态没变,防止抖动")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
lastState = state
|
lastState = state
|
||||||
var callIsIncoming: Boolean by SharedPreference("CALL_IS_INCOMING", false)
|
var callIsIncoming: Boolean by SharedPreference("CALL_IS_INCOMING", false)
|
||||||
var callSavedNumber: String by SharedPreference("CALL_SAVED_NUMBER", "")
|
Log.d(TAG, "lastState=$lastState, callIsIncoming=$callIsIncoming, callSavedNumber=$callSavedNumber")
|
||||||
|
|
||||||
when (state) {
|
when (state) {
|
||||||
TelephonyManager.CALL_STATE_RINGING -> {
|
TelephonyManager.CALL_STATE_RINGING -> {
|
||||||
Log.d(TAG, "来电响铃")
|
Log.d(TAG, "电话响铃")
|
||||||
callIsIncoming = true
|
callIsIncoming = true
|
||||||
callSavedNumber = number.toString()
|
|
||||||
|
|
||||||
//来电提醒
|
//来电提醒
|
||||||
if (!TextUtils.isEmpty(number) && SettingUtils.enableCallType4) {
|
if (!TextUtils.isEmpty(number) && SettingUtils.enableCallType4) {
|
||||||
@ -101,6 +96,7 @@ class PhoneStateReceiver : BroadcastReceiver() {
|
|||||||
callIsIncoming = when {
|
callIsIncoming = when {
|
||||||
lastState != TelephonyManager.CALL_STATE_RINGING -> {
|
lastState != TelephonyManager.CALL_STATE_RINGING -> {
|
||||||
Log.d(TAG, "去电接通")
|
Log.d(TAG, "去电接通")
|
||||||
|
if (!TextUtils.isEmpty(number)) callSavedNumber = number.toString()
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
@ -114,17 +110,24 @@ class PhoneStateReceiver : BroadcastReceiver() {
|
|||||||
lastState == TelephonyManager.CALL_STATE_RINGING -> {
|
lastState == TelephonyManager.CALL_STATE_RINGING -> {
|
||||||
Log.d(TAG, "来电未接")
|
Log.d(TAG, "来电未接")
|
||||||
sendReceiveCallMsg(context, 3, callSavedNumber)
|
sendReceiveCallMsg(context, 3, callSavedNumber)
|
||||||
|
callSavedNumber = ""
|
||||||
}
|
}
|
||||||
callIsIncoming -> {
|
callIsIncoming -> {
|
||||||
Log.d(TAG, "来电挂机")
|
Log.d(TAG, "来电挂机")
|
||||||
sendReceiveCallMsg(context, 1, callSavedNumber)
|
sendReceiveCallMsg(context, 1, callSavedNumber)
|
||||||
|
callSavedNumber = ""
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
Log.d(TAG, "去电挂机")
|
Log.d(TAG, "去电挂机")
|
||||||
sendReceiveCallMsg(context, 2, callSavedNumber)
|
sendReceiveCallMsg(context, 2, callSavedNumber)
|
||||||
|
callSavedNumber = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, e.message.toString())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendReceiveCallMsg(context: Context, callType: Int, phoneNumber: String?) {
|
private fun sendReceiveCallMsg(context: Context, callType: Int, phoneNumber: String?) {
|
||||||
@ -158,7 +161,7 @@ class PhoneStateReceiver : BroadcastReceiver() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val msgInfo = MsgInfo(
|
val msgInfo = MsgInfo(
|
||||||
"call", callInfo.number, PhoneUtils.getCallMsg(callInfo), Date(), simInfo, simSlot
|
"call", callInfo.number, PhoneUtils.getCallMsg(callInfo), Date(), simInfo, simSlot, callInfo.subId
|
||||||
)
|
)
|
||||||
val request = OneTimeWorkRequestBuilder<SendWorker>().setInputData(
|
val request = OneTimeWorkRequestBuilder<SendWorker>().setInputData(
|
||||||
workDataOf(
|
workDataOf(
|
||||||
|
@ -34,9 +34,6 @@ class SmsReceiver : BroadcastReceiver() {
|
|||||||
//过滤广播
|
//过滤广播
|
||||||
if (intent.action != Telephony.Sms.Intents.SMS_RECEIVED_ACTION && intent.action != Telephony.Sms.Intents.SMS_DELIVER_ACTION) return
|
if (intent.action != Telephony.Sms.Intents.SMS_RECEIVED_ACTION && intent.action != Telephony.Sms.Intents.SMS_DELIVER_ACTION) return
|
||||||
|
|
||||||
//权限判断
|
|
||||||
//if (ActivityCompat.checkSelfPermission(context, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED) return
|
|
||||||
|
|
||||||
var from = ""
|
var from = ""
|
||||||
var content = ""
|
var content = ""
|
||||||
for (smsMessage in Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
|
for (smsMessage in Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
|
||||||
@ -46,12 +43,6 @@ class SmsReceiver : BroadcastReceiver() {
|
|||||||
Log.d(TAG, "from = $from")
|
Log.d(TAG, "from = $from")
|
||||||
Log.d(TAG, "content = $content")
|
Log.d(TAG, "content = $content")
|
||||||
|
|
||||||
//获取卡槽信息
|
|
||||||
if (App.SimInfoList.isEmpty()) {
|
|
||||||
App.SimInfoList = PhoneUtils.getSimMultiInfo()
|
|
||||||
}
|
|
||||||
Log.e(TAG, "SimInfoList = " + App.SimInfoList.toString())
|
|
||||||
|
|
||||||
//TODO:准确获取卡槽信息,目前测试结果只有 subscription 相对靠谱
|
//TODO:准确获取卡槽信息,目前测试结果只有 subscription 相对靠谱
|
||||||
val slot = intent.extras?.getInt("slot") ?: -1
|
val slot = intent.extras?.getInt("slot") ?: -1
|
||||||
val simId = intent.extras?.getInt("simId") ?: slot
|
val simId = intent.extras?.getInt("simId") ?: slot
|
||||||
@ -60,6 +51,16 @@ class SmsReceiver : BroadcastReceiver() {
|
|||||||
|
|
||||||
//卡槽id:-1=获取失败、0=卡槽1、1=卡槽2
|
//卡槽id:-1=获取失败、0=卡槽1、1=卡槽2
|
||||||
var simSlot = -1
|
var simSlot = -1
|
||||||
|
//以自定义卡槽信息优先
|
||||||
|
if (SettingUtils.subidSim1 > 0 || SettingUtils.subidSim2 > 0) {
|
||||||
|
simSlot = if (subscription == SettingUtils.subidSim1) 0 else 1
|
||||||
|
} else {
|
||||||
|
//获取卡槽信息
|
||||||
|
if (App.SimInfoList.isEmpty()) {
|
||||||
|
App.SimInfoList = PhoneUtils.getSimMultiInfo()
|
||||||
|
}
|
||||||
|
Log.d(TAG, "SimInfoList = " + App.SimInfoList.toString())
|
||||||
|
|
||||||
if (App.SimInfoList.isNotEmpty()) {
|
if (App.SimInfoList.isNotEmpty()) {
|
||||||
for (simInfo in App.SimInfoList.values) {
|
for (simInfo in App.SimInfoList.values) {
|
||||||
if (simInfo.mSubscriptionId == subscription) {
|
if (simInfo.mSubscriptionId == subscription) {
|
||||||
@ -68,6 +69,8 @@ class SmsReceiver : BroadcastReceiver() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//获取卡槽信息
|
//获取卡槽信息
|
||||||
val simInfo = when (simSlot) {
|
val simInfo = when (simSlot) {
|
||||||
0 -> "SIM1_" + SettingUtils.extraSim1
|
0 -> "SIM1_" + SettingUtils.extraSim1
|
||||||
@ -75,16 +78,14 @@ class SmsReceiver : BroadcastReceiver() {
|
|||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
|
|
||||||
val msgInfo = MsgInfo("sms", from, content, Date(), simInfo, simSlot)
|
val msgInfo = MsgInfo("sms", from, content, Date(), simInfo, simSlot, subscription)
|
||||||
Log.d(TAG, "msgInfo = $msgInfo")
|
Log.d(TAG, "msgInfo = $msgInfo")
|
||||||
|
|
||||||
val request = OneTimeWorkRequestBuilder<SendWorker>()
|
val request = OneTimeWorkRequestBuilder<SendWorker>().setInputData(
|
||||||
.setInputData(
|
|
||||||
workDataOf(
|
workDataOf(
|
||||||
Worker.sendMsgInfo to Gson().toJson(msgInfo)
|
Worker.sendMsgInfo to Gson().toJson(msgInfo)
|
||||||
)
|
)
|
||||||
)
|
).build()
|
||||||
.build()
|
|
||||||
WorkManager.getInstance(context).enqueue(request)
|
WorkManager.getInstance(context).enqueue(request)
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
@ -65,6 +65,8 @@ const val SP_REQUEST_TIMEOUT = "request_timeout"
|
|||||||
|
|
||||||
const val SP_NOTIFY_CONTENT = "notify_content"
|
const val SP_NOTIFY_CONTENT = "notify_content"
|
||||||
const val SP_EXTRA_DEVICE_MARK = "extra_device_mark"
|
const val SP_EXTRA_DEVICE_MARK = "extra_device_mark"
|
||||||
|
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_SIM1 = "extra_sim1"
|
||||||
const val SP_EXTRA_SIM2 = "extra_sim2"
|
const val SP_EXTRA_SIM2 = "extra_sim2"
|
||||||
const val SP_ENABLE_SMS_TEMPLATE = "enable_sms_template"
|
const val SP_ENABLE_SMS_TEMPLATE = "enable_sms_template"
|
||||||
|
@ -45,14 +45,11 @@ class PhoneUtils private constructor() {
|
|||||||
try {
|
try {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
|
||||||
println("1.版本超过5.1,调用系统方法")
|
println("1.版本超过5.1,调用系统方法")
|
||||||
val mSubscriptionManager = XUtil.getContext()
|
val mSubscriptionManager = XUtil.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
|
||||||
.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
|
|
||||||
ActivityCompat.checkSelfPermission(
|
ActivityCompat.checkSelfPermission(
|
||||||
XUtil.getContext(),
|
XUtil.getContext(), permission.READ_PHONE_STATE
|
||||||
permission.READ_PHONE_STATE
|
|
||||||
)
|
)
|
||||||
val activeSubscriptionInfoList: List<SubscriptionInfo>? =
|
val activeSubscriptionInfoList: List<SubscriptionInfo>? = mSubscriptionManager.activeSubscriptionInfoList
|
||||||
mSubscriptionManager.activeSubscriptionInfoList
|
|
||||||
if (activeSubscriptionInfoList != null && activeSubscriptionInfoList.isNotEmpty()) {
|
if (activeSubscriptionInfoList != null && activeSubscriptionInfoList.isNotEmpty()) {
|
||||||
//1.1.1 有使用的卡,就遍历所有卡
|
//1.1.1 有使用的卡,就遍历所有卡
|
||||||
for (subscriptionInfo in activeSubscriptionInfoList) {
|
for (subscriptionInfo in activeSubscriptionInfoList) {
|
||||||
@ -72,30 +69,14 @@ class PhoneUtils private constructor() {
|
|||||||
val uri = Uri.parse("content://telephony/siminfo") //访问raw_contacts表
|
val uri = Uri.parse("content://telephony/siminfo") //访问raw_contacts表
|
||||||
val resolver: ContentResolver = XUtil.getContext().contentResolver
|
val resolver: ContentResolver = XUtil.getContext().contentResolver
|
||||||
val cursor = resolver.query(
|
val cursor = resolver.query(
|
||||||
uri,
|
uri, arrayOf(
|
||||||
arrayOf(
|
"_id", "icc_id", "sim_id", "display_name", "carrier_name", "name_source", "color", "number", "display_number_format", "data_roaming", "mcc", "mnc"
|
||||||
"_id",
|
), null, null, null
|
||||||
"icc_id",
|
|
||||||
"sim_id",
|
|
||||||
"display_name",
|
|
||||||
"carrier_name",
|
|
||||||
"name_source",
|
|
||||||
"color",
|
|
||||||
"number",
|
|
||||||
"display_number_format",
|
|
||||||
"data_roaming",
|
|
||||||
"mcc",
|
|
||||||
"mnc"
|
|
||||||
),
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null
|
|
||||||
)
|
)
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
do {
|
do {
|
||||||
val simInfo = SimInfo()
|
val simInfo = SimInfo()
|
||||||
simInfo.mCarrierName =
|
simInfo.mCarrierName = cursor.getString(cursor.getColumnIndex("carrier_name"))
|
||||||
cursor.getString(cursor.getColumnIndex("carrier_name"))
|
|
||||||
simInfo.mIccId = cursor.getString(cursor.getColumnIndex("icc_id"))
|
simInfo.mIccId = cursor.getString(cursor.getColumnIndex("icc_id"))
|
||||||
simInfo.mSimSlotIndex = cursor.getInt(cursor.getColumnIndex("sim_id"))
|
simInfo.mSimSlotIndex = cursor.getInt(cursor.getColumnIndex("sim_id"))
|
||||||
simInfo.mNumber = cursor.getString(cursor.getColumnIndex("number"))
|
simInfo.mNumber = cursor.getString(cursor.getColumnIndex("number"))
|
||||||
@ -141,13 +122,10 @@ class PhoneUtils private constructor() {
|
|||||||
val mobileArray = mobiles.split(";".toRegex()).toTypedArray()
|
val mobileArray = mobiles.split(";".toRegex()).toTypedArray()
|
||||||
for (mobile in mobileArray) {
|
for (mobile in mobileArray) {
|
||||||
try {
|
try {
|
||||||
val sendFlags =
|
val sendFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) PendingIntent.FLAG_IMMUTABLE else PendingIntent.FLAG_ONE_SHOT
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) PendingIntent.FLAG_IMMUTABLE else PendingIntent.FLAG_ONE_SHOT
|
val sendPI = PendingIntent.getBroadcast(XUtil.getContext(), 0, Intent(), sendFlags)
|
||||||
val sendPI =
|
|
||||||
PendingIntent.getBroadcast(XUtil.getContext(), 0, Intent(), sendFlags)
|
|
||||||
|
|
||||||
val smsManager =
|
val smsManager = if (subId > -1 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) SmsManager.getSmsManagerForSubscriptionId(
|
||||||
if (subId > -1 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) SmsManager.getSmsManagerForSubscriptionId(
|
|
||||||
subId
|
subId
|
||||||
) else SmsManager.getDefault()
|
) else SmsManager.getDefault()
|
||||||
// Android 5.1.1 以下使用反射指定卡槽
|
// Android 5.1.1 以下使用反射指定卡槽
|
||||||
@ -161,13 +139,9 @@ class PhoneUtils private constructor() {
|
|||||||
|
|
||||||
// 切割长短信
|
// 切割长短信
|
||||||
if (message.length >= 70) {
|
if (message.length >= 70) {
|
||||||
val deliverFlags =
|
val deliverFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) PendingIntent.FLAG_IMMUTABLE else 0
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) PendingIntent.FLAG_IMMUTABLE else 0
|
|
||||||
val deliverPI = PendingIntent.getBroadcast(
|
val deliverPI = PendingIntent.getBroadcast(
|
||||||
XUtil.getContext(),
|
XUtil.getContext(), 0, Intent("DELIVERED_SMS_ACTION"), deliverFlags
|
||||||
0,
|
|
||||||
Intent("DELIVERED_SMS_ACTION"),
|
|
||||||
deliverFlags
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val sentPendingIntents = ArrayList<PendingIntent>()
|
val sentPendingIntents = ArrayList<PendingIntent>()
|
||||||
@ -179,11 +153,7 @@ class PhoneUtils private constructor() {
|
|||||||
deliveredPendingIntents.add(i, deliverPI)
|
deliveredPendingIntents.add(i, deliverPI)
|
||||||
}
|
}
|
||||||
smsManager.sendMultipartTextMessage(
|
smsManager.sendMultipartTextMessage(
|
||||||
mobile,
|
mobile, null, divideContents, sentPendingIntents, deliveredPendingIntents
|
||||||
null,
|
|
||||||
divideContents,
|
|
||||||
sentPendingIntents,
|
|
||||||
deliveredPendingIntents
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
smsManager.sendTextMessage(mobile, null, message, sendPI, null)
|
smsManager.sendTextMessage(mobile, null, message, sendPI, null)
|
||||||
@ -199,10 +169,7 @@ class PhoneUtils private constructor() {
|
|||||||
|
|
||||||
//获取通话记录列表
|
//获取通话记录列表
|
||||||
fun getCallInfoList(
|
fun getCallInfoList(
|
||||||
type: Int,
|
type: Int, limit: Int, offset: Int, phoneNumber: String?
|
||||||
limit: Int,
|
|
||||||
offset: Int,
|
|
||||||
phoneNumber: String?
|
|
||||||
): MutableList<CallInfo> {
|
): MutableList<CallInfo> {
|
||||||
val callInfoList: MutableList<CallInfo> = mutableListOf()
|
val callInfoList: MutableList<CallInfo> = mutableListOf()
|
||||||
try {
|
try {
|
||||||
@ -221,11 +188,7 @@ class PhoneUtils private constructor() {
|
|||||||
|
|
||||||
//为了兼容性这里全部取出后手动分页
|
//为了兼容性这里全部取出后手动分页
|
||||||
val cursor = Core.app.contentResolver.query(
|
val cursor = Core.app.contentResolver.query(
|
||||||
CallLog.Calls.CONTENT_URI,
|
CallLog.Calls.CONTENT_URI, null, selection, selectionArgs.toTypedArray(), CallLog.Calls.DEFAULT_SORT_ORDER // + " limit $limit offset $offset"
|
||||||
null,
|
|
||||||
selection,
|
|
||||||
selectionArgs.toTypedArray(),
|
|
||||||
CallLog.Calls.DEFAULT_SORT_ORDER // + " limit $limit offset $offset"
|
|
||||||
) ?: return callInfoList
|
) ?: return callInfoList
|
||||||
Log.i(TAG, "cursor count:" + cursor.count)
|
Log.i(TAG, "cursor count:" + cursor.count)
|
||||||
|
|
||||||
@ -242,20 +205,26 @@ class PhoneUtils private constructor() {
|
|||||||
val indexDate = cursor.getColumnIndex(CallLog.Calls.DATE)
|
val indexDate = cursor.getColumnIndex(CallLog.Calls.DATE)
|
||||||
val indexDuration = cursor.getColumnIndex(CallLog.Calls.DURATION)
|
val indexDuration = cursor.getColumnIndex(CallLog.Calls.DURATION)
|
||||||
val indexType = cursor.getColumnIndex(CallLog.Calls.TYPE)
|
val indexType = cursor.getColumnIndex(CallLog.Calls.TYPE)
|
||||||
val indexViaNumber =
|
val indexViaNumber = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && cursor.getColumnIndex("via_number") != -1) cursor.getColumnIndex("via_number") else -1
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && cursor.getColumnIndex(
|
var indexSimId = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) cursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID) else -1
|
||||||
"via_number"
|
var indexSubId = indexSimId
|
||||||
) != -1
|
|
||||||
) cursor.getColumnIndex("via_number") else -1
|
/**
|
||||||
//TODO:卡槽识别,这里需要适配机型
|
* TODO:卡槽识别,这里需要适配机型
|
||||||
|
* MIUI系统:simid 字段实际为 subscription_id
|
||||||
|
* EMUI系统:subscription_id 实际为 sim_id
|
||||||
|
*/
|
||||||
var isSimId = false
|
var isSimId = false
|
||||||
var indexSimId = -1
|
val manufacturer = Build.MANUFACTURER.lowercase(Locale.getDefault())
|
||||||
if (cursor.getColumnIndex("simid") != -1) { //MIUI系统必须用这个字段
|
Log.i(TAG, "manufacturer = $manufacturer")
|
||||||
indexSimId = cursor.getColumnIndex("simid")
|
if (manufacturer.contains(Regex(pattern = "xiaomi|redmi"))) {
|
||||||
|
if (cursor.getColumnIndex("simid") != -1) indexSimId = cursor.getColumnIndex("simid")
|
||||||
|
indexSubId = indexSimId
|
||||||
|
} else if (manufacturer.contains(Regex(pattern = "huawei|honor"))) {
|
||||||
|
indexSubId = -1 //TODO:暂时不支持华为
|
||||||
isSimId = true
|
isSimId = true
|
||||||
} else if (cursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID) != -1) {
|
|
||||||
indexSimId = cursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var curOffset = 0
|
var curOffset = 0
|
||||||
do {
|
do {
|
||||||
if (curOffset >= offset) {
|
if (curOffset >= offset) {
|
||||||
@ -266,10 +235,8 @@ class PhoneUtils private constructor() {
|
|||||||
cursor.getInt(indexDuration), //获取通话时长,值为多少秒
|
cursor.getInt(indexDuration), //获取通话时长,值为多少秒
|
||||||
cursor.getInt(indexType), //获取通话类型:1.呼入 2.呼出 3.未接
|
cursor.getInt(indexType), //获取通话类型:1.呼入 2.呼出 3.未接
|
||||||
if (indexViaNumber != -1) cursor.getString(indexViaNumber) else "", //来源号码
|
if (indexViaNumber != -1) cursor.getString(indexViaNumber) else "", //来源号码
|
||||||
if (indexSimId != -1) getSimId(
|
if (indexSimId != -1) getSimId(cursor.getInt(indexSimId), isSimId) else -1, //卡槽ID: 0=Sim1, 1=Sim2, -1=获取失败
|
||||||
cursor.getInt(indexSimId),
|
if (indexSubId != -1) cursor.getInt(indexSubId) else 0, //卡槽主键
|
||||||
isSimId
|
|
||||||
) else -1 //卡槽id
|
|
||||||
)
|
)
|
||||||
Log.d(TAG, callInfo.toString())
|
Log.d(TAG, callInfo.toString())
|
||||||
callInfoList.add(callInfo)
|
callInfoList.add(callInfo)
|
||||||
@ -300,10 +267,7 @@ class PhoneUtils private constructor() {
|
|||||||
|
|
||||||
//获取联系人列表
|
//获取联系人列表
|
||||||
fun getContactInfoList(
|
fun getContactInfoList(
|
||||||
limit: Int,
|
limit: Int, offset: Int, phoneNumber: String?, name: String?
|
||||||
offset: Int,
|
|
||||||
phoneNumber: String?,
|
|
||||||
name: String?
|
|
||||||
): MutableList<ContactInfo> {
|
): MutableList<ContactInfo> {
|
||||||
val contactInfoList: MutableList<ContactInfo> = mutableListOf()
|
val contactInfoList: MutableList<ContactInfo> = mutableListOf()
|
||||||
|
|
||||||
@ -322,11 +286,7 @@ class PhoneUtils private constructor() {
|
|||||||
Log.d(TAG, "selectionArgs = $selectionArgs")
|
Log.d(TAG, "selectionArgs = $selectionArgs")
|
||||||
|
|
||||||
val cursor = Core.app.contentResolver.query(
|
val cursor = Core.app.contentResolver.query(
|
||||||
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
|
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, selection, selectionArgs.toTypedArray(), ContactsContract.CommonDataKinds.Phone.SORT_KEY_PRIMARY
|
||||||
null,
|
|
||||||
selection,
|
|
||||||
selectionArgs.toTypedArray(),
|
|
||||||
ContactsContract.CommonDataKinds.Phone.SORT_KEY_PRIMARY
|
|
||||||
) ?: return contactInfoList
|
) ?: return contactInfoList
|
||||||
Log.i(TAG, "cursor count:" + cursor.count)
|
Log.i(TAG, "cursor count:" + cursor.count)
|
||||||
|
|
||||||
@ -337,10 +297,8 @@ class PhoneUtils private constructor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
val displayNameIndex =
|
val displayNameIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)
|
||||||
cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)
|
val mobileNoIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
|
||||||
val mobileNoIndex =
|
|
||||||
cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
|
|
||||||
do {
|
do {
|
||||||
val contactInfo = ContactInfo(
|
val contactInfo = ContactInfo(
|
||||||
cursor.getString(displayNameIndex), //姓名
|
cursor.getString(displayNameIndex), //姓名
|
||||||
@ -373,12 +331,10 @@ class PhoneUtils private constructor() {
|
|||||||
fun getCallMsg(callInfo: CallInfo): String {
|
fun getCallMsg(callInfo: CallInfo): String {
|
||||||
val sb = StringBuilder()
|
val sb = StringBuilder()
|
||||||
sb.append(ResUtils.getString(R.string.linkman)).append(callInfo.name).append("\n")
|
sb.append(ResUtils.getString(R.string.linkman)).append(callInfo.name).append("\n")
|
||||||
if (!TextUtils.isEmpty(callInfo.viaNumber)) sb.append(ResUtils.getString(R.string.via_number))
|
if (!TextUtils.isEmpty(callInfo.viaNumber)) sb.append(ResUtils.getString(R.string.via_number)).append(callInfo.viaNumber).append("\n")
|
||||||
.append(callInfo.viaNumber).append("\n")
|
|
||||||
if (callInfo.dateLong > 0L) sb.append(ResUtils.getString(R.string.call_date)).append(
|
if (callInfo.dateLong > 0L) sb.append(ResUtils.getString(R.string.call_date)).append(
|
||||||
DateUtils.millis2String(
|
DateUtils.millis2String(
|
||||||
callInfo.dateLong,
|
callInfo.dateLong, SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
|
||||||
SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
|
|
||||||
)
|
)
|
||||||
).append("\n")
|
).append("\n")
|
||||||
if (callInfo.duration > 0) {
|
if (callInfo.duration > 0) {
|
||||||
@ -402,10 +358,7 @@ class PhoneUtils private constructor() {
|
|||||||
|
|
||||||
// 获取用户短信列表
|
// 获取用户短信列表
|
||||||
fun getSmsInfoList(
|
fun getSmsInfoList(
|
||||||
type: Int,
|
type: Int, limit: Int, offset: Int, keyword: String
|
||||||
limit: Int,
|
|
||||||
offset: Int,
|
|
||||||
keyword: String
|
|
||||||
): MutableList<SmsInfo> {
|
): MutableList<SmsInfo> {
|
||||||
val smsInfoList: MutableList<SmsInfo> = mutableListOf()
|
val smsInfoList: MutableList<SmsInfo> = mutableListOf()
|
||||||
try {
|
try {
|
||||||
@ -424,11 +377,7 @@ class PhoneUtils private constructor() {
|
|||||||
|
|
||||||
// 避免超过总数后循环取出
|
// 避免超过总数后循环取出
|
||||||
val cursorTotal = Core.app.contentResolver.query(
|
val cursorTotal = Core.app.contentResolver.query(
|
||||||
Uri.parse("content://sms/"),
|
Uri.parse("content://sms/"), null, selection, selectionArgs.toTypedArray(), "date desc"
|
||||||
null,
|
|
||||||
selection,
|
|
||||||
selectionArgs.toTypedArray(),
|
|
||||||
"date desc"
|
|
||||||
) ?: return smsInfoList
|
) ?: return smsInfoList
|
||||||
if (offset >= cursorTotal.count) {
|
if (offset >= cursorTotal.count) {
|
||||||
cursorTotal.close()
|
cursorTotal.close()
|
||||||
@ -436,11 +385,7 @@ class PhoneUtils private constructor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val cursor = Core.app.contentResolver.query(
|
val cursor = Core.app.contentResolver.query(
|
||||||
Uri.parse("content://sms/"),
|
Uri.parse("content://sms/"), null, selection, selectionArgs.toTypedArray(), "date desc limit $limit offset $offset"
|
||||||
null,
|
|
||||||
selection,
|
|
||||||
selectionArgs.toTypedArray(),
|
|
||||||
"date desc limit $limit offset $offset"
|
|
||||||
) ?: return smsInfoList
|
) ?: return smsInfoList
|
||||||
|
|
||||||
Log.i(TAG, "cursor count:" + cursor.count)
|
Log.i(TAG, "cursor count:" + cursor.count)
|
||||||
@ -455,22 +400,30 @@ class PhoneUtils private constructor() {
|
|||||||
val indexBody = cursor.getColumnIndex("body")
|
val indexBody = cursor.getColumnIndex("body")
|
||||||
val indexDate = cursor.getColumnIndex("date")
|
val indexDate = cursor.getColumnIndex("date")
|
||||||
val indexType = cursor.getColumnIndex("type")
|
val indexType = cursor.getColumnIndex("type")
|
||||||
//TODO:卡槽识别,这里需要适配机型
|
var indexSimId = cursor.getColumnIndex("sim_id")
|
||||||
|
var indexSubId = cursor.getColumnIndex("sub_id")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO:卡槽识别,这里需要适配机型
|
||||||
|
* MIUI系统:sim_id 字段实际为 subscription_id
|
||||||
|
* EMUI系统:sub_id 实际为 sim_id
|
||||||
|
*/
|
||||||
var isSimId = false
|
var isSimId = false
|
||||||
var indexSimId = -1
|
val manufacturer = Build.MANUFACTURER.lowercase(Locale.getDefault())
|
||||||
if (cursor.getColumnIndex("sim_id") != -1) { //MIUI系统必须用这个字段
|
Log.i(TAG, "manufacturer = $manufacturer")
|
||||||
indexSimId = cursor.getColumnIndex("sim_id")
|
if (manufacturer.contains(Regex(pattern = "xiaomi|redmi"))) {
|
||||||
isSimId = true
|
indexSubId = cursor.getColumnIndex("sim_id")
|
||||||
} else if (cursor.getColumnIndex("sub_id") != -1) {
|
} else if (manufacturer.contains(Regex(pattern = "huawei|honor"))) {
|
||||||
indexSimId = cursor.getColumnIndex("sub_id")
|
indexSimId = cursor.getColumnIndex("sub_id")
|
||||||
|
isSimId = true
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
val smsInfo = SmsInfo()
|
val smsInfo = SmsInfo()
|
||||||
val phoneNumber = cursor.getString(indexAddress)
|
val phoneNumber = cursor.getString(indexAddress)
|
||||||
// 根据手机号码查询用户名
|
// 根据手机号码查询用户名
|
||||||
val contacts = getContactByNumber(phoneNumber)
|
val contacts = getContactByNumber(phoneNumber)
|
||||||
smsInfo.name =
|
smsInfo.name = if (contacts.isNotEmpty()) contacts[0].name else ResUtils.getString(R.string.unknown_number)
|
||||||
if (contacts.isNotEmpty()) contacts[0].name else ResUtils.getString(R.string.unknown_number)
|
|
||||||
// 联系人号码
|
// 联系人号码
|
||||||
smsInfo.number = phoneNumber
|
smsInfo.number = phoneNumber
|
||||||
// 短信内容
|
// 短信内容
|
||||||
@ -479,11 +432,11 @@ class PhoneUtils private constructor() {
|
|||||||
smsInfo.date = cursor.getLong(indexDate)
|
smsInfo.date = cursor.getLong(indexDate)
|
||||||
// 短信类型: 1=接收, 2=发送
|
// 短信类型: 1=接收, 2=发送
|
||||||
smsInfo.type = cursor.getInt(indexType)
|
smsInfo.type = cursor.getInt(indexType)
|
||||||
// 卡槽id
|
// 卡槽ID: 0=Sim1, 1=Sim2, -1=获取失败
|
||||||
smsInfo.simId = if (indexSimId != -1) getSimId(
|
smsInfo.simId = if (indexSimId != -1) getSimId(cursor.getInt(indexSimId), isSimId) else -1
|
||||||
cursor.getInt(indexSimId),
|
// 卡槽主键
|
||||||
isSimId
|
smsInfo.subId = if (indexSubId != -1) cursor.getInt(indexSubId) else 0
|
||||||
) else -1
|
|
||||||
smsInfoList.add(smsInfo)
|
smsInfoList.add(smsInfo)
|
||||||
} while (cursor.moveToNext())
|
} while (cursor.moveToNext())
|
||||||
|
|
||||||
@ -527,22 +480,11 @@ class PhoneUtils private constructor() {
|
|||||||
*/
|
*/
|
||||||
private fun getSimId(mId: Int, isSimId: Boolean): Int {
|
private fun getSimId(mId: Int, isSimId: Boolean): Int {
|
||||||
Log.i(TAG, "mId = $mId, isSimId = $isSimId")
|
Log.i(TAG, "mId = $mId, isSimId = $isSimId")
|
||||||
//if (isSimId) return mId
|
if (isSimId) return mId
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO:特别处理
|
|
||||||
* MIUI系统:simId 字段实际为 subscription_id
|
|
||||||
* EMUI系统:subscription_id 实际为 simId
|
|
||||||
*/
|
|
||||||
val manufacturer = Build.MANUFACTURER.lowercase(Locale.getDefault())
|
|
||||||
Log.i(TAG, "manufacturer = $manufacturer")
|
|
||||||
if (isSimId && !manufacturer.contains(Regex(pattern = "xiaomi|redmi"))) {
|
|
||||||
return mId
|
|
||||||
}
|
|
||||||
if (!isSimId && manufacturer.contains(Regex(pattern = "huawei|honor"))) {
|
|
||||||
return mId
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (SettingUtils.subidSim1 > 0 || SettingUtils.subidSim2 > 0) {
|
||||||
|
return if (mId == SettingUtils.subidSim1) 0 else 1
|
||||||
|
} else {
|
||||||
//获取卡槽信息
|
//获取卡槽信息
|
||||||
if (App.SimInfoList.isEmpty()) {
|
if (App.SimInfoList.isEmpty()) {
|
||||||
App.SimInfoList = getSimMultiInfo()
|
App.SimInfoList = getSimMultiInfo()
|
||||||
@ -559,6 +501,7 @@ class PhoneUtils private constructor() {
|
|||||||
}
|
}
|
||||||
return simSlot
|
return simSlot
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,6 +114,12 @@ class SettingUtils private constructor() {
|
|||||||
//设备名称
|
//设备名称
|
||||||
var extraDeviceMark: String by SharedPreference(SP_EXTRA_DEVICE_MARK, "")
|
var extraDeviceMark: String by SharedPreference(SP_EXTRA_DEVICE_MARK, "")
|
||||||
|
|
||||||
|
//SM1主键
|
||||||
|
var subidSim1: Int by SharedPreference(SP_SUBID_SIM1, 0)
|
||||||
|
|
||||||
|
//SM2主键
|
||||||
|
var subidSim2: Int by SharedPreference(SP_SUBID_SIM2, 0)
|
||||||
|
|
||||||
//SM1备注
|
//SM1备注
|
||||||
var extraSim1: String by SharedPreference(SP_EXTRA_SIM1, "")
|
var extraSim1: String by SharedPreference(SP_EXTRA_SIM1, "")
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ class SmsUtils {
|
|||||||
val content: String = if (rule != null) {
|
val content: String = if (rule != null) {
|
||||||
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
|
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
|
||||||
} else {
|
} else {
|
||||||
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
|
msgInfo.getContentForSend(SettingUtils.smsTemplate)
|
||||||
}
|
}
|
||||||
|
|
||||||
//【注意】判断卡槽配置:0=原进原出、1=卡槽1、2=卡槽2
|
//【注意】判断卡槽配置:0=原进原出、1=卡槽1、2=卡槽2
|
||||||
|
@ -83,7 +83,7 @@ class SendWorker(
|
|||||||
for (rule in ruleList) {
|
for (rule in ruleList) {
|
||||||
if (!rule.rule.checkMsg(msgInfo)) continue
|
if (!rule.rule.checkMsg(msgInfo)) continue
|
||||||
val log = Logs(
|
val log = Logs(
|
||||||
0, msgInfo.type, msgInfo.from, msgInfo.content, rule.rule.id, msgInfo.simInfo
|
0, msgInfo.type, msgInfo.from, msgInfo.content, rule.rule.id, msgInfo.simInfo, msgInfo.subId
|
||||||
)
|
)
|
||||||
val logId = Core.logs.insert(log)
|
val logId = Core.logs.insert(log)
|
||||||
SendUtils.sendMsgSender(msgInfo, rule.rule, rule.sender, logId)
|
SendUtils.sendMsgSender(msgInfo, rule.rule, rule.sender, logId)
|
||||||
|
@ -1110,12 +1110,30 @@
|
|||||||
tools:ignore="SmallSp" />
|
tools:ignore="SmallSp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<com.xuexiang.xui.widget.edittext.ClearEditText
|
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
|
||||||
android:id="@+id/et_extra_sim1"
|
android:id="@+id/et_subid_sim1"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:layout_weight="1" />
|
android:layout_weight="1"
|
||||||
|
android:hint="@string/sim_sub_id"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAlignment="center"
|
||||||
|
app:met_allowEmpty="false"
|
||||||
|
app:met_autoValidate="true"
|
||||||
|
app:met_errorMessage="@string/tip_number_only_error_message"
|
||||||
|
app:met_regexp="@string/regexp_number_only"
|
||||||
|
app:met_validateOnFocusLost="true" />
|
||||||
|
|
||||||
|
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
|
||||||
|
android:id="@+id/et_extra_sim1"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="2dp"
|
||||||
|
android:layout_weight="3"
|
||||||
|
android:hint="@string/custom_settings_tips"
|
||||||
|
android:singleLine="true"
|
||||||
|
app:met_clearButton="true" />
|
||||||
|
|
||||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||||
android:id="@+id/btn_extra_sim1"
|
android:id="@+id/btn_extra_sim1"
|
||||||
@ -1161,12 +1179,30 @@
|
|||||||
tools:ignore="SmallSp" />
|
tools:ignore="SmallSp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<com.xuexiang.xui.widget.edittext.ClearEditText
|
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
|
||||||
android:id="@+id/et_extra_sim2"
|
android:id="@+id/et_subid_sim2"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:layout_weight="1" />
|
android:layout_weight="1"
|
||||||
|
android:hint="@string/sim_sub_id"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAlignment="center"
|
||||||
|
app:met_allowEmpty="false"
|
||||||
|
app:met_autoValidate="true"
|
||||||
|
app:met_errorMessage="@string/tip_number_only_error_message"
|
||||||
|
app:met_regexp="@string/regexp_number_only"
|
||||||
|
app:met_validateOnFocusLost="true" />
|
||||||
|
|
||||||
|
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
|
||||||
|
android:id="@+id/et_extra_sim2"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="2dp"
|
||||||
|
android:layout_weight="3"
|
||||||
|
android:hint="@string/custom_settings_tips"
|
||||||
|
android:singleLine="true"
|
||||||
|
app:met_clearButton="true" />
|
||||||
|
|
||||||
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
|
||||||
android:id="@+id/btn_extra_sim2"
|
android:id="@+id/btn_extra_sim2"
|
||||||
|
@ -334,9 +334,12 @@
|
|||||||
<!--SettingActivity-->
|
<!--SettingActivity-->
|
||||||
<string name="notify_content">Notify Content</string>
|
<string name="notify_content">Notify Content</string>
|
||||||
<string name="device_name">Device Name</string>
|
<string name="device_name">Device Name</string>
|
||||||
<string name="sim1_remark" tools:ignore="Typos">SIM1 Label</string>
|
<string name="sim_sub_id">SIM1 SubId</string>
|
||||||
<string name="sim2_remark" tools:ignore="Typos">SIM2 Label</string>
|
<string name="sim1_remark" tools:ignore="Typos">SIM1 SubId/Label</string>
|
||||||
|
<string name="sim2_remark" tools:ignore="Typos">SIM2 SubId/Label</string>
|
||||||
<string name="carrier_mobile" tools:ignore="Typos">Label of SIM,\neg. AT&T_88888888</string>
|
<string name="carrier_mobile" tools:ignore="Typos">Label of SIM,\neg. AT&T_88888888</string>
|
||||||
|
<string name="tip_number_only_error_message">Number must be greater than 0!</string>
|
||||||
|
<string name="regexp_number_only">^[1-9]?\\d+$</string>
|
||||||
<string name="low_power_alarm_threshold">Low Power Alarm</string>
|
<string name="low_power_alarm_threshold">Low Power Alarm</string>
|
||||||
<string name="low_power_alarm_threshold_tips">Value range: 0–99.\nLeft blank or 0 is disabled</string>
|
<string name="low_power_alarm_threshold_tips">Value range: 0–99.\nLeft blank or 0 is disabled</string>
|
||||||
<string name="retry_interval">Retry Interval</string>
|
<string name="retry_interval">Retry Interval</string>
|
||||||
@ -543,6 +546,7 @@
|
|||||||
<string name="tag_app_name">{{APP_NAME}}</string>
|
<string name="tag_app_name">{{APP_NAME}}</string>
|
||||||
<string name="tag_msg">{{MSG}}</string>
|
<string name="tag_msg">{{MSG}}</string>
|
||||||
<string name="tag_card_slot">{{CARD_SLOT}}</string>
|
<string name="tag_card_slot">{{CARD_SLOT}}</string>
|
||||||
|
<string name="tag_card_subid">{{CARD_SUBID}}</string>
|
||||||
<string name="tag_receive_time">{{RECEIVE_TIME}}</string>
|
<string name="tag_receive_time">{{RECEIVE_TIME}}</string>
|
||||||
<string name="tag_device_name">{{DEVICE_NAME}}</string>
|
<string name="tag_device_name">{{DEVICE_NAME}}</string>
|
||||||
<string name="tag_app_version">{{APP_VERSION}}</string>
|
<string name="tag_app_version">{{APP_VERSION}}</string>
|
||||||
|
@ -335,9 +335,12 @@
|
|||||||
<!--SettingActivity-->
|
<!--SettingActivity-->
|
||||||
<string name="notify_content">通知文案</string>
|
<string name="notify_content">通知文案</string>
|
||||||
<string name="device_name">设备名称</string>
|
<string name="device_name">设备名称</string>
|
||||||
<string name="sim1_remark" tools:ignore="Typos">SIM1备注</string>
|
<string name="sim_sub_id">卡槽主键</string>
|
||||||
<string name="sim2_remark" tools:ignore="Typos">SIM2备注</string>
|
<string name="sim1_remark" tools:ignore="Typos">SIM1主键/备注</string>
|
||||||
<string name="carrier_mobile">运营商_手机号</string>
|
<string name="sim2_remark" tools:ignore="Typos">SIM2主键/备注</string>
|
||||||
|
<string name="carrier_mobile">序号/运营商_手机号</string>
|
||||||
|
<string name="tip_number_only_error_message">数字必须大于0!</string>
|
||||||
|
<string name="regexp_number_only">^[1-9]?\\d+$</string>
|
||||||
<string name="low_power_alarm_threshold">安全电量范围(%)</string>
|
<string name="low_power_alarm_threshold">安全电量范围(%)</string>
|
||||||
<string name="low_power_alarm_threshold_tips">超出安全范围将发出预警</string>
|
<string name="low_power_alarm_threshold_tips">超出安全范围将发出预警</string>
|
||||||
<string name="retry_interval">请求重试机制</string>
|
<string name="retry_interval">请求重试机制</string>
|
||||||
@ -544,6 +547,7 @@
|
|||||||
<string name="tag_app_name">{{APP名称}}</string>
|
<string name="tag_app_name">{{APP名称}}</string>
|
||||||
<string name="tag_msg">{{通知内容}}</string>
|
<string name="tag_msg">{{通知内容}}</string>
|
||||||
<string name="tag_card_slot">{{卡槽信息}}</string>
|
<string name="tag_card_slot">{{卡槽信息}}</string>
|
||||||
|
<string name="tag_card_subid">{{卡槽主键}}</string>
|
||||||
<string name="tag_receive_time">{{接收时间}}</string>
|
<string name="tag_receive_time">{{接收时间}}</string>
|
||||||
<string name="tag_device_name">{{设备名称}}</string>
|
<string name="tag_device_name">{{设备名称}}</string>
|
||||||
<string name="tag_app_version">{{当前应用版本号}}</string>
|
<string name="tag_app_version">{{当前应用版本号}}</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user