mirror of
https://github.com/pppscn/SmsForwarder
synced 2025-08-03 09:27:41 +08:00
新增:短信指令(根据短信指令开关对应功能) #I5YX3F
This commit is contained in:
parent
dd798e42cc
commit
6571775a0f
@ -22,11 +22,13 @@ class FrpcPagingAdapter(private val itemClickListener: OnItemClickListener) : Pa
|
||||
return MyViewHolder(binding)
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
|
||||
val item = getItem(position)
|
||||
if (item != null) {
|
||||
holder.binding.ivImage.setImageResource(R.drawable.ic_menu_frpc)
|
||||
holder.binding.ivAutorun.setImageResource(item.autorunImageId)
|
||||
holder.binding.tvUid.text = "UID:${item.uid}"
|
||||
holder.binding.tvName.text = item.name
|
||||
|
||||
if (item.connecting || Frpclib.isRunning(item.uid)) {
|
||||
@ -41,9 +43,13 @@ class FrpcPagingAdapter(private val itemClickListener: OnItemClickListener) : Pa
|
||||
}
|
||||
}
|
||||
|
||||
holder.binding.ivCopy.setImageResource(R.drawable.ic_copy)
|
||||
holder.binding.ivEdit.setImageResource(R.drawable.ic_edit)
|
||||
holder.binding.ivDelete.setImageResource(R.drawable.ic_delete)
|
||||
|
||||
holder.binding.ivCopy.setOnClickListener { view: View? ->
|
||||
itemClickListener.onItemClicked(view, item)
|
||||
}
|
||||
holder.binding.ivPlay.setOnClickListener { view: View? ->
|
||||
itemClickListener.onItemClicked(view, item)
|
||||
}
|
||||
|
@ -24,6 +24,9 @@ interface FrpcDao {
|
||||
fun get(uid: String): Single<Frpc>
|
||||
|
||||
//TODO:允许主线程访问,后面再优化
|
||||
@Query("SELECT * FROM Frpc where uid=:uid")
|
||||
fun getOne(uid: String): Frpc
|
||||
|
||||
@Query("SELECT * FROM Frpc where autorun=1")
|
||||
fun getAutorun(): List<Frpc>
|
||||
|
||||
|
@ -9,84 +9,130 @@ import java.io.Serializable
|
||||
data class CloneInfo(
|
||||
@SerializedName("version_code")
|
||||
var versionCode: Int = 0,
|
||||
|
||||
@SerializedName("version_name")
|
||||
var versionName: String? = null,
|
||||
|
||||
@SerializedName("enable_sms")
|
||||
var enableSms: Boolean = false,
|
||||
|
||||
@SerializedName("enable_phone")
|
||||
var enablePhone: Boolean = false,
|
||||
|
||||
@SerializedName("call_type1")
|
||||
var callType1: Boolean = false,
|
||||
|
||||
@SerializedName("call_type2")
|
||||
var callType2: Boolean = false,
|
||||
|
||||
@SerializedName("call_type3")
|
||||
var callType3: Boolean = false,
|
||||
|
||||
@SerializedName("call_type4")
|
||||
var callType4: Boolean = false,
|
||||
|
||||
@SerializedName("call_type5")
|
||||
var callType5: Boolean = false,
|
||||
|
||||
@SerializedName("call_type6")
|
||||
var callType6: Boolean = false,
|
||||
|
||||
@SerializedName("enable_app_notify")
|
||||
var enableAppNotify: Boolean = false,
|
||||
|
||||
@SerializedName("cancel_app_notify")
|
||||
var cancelAppNotify: Boolean = false,
|
||||
|
||||
@SerializedName("cancel_extra_app_notify")
|
||||
var cancelExtraAppNotify: String? = null,
|
||||
|
||||
@SerializedName("enable_not_user_present")
|
||||
var enableNotUserPresent: Boolean = false,
|
||||
|
||||
@SerializedName("enable_load_app_list")
|
||||
var enableLoadAppList: Boolean = false,
|
||||
|
||||
@SerializedName("enable_load_user_app_list")
|
||||
var enableLoadUserAppList: Boolean = false,
|
||||
|
||||
@SerializedName("enable_load_system_app_list")
|
||||
var enableLoadSystemAppList: Boolean = false,
|
||||
|
||||
@SerializedName("duplicate_messages_limits")
|
||||
var duplicateMessagesLimits: Int = 0,
|
||||
|
||||
@SerializedName("enable_network_state_receiver")
|
||||
var enableNetworkStateReceiver: Boolean = false,
|
||||
|
||||
@SerializedName("enable_battery_receiver")
|
||||
var enableBatteryReceiver: Boolean = false,
|
||||
|
||||
@SerializedName("battery_level_min")
|
||||
var batteryLevelMin: Int = 0,
|
||||
|
||||
@SerializedName("battery_level_max")
|
||||
var batteryLevelMax: Int = 0,
|
||||
|
||||
@SerializedName("battery_level_once")
|
||||
var batteryLevelOnce: Boolean = false,
|
||||
|
||||
@SerializedName("enable_battery_cron")
|
||||
var enableBatteryCron: Boolean = false,
|
||||
|
||||
@SerializedName("battery_cron_start_time")
|
||||
var batteryCronStartTime: String? = null,
|
||||
|
||||
@SerializedName("battery_cron_interval")
|
||||
var batteryCronInterval: Int = 0,
|
||||
|
||||
@SerializedName("enable_exclude_from_recents")
|
||||
var enableExcludeFromRecents: Boolean = false,
|
||||
|
||||
@SerializedName("enable_cactus")
|
||||
var enableCactus: Boolean = false,
|
||||
|
||||
@SerializedName("enable_play_silence_music")
|
||||
var enablePlaySilenceMusic: Boolean = false,
|
||||
|
||||
@SerializedName("enable_one_pixel_activity")
|
||||
var enableOnePixelActivity: Boolean = false,
|
||||
|
||||
@SerializedName("request_retry_times")
|
||||
var requestRetryTimes: Int = 0,
|
||||
|
||||
@SerializedName("request_delay_time")
|
||||
var requestDelayTime: Int = 0,
|
||||
|
||||
@SerializedName("request_timeout")
|
||||
var requestTimeout: Int = 0,
|
||||
|
||||
@SerializedName("notify_content")
|
||||
var notifyContent: String? = null,
|
||||
|
||||
@SerializedName("enable_sms_template")
|
||||
var enableSmsTemplate: Boolean = false,
|
||||
|
||||
@SerializedName("sms_template")
|
||||
var smsTemplate: String? = null,
|
||||
|
||||
@SerializedName("enable_help_tip")
|
||||
var enableHelpTip: Boolean = false,
|
||||
|
||||
@SerializedName("enable_pure_client_mode")
|
||||
var enablePureClientMode: Boolean = false,
|
||||
|
||||
@SerializedName("enable_sms_command")
|
||||
var enableSmsCommand: Boolean = false,
|
||||
|
||||
@SerializedName("sms_command_safe_phone")
|
||||
var smsCommandSafePhone: String? = null,
|
||||
|
||||
@SerializedName("sender_list")
|
||||
var senderList: List<Sender>? = null,
|
||||
|
||||
@SerializedName("rule_list")
|
||||
var ruleList: List<Rule>? = null,
|
||||
|
||||
@SerializedName("frpc_list")
|
||||
var frpcList: List<Frpc>? = null,
|
||||
) : Serializable
|
@ -28,6 +28,7 @@ import com.xuexiang.xui.utils.ThemeUtils
|
||||
import com.xuexiang.xui.utils.WidgetUtils
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.LoadingDialog
|
||||
import com.xuexiang.xutil.system.ClipboardUtils
|
||||
import frpclib.Frpclib
|
||||
import io.reactivex.CompletableObserver
|
||||
import io.reactivex.Observer
|
||||
@ -60,22 +61,19 @@ class FrpcFragment : BaseFragment<FragmentFrpcsBinding?>(), FrpcPagingAdapter.On
|
||||
titleBar!!.addAction(object : TitleBar.ImageAction(R.drawable.ic_add) {
|
||||
@SingleClick
|
||||
override fun performAction(view: View) {
|
||||
FrpcUtils.getStringFromRaw(context!!, R.raw.frpc)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Observer<String?> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
override fun onNext(content: String) {
|
||||
LiveEventBus.get<Frpc>(INTENT_FRPC_EDIT_FILE).post(Frpc(content))
|
||||
PageOption.to(FrpcEditFragment::class.java).setNewActivity(true).open((context as XPageActivity?)!!)
|
||||
}
|
||||
FrpcUtils.getStringFromRaw(context!!, R.raw.frpc).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(object : Observer<String?> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
override fun onNext(content: String) {
|
||||
LiveEventBus.get<Frpc>(INTENT_FRPC_EDIT_FILE).post(Frpc(content))
|
||||
PageOption.to(FrpcEditFragment::class.java).setNewActivity(true).open((context as XPageActivity?)!!)
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.message?.let { XToastUtils.error(it) }
|
||||
}
|
||||
override fun onError(e: Throwable) {
|
||||
e.message?.let { XToastUtils.error(it) }
|
||||
}
|
||||
|
||||
override fun onComplete() {}
|
||||
})
|
||||
override fun onComplete() {}
|
||||
})
|
||||
}
|
||||
})
|
||||
return titleBar
|
||||
@ -118,7 +116,6 @@ class FrpcFragment : BaseFragment<FragmentFrpcsBinding?>(), FrpcPagingAdapter.On
|
||||
//运行出错时间
|
||||
LiveEventBus.get(EVENT_FRPC_RUNNING_ERROR, String::class.java).observe(this) {
|
||||
XToastUtils.error(getString(R.string.frpc_failed_to_run))
|
||||
//FrpcUtils.checkAndStopService(requireContext())
|
||||
adapter.refresh()
|
||||
}
|
||||
|
||||
@ -129,30 +126,29 @@ class FrpcFragment : BaseFragment<FragmentFrpcsBinding?>(), FrpcPagingAdapter.On
|
||||
}
|
||||
|
||||
override fun onItemClicked(view: View?, item: Frpc) {
|
||||
val id = view?.id
|
||||
if (id == R.id.iv_play) {
|
||||
//if (!FrpcUtils.isServiceRunning(ForegroundService::class.java.name, requireContext())) {
|
||||
if (!ForegroundService.isRunning) {
|
||||
val intent = Intent(requireContext(), ForegroundService::class.java)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
requireContext().startForegroundService(intent)
|
||||
} else {
|
||||
requireContext().startService(intent)
|
||||
when (val id = view?.id) {
|
||||
R.id.iv_copy -> {
|
||||
ClipboardUtils.copyText(item.uid)
|
||||
XToastUtils.info(String.format(getString(R.string.copied_to_clipboard), item.uid))
|
||||
}
|
||||
R.id.iv_play -> {
|
||||
if (!ForegroundService.isRunning) {
|
||||
val intent = Intent(requireContext(), ForegroundService::class.java)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
requireContext().startForegroundService(intent)
|
||||
} else {
|
||||
requireContext().startService(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Frpclib.isRunning(item.uid)) {
|
||||
Frpclib.close(item.uid)
|
||||
item.setConnecting(false)
|
||||
LiveEventBus.get<Frpc>(EVENT_FRPC_UPDATE_CONFIG).post(item)
|
||||
//FrpcUtils.checkAndStopService(requireContext())
|
||||
return
|
||||
}
|
||||
if (Frpclib.isRunning(item.uid)) {
|
||||
Frpclib.close(item.uid)
|
||||
item.setConnecting(false)
|
||||
LiveEventBus.get<Frpc>(EVENT_FRPC_UPDATE_CONFIG).post(item)
|
||||
return
|
||||
}
|
||||
|
||||
FrpcUtils.waitService(ForegroundService::class.java.name, requireContext())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : CompletableObserver {
|
||||
FrpcUtils.waitService(ForegroundService::class.java.name, requireContext()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(object : CompletableObserver {
|
||||
var mLoadingDialog: LoadingDialog = WidgetUtils.getLoadingDialog(context!!).setIconScale(0.4f).setLoadingSpeed(8)
|
||||
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
@ -177,22 +173,27 @@ class FrpcFragment : BaseFragment<FragmentFrpcsBinding?>(), FrpcPagingAdapter.On
|
||||
LiveEventBus.get<Frpc>(EVENT_FRPC_UPDATE_CONFIG).post(item)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
//编辑或删除需要先停止客户端
|
||||
if (Frpclib.isRunning(item.uid)) {
|
||||
XToastUtils.warning(R.string.tipServiceRunning)
|
||||
return
|
||||
}
|
||||
if (id == R.id.iv_edit) {
|
||||
LiveEventBus.get<Frpc>(INTENT_FRPC_EDIT_FILE).post(item)
|
||||
openNewPage(FrpcEditFragment::class.java)
|
||||
} else if (id == R.id.iv_delete) {
|
||||
try {
|
||||
viewModel.delete(item)
|
||||
LiveEventBus.get<Frpc>(EVENT_FRPC_DELETE_CONFIG).post(item)
|
||||
XToastUtils.success(getString(R.string.successfully_deleted))
|
||||
} catch (e: Exception) {
|
||||
e.message?.let { XToastUtils.error(it) }
|
||||
else -> {
|
||||
//编辑或删除需要先停止客户端
|
||||
if (Frpclib.isRunning(item.uid)) {
|
||||
XToastUtils.warning(R.string.tipServiceRunning)
|
||||
return
|
||||
}
|
||||
when (id) {
|
||||
R.id.iv_edit -> {
|
||||
LiveEventBus.get<Frpc>(INTENT_FRPC_EDIT_FILE).post(item)
|
||||
openNewPage(FrpcEditFragment::class.java)
|
||||
}
|
||||
R.id.iv_delete -> {
|
||||
try {
|
||||
viewModel.delete(item)
|
||||
LiveEventBus.get<Frpc>(EVENT_FRPC_DELETE_CONFIG).post(item)
|
||||
XToastUtils.success(getString(R.string.successfully_deleted))
|
||||
} catch (e: Exception) {
|
||||
e.message?.let { XToastUtils.error(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +97,10 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
||||
switchEnableAppNotify(
|
||||
binding!!.sbEnableAppNotify, binding!!.scbCancelAppNotify, binding!!.scbNotUserPresent
|
||||
)
|
||||
|
||||
//短信指令
|
||||
switchEnableSmsCommand(binding!!.sbEnableSmsCommand, binding!!.etSafePhone)
|
||||
|
||||
//设置自动消除额外APP通知
|
||||
editExtraAppList(binding!!.etAppList)
|
||||
//启动时异步获取已安装App信息
|
||||
@ -440,12 +444,12 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
||||
|
||||
val layoutOptionalAction: LinearLayout = binding!!.layoutOptionalAction
|
||||
layoutOptionalAction.visibility = if (isEnable) View.VISIBLE else View.GONE
|
||||
val layoutAppList: LinearLayout = binding!!.layoutAppList
|
||||
layoutAppList.visibility = if (isEnable) View.VISIBLE else View.GONE
|
||||
//val layoutAppList: LinearLayout = binding!!.layoutAppList
|
||||
//layoutAppList.visibility = if (isEnable) View.VISIBLE else View.GONE
|
||||
|
||||
sbEnableAppNotify.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
|
||||
layoutOptionalAction.visibility = if (isChecked) View.VISIBLE else View.GONE
|
||||
layoutAppList.visibility = if (isChecked) View.VISIBLE else View.GONE
|
||||
//layoutAppList.visibility = if (isChecked) View.VISIBLE else View.GONE
|
||||
SettingUtils.enableAppNotify = isChecked
|
||||
if (isChecked) {
|
||||
//检查权限是否获取
|
||||
@ -473,6 +477,57 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
|
||||
}
|
||||
}
|
||||
|
||||
//接受短信指令
|
||||
@SuppressLint("UseSwitchCompatOrMaterialCode")
|
||||
fun switchEnableSmsCommand(sbEnableSmsCommand: SwitchButton, etSafePhone: EditText) {
|
||||
sbEnableSmsCommand.isChecked = SettingUtils.enableSmsCommand
|
||||
etSafePhone.visibility = if (SettingUtils.enableSmsCommand) View.VISIBLE else View.GONE
|
||||
|
||||
sbEnableSmsCommand.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
|
||||
SettingUtils.enableSmsCommand = isChecked
|
||||
etSafePhone.visibility = if (isChecked) View.VISIBLE else View.GONE
|
||||
if (isChecked) {
|
||||
//检查权限是否获取
|
||||
XXPermissions.with(this)
|
||||
// 接收短信
|
||||
.permission(Permission.RECEIVE_SMS)
|
||||
// 发送短信
|
||||
//.permission(Permission.SEND_SMS)
|
||||
// 读取短信
|
||||
.permission(Permission.READ_SMS).request(object : OnPermissionCallback {
|
||||
override fun onGranted(permissions: List<String>, all: Boolean) {
|
||||
if (all) {
|
||||
XToastUtils.info(R.string.toast_granted_all)
|
||||
} else {
|
||||
XToastUtils.info(R.string.toast_granted_part)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDenied(permissions: List<String>, never: Boolean) {
|
||||
if (never) {
|
||||
XToastUtils.info(R.string.toast_denied_never)
|
||||
// 如果是被永久拒绝就跳转到应用权限系统设置页面
|
||||
XXPermissions.startPermissionActivity(requireContext(), permissions)
|
||||
} else {
|
||||
XToastUtils.info(R.string.toast_denied)
|
||||
}
|
||||
SettingUtils.enableSmsCommand = false
|
||||
sbEnableSmsCommand.isChecked = false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
etSafePhone.setText(SettingUtils.smsCommandSafePhone)
|
||||
etSafePhone.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) {
|
||||
SettingUtils.smsCommandSafePhone = etSafePhone.text.toString().trim().removeSuffix("\n")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//设置自动消除额外APP通知
|
||||
private fun editExtraAppList(textAppList: EditText) {
|
||||
textAppList.setText(SettingUtils.cancelExtraAppNotify)
|
||||
|
@ -10,15 +10,25 @@ import androidx.work.WorkManager
|
||||
import androidx.work.workDataOf
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.App
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.service.HttpService
|
||||
import com.idormy.sms.forwarder.utils.PhoneUtils
|
||||
import com.idormy.sms.forwarder.utils.SettingUtils
|
||||
import com.idormy.sms.forwarder.utils.Worker
|
||||
import com.idormy.sms.forwarder.workers.SendWorker
|
||||
import com.xuexiang.xrouter.utils.TextUtils
|
||||
import com.xuexiang.xutil.file.FileUtils
|
||||
import frpclib.Frpclib
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.async
|
||||
import java.util.*
|
||||
|
||||
//短信广播
|
||||
@Suppress("PrivatePropertyName", "DEPRECATION")
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
@Suppress("PrivatePropertyName", "DEPRECATION", "DeferredResultUnused", "SENSELESS_COMPARISON")
|
||||
class SmsReceiver : BroadcastReceiver() {
|
||||
|
||||
private var TAG = "SmsReceiver"
|
||||
@ -28,20 +38,25 @@ class SmsReceiver : BroadcastReceiver() {
|
||||
//纯客户端模式
|
||||
if (SettingUtils.enablePureClientMode) return
|
||||
|
||||
//总开关
|
||||
if (!SettingUtils.enableSms) return
|
||||
|
||||
//过滤广播
|
||||
if (intent.action != Telephony.Sms.Intents.SMS_RECEIVED_ACTION && intent.action != Telephony.Sms.Intents.SMS_DELIVER_ACTION) return
|
||||
|
||||
var from = ""
|
||||
var content = ""
|
||||
var message = ""
|
||||
for (smsMessage in Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
|
||||
from = smsMessage.displayOriginatingAddress
|
||||
content += smsMessage.messageBody
|
||||
message += smsMessage.messageBody
|
||||
}
|
||||
Log.d(TAG, "from = $from")
|
||||
Log.d(TAG, "content = $content")
|
||||
Log.d(TAG, "from = $from, message = $message")
|
||||
|
||||
//短信指令
|
||||
if (SettingUtils.enableSmsCommand && message.startsWith("smsf#")) {
|
||||
doSmsCommand(context, from, message)
|
||||
return
|
||||
}
|
||||
|
||||
//总开关
|
||||
if (!SettingUtils.enableSms) return
|
||||
|
||||
//TODO:准确获取卡槽信息,目前测试结果只有 subscription 相对靠谱
|
||||
val slot = intent.extras?.getInt("slot") ?: -1
|
||||
@ -78,7 +93,7 @@ class SmsReceiver : BroadcastReceiver() {
|
||||
else -> ""
|
||||
}
|
||||
|
||||
val msgInfo = MsgInfo("sms", from, content, Date(), simInfo, simSlot, subscription)
|
||||
val msgInfo = MsgInfo("sms", from, message, Date(), simInfo, simSlot, subscription)
|
||||
Log.d(TAG, "msgInfo = $msgInfo")
|
||||
|
||||
val request = OneTimeWorkRequestBuilder<SendWorker>().setInputData(
|
||||
@ -93,4 +108,97 @@ class SmsReceiver : BroadcastReceiver() {
|
||||
}
|
||||
}
|
||||
|
||||
//处理短信指令
|
||||
private fun doSmsCommand(context: Context, from: String, message: String) {
|
||||
var safePhone = SettingUtils.smsCommandSafePhone
|
||||
Log.d(TAG, "safePhone = $safePhone")
|
||||
|
||||
if (!TextUtils.isEmpty(safePhone)) {
|
||||
var isSafePhone = false
|
||||
safePhone = safePhone.replace(";", ",").replace(";", ",").replace(",", ",").trim()
|
||||
for (phone in safePhone.split(",")) {
|
||||
if (!TextUtils.isEmpty(phone.trim()) && from.endsWith(phone.trim())) {
|
||||
isSafePhone = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!isSafePhone) {
|
||||
Log.d(TAG, "from = $from is not safePhone = $safePhone")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
val smsCommand = message.substring(5)
|
||||
val cmdList = smsCommand.split("#")
|
||||
Log.d(TAG, "smsCommand = $smsCommand, cmdList = $cmdList")
|
||||
if (cmdList.count() < 2) return
|
||||
|
||||
val function = cmdList[0]
|
||||
val action = cmdList[1]
|
||||
val param = if (cmdList.count() > 2) cmdList[2] else ""
|
||||
when (function) {
|
||||
"frpc" -> {
|
||||
if (!FileUtils.isFileExists(context.filesDir?.absolutePath + "/libs/libgojni.so")) {
|
||||
Log.d(TAG, "还未下载Frpc库")
|
||||
return
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(param)) {
|
||||
GlobalScope.async(Dispatchers.IO) {
|
||||
val frpcList = AppDatabase.getInstance(App.context).frpcDao().getAutorun()
|
||||
|
||||
if (frpcList.isEmpty()) {
|
||||
Log.d(TAG, "没有自启动的Frpc")
|
||||
return@async
|
||||
}
|
||||
|
||||
for (frpc in frpcList) {
|
||||
if (action == "start") {
|
||||
if (!Frpclib.isRunning(frpc.uid)) {
|
||||
val error = Frpclib.runContent(frpc.uid, frpc.config)
|
||||
if (!TextUtils.isEmpty(error)) {
|
||||
Log.e(TAG, error)
|
||||
}
|
||||
}
|
||||
} else if (action == "stop") {
|
||||
if (Frpclib.isRunning(frpc.uid)) {
|
||||
Frpclib.close(frpc.uid)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
GlobalScope.async(Dispatchers.IO) {
|
||||
val frpc = AppDatabase.getInstance(App.context).frpcDao().getOne(param)
|
||||
|
||||
if (frpc == null) {
|
||||
Log.d(TAG, "没有找到指定的Frpc")
|
||||
return@async
|
||||
}
|
||||
|
||||
if (action == "start") {
|
||||
if (!Frpclib.isRunning(frpc.uid)) {
|
||||
val error = Frpclib.runContent(frpc.uid, frpc.config)
|
||||
if (!TextUtils.isEmpty(error)) {
|
||||
Log.e(TAG, error)
|
||||
}
|
||||
}
|
||||
} else if (action == "stop") {
|
||||
if (Frpclib.isRunning(frpc.uid)) {
|
||||
Frpclib.close(frpc.uid)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"httpserver" -> {
|
||||
if (action == "start") {
|
||||
context.startService(Intent(context, HttpService::class.java))
|
||||
} else if (action == "stop") {
|
||||
context.stopService(Intent(context, HttpService::class.java))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -48,9 +48,6 @@ class NotifyService : NotificationListenerService() {
|
||||
//纯客户端模式
|
||||
if (SettingUtils.enablePureClientMode) return
|
||||
|
||||
//总开关
|
||||
if (!SettingUtils.enableAppNotify) return
|
||||
|
||||
//异常通知跳过
|
||||
if (sbn!!.notification == null) return
|
||||
if (sbn.notification.extras == null) return
|
||||
@ -70,6 +67,9 @@ class NotifyService : NotificationListenerService() {
|
||||
}
|
||||
}
|
||||
|
||||
//总开关
|
||||
if (!SettingUtils.enableAppNotify) return
|
||||
|
||||
//仅锁屏状态转发APP通知
|
||||
if (SettingUtils.enableNotUserPresent && !ScreenUtils.isScreenLock()) return
|
||||
|
||||
|
@ -41,6 +41,9 @@ const val SP_ENABLE_CANCEL_APP_NOTIFY = "enable_cancel_app_notify"
|
||||
const val SP_CANCEL_EXTRA_APP_NOTIFY = "cancel_extra_app_notify_list"
|
||||
const val SP_ENABLE_NOT_USER_PRESENT = "enable_not_user_present"
|
||||
|
||||
const val SP_ENABLE_SMS_COMMAND = "enable_sms_command"
|
||||
const val SP_SMS_COMMAND_SAFE_PHONE = "sms_command_safe_phone"
|
||||
|
||||
const val ENABLE_LOAD_APP_LIST = "enable_load_app_list"
|
||||
const val ENABLE_LOAD_USER_APP_LIST = "enable_load_user_app_list"
|
||||
const val ENABLE_LOAD_SYSTEM_APP_LIST = "enable_load_system_app_list"
|
||||
|
@ -180,6 +180,8 @@ class HttpServerUtils private constructor() {
|
||||
cloneInfo.smsTemplate = SettingUtils.smsTemplate
|
||||
cloneInfo.enableHelpTip = SettingUtils.enableHelpTip
|
||||
cloneInfo.enablePureClientMode = SettingUtils.enablePureClientMode
|
||||
cloneInfo.enableSmsCommand = SettingUtils.enableSmsCommand
|
||||
cloneInfo.smsCommandSafePhone = SettingUtils.smsCommandSafePhone
|
||||
cloneInfo.senderList = Core.sender.all
|
||||
cloneInfo.ruleList = Core.rule.all
|
||||
cloneInfo.frpcList = Core.frpc.all
|
||||
@ -227,6 +229,8 @@ class HttpServerUtils private constructor() {
|
||||
SettingUtils.smsTemplate = cloneInfo.smsTemplate.toString()
|
||||
SettingUtils.enableHelpTip = cloneInfo.enableHelpTip
|
||||
SettingUtils.enablePureClientMode = cloneInfo.enablePureClientMode
|
||||
SettingUtils.enableSmsCommand = cloneInfo.enableSmsCommand
|
||||
SettingUtils.smsCommandSafePhone = cloneInfo.smsCommandSafePhone.toString()
|
||||
//删除发送通道、转发规则、转发日志
|
||||
Core.sender.deleteAll()
|
||||
//发送通道
|
||||
|
@ -39,6 +39,10 @@ class SettingUtils private constructor() {
|
||||
//是否转发应用通知
|
||||
var enableAppNotify: Boolean by SharedPreference(SP_ENABLE_APP_NOTIFY, false)
|
||||
|
||||
//是否接受短信指令
|
||||
var enableSmsCommand: Boolean by SharedPreference(SP_ENABLE_SMS_COMMAND, false)
|
||||
var smsCommandSafePhone: String by SharedPreference(SP_SMS_COMMAND_SAFE_PHONE, "")
|
||||
|
||||
//是否转发应用通知——自动消除通知
|
||||
var enableCancelAppNotify: Boolean by SharedPreference(SP_ENABLE_CANCEL_APP_NOTIFY, false)
|
||||
|
||||
|
@ -17,6 +17,8 @@
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
@ -41,39 +43,81 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:lines="1"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp" />
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_play"
|
||||
android:layout_width="@dimen/card_view_image_size"
|
||||
android:layout_height="@dimen/card_view_image_size"
|
||||
android:padding="@dimen/card_view_image_padding"
|
||||
app:tint="@color/colorStart"
|
||||
tools:ignore="ContentDescription" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_edit"
|
||||
android:layout_width="@dimen/card_view_image_size"
|
||||
android:layout_height="@dimen/card_view_image_size"
|
||||
android:padding="@dimen/card_view_image_padding"
|
||||
app:tint="@color/toast_info_color"
|
||||
tools:ignore="ContentDescription,PrivateResource" />
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:lines="1"
|
||||
android:paddingEnd="15dp"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_delete"
|
||||
android:layout_width="@dimen/card_view_image_size"
|
||||
android:layout_height="@dimen/card_view_image_size"
|
||||
android:padding="@dimen/card_view_image_padding"
|
||||
app:tint="@color/toast_error_color"
|
||||
tools:ignore="ContentDescription,PrivateResource" />
|
||||
<ImageView
|
||||
android:id="@+id/iv_play"
|
||||
android:layout_width="@dimen/card_view_image_size"
|
||||
android:layout_height="@dimen/card_view_image_size"
|
||||
android:padding="@dimen/card_view_image_padding"
|
||||
app:tint="@color/colorStart"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_edit"
|
||||
android:layout_width="@dimen/card_view_image_size"
|
||||
android:layout_height="@dimen/card_view_image_size"
|
||||
android:padding="@dimen/card_view_image_padding"
|
||||
app:tint="@color/toast_info_color"
|
||||
tools:ignore="ContentDescription,PrivateResource" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_delete"
|
||||
android:layout_width="@dimen/card_view_image_size"
|
||||
android:layout_height="@dimen/card_view_image_size"
|
||||
android:padding="@dimen/card_view_image_padding"
|
||||
app:tint="@color/toast_error_color"
|
||||
tools:ignore="ContentDescription,PrivateResource" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_copy"
|
||||
android:layout_width="@dimen/config_padding_18dp"
|
||||
android:layout_height="@dimen/config_padding_18dp"
|
||||
app:tint="@color/colorStart"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_uid"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:lines="1"
|
||||
android:textSize="11sp"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
android:orientation="vertical"
|
||||
tools:ignore="TooManyViews">
|
||||
|
||||
|
||||
<androidx.core.widget.NestedScrollView style="@style/ScrollViewStyle">
|
||||
|
||||
<LinearLayout
|
||||
@ -242,118 +243,32 @@
|
||||
style="@style/settingBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<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/forward_app_notify"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RelativeOverlap" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/forward_app_notify_tips"
|
||||
android:textSize="9sp"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_optional_action"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="25dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/optional_action"
|
||||
android:textSize="10sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.SmoothCheckBox
|
||||
android:id="@+id/scb_cancel_app_notify"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="15dp"
|
||||
app:scb_color_checked="@color/colorPrimary" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/cancel_app_notify"
|
||||
android:textSize="10sp"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.SmoothCheckBox
|
||||
android:id="@+id/scb_not_user_present"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="15dp"
|
||||
android:layout_marginStart="5dp"
|
||||
app:scb_color_checked="@color/colorPrimary" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/not_user_present"
|
||||
android:textSize="10sp"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
|
||||
android:id="@+id/sb_enable_app_notify"
|
||||
style="@style/SwitchButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_app_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
android:paddingEnd="10dp"
|
||||
android:visibility="gone"
|
||||
tools:ignore="RtlSymmetry">
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/extra_app"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold" />
|
||||
android:text="@string/forward_app_notify"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RelativeOverlap" />
|
||||
|
||||
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
|
||||
android:id="@+id/et_app_list"
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/extra_app_hint"
|
||||
android:inputType="textMultiLine"
|
||||
app:met_clearButton="true" />
|
||||
android:text="@string/forward_app_notify_tips"
|
||||
android:textSize="9sp"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_sp_app"
|
||||
android:id="@+id/layout_optional_action"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_height="25dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
@ -361,23 +276,115 @@
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/choose_app"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold" />
|
||||
android:text="@string/optional_action"
|
||||
android:textSize="10sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
<com.xuexiang.xui.widget.spinner.editspinner.EditSpinner
|
||||
android:id="@+id/sp_app"
|
||||
android:layout_width="match_parent"
|
||||
<com.xuexiang.xui.widget.button.SmoothCheckBox
|
||||
android:id="@+id/scb_cancel_app_notify"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="15dp"
|
||||
app:scb_color_checked="@color/colorPrimary" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/cancel_app_notify"
|
||||
android:textSize="10sp"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
<com.xuexiang.xui.widget.button.SmoothCheckBox
|
||||
android:id="@+id/scb_not_user_present"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="15dp"
|
||||
android:layout_marginStart="5dp"
|
||||
app:es_hint="@string/choose_app_hint"
|
||||
app:es_maxLength="20"
|
||||
app:es_maxLine="1" />
|
||||
app:scb_color_checked="@color/colorPrimary" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/not_user_present"
|
||||
android:textSize="10sp"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
|
||||
android:id="@+id/sb_enable_app_notify"
|
||||
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"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="5dp"
|
||||
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/extra_function"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:text="@string/extra_function_tips"
|
||||
android:textSize="10sp"
|
||||
tools:ignore="SmallSp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
style="@style/settingBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/sms_command"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RelativeOverlap" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/sms_command_tips"
|
||||
android:textSize="9sp"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
<com.xuexiang.xui.widget.edittext.ClearEditText
|
||||
android:id="@+id/et_safe_phone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/safe_phone_tips"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
|
||||
android:id="@+id/sb_enable_sms_command"
|
||||
style="@style/SwitchButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@ -459,6 +466,58 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_app_list"
|
||||
style="@style/settingBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/extra_app"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RelativeOverlap" />
|
||||
|
||||
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
|
||||
android:id="@+id/et_app_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/extra_app_hint"
|
||||
android:inputType="textMultiLine"
|
||||
app:met_clearButton="true" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_sp_app"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="3dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/choose_app"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.xuexiang.xui.widget.spinner.editspinner.EditSpinner
|
||||
android:id="@+id/sp_app"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
app:es_hint="@string/choose_app_hint"
|
||||
app:es_maxLength="20"
|
||||
app:es_maxLine="1" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
style="@style/settingBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -353,6 +353,10 @@
|
||||
<string name="filtering_duplicate_messages_tips">0=disabled, judge duplicate: type+source+content</string>
|
||||
<string name="forward_sms">Forward Sms</string>
|
||||
<string name="forward_sms_tips">Main switch, requires permissions to read and sned SMS messages, especially verification SMS texts.</string>
|
||||
<string name="sms_command">Sms Command</string>
|
||||
<string name="sms_command_tips">Open the HttpServer or FRPC by the SMS command</string>
|
||||
<string name="safe_phone">Safe Phone</string>
|
||||
<string name="safe_phone_tips">Only handle requests from specified phones</string>
|
||||
<string name="forward_missed_calls">Forward Calls Log</string>
|
||||
<string name="forward_missed_calls_tips">Main switch, requires permissions to read call log and contacts.</string>
|
||||
<string name="forward_app_notify">Forward App Notify</string>
|
||||
@ -524,6 +528,8 @@
|
||||
<string name="todo">TODO</string>
|
||||
<string name="forwarding_function">Forwarding Function</string>
|
||||
<string name="forwarding_function_tips">Main switch: Enable the forwarding function as required</string>
|
||||
<string name="extra_function">Extra Function</string>
|
||||
<string name="extra_function_tips">Enable the extra function as required</string>
|
||||
<string name="call_date">Call date: </string>
|
||||
<string name="call_duration">Call duration: </string>
|
||||
<string name="ring_duration">Ring duration: </string>
|
||||
|
@ -354,6 +354,10 @@
|
||||
<string name="filtering_duplicate_messages_tips">0=禁用,判断重复:类型+来源+内容</string>
|
||||
<string name="forward_sms">转发短信广播</string>
|
||||
<string name="forward_sms_tips">请授予读取短信、通知类短信、发送短信等权限,关闭验证码保护</string>
|
||||
<string name="sms_command">短信指令</string>
|
||||
<string name="sms_command_tips">根据短信指令开关对应功能,指令格式:smsf#功能名#动作名</string>
|
||||
<string name="safe_phone">安全手机</string>
|
||||
<string name="safe_phone_tips">仅处理指定手机请求,多个手机以逗号分隔</string>
|
||||
<string name="forward_missed_calls">转发通话记录</string>
|
||||
<string name="forward_missed_calls_tips">请授予读取通话记录、联系人等权限,并选择转发类型,再开启</string>
|
||||
<string name="forward_app_notify">转发应用通知</string>
|
||||
@ -525,6 +529,8 @@
|
||||
<string name="todo">TODO</string>
|
||||
<string name="forwarding_function">转发功能</string>
|
||||
<string name="forwarding_function_tips">总开关,请根据实际需要,启用对应的转发功能</string>
|
||||
<string name="extra_function">增强功能</string>
|
||||
<string name="extra_function_tips">请根据实际需要,启用对应的增强设置</string>
|
||||
<string name="call_date">通话时间:</string>
|
||||
<string name="call_duration">通话时长:</string>
|
||||
<string name="ring_duration">响铃时长:</string>
|
||||
@ -544,11 +550,11 @@
|
||||
<string name="httpserver">被动接收本地 HttpServer</string>
|
||||
<string name="httpserver_tips">WiFi网络下可用,启动后局域网内其他机器可直接调用本机接口</string>
|
||||
<string name="network_state_monitor">网络状态监控</string>
|
||||
<string name="network_state_monitor_tips">【注意】需要手动创建APP转发规则,包名:77777777</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="battery_monitor">电池监控</string>
|
||||
<string name="battery_monitor_tips">【注意】需要手动创建APP转发规则,包名:88888888</string>
|
||||
<string name="battery_monitor_tips">需要手动创建APP转发规则,包名:88888888</string>
|
||||
<string name="keep_alive">保活措施</string>
|
||||
<string name="keep_alive_tips">建议开启前三项授权或设置,不要禁用通知栏,避免APP被杀</string>
|
||||
<string name="custom_settings">个性设置</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user