新增:启动时异步获取已安装App信息开关

新增:应用列表分类展示(用户应用/系统应用)/按应用名排序
新增:自定义模板支持{{APP名称}}标签(仅启用异步获取App列表时有值)
This commit is contained in:
pppscn 2022-06-13 15:45:08 +08:00
parent 51e845dcea
commit 82b552672f
15 changed files with 322 additions and 30 deletions

View File

@ -63,7 +63,8 @@ class App : Application(), CactusCallback, Configuration.Provider by Core {
var SimInfoList: MutableMap<Int, SimInfo> = mutableMapOf()
//已安装App信息
var AppInfoList: List<AppUtils.AppInfo> = arrayListOf()
var UserAppList: MutableList<AppUtils.AppInfo> = mutableListOf()
var SystemAppList: MutableList<AppUtils.AppInfo> = mutableListOf()
/**
* @return 当前app是否是调试开发模式
@ -123,15 +124,30 @@ class App : Application(), CactusCallback, Configuration.Provider by Core {
startService(batteryServiceIntent)
//异步获取所有已安装 App 信息
val get = GlobalScope.async(Dispatchers.IO) {
AppInfoList = AppUtils.getAppsInfo()
}
GlobalScope.launch(Dispatchers.Main) {
runCatching {
get.await()
Log.d("GlobalScope", "AppUtils.getAppsInfo() Done")
}.onFailure {
Log.e("GlobalScope", it.message.toString())
if (SettingUtils.enableLoadAppList) {
val enableLoadUserAppList = SettingUtils.enableLoadUserAppList
val enableLoadSystemAppList = SettingUtils.enableLoadSystemAppList
val get = GlobalScope.async(Dispatchers.IO) {
val appInfoList = AppUtils.getAppsInfo()
for (appInfo in appInfoList) {
if (appInfo.isSystem && enableLoadSystemAppList) {
SystemAppList.add(appInfo)
} else if (enableLoadUserAppList) {
UserAppList.add(appInfo)
}
}
UserAppList.sortBy { appInfo -> appInfo.name }
SystemAppList.sortBy { appInfo -> appInfo.name }
}
GlobalScope.launch(Dispatchers.Main) {
runCatching {
get.await()
Log.d("GlobalScope", "AppUtils.getAppsInfo() Done")
Log.d("GlobalScope", "UserAppList = $UserAppList")
Log.d("GlobalScope", "SystemAppList = $SystemAppList")
}.onFailure {
Log.e("GlobalScope", it.message.toString())
}
}
}

View File

@ -26,6 +26,12 @@ data class CloneInfo(
var cancelAppNotify: Boolean = false,
@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_battery_receiver")
@ -44,8 +50,12 @@ data class CloneInfo(
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")
@ -60,6 +70,8 @@ data class CloneInfo(
var smsTemplate: String? = null,
@SerializedName("enable_help_tip")
var enableHelpTip: Boolean = false,
@SerializedName("enable_pure_client_mode")
var enablePureClientMode: Boolean = false,
@SerializedName("sender_list")
var senderList: List<Sender>? = null,
@SerializedName("rule_list")

View File

@ -3,7 +3,9 @@ package com.idormy.sms.forwarder.entity
import android.annotation.SuppressLint
import android.text.TextUtils
import android.util.Log
import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.SettingUtils.Companion.enableSmsTemplate
import com.idormy.sms.forwarder.utils.SettingUtils.Companion.extraDeviceMark
import com.idormy.sms.forwarder.utils.SettingUtils.Companion.smsTemplate
@ -46,7 +48,7 @@ data class MsgInfo(
.replace(getString(R.string.tag_device_name), deviceMark)
.replace(getString(R.string.tag_app_version), versionName)
.trim()
return regexReplace(regexReplace, titleForSend)
return replaceAppName(regexReplace(titleForSend, regexReplace), from)
}
val smsVoForSend: String
@ -86,13 +88,13 @@ data class MsgInfo(
.replace(getString(R.string.tag_device_name), deviceMark)
.replace(getString(R.string.tag_app_version), versionName)
.trim()
return regexReplace(regexReplace, smsVoForSend)
return replaceAppName(regexReplace(smsVoForSend, regexReplace), from)
}
//正则替换内容
private fun regexReplace(regexReplace: String, Content: String): String {
return if (TextUtils.isEmpty(regexReplace)) Content else try {
var newContent = Content
private fun regexReplace(content: String, regexReplace: String): String {
return if (TextUtils.isEmpty(regexReplace)) content else try {
var newContent = content
val lineArray = regexReplace.split("\\n".toRegex()).toTypedArray()
for (line in lineArray) {
val lineSplit = line.split("===".toRegex()).toTypedArray()
@ -105,10 +107,32 @@ data class MsgInfo(
newContent
} catch (e: Exception) {
Log.e("RegexReplace", "Failed to get the receiving phone number:" + e.message)
Content
content
}
}
//替换{{APP名称}}标签
private fun replaceAppName(content: String, packageName: String): String {
var appName = ""
if (SettingUtils.enableLoadUserAppList && App.UserAppList.isNotEmpty()) {
for (appInfo in App.UserAppList) {
if (appInfo.packageName == packageName) {
appName = appInfo.name
break
}
}
}
if (TextUtils.isEmpty(appName) && SettingUtils.enableLoadSystemAppList && App.SystemAppList.isNotEmpty()) {
for (appInfo in App.SystemAppList) {
if (appInfo.packageName == packageName) {
appName = appInfo.name
break
}
}
}
return content.replace(getString(R.string.tag_app_name), appName)
}
override fun toString(): String {
return "MsgInfo{" +
"mobile='" + from + '\'' +

View File

@ -27,6 +27,7 @@ import com.xuexiang.xutil.app.AppUtils
class AppListFragment : BaseFragment<FragmentAppListBinding?>() {
var appListAdapter: AppListAdapter? = null
private var currentType: String = "user"
override fun viewBindingInflate(
inflater: LayoutInflater,
@ -53,6 +54,18 @@ class AppListFragment : BaseFragment<FragmentAppListBinding?>() {
override fun initViews() {
WidgetUtils.initRecyclerView(binding!!.recyclerView, DensityUtils.dp2px(5f), ThemeUtils.resolveColor(context, R.attr.xui_config_color_background))
binding!!.recyclerView.adapter = AppListAdapter(true).also { appListAdapter = it }
binding!!.tabBar.setTabTitles(ResUtils.getStringArray(R.array.app_type_option))
binding!!.tabBar.setOnTabClickListener { _, position ->
//XToastUtils.toast("点击了$title--$position")
currentType = when (position) {
1 -> "system"
else -> "user"
}
appListAdapter?.refresh(getAppsList(false))
binding!!.refreshLayout.finishRefresh()
binding!!.recyclerView.scrollToPosition(0)
}
}
override fun initListeners() {
@ -65,7 +78,7 @@ class AppListFragment : BaseFragment<FragmentAppListBinding?>() {
override fun onRefresh(refreshLayout: RefreshLayout) {
refreshLayout.layout.postDelayed({
appListAdapter?.refresh(AppUtils.getAppsInfo())
appListAdapter?.refresh(getAppsList(true))
refreshLayout.finishRefresh()
}, 3000)
}
@ -80,12 +93,7 @@ class AppListFragment : BaseFragment<FragmentAppListBinding?>() {
//设置刷新加载时禁止所有列表操作
binding!!.refreshLayout.setDisableContentWhenRefresh(true)
binding!!.refreshLayout.setDisableContentWhenLoading(true)
//binding!!.refreshLayout.autoRefresh()
if (App.AppInfoList.isEmpty()) {
appListAdapter?.refresh(AppUtils.getAppsInfo())
} else {
appListAdapter?.refresh(App.AppInfoList)
}
appListAdapter?.refresh(getAppsList(false))
binding!!.refreshLayout.finishRefresh()
}
@ -93,4 +101,24 @@ class AppListFragment : BaseFragment<FragmentAppListBinding?>() {
appListAdapter?.recycle()
super.onDestroyView()
}
private fun getAppsList(refresh: Boolean): MutableList<AppUtils.AppInfo> {
if (refresh || (currentType == "user" && App.UserAppList.isEmpty()) || (currentType == "system" && App.SystemAppList.isEmpty())) {
App.UserAppList.clear()
App.SystemAppList.clear()
val appInfoList = AppUtils.getAppsInfo()
for (appInfo in appInfoList) {
if (appInfo.isSystem) {
App.SystemAppList.add(appInfo)
} else {
App.UserAppList.add(appInfo)
}
}
App.UserAppList.sortBy { appInfo -> appInfo.name }
App.SystemAppList.sortBy { appInfo -> appInfo.name }
}
return if (currentType == "system") App.SystemAppList else App.UserAppList
}
}

View File

@ -352,17 +352,40 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
if (ruleType != "app") return
val get = GlobalScope.async(Dispatchers.IO) {
App.AppInfoList = AppUtils.getAppsInfo()
if ((SettingUtils.enableLoadUserAppList && App.UserAppList.isEmpty())
|| SettingUtils.enableLoadSystemAppList && App.SystemAppList.isEmpty()
) {
App.UserAppList.clear()
App.SystemAppList.clear()
val appInfoList = AppUtils.getAppsInfo()
for (appInfo in appInfoList) {
if (appInfo.isSystem) {
App.SystemAppList.add(appInfo)
} else {
App.UserAppList.add(appInfo)
}
}
App.UserAppList.sortBy { appInfo -> appInfo.name }
App.SystemAppList.sortBy { appInfo -> appInfo.name }
}
}
GlobalScope.launch(Dispatchers.Main) {
runCatching {
get.await()
if (App.AppInfoList.isEmpty()) return@runCatching
if (App.UserAppList.isEmpty() && App.SystemAppList.isEmpty()) return@runCatching
Log.e(TAG, App.AppInfoList.toString())
for (appInfo in App.AppInfoList) {
appListSpinnerList.add(AppListAdapterItem(appInfo.name, appInfo.icon, appInfo.packageName))
appListSpinnerList.clear()
if (SettingUtils.enableLoadUserAppList) {
for (appInfo in App.UserAppList) {
appListSpinnerList.add(AppListAdapterItem(appInfo.name, appInfo.icon, appInfo.packageName))
}
}
if (SettingUtils.enableLoadSystemAppList) {
for (appInfo in App.SystemAppList) {
appListSpinnerList.add(AppListAdapterItem(appInfo.name, appInfo.icon, appInfo.packageName))
}
}
appListSpinnerAdapter = AppListSpinnerAdapter(appListSpinnerList)
//.setTextColor(ResUtils.getColor(R.color.green))
//.setTextSize(12F)

View File

@ -78,6 +78,8 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
switchEnablePhone(binding!!.sbEnablePhone, binding!!.scbCallType1, binding!!.scbCallType2, binding!!.scbCallType3)
//转发应用通知
switchEnableAppNotify(binding!!.sbEnableAppNotify, binding!!.scbCancelAppNotify, binding!!.scbNotUserPresent)
//启动时异步获取已安装App信息
switchEnableLoadAppList(binding!!.sbEnableLoadAppList, binding!!.scbLoadUserApp, binding!!.scbLoadSystemApp)
//过滤多久内重复消息
binding!!.xsbDuplicateMessagesLimits.setDefaultValue(SettingUtils.duplicateMessagesLimits)
binding!!.xsbDuplicateMessagesLimits.setOnSeekBarListener { _: XSeekBar?, newValue: Int ->
@ -368,6 +370,41 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
}
}
//启动时异步获取已安装App信息 (binding!!.sbEnableLoadAppList, binding!!.scbLoadUserApp, binding!!.scbLoadSystemApp)
@SuppressLint("UseSwitchCompatOrMaterialCode")
fun switchEnableLoadAppList(sbEnableLoadAppList: SwitchButton, scbLoadUserApp: SmoothCheckBox, scbLoadSystemApp: SmoothCheckBox) {
val isEnable: Boolean = SettingUtils.enableLoadAppList
sbEnableLoadAppList.isChecked = isEnable
sbEnableLoadAppList.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
if (isChecked && !SettingUtils.enableLoadUserAppList && !SettingUtils.enableLoadSystemAppList) {
sbEnableLoadAppList.isChecked = false
SettingUtils.enableLoadAppList = false
XToastUtils.error(getString(R.string.load_app_list_toast))
return@setOnCheckedChangeListener
}
SettingUtils.enableLoadAppList = isChecked
}
scbLoadUserApp.isChecked = SettingUtils.enableLoadUserAppList
scbLoadUserApp.setOnCheckedChangeListener { _: SmoothCheckBox, isChecked: Boolean ->
SettingUtils.enableLoadUserAppList = isChecked
if (SettingUtils.enableLoadAppList && !SettingUtils.enableLoadUserAppList && !SettingUtils.enableLoadSystemAppList) {
sbEnableLoadAppList.isChecked = false
SettingUtils.enableLoadAppList = false
XToastUtils.error(getString(R.string.load_app_list_toast))
}
}
scbLoadSystemApp.isChecked = SettingUtils.enableLoadSystemAppList
scbLoadSystemApp.setOnCheckedChangeListener { _: SmoothCheckBox, isChecked: Boolean ->
SettingUtils.enableLoadSystemAppList = isChecked
if (SettingUtils.enableLoadAppList && !SettingUtils.enableLoadUserAppList && !SettingUtils.enableLoadSystemAppList) {
sbEnableLoadAppList.isChecked = false
SettingUtils.enableLoadAppList = false
XToastUtils.error(getString(R.string.load_app_list_toast))
}
}
}
//监听电池状态变化
@SuppressLint("UseSwitchCompatOrMaterialCode")
fun switchBatteryReceiver(sbBatteryReceiver: SwitchButton) {

View File

@ -34,6 +34,10 @@ const val SP_ENABLE_APP_NOTIFY = "enable_app_notify"
const val SP_ENABLE_CANCEL_APP_NOTIFY = "enable_cancel_app_notify"
const val SP_ENABLE_NOT_USER_PRESENT = "enable_not_user_present"
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"
const val SP_DUPLICATE_MESSAGES_LIMITS = "duplicate_messages_limits"
const val SP_BATTERY_RECEIVER = "enable_battery_receiver"

View File

@ -153,6 +153,9 @@ class HttpServerUtils private constructor() {
cloneInfo.enableAppNotify = SettingUtils.enableAppNotify
cloneInfo.cancelAppNotify = SettingUtils.enableCancelAppNotify
cloneInfo.enableNotUserPresent = SettingUtils.enableNotUserPresent
cloneInfo.enableLoadAppList = SettingUtils.enableLoadAppList
cloneInfo.enableLoadUserAppList = SettingUtils.enableLoadUserAppList
cloneInfo.enableLoadSystemAppList = SettingUtils.enableLoadSystemAppList
cloneInfo.duplicateMessagesLimits = SettingUtils.duplicateMessagesLimits
cloneInfo.enableBatteryReceiver = SettingUtils.enableBatteryReceiver
cloneInfo.batteryLevelMin = SettingUtils.batteryLevelMin
@ -162,7 +165,9 @@ class HttpServerUtils private constructor() {
cloneInfo.batteryCronStartTime = SettingUtils.batteryCronStartTime
cloneInfo.batteryCronInterval = SettingUtils.batteryCronInterval
cloneInfo.enableExcludeFromRecents = SettingUtils.enableExcludeFromRecents
cloneInfo.enableCactus = SettingUtils.enableCactus
cloneInfo.enablePlaySilenceMusic = SettingUtils.enablePlaySilenceMusic
cloneInfo.enableOnePixelActivity = SettingUtils.enableOnePixelActivity
cloneInfo.requestRetryTimes = SettingUtils.requestRetryTimes
cloneInfo.requestDelayTime = SettingUtils.requestDelayTime
cloneInfo.requestTimeout = SettingUtils.requestTimeout
@ -170,6 +175,7 @@ class HttpServerUtils private constructor() {
cloneInfo.enableSmsTemplate = SettingUtils.enableSmsTemplate
cloneInfo.smsTemplate = SettingUtils.smsTemplate
cloneInfo.enableHelpTip = SettingUtils.enableHelpTip
cloneInfo.enablePureClientMode = SettingUtils.enablePureClientMode
cloneInfo.senderList = Core.sender.all
cloneInfo.ruleList = Core.rule.all
@ -188,6 +194,9 @@ class HttpServerUtils private constructor() {
SettingUtils.enableAppNotify = cloneInfo.enableAppNotify
SettingUtils.enableCancelAppNotify = cloneInfo.cancelAppNotify
SettingUtils.enableNotUserPresent = cloneInfo.enableNotUserPresent
SettingUtils.enableLoadAppList = cloneInfo.enableLoadAppList
SettingUtils.enableLoadUserAppList = cloneInfo.enableLoadUserAppList
SettingUtils.enableLoadSystemAppList = cloneInfo.enableLoadSystemAppList
SettingUtils.duplicateMessagesLimits = cloneInfo.duplicateMessagesLimits
SettingUtils.enableBatteryReceiver = cloneInfo.enableBatteryReceiver
SettingUtils.batteryLevelMin = cloneInfo.batteryLevelMin
@ -197,7 +206,9 @@ class HttpServerUtils private constructor() {
SettingUtils.batteryCronStartTime = cloneInfo.batteryCronStartTime
SettingUtils.batteryCronInterval = cloneInfo.batteryCronInterval
SettingUtils.enableExcludeFromRecents = cloneInfo.enableExcludeFromRecents
SettingUtils.enableCactus = cloneInfo.enableCactus
SettingUtils.enablePlaySilenceMusic = cloneInfo.enablePlaySilenceMusic
SettingUtils.enableOnePixelActivity = cloneInfo.enableOnePixelActivity
SettingUtils.requestRetryTimes = cloneInfo.requestRetryTimes
SettingUtils.requestDelayTime = cloneInfo.requestDelayTime
SettingUtils.requestTimeout = cloneInfo.requestTimeout
@ -205,6 +216,7 @@ class HttpServerUtils private constructor() {
SettingUtils.enableSmsTemplate = cloneInfo.enableSmsTemplate
SettingUtils.smsTemplate = cloneInfo.smsTemplate
SettingUtils.enableHelpTip = cloneInfo.enableHelpTip
SettingUtils.enablePureClientMode = cloneInfo.enablePureClientMode
//删除发送通道、转发规则、转发日志
Core.sender.deleteAll()
//发送通道

View File

@ -85,6 +85,30 @@ class SettingUtils private constructor() {
MMKVUtils.put(SP_ENABLE_NOT_USER_PRESENT, enableNotUserPresent)
}
//是否加载应用列表
@JvmStatic
var enableLoadAppList: Boolean
get() = MMKVUtils.getBoolean(ENABLE_LOAD_APP_LIST, false)
set(enableLoadAppList) {
MMKVUtils.put(ENABLE_LOAD_APP_LIST, enableLoadAppList)
}
//是否加载应用列表——用户应用
@JvmStatic
var enableLoadUserAppList: Boolean
get() = MMKVUtils.getBoolean(ENABLE_LOAD_USER_APP_LIST, false)
set(enableLoadUserAppList) {
MMKVUtils.put(ENABLE_LOAD_USER_APP_LIST, enableLoadUserAppList)
}
//是否加载应用列表——系统应用
@JvmStatic
var enableLoadSystemAppList: Boolean
get() = MMKVUtils.getBoolean(ENABLE_LOAD_SYSTEM_APP_LIST, false)
set(enableLoadSystemAppList) {
MMKVUtils.put(ENABLE_LOAD_SYSTEM_APP_LIST, enableLoadSystemAppList)
}
//过滤多久内重复消息
@JvmStatic
var duplicateMessagesLimits: Int
@ -176,9 +200,9 @@ class SettingUtils private constructor() {
//是否转发应用通知
@JvmStatic
var enableCactus: Boolean
get() = MMKVUtils.getBoolean(SP_ENABLE_APP_NOTIFY, false)
get() = MMKVUtils.getBoolean(SP_ENABLE_CACTUS, false)
set(enableAppNotify) {
MMKVUtils.put(SP_ENABLE_APP_NOTIFY, enableAppNotify)
MMKVUtils.put(SP_ENABLE_CACTUS, enableAppNotify)
}
//是否播放静音音乐

View File

@ -6,6 +6,17 @@
android:layout_height="match_parent"
android:orientation="vertical">
<com.xuexiang.xui.widget.tabbar.EasyIndicator
android:id="@+id/tabBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
app:indicator_height="42dp"
app:indicator_line_height="2dp"
app:indicator_line_show="true"
app:indicator_textSize="14sp"
app:indicator_width="0dp" />
<com.scwang.smartrefresh.layout.SmartRefreshLayout
android:id="@+id/refreshLayout"
android:layout_width="match_parent"

View File

@ -245,6 +245,85 @@
</LinearLayout>
<LinearLayout
style="@style/settingBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/load_app_list"
android:textStyle="bold"
tools:ignore="RelativeOverlap" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/load_app_list_tips"
android:textSize="9sp"
tools:ignore="SmallSp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="25dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/optional_type"
android:textSize="10sp"
android:textStyle="bold"
tools:ignore="SmallSp" />
<com.xuexiang.xui.widget.button.SmoothCheckBox
android:id="@+id/scb_load_user_app"
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:layout_marginStart="2dp"
android:checked="true"
android:text="@string/user_app"
android:textSize="11sp" />
<com.xuexiang.xui.widget.button.SmoothCheckBox
android:id="@+id/scb_load_system_app"
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:layout_marginStart="2dp"
android:text="@string/system_app"
android:textSize="11sp" />
</LinearLayout>
</LinearLayout>
<com.xuexiang.xui.widget.button.switchbutton.SwitchButton
android:id="@+id/sb_enable_load_app_list"
style="@style/SwitchButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
style="@style/settingBarStyle"
android:layout_width="match_parent"

View File

@ -74,6 +74,12 @@
<item>Offline Mode</item>
</string-array>
<!--APP类型-->
<string-array name="app_type_option">
<item>User App</item>
<item>System App</item>
</string-array>
<string-array name="MailType">
<item>\@qq.com</item>
<item>\@foxmail.com</item>

View File

@ -494,6 +494,7 @@
<string name="received_call">Received</string>
<string name="local_outgoing_call">Call out</string>
<string name="optional_action">Optional: </string>
<string name="optional_type">Optional: </string>
<string name="active_request">Active request</string>
<string name="active_request_tips">Obtain instructions through passive reception or active polling to operate the machine</string>
<string name="httpserver">Local HttpServer</string>
@ -527,6 +528,7 @@
<string name="tag_from">{{FROM}}</string>
<string name="tag_sms">{{SMS}}</string>
<string name="tag_package_name">{{PACKAGE_NAME}}</string>
<string name="tag_app_name">{{APP_NAME}}</string>
<string name="tag_msg">{{MSG}}</string>
<string name="tag_card_slot">{{CARD_SLOT}}</string>
<string name="tag_receive_time">{{RECEIVE_TIME}}</string>
@ -859,4 +861,7 @@
<string name="optional_components">Optional:</string>
<string name="enable_cactus">Enable Cactus Keep Alive</string>
<string name="enabe_cactus_tips">Dual process foreground service/JobScheduler/WorkManager/1px/silent music</string>
<string name="load_app_list">Get installed app info async at startup</string>
<string name="load_app_list_tips">Used to speed up entering the application list/editing forwarding rules drop-down selection/replacement {{APP_NAME}}</string>
<string name="load_app_list_toast">A type must be selected when enabling asynchronous loading of the list of installed apps</string>
</resources>

View File

@ -74,6 +74,12 @@
<item>离线模式</item>
</string-array>
<!--APP类型-->
<string-array name="app_type_option">
<item>用户应用</item>
<item>系统应用</item>
</string-array>
<string-array name="MailType">
<item>\@qq.com</item>
<item>\@foxmail.com</item>

View File

@ -495,6 +495,7 @@
<string name="received_call">已接来电</string>
<string name="local_outgoing_call">本机去电</string>
<string name="optional_action">可选操作:</string>
<string name="optional_type">可选类型:</string>
<string name="active_request">主动请求</string>
<string name="active_request_tips">通过 被动接收 或者 主动轮询 获取指令,从而操作本机</string>
<string name="httpserver">被动接收本地 HttpServer</string>
@ -528,6 +529,7 @@
<string name="tag_from">{{来源号码}}</string>
<string name="tag_sms">{{短信内容}}</string>
<string name="tag_package_name">{{APP包名}}</string>
<string name="tag_app_name">{{APP名称}}</string>
<string name="tag_msg">{{通知内容}}</string>
<string name="tag_card_slot">{{卡槽信息}}</string>
<string name="tag_receive_time">{{接收时间}}</string>
@ -860,4 +862,7 @@
<string name="optional_components">可选组件:</string>
<string name="enable_cactus">启用 Cactus 增强保活措施(会增加耗电)</string>
<string name="enabe_cactus_tips">双进程前台服务/JobScheduler/WorkManager/1像素/无声音乐</string>
<string name="load_app_list">启动时异步获取已安装App列表</string>
<string name="load_app_list_tips">用于加速进入应用列表/编辑转发规则下拉选择/替换{{APP名称}}</string>
<string name="load_app_list_toast">开启异步获取已安装App列表时必选一个类型</string>
</resources>