优化:一键换新机·导出/导入通用设置的机制

优化:手动重启app的方式
This commit is contained in:
pppscn 2023-02-23 15:55:06 +08:00
parent 7194c9ba3f
commit 197fb7ac36
15 changed files with 162 additions and 278 deletions

View File

@ -447,10 +447,18 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(),
val destFile = File("$libPath/libgojni.so")
FileUtils.moveFile(srcFile, destFile, null)
val intent: Intent? = packageManager.getLaunchIntentForPackage(packageName)
intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
MaterialDialog.Builder(this@MainActivity)
.iconRes(R.drawable.ic_menu_frpc)
.title(R.string.menu_frpc)
.content(R.string.download_frpc_tips2)
.cancelable(false)
.positiveText(R.string.confirm)
.onPositive { _: MaterialDialog?, _: DialogAction? ->
val intent = Intent(App.context, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(intent)
android.os.Process.killProcess(android.os.Process.myPid()) //杀掉以前进程
}
.show()
}
})

View File

@ -22,6 +22,9 @@ interface LogsDao {
@Query("DELETE FROM Logs where type=:type")
fun deleteAll(type: String): Completable
@Query("DELETE FROM Logs")
fun deleteAll()
@Query("DELETE FROM Logs where time<:time")
fun deleteTimeAgo(time: Long)

View File

@ -22,6 +22,9 @@ interface MsgDao {
@Query("DELETE FROM Msg where type=:type")
fun deleteAll(type: String): Completable
@Query("DELETE FROM Msg")
fun deleteAll()
@Query("DELETE FROM Msg where time<:time")
fun deleteTimeAgo(time: Long)

View File

@ -19,6 +19,9 @@ interface RuleDao {
@Query("DELETE FROM Rule where id=:id")
fun delete(id: Long)
@Query("DELETE FROM Rule")
fun deleteAll()
@Update
fun update(rule: Rule)

View File

@ -24,4 +24,8 @@ class LogsRepository(private val logsDao: LogsDao) {
logsDao.updateStatus(id, status, response)
fun getOne(id: Long) = logsDao.getOne(id)
fun deleteAll() {
logsDao.deleteAll()
}
}

View File

@ -19,4 +19,8 @@ class MsgRepository(private val msgDao: MsgDao) {
@WorkerThread
suspend fun insert(msg: Msg): Long = msgDao.insert(msg)
fun deleteAll() {
msgDao.deleteAll()
}
}

View File

@ -36,4 +36,8 @@ class RuleRepository(
//TODO:允许主线程访问,后面再优化
val all: List<Rule> = ruleDao.getAll()
fun deleteAll() {
ruleDao.deleteAll()
}
}

View File

@ -13,119 +13,8 @@ data class CloneInfo(
@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("settings")
var settings: String = "",
@SerializedName("sender_list")
var senderList: List<Sender>? = null,

View File

@ -4,7 +4,9 @@ import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.activity.MainActivity
import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.core.webview.AgentWebActivity
import com.idormy.sms.forwarder.databinding.FragmentAboutBinding
@ -19,6 +21,8 @@ import com.idormy.sms.forwarder.utils.sdkinit.XUpdateInit
import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xpage.annotation.Page
import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import com.xuexiang.xui.widget.textview.supertextview.SuperTextView
import com.xuexiang.xutil.app.AppUtils
import com.xuexiang.xutil.file.FileUtils
@ -74,12 +78,18 @@ class AboutFragment : BaseFragment<FragmentAboutBinding?>(), SuperTextView.OnSup
try {
val soFile = File(context?.filesDir?.absolutePath + "/libs/libgojni.so")
if (soFile.exists()) soFile.delete()
XToastUtils.success(R.string.about_frpc_deleted)
val intent: Intent? = context?.packageManager?.getLaunchIntentForPackage(context?.packageName.toString())
intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
MaterialDialog.Builder(requireContext())
.iconRes(R.drawable.ic_menu_frpc)
.title(R.string.menu_frpc)
.content(R.string.about_frpc_deleted)
.cancelable(false)
.positiveText(R.string.confirm)
.onPositive { _: MaterialDialog?, _: DialogAction? ->
val intent = Intent(App.context, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(intent)
android.os.Process.killProcess(android.os.Process.myPid()) //杀掉以前进程
}
.show()
} catch (e: Exception) {
e.printStackTrace()
XToastUtils.error(e.message.toString())

View File

@ -1,6 +1,7 @@
package com.idormy.sms.forwarder.fragment.client
import android.annotation.SuppressLint
import android.content.Intent
import android.os.Environment
import android.util.Log
import android.view.LayoutInflater
@ -13,7 +14,9 @@ import com.google.gson.reflect.TypeToken
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.activity.MainActivity
import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.databinding.FragmentClientCloneBinding
import com.idormy.sms.forwarder.entity.CloneInfo
@ -30,6 +33,8 @@ import com.xuexiang.xrouter.utils.TextUtils
import com.xuexiang.xui.utils.CountDownButtonHelper
import com.xuexiang.xui.utils.ResUtils
import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import com.xuexiang.xutil.app.AppUtils
import com.xuexiang.xutil.data.ConvertTools
import com.xuexiang.xutil.file.FileIOUtils
@ -70,12 +75,10 @@ class CloneFragment : BaseFragment<FragmentClientCloneBinding?>(), View.OnClickL
// 申请储存权限
XXPermissions.with(this)
//.permission(*Permission.Group.STORAGE)
.permission(Permission.MANAGE_EXTERNAL_STORAGE)
.request(object : OnPermissionCallback {
.permission(Permission.MANAGE_EXTERNAL_STORAGE).request(object : OnPermissionCallback {
@SuppressLint("SetTextI18n")
override fun onGranted(permissions: List<String>, all: Boolean) {
backupPath =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).path
backupPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).path
binding!!.tvBackupPath.text = backupPath + File.separator + backupFile
}
@ -105,8 +108,7 @@ class CloneFragment : BaseFragment<FragmentClientCloneBinding?>(), View.OnClickL
//按钮增加倒计时,避免重复点击
pushCountDownHelper = CountDownButtonHelper(binding!!.btnPush, SettingUtils.requestTimeout)
pushCountDownHelper!!.setOnCountDownListener(object :
CountDownButtonHelper.OnCountDownListener {
pushCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
override fun onCountDown(time: Int) {
binding!!.btnPush.text = String.format(getString(R.string.seconds_n), time)
}
@ -116,8 +118,7 @@ class CloneFragment : BaseFragment<FragmentClientCloneBinding?>(), View.OnClickL
}
})
pullCountDownHelper = CountDownButtonHelper(binding!!.btnPull, SettingUtils.requestTimeout)
pullCountDownHelper!!.setOnCountDownListener(object :
CountDownButtonHelper.OnCountDownListener {
pullCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
override fun onCountDown(time: Int) {
binding!!.btnPull.text = String.format(getString(R.string.seconds_n), time)
}
@ -127,8 +128,7 @@ class CloneFragment : BaseFragment<FragmentClientCloneBinding?>(), View.OnClickL
}
})
exportCountDownHelper = CountDownButtonHelper(binding!!.btnExport, 3)
exportCountDownHelper!!.setOnCountDownListener(object :
CountDownButtonHelper.OnCountDownListener {
exportCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
override fun onCountDown(time: Int) {
binding!!.btnExport.text = String.format(getString(R.string.seconds_n), time)
}
@ -138,8 +138,7 @@ class CloneFragment : BaseFragment<FragmentClientCloneBinding?>(), View.OnClickL
}
})
importCountDownHelper = CountDownButtonHelper(binding!!.btnImport, 3)
importCountDownHelper!!.setOnCountDownListener(object :
CountDownButtonHelper.OnCountDownListener {
importCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
override fun onCountDown(time: Int) {
binding!!.btnImport.text = String.format(getString(R.string.seconds_n), time)
}
@ -203,9 +202,7 @@ class CloneFragment : BaseFragment<FragmentClientCloneBinding?>(), View.OnClickL
//替换Date字段为当前时间
val builder = GsonBuilder()
builder.registerTypeAdapter(
Date::class.java,
JsonDeserializer<Any?> { _, _, _ -> Date() })
builder.registerTypeAdapter(Date::class.java, JsonDeserializer<Any?> { _, _, _ -> Date() })
val gson = builder.create()
val cloneInfo = gson.fromJson(jsonStr, CloneInfo::class.java)
Log.d(TAG, "cloneInfo = $cloneInfo")
@ -214,7 +211,18 @@ class CloneFragment : BaseFragment<FragmentClientCloneBinding?>(), View.OnClickL
HttpServerUtils.compareVersion(cloneInfo)
if (HttpServerUtils.restoreSettings(cloneInfo)) {
XToastUtils.success(getString(R.string.import_succeeded))
MaterialDialog.Builder(requireContext())
.iconRes(R.drawable.icon_api_clone)
.title(R.string.clone)
.content(R.string.import_succeeded)
.cancelable(false)
.positiveText(R.string.confirm)
.onPositive { _: MaterialDialog?, _: DialogAction? ->
val intent = Intent(App.context, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(intent)
}
.show()
} else {
XToastUtils.error(getString(R.string.import_failed))
}
@ -242,19 +250,15 @@ class CloneFragment : BaseFragment<FragmentClientCloneBinding?>(), View.OnClickL
msgMap["timestamp"] = timestamp
val clientSignKey = HttpServerUtils.clientSignKey
if (!TextUtils.isEmpty(clientSignKey)) {
msgMap["sign"] =
HttpServerUtils.calcSign(timestamp.toString(), clientSignKey)
msgMap["sign"] = HttpServerUtils.calcSign(timestamp.toString(), clientSignKey)
}
msgMap["data"] = HttpServerUtils.exportSettings()
var requestMsg: String = Gson().toJson(msgMap)
Log.i(TAG, "requestMsg:$requestMsg")
val postRequest = XHttp.post(requestUrl)
.keepJson(true)
.timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE)
.timeStamp(true)
val postRequest = XHttp.post(requestUrl).keepJson(true).timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE).timeStamp(true)
when (HttpServerUtils.clientSafetyMeasures) {
2 -> {
@ -342,8 +346,7 @@ class CloneFragment : BaseFragment<FragmentClientCloneBinding?>(), View.OnClickL
msgMap["timestamp"] = timestamp
val clientSignKey = HttpServerUtils.clientSignKey
if (!TextUtils.isEmpty(clientSignKey)) {
msgMap["sign"] =
HttpServerUtils.calcSign(timestamp.toString(), clientSignKey)
msgMap["sign"] = HttpServerUtils.calcSign(timestamp.toString(), clientSignKey)
}
val dataMap: MutableMap<String, Any> = mutableMapOf()
@ -353,11 +356,8 @@ class CloneFragment : BaseFragment<FragmentClientCloneBinding?>(), View.OnClickL
var requestMsg: String = Gson().toJson(msgMap)
Log.i(TAG, "requestMsg:$requestMsg")
val postRequest = XHttp.post(requestUrl)
.keepJson(true)
.timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE)
.timeStamp(true)
val postRequest = XHttp.post(requestUrl).keepJson(true).timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE).timeStamp(true)
when (HttpServerUtils.clientSafetyMeasures) {
2 -> {
@ -415,9 +415,7 @@ class CloneFragment : BaseFragment<FragmentClientCloneBinding?>(), View.OnClickL
//替换Date字段为当前时间
val builder = GsonBuilder()
builder.registerTypeAdapter(
Date::class.java,
JsonDeserializer<Any?> { _, _, _ -> Date() })
builder.registerTypeAdapter(Date::class.java, JsonDeserializer<Any?> { _, _, _ -> Date() })
val gson = builder.create()
val resp: BaseResponse<CloneInfo> = gson.fromJson(json, object : TypeToken<BaseResponse<CloneInfo>>() {}.type)
if (resp.code == 200) {

View File

@ -18,9 +18,8 @@ class BootReceiver : BroadcastReceiver() {
try {
Log.d(TAG, "强制重启APP一次")
val intent1 = Intent(context, SplashActivity::class.java)
intent1.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
context.startActivity(intent1)
android.os.Process.killProcess(android.os.Process.myPid()) //杀掉以前进程
} catch (e: Exception) {
e.printStackTrace()
}

View File

@ -144,48 +144,10 @@ class HttpServerUtils private constructor() {
val cloneInfo = CloneInfo()
cloneInfo.versionCode = AppUtils.getAppVersionCode()
cloneInfo.versionName = AppUtils.getAppVersionName()
cloneInfo.enableSms = SettingUtils.enableSms
cloneInfo.enablePhone = SettingUtils.enablePhone
cloneInfo.callType1 = SettingUtils.enableCallType1
cloneInfo.callType2 = SettingUtils.enableCallType2
cloneInfo.callType3 = SettingUtils.enableCallType3
cloneInfo.callType4 = SettingUtils.enableCallType4
cloneInfo.callType5 = SettingUtils.enableCallType5
cloneInfo.callType6 = SettingUtils.enableCallType6
cloneInfo.enableAppNotify = SettingUtils.enableAppNotify
cloneInfo.cancelAppNotify = SettingUtils.enableCancelAppNotify
cloneInfo.cancelExtraAppNotify = SettingUtils.cancelExtraAppNotify
cloneInfo.enableNotUserPresent = SettingUtils.enableNotUserPresent
cloneInfo.enableLoadAppList = SettingUtils.enableLoadAppList
cloneInfo.enableLoadUserAppList = SettingUtils.enableLoadUserAppList
cloneInfo.enableLoadSystemAppList = SettingUtils.enableLoadSystemAppList
cloneInfo.duplicateMessagesLimits = SettingUtils.duplicateMessagesLimits
cloneInfo.enableNetworkStateReceiver = SettingUtils.enableNetworkStateReceiver
cloneInfo.enableBatteryReceiver = SettingUtils.enableBatteryReceiver
cloneInfo.batteryLevelMin = SettingUtils.batteryLevelMin
cloneInfo.batteryLevelMax = SettingUtils.batteryLevelMax
cloneInfo.batteryLevelOnce = SettingUtils.batteryLevelOnce
cloneInfo.enableBatteryCron = SettingUtils.enableBatteryCron
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
cloneInfo.notifyContent = SettingUtils.notifyContent
cloneInfo.enableSmsTemplate = SettingUtils.enableSmsTemplate
cloneInfo.smsTemplate = SettingUtils.smsTemplate
cloneInfo.enableHelpTip = SettingUtils.enableHelpTip
cloneInfo.enablePureClientMode = SettingUtils.enablePureClientMode
cloneInfo.enableSmsCommand = SettingUtils.enableSmsCommand
cloneInfo.smsCommandSafePhone = SettingUtils.smsCommandSafePhone
cloneInfo.settings = SharedPreference.exportPreference()
cloneInfo.senderList = Core.sender.all
cloneInfo.ruleList = Core.rule.all
cloneInfo.frpcList = Core.frpc.all
return cloneInfo
}
@ -193,53 +155,26 @@ class HttpServerUtils private constructor() {
fun restoreSettings(cloneInfo: CloneInfo): Boolean {
return try {
//应用配置
SettingUtils.enableSms = cloneInfo.enableSms
SettingUtils.enablePhone = cloneInfo.enablePhone
SettingUtils.enableCallType1 = cloneInfo.callType1
SettingUtils.enableCallType2 = cloneInfo.callType2
SettingUtils.enableCallType3 = cloneInfo.callType3
SettingUtils.enableCallType4 = cloneInfo.callType4
SettingUtils.enableCallType5 = cloneInfo.callType5
SettingUtils.enableCallType6 = cloneInfo.callType6
SettingUtils.enableAppNotify = cloneInfo.enableAppNotify
SettingUtils.enableCancelAppNotify = cloneInfo.cancelAppNotify
SettingUtils.cancelExtraAppNotify = cloneInfo.cancelExtraAppNotify.toString()
SettingUtils.enableNotUserPresent = cloneInfo.enableNotUserPresent
SettingUtils.enableLoadAppList = cloneInfo.enableLoadAppList
SettingUtils.enableLoadUserAppList = cloneInfo.enableLoadUserAppList
SettingUtils.enableLoadSystemAppList = cloneInfo.enableLoadSystemAppList
SettingUtils.duplicateMessagesLimits = cloneInfo.duplicateMessagesLimits
SettingUtils.enableNetworkStateReceiver = cloneInfo.enableNetworkStateReceiver
SettingUtils.enableBatteryReceiver = cloneInfo.enableBatteryReceiver
SettingUtils.batteryLevelMin = cloneInfo.batteryLevelMin
SettingUtils.batteryLevelMax = cloneInfo.batteryLevelMax
SettingUtils.batteryLevelOnce = cloneInfo.batteryLevelOnce
SettingUtils.enableBatteryCron = cloneInfo.enableBatteryCron
SettingUtils.batteryCronStartTime = cloneInfo.batteryCronStartTime.toString()
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
SettingUtils.notifyContent = cloneInfo.notifyContent.toString()
SettingUtils.enableSmsTemplate = cloneInfo.enableSmsTemplate
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()
SharedPreference.clearPreference()
SharedPreference.importPreference(cloneInfo.settings)
//需要排除的配置
SettingUtils.extraDeviceMark = ""
SettingUtils.subidSim1 = 0
SettingUtils.extraSim1 = ""
SettingUtils.subidSim2 = 0
SettingUtils.extraSim2 = ""
//删除消息与转发日志
Core.logs.deleteAll()
Core.msg.deleteAll()
//发送通道
Core.sender.deleteAll()
if (!cloneInfo.senderList.isNullOrEmpty()) {
for (sender in cloneInfo.senderList!!) {
Core.sender.insert(sender)
}
}
//转发规则
Core.rule.deleteAll()
if (!cloneInfo.ruleList.isNullOrEmpty()) {
for (rule in cloneInfo.ruleList!!) {
Core.rule.insert(rule)

View File

@ -27,45 +27,27 @@ class SharedPreference<T>(private val name: String, private val default: T) : Re
//根据key删除存储数据
fun clearPreference(key: String) = preference.edit().remove(key).commit()
//导出全部数据
fun exportPreference(): String {
return serialize(preference.all)
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
return putPreference(name, value)
}
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
return getPreference(name, default)
}
/**
* 查找数据 返回给调用方法一个具体的对象
* 如果查找不到类型就采用反序列化方法来返回类型
* default是默认对象 以防止会返回空对象的异常
* 即如果name没有查找到value 就返回默认的序列化对象然后经过反序列化返回
*/
private fun getPreference(name: String, default: T): T = with(preference) {
val res: Any = when (default) {
is Long -> getLong(name, default)
is String -> this.getString(name, default)!!
is Int -> getInt(name, default)
is Boolean -> getBoolean(name, default)
is Float -> getFloat(name, default)
//else -> throw IllegalArgumentException("This type can be get from Preferences")
else -> deSerialization(getString(name, serialize(default)).toString())
}
return res as T
}
private fun putPreference(name: String, value: T) = with(preference.edit()) {
//导入全部数据
fun importPreference(data: String) {
val map = deSerialization<Map<String, Any>>(data)
val editor = preference.edit()
for ((key, value) in map) {
when (value) {
is Long -> putLong(name, value)
is Int -> putInt(name, value)
is String -> putString(name, value)
is Boolean -> putBoolean(name, value)
is Float -> putFloat(name, value)
//else -> throw IllegalArgumentException("This type can be saved into Preferences")
else -> putString(name, serialize(value))
}.apply()
is Long -> editor.putLong(key, value)
is Int -> editor.putInt(key, value)
is String -> editor.putString(key, value)
is Boolean -> editor.putBoolean(key, value)
is Float -> editor.putFloat(key, value)
else -> editor.putString(key, serialize(value))
}
}
editor.apply()
}
/**
@ -106,4 +88,44 @@ class SharedPreference<T>(private val name: String, private val default: T) : Re
byteArrayInputStream.close()
return obj
}
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
return putPreference(name, value)
}
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
return getPreference(name, default)
}
/**
* 查找数据 返回给调用方法一个具体的对象
* 如果查找不到类型就采用反序列化方法来返回类型
* default是默认对象 以防止会返回空对象的异常
* 即如果name没有查找到value 就返回默认的序列化对象然后经过反序列化返回
*/
private fun getPreference(name: String, default: T): T = with(preference) {
val res: Any = when (default) {
is Long -> getLong(name, default)
is String -> this.getString(name, default)!!
is Int -> getInt(name, default)
is Boolean -> getBoolean(name, default)
is Float -> getFloat(name, default)
//else -> throw IllegalArgumentException("This type can be get from Preferences")
else -> deSerialization(getString(name, serialize(default)).toString())
}
return res as T
}
private fun putPreference(name: String, value: T) = with(preference.edit()) {
when (value) {
is Long -> putLong(name, value)
is Int -> putInt(name, value)
is String -> putString(name, value)
is Boolean -> putBoolean(name, value)
is Float -> putFloat(name, value)
//else -> throw IllegalArgumentException("This type can be saved into Preferences")
else -> putString(name, serialize(value))
}.apply()
}
}

View File

@ -956,6 +956,7 @@
<string name="silent_time_period">Disable forwarding period</string>
<string name="silent_time_period_tips">If the end time is less than the start time, it will span days; if it is equal, it will be disabled</string>
<string name="download_frpc_tips">Do you want to download and restart to load!</string>
<string name="download_frpc_tips2">Download successful, do you want to restart the loading now?</string>
<string name="appkey">AppKey</string>
<string name="appsecret">AppSecret</string>
<string name="sampleText">Text</string>

View File

@ -28,7 +28,7 @@
<string name="about_frpc_version">Frpc版本%s</string>
<string name="about_item_wechat_miniprogram">微信小程序</string>
<string name="about_cache_purged">已清理缓存</string>
<string name="about_frpc_deleted">已删除动态库重启APP中…</string>
<string name="about_frpc_deleted">已删除动态库重启APP以便生效!</string>
<string name="about_copyright">© %1$s PPPSCN All rights reserved.</string>
<string name="about_item_open_source">开源仓库</string>
<string name="about_item_github">GitHub</string>
@ -916,7 +916,7 @@
<string name="export_failed_tips">导出失败: %s</string>
<string name="import_failed">导入失败:请检查是否有外部存储访问权限!</string>
<string name="import_failed_file_not_exist">导入失败:本地备份文件不存在!</string>
<string name="import_succeeded">导入配置成功!</string>
<string name="import_succeeded">导入配置成功!\n需要重启APP以便生效\n重启后请再次核对所有配置项</string>
<string name="import_failed_tips">导入失败: %s</string>
<string name="restore_failed">还原失败</string>
<string name="battery_status_monitor">电池状态监听</string>
@ -957,6 +957,7 @@
<string name="silent_time_period">免打扰(禁用转发)时间段</string>
<string name="silent_time_period_tips">结束时间小于开始时间则跨天;相等则禁用</string>
<string name="download_frpc_tips">是否立即下载,并重启加载?</string>
<string name="download_frpc_tips2">下载成功,是否立即重启加载?</string>
<string name="appkey">AppKey</string>
<string name="appsecret">AppSecret</string>
<string name="sampleText">文本类型</string>