mirror of
https://github.com/LittleTurtle2333/SimplicityTools.git
synced 2026-07-13 11:51:22 +08:00
使用YukiHook重构(未完成)
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
package com.lt2333.simplicitytools.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import cn.fkj233.ui.activity.MIUIActivity
|
||||
import cn.fkj233.ui.dialog.MIUIDialog
|
||||
import com.lt2333.simplicitytools.BuildConfig
|
||||
import com.lt2333.simplicitytools.R
|
||||
import com.lt2333.simplicitytools.activity.pages.all.AboutPage
|
||||
import com.lt2333.simplicitytools.activity.pages.all.MenuPage
|
||||
import com.lt2333.simplicitytools.activity.pages.s.*
|
||||
import com.lt2333.simplicitytools.activity.pages.t.*
|
||||
import java.util.*
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
class MainActivity : MIUIActivity() {
|
||||
private val activity = this
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
if (!checkLSPosed()) isLoad = false
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
//检测LSPosed是否激活
|
||||
@SuppressLint("WorldReadableFiles")
|
||||
private fun checkLSPosed(): Boolean {
|
||||
try {
|
||||
setSP(getSharedPreferences("config", MODE_WORLD_READABLE))
|
||||
return true
|
||||
} catch (exception: SecurityException) {
|
||||
MIUIDialog(this) {
|
||||
setTitle(R.string.Tips)
|
||||
setMessage(R.string.not_support)
|
||||
setCancelable(false)
|
||||
setRButton(R.string.Done) {
|
||||
exitProcess(0)
|
||||
}
|
||||
}.show()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
init {
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
Build.VERSION_CODES.TIRAMISU -> {
|
||||
registerPage(MainPageForT::class.java)
|
||||
registerPage(SystemUIPageForT::class.java)
|
||||
registerPage(AndroidPageForT::class.java)
|
||||
registerPage(OtherPageForT::class.java)
|
||||
registerPage(HideIconPageForT::class.java)
|
||||
registerPage(AboutPage::class.java)
|
||||
registerPage(MenuPage::class.java)
|
||||
}
|
||||
Build.VERSION_CODES.S -> {
|
||||
registerPage(MainPageForS::class.java)
|
||||
registerPage(SystemUIPageForS::class.java)
|
||||
registerPage(AndroidPageForS::class.java)
|
||||
registerPage(OtherPageForS::class.java)
|
||||
registerPage(HideIconPageForS::class.java)
|
||||
registerPage(AboutPage::class.java)
|
||||
registerPage(MenuPage::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
package com.lt2333.simplicitytools.activity.pages.all
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.widget.Toast
|
||||
import cn.fkj233.ui.activity.annotation.BMPage
|
||||
import cn.fkj233.ui.activity.data.BasePage
|
||||
import cn.fkj233.ui.activity.view.TextSummaryV
|
||||
import com.lt2333.simplicitytools.BuildConfig
|
||||
import com.lt2333.simplicitytools.R
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
|
||||
@BMPage("about_module","About Module", hideMenu = true)
|
||||
class AboutPage : BasePage() {
|
||||
|
||||
override fun onCreate() {
|
||||
Author(
|
||||
authorHead = getDrawable(R.drawable.app_icon)!!,
|
||||
authorName = getString(R.string.app_name),
|
||||
authorTips = "${
|
||||
SimpleDateFormat(
|
||||
"yyyy-MM-dd HH:mm:ss",
|
||||
Locale.getDefault()
|
||||
).format(BuildConfig.BUILD_TIME.toLong())
|
||||
}\n${BuildConfig.VERSION_NAME}(${BuildConfig.BUILD_TYPE})",
|
||||
onClickListener = {
|
||||
try {
|
||||
activity.startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse("coolmarket://apk/com.lt2333.simplicitytools")
|
||||
)
|
||||
)
|
||||
Toast.makeText(activity, "恳求一个五星好评,Thanks♪(・ω・)ノ", Toast.LENGTH_LONG)
|
||||
.show()
|
||||
} catch (e: Exception) {
|
||||
val uri =
|
||||
Uri.parse("https://github.com/Xposed-Modules-Repo/com.lt2333.simplicitytools/releases")
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
activity.startActivity(intent)
|
||||
}
|
||||
})
|
||||
Line()
|
||||
TitleText(text = getString(R.string.developer))
|
||||
Author(
|
||||
authorHead = getDrawable(R.drawable.lt)!!,
|
||||
authorName = "乌堆小透明",
|
||||
authorTips = "LittleTurtle2333",
|
||||
onClickListener = {
|
||||
try {
|
||||
activity.startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse("coolmarket://u/883441")
|
||||
)
|
||||
)
|
||||
Toast.makeText(activity, "乌堆小透明:靓仔,点个关注吧!", Toast.LENGTH_SHORT).show()
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(activity, "本机未安装酷安应用", Toast.LENGTH_SHORT).show()
|
||||
val uri = Uri.parse("https://www.coolapk.com/u/883441")
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
activity.startActivity(intent)
|
||||
}
|
||||
})
|
||||
Line()
|
||||
TitleText(text = getString(R.string.thank_list))
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.contributor_list,
|
||||
onClickListener = {
|
||||
try {
|
||||
val uri =
|
||||
Uri.parse("https://github.com/LittleTurtle2333/SimplicityTools/graphs/contributors")
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
activity.startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(activity, "访问失败", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
})
|
||||
)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.third_party_open_source_statement,
|
||||
onClickListener = {
|
||||
try {
|
||||
val uri =
|
||||
Uri.parse("https://github.com/LittleTurtle2333/SimplicityTools#%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BC%80%E6%BA%90%E5%BC%95%E7%94%A8")
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
activity.startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(activity, "访问失败", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
})
|
||||
)
|
||||
Line()
|
||||
TitleText(text = getString(R.string.discussions))
|
||||
TextSummaryWithArrow(TextSummaryV(textId = R.string.qq_channel, onClickListener = {
|
||||
try {
|
||||
val uri =
|
||||
Uri.parse("https://qun.qq.com/qqweb/qunpro/share?_wv=3&_wwv=128&inviteCode=29Mu64&from=246610&biz=ka")
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
activity.startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(activity, "访问失败", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}))
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.tg_channel,
|
||||
tipsId = R.string.tg_channel_summary,
|
||||
onClickListener = {
|
||||
try {
|
||||
activity.startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse("tg://resolve?domain=simplicityrom")
|
||||
)
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(activity, "本机未安装Telegram应用", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
val uri = Uri.parse("https://t.me/simplicityrom")
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
activity.startActivity(intent)
|
||||
}
|
||||
})
|
||||
)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.issues,
|
||||
tipsId = R.string.issues_url,
|
||||
onClickListener = {
|
||||
try {
|
||||
val uri =
|
||||
Uri.parse("https://github.com/LittleTurtle2333/SimplicityTools/issues")
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
activity.startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(activity, "访问失败", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
})
|
||||
)
|
||||
Line()
|
||||
TitleText(getString(R.string.other))
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.app_coolapk_url,
|
||||
tipsId = R.string.app_coolapk_url_summary,
|
||||
onClickListener = {
|
||||
try {
|
||||
activity.startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse("coolmarket://apk/com.lt2333.simplicitytools")
|
||||
)
|
||||
)
|
||||
Toast.makeText(
|
||||
activity,
|
||||
"恳求一个五星好评,Thanks♪(・ω・)ノ",
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(activity, "本机未安装酷安应用", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
})
|
||||
)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.opensource,
|
||||
tipsId = R.string.github_url,
|
||||
onClickListener = {
|
||||
try {
|
||||
val uri =
|
||||
Uri.parse("https://github.com/LittleTurtle2333/SimplicityTools")
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
activity.startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(activity, "访问失败", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
})
|
||||
)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.participate_in_translation,
|
||||
tipsId = R.string.participate_in_translation_summary,
|
||||
onClickListener = {
|
||||
try {
|
||||
val uri = Uri.parse("https://crowdin.com/project/simplicitytools")
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
activity.startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(activity, "访问失败", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.lt2333.simplicitytools.activity.pages.all
|
||||
|
||||
import cn.fkj233.ui.activity.annotation.BMMenuPage
|
||||
import cn.fkj233.ui.activity.data.BasePage
|
||||
import cn.fkj233.ui.activity.view.TextSummaryV
|
||||
import cn.fkj233.ui.dialog.MIUIDialog
|
||||
import com.lt2333.simplicitytools.R
|
||||
import com.lt2333.simplicitytools.utils.ShellUtils
|
||||
import java.util.*
|
||||
|
||||
|
||||
@BMMenuPage("Menu")
|
||||
class MenuPage : BasePage() {
|
||||
|
||||
override fun onCreate() {
|
||||
TextSummaryWithArrow(TextSummaryV(textId = R.string.reboot, onClickListener = {
|
||||
MIUIDialog(activity) {
|
||||
setTitle(R.string.Tips)
|
||||
setMessage(R.string.are_you_sure_reboot)
|
||||
setLButton(R.string.cancel) {
|
||||
dismiss()
|
||||
}
|
||||
setRButton(R.string.Done) {
|
||||
val command = arrayOf("reboot")
|
||||
ShellUtils.execCommand(command, true)
|
||||
dismiss()
|
||||
}
|
||||
}.show()
|
||||
}))
|
||||
|
||||
TextSummaryWithArrow(TextSummaryV(textId = R.string.reboot_host, onClickListener = {
|
||||
MIUIDialog(activity) {
|
||||
setTitle(R.string.Tips)
|
||||
setMessage(R.string.are_you_sure_reboot_scope)
|
||||
setLButton(R.string.cancel) {
|
||||
dismiss()
|
||||
}
|
||||
setRButton(R.string.Done) {
|
||||
val command = arrayOf(
|
||||
"killall com.android.systemui",
|
||||
"killall com.miui.home",
|
||||
"killall com.miui.securitycenter ",
|
||||
"killall com.android.settings",
|
||||
"killall com.miui.powerkeeper",
|
||||
"killall com.android.updater",
|
||||
"killall com.miui.mediaeditor",
|
||||
"killall com.miui.screenshot",
|
||||
"killall com.milink.service",
|
||||
"killall com.xiaomi.misubscreenui",
|
||||
"killall com.miui.packageinstaller"
|
||||
)
|
||||
ShellUtils.execCommand(command, true)
|
||||
dismiss()
|
||||
}
|
||||
}.show()
|
||||
}))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package com.lt2333.simplicitytools.activity.pages.s
|
||||
|
||||
import android.view.View
|
||||
import android.widget.Switch
|
||||
import cn.fkj233.ui.activity.MIUIActivity
|
||||
import cn.fkj233.ui.activity.annotation.BMPage
|
||||
import cn.fkj233.ui.activity.data.BasePage
|
||||
import cn.fkj233.ui.activity.view.SwitchV
|
||||
import cn.fkj233.ui.activity.view.TextSummaryV
|
||||
import cn.fkj233.ui.dialog.MIUIDialog
|
||||
import com.lt2333.simplicitytools.R
|
||||
|
||||
|
||||
@BMPage("scope_android","Android", hideMenu = false)
|
||||
class AndroidPageForS : BasePage() {
|
||||
|
||||
override fun onCreate() {
|
||||
TitleText(textId = R.string.corepacth)
|
||||
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.downgr,
|
||||
tipsId = R.string.downgr_summary
|
||||
), SwitchV("downgrade")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.authcreak,
|
||||
tipsId = R.string.authcreak_summary
|
||||
), SwitchV("authcreak")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.digestCreak,
|
||||
tipsId = R.string.digestCreak_summary
|
||||
), SwitchV("digestCreak")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.UsePreSig,
|
||||
tipsId = R.string.UsePreSig_summary
|
||||
), SwitchV("UsePreSig")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.enhancedMode,
|
||||
tipsId = R.string.enhancedMode_summary
|
||||
), SwitchV("enhancedMode")
|
||||
)
|
||||
Line()
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.disable_flag_secure,
|
||||
tipsId = R.string.disable_flag_secure_summary
|
||||
), SwitchV("disable_flag_secure")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.delete_on_post_notification,
|
||||
tipsId = R.string.delete_on_post_notification_summary
|
||||
), SwitchV("delete_on_post_notification")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.remove_small_window_restrictions,
|
||||
tipsId = R.string.remove_small_window_restrictions_summary
|
||||
), SwitchV("remove_small_window_restrictions")
|
||||
)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.max_wallpaper_scale,
|
||||
onClickListener = {
|
||||
MIUIDialog(activity) {
|
||||
setTitle(R.string.max_wallpaper_scale)
|
||||
setEditText(
|
||||
"",
|
||||
"${activity.getString(R.string.def)}1.1, ${activity.getString(R.string.current)}${
|
||||
MIUIActivity.safeSP.getFloat("max_wallpaper_scale", 1.1f)
|
||||
}"
|
||||
)
|
||||
setLButton(textId = R.string.cancel) {
|
||||
dismiss()
|
||||
}
|
||||
setRButton(textId = R.string.Done) {
|
||||
if (getEditText() != "") {
|
||||
MIUIActivity.safeSP.putAny(
|
||||
"max_wallpaper_scale",
|
||||
getEditText().toFloat()
|
||||
)
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
}.show()
|
||||
})
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.allow_untrusted_touches,
|
||||
tipsId = R.string.take_effect_after_reboot
|
||||
), SwitchV("allow_untrusted_touches")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.sound)
|
||||
val mediaVolumeStepsSwitchBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"media_volume_steps_switch",
|
||||
false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.media_volume_steps_switch,
|
||||
tips = "${getString(R.string.take_effect_after_reboot)}\n${getString(R.string.media_volume_steps_summary)}"
|
||||
),
|
||||
SwitchV(
|
||||
"media_volume_steps_switch",
|
||||
dataBindingSend = mediaVolumeStepsSwitchBinding.bindingSend
|
||||
)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"media_volume_steps",
|
||||
15,
|
||||
29,
|
||||
15,
|
||||
dataBindingRecv = mediaVolumeStepsSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.lt2333.simplicitytools.activity.pages.s
|
||||
|
||||
import android.view.View
|
||||
import android.widget.Switch
|
||||
import cn.fkj233.ui.activity.MIUIActivity
|
||||
import cn.fkj233.ui.activity.annotation.BMPage
|
||||
import cn.fkj233.ui.activity.data.BasePage
|
||||
import cn.fkj233.ui.activity.view.SwitchV
|
||||
import cn.fkj233.ui.activity.view.TextSummaryV
|
||||
import cn.fkj233.ui.activity.view.TextV
|
||||
import cn.fkj233.ui.dialog.MIUIDialog
|
||||
import com.lt2333.simplicitytools.R
|
||||
|
||||
|
||||
@BMPage("hide_icon","Hide Icon", hideMenu = false)
|
||||
class HideIconPageForS : BasePage() {
|
||||
|
||||
override fun onCreate() {
|
||||
TitleText(textId = R.string.status_bar_icon)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_battery_icon),
|
||||
SwitchV("hide_battery_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_battery_charging_icon),
|
||||
SwitchV("hide_battery_charging_icon")
|
||||
)
|
||||
TextWithSwitch(TextV(textId = R.string.hide_gps_icon), SwitchV("hide_gps_icon"))
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_bluetooth_icon),
|
||||
SwitchV("hide_bluetooth_icon")
|
||||
)
|
||||
|
||||
TextWithSwitch(TextV(textId = R.string.hide_nfc_icon), SwitchV("hide_nfc_icon"))
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_bluetooth_battery_icon),
|
||||
SwitchV("hide_bluetooth_battery_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_small_hd_icon),
|
||||
SwitchV("hide_small_hd_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_big_hd_icon),
|
||||
SwitchV("hide_big_hd_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_new_hd_icon),
|
||||
SwitchV("hide_new_hd_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_hd_no_service_icon),
|
||||
SwitchV("hide_hd_no_service_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_no_sim_icon),
|
||||
SwitchV("hide_no_sim_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_sim_one_icon),
|
||||
SwitchV("hide_sim_one_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_sim_two_icon),
|
||||
SwitchV("hide_sim_two_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_mobile_activity_icon),
|
||||
SwitchV("hide_mobile_activity_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_mobile_type_icon),
|
||||
SwitchV("hide_mobile_type_icon")
|
||||
)
|
||||
TextWithSwitch(TextV(textId = R.string.hide_wifi_icon), SwitchV("hide_wifi_icon"))
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_wifi_activity_icon),
|
||||
SwitchV("hide_wifi_activity_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_wifi_standard_icon),
|
||||
SwitchV("hide_wifi_standard_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_slave_wifi_icon),
|
||||
SwitchV("hide_slave_wifi_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_hotspot_icon),
|
||||
SwitchV("hide_hotspot_icon")
|
||||
)
|
||||
TextWithSwitch(TextV(textId = R.string.hide_vpn_icon), SwitchV("hide_vpn_icon"))
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_airplane_icon),
|
||||
SwitchV("hide_airplane_icon")
|
||||
)
|
||||
TextWithSwitch(TextV(textId = R.string.hide_alarm_icon), SwitchV("hide_alarm_icon"))
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_headset_icon),
|
||||
SwitchV("hide_headset_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_volume_icon),
|
||||
SwitchV("hide_volume_icon")
|
||||
)
|
||||
TextWithSwitch(TextV(textId = R.string.hide_zen_icon), SwitchV("hide_zen_icon"))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.lt2333.simplicitytools.activity.pages.s
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.pm.PackageManager
|
||||
import cn.fkj233.ui.activity.annotation.BMMainPage
|
||||
import cn.fkj233.ui.activity.data.BasePage
|
||||
import cn.fkj233.ui.activity.view.SwitchV
|
||||
import cn.fkj233.ui.activity.view.TextSummaryV
|
||||
import cn.fkj233.ui.dialog.MIUIDialog
|
||||
import com.lt2333.simplicitytools.BuildConfig
|
||||
import com.lt2333.simplicitytools.R
|
||||
|
||||
|
||||
@BMMainPage("WooBox[MIUI13]")
|
||||
class MainPageForS : BasePage() {
|
||||
|
||||
override fun onCreate() {
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.main_switch,
|
||||
colorId = R.color.blue
|
||||
), SwitchV("main_switch", true)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.HideLauncherIcon),
|
||||
SwitchV("hLauncherIcon", onClickListener = {
|
||||
activity.packageManager.setComponentEnabledSetting(
|
||||
ComponentName(activity, "${BuildConfig.APPLICATION_ID}.launcher"),
|
||||
if (it) {
|
||||
PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|
||||
} else {
|
||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED
|
||||
},
|
||||
PackageManager.DONT_KILL_APP
|
||||
)
|
||||
})
|
||||
)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.matters_needing_attention,
|
||||
colorId = R.color.red,
|
||||
onClickListener = {
|
||||
MIUIDialog(activity) {
|
||||
setTitle(R.string.matters_needing_attention)
|
||||
setMessage(R.string.matters_needing_attention_context)
|
||||
setRButton(R.string.Done) {
|
||||
dismiss()
|
||||
}
|
||||
}.show()
|
||||
})
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.scope)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.scope_systemui,
|
||||
tipsId = R.string.scope_systemui_summary,
|
||||
onClickListener = { showFragment("scope_systemui") })
|
||||
)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.scope_android,
|
||||
tipsId = R.string.scope_android_summary,
|
||||
onClickListener = { showFragment("scope_android") })
|
||||
)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.scope_other,
|
||||
tipsId = R.string.scope_other_summary,
|
||||
onClickListener = { showFragment("scope_other") })
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.about)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.about_module,
|
||||
tips = getString(R.string.about_module_summary),
|
||||
onClickListener = { showFragment("about_module") })
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
package com.lt2333.simplicitytools.activity.pages.s
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.view.View
|
||||
import android.widget.Switch
|
||||
import android.widget.Toast
|
||||
import cn.fkj233.ui.activity.MIUIActivity
|
||||
import cn.fkj233.ui.activity.annotation.BMPage
|
||||
import cn.fkj233.ui.activity.data.BasePage
|
||||
import cn.fkj233.ui.activity.view.SwitchV
|
||||
import cn.fkj233.ui.activity.view.TextSummaryV
|
||||
import com.lt2333.simplicitytools.R
|
||||
|
||||
|
||||
@BMPage("scope_other", "Other", hideMenu = false)
|
||||
class OtherPageForS : BasePage() {
|
||||
|
||||
override fun onCreate() {
|
||||
TitleText(textId = R.string.scope_miuihome)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.home_time,
|
||||
tipsId = R.string.home_time_summary
|
||||
), SwitchV("home_time")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.double_tap_to_sleep,
|
||||
tipsId = R.string.home_double_tap_to_sleep_summary
|
||||
), SwitchV("double_tap_to_sleep")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.miuihome_recentwiew_wallpaper_darkening, tipsId = R.string.miuihome_recentwiew_wallpaper_darkening_summary
|
||||
), SwitchV("miuihome_recentwiew_wallpaper_darkening", false)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.miuihome_recentview_remove_card_animation, tipsId = R.string.miuihome_recentview_remove_card_animation_summary
|
||||
), SwitchV("miuihome_recentview_remove_card_animation", false)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.miuihome_shortcut_add_small_window, tipsId = R.string.miuihome_shortcut_add_small_window_summary),
|
||||
SwitchV("miuihome_shortcut_add_small_window", false)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.miuihome_scroll_icon_name, tipsId = R.string.miuihome_scroll_icon_name_summary),
|
||||
SwitchV("miuihome_scroll_icon_name", false)
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.scope_powerkeeper)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.lock_max_fps,
|
||||
tipsId = R.string.lock_max_fps_summary
|
||||
), SwitchV("lock_max_fps")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.prevent_recovery_of_battery_optimization_white_list,
|
||||
tipsId = R.string.failed_after_restart
|
||||
), SwitchV("prevent_recovery_of_battery_optimization_white_list")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.do_not_clear_app,
|
||||
tipsId = R.string.do_not_clear_app_summary
|
||||
), SwitchV("do_not_clear_app")
|
||||
)
|
||||
val makeMilletMoreAggressiveSwitchBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"make_millet_more_aggressive",
|
||||
false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.make_millet_more_aggressive,
|
||||
tipsId = R.string.make_millet_more_aggressive_summary
|
||||
),
|
||||
SwitchV(
|
||||
"make_millet_more_aggressive",
|
||||
dataBindingSend = makeMilletMoreAggressiveSwitchBinding.bindingSend
|
||||
)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.make_millet_ignore_active,
|
||||
tipsId = R.string.make_millet_ignore_active_summary
|
||||
),
|
||||
SwitchV("make_millet_ignore_active"),
|
||||
dataBindingRecv = makeMilletMoreAggressiveSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.battery_optimization,
|
||||
tipsId = R.string.battery_optimization_summary,
|
||||
onClickListener = {
|
||||
try {
|
||||
val intent = Intent()
|
||||
val comp = ComponentName(
|
||||
"com.android.settings",
|
||||
"com.android.settings.Settings\$HighPowerApplicationsActivity"
|
||||
)
|
||||
intent.component = comp
|
||||
activity.startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(activity, "启动失败,可能是不支持", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
})
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.scope_securitycenter)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.skip_waiting_time,
|
||||
tipsId = R.string.skip_waiting_time_summary
|
||||
), SwitchV("skip_waiting_time")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.remove_open_app_confirmation_popup,
|
||||
tipsId = R.string.remove_open_app_confirmation_popup_summary
|
||||
), SwitchV("remove_open_app_confirmation_popup")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.lock_one_hundred,
|
||||
tipsId = R.string.lock_one_hundred_summary
|
||||
), SwitchV("lock_one_hundred")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.remove_macro_blacklist),
|
||||
SwitchV("remove_macro_blacklist")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.battery_life_function),
|
||||
SwitchV("battery_life_function")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.scope_mediaeditor)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.unlock_unlimited_cropping,
|
||||
tipsId = R.string.unlock_unlimited_cropping_summary
|
||||
), SwitchV("unlock_unlimited_cropping")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.updater)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.remove_ota_validate,
|
||||
tipsId = R.string.remove_ota_validate_summary
|
||||
), SwitchV("remove_ota_validate")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.settings)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.show_notification_importance,
|
||||
tipsId = R.string.show_notification_importance_summary
|
||||
), SwitchV("show_notification_importance")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.cast)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.force_support_send_app,
|
||||
), SwitchV("force_support_send_app")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.rear_display)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.show_weather_main_switch,
|
||||
), SwitchV("rear_show_weather")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.remove_ad)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.remove_thememanager_ads),
|
||||
SwitchV("remove_thememanager_ads")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.pkg_installer)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.pkg_installer_summary),
|
||||
SwitchV("pkg_installer_count_checking")
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,740 @@
|
||||
package com.lt2333.simplicitytools.activity.pages.s
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.view.View
|
||||
import android.widget.Switch
|
||||
import android.widget.Toast
|
||||
import cn.fkj233.ui.activity.MIUIActivity
|
||||
import cn.fkj233.ui.activity.annotation.BMPage
|
||||
import cn.fkj233.ui.activity.data.BasePage
|
||||
import cn.fkj233.ui.activity.view.SpinnerV
|
||||
import cn.fkj233.ui.activity.view.SwitchV
|
||||
import cn.fkj233.ui.activity.view.TextSummaryV
|
||||
import cn.fkj233.ui.activity.view.TextV
|
||||
import cn.fkj233.ui.dialog.MIUIDialog
|
||||
import cn.fkj233.ui.dialog.NewDialog
|
||||
import com.lt2333.simplicitytools.R
|
||||
|
||||
|
||||
@BMPage("scope_systemui", "System UI", hideMenu = false)
|
||||
class SystemUIPageForS : BasePage() {
|
||||
|
||||
override fun onCreate() {
|
||||
TitleText(textId = R.string.statusbar)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.double_tap_to_sleep),
|
||||
SwitchV("status_bar_double_tap_to_sleep")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.status_bar_layout)
|
||||
val statusBarLayoutMode: HashMap<Int, String> = hashMapOf<Int, String>().also {
|
||||
it[0] = getString(R.string.default1)
|
||||
it[1] = getString(R.string.clock_center)
|
||||
it[2] = getString(R.string.clock_right)
|
||||
it[3] = getString(R.string.clock_center_and_icon_left)
|
||||
}
|
||||
TextWithSpinner(
|
||||
TextV(textId = R.string.status_bar_layout_mode),
|
||||
SpinnerV(
|
||||
statusBarLayoutMode[MIUIActivity.safeSP.getInt(
|
||||
"status_bar_layout_mode",
|
||||
0
|
||||
)].toString()
|
||||
) {
|
||||
add(statusBarLayoutMode[0].toString()) {
|
||||
MIUIActivity.safeSP.putAny("status_bar_layout_mode", 0)
|
||||
}
|
||||
add(statusBarLayoutMode[1].toString()) {
|
||||
MIUIActivity.safeSP.putAny("status_bar_layout_mode", 1)
|
||||
}
|
||||
add(statusBarLayoutMode[2].toString()) {
|
||||
MIUIActivity.safeSP.putAny("status_bar_layout_mode", 2)
|
||||
}
|
||||
add(statusBarLayoutMode[3].toString()) {
|
||||
MIUIActivity.safeSP.putAny("status_bar_layout_mode", 3)
|
||||
}
|
||||
})
|
||||
|
||||
val layoutCompatibilityBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"layout_compatibility_mode", false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.layout_compatibility_mode, tipsId = R.string.layout_compatibility_mode_summary
|
||||
), SwitchV("layout_compatibility_mode", dataBindingSend = layoutCompatibilityBinding.bindingSend)
|
||||
)
|
||||
|
||||
Text(
|
||||
textId = R.string.left_margin, dataBindingRecv = layoutCompatibilityBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"status_bar_left_margin", 0, 300, 0, dataBindingRecv = layoutCompatibilityBinding.binding.getRecv(2)
|
||||
)
|
||||
Text(
|
||||
textId = R.string.right_margin, dataBindingRecv = layoutCompatibilityBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"status_bar_right_margin", 0, 300, 0, dataBindingRecv = layoutCompatibilityBinding.binding.getRecv(2)
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.status_bar_clock_format)
|
||||
|
||||
|
||||
val customClockPresetBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getInt(
|
||||
"custom_clock_mode",
|
||||
0
|
||||
) == 1
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
val customClockGeekBinding =
|
||||
GetDataBinding({ MIUIActivity.safeSP.getInt("custom_clock_mode", 0) == 2 }
|
||||
|
||||
) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
val customClockMode: HashMap<Int, String> = hashMapOf<Int, String>().also {
|
||||
it[0] = getString(R.string.off)
|
||||
it[1] = getString(R.string.preset)
|
||||
it[2] = getString(R.string.geek)
|
||||
}
|
||||
TextWithSpinner(
|
||||
TextV(textId = R.string.custom_clock_mode),
|
||||
SpinnerV(customClockMode[MIUIActivity.safeSP.getInt("custom_clock_mode", 0)].toString()) {
|
||||
add(customClockMode[0].toString()) {
|
||||
MIUIActivity.safeSP.putAny("custom_clock_mode", 0)
|
||||
customClockPresetBinding.binding.Send().send(false)
|
||||
customClockGeekBinding.binding.Send().send(false)
|
||||
}
|
||||
add(customClockMode[1].toString()) {
|
||||
MIUIActivity.safeSP.putAny("custom_clock_mode", 1)
|
||||
customClockPresetBinding.binding.Send().send(true)
|
||||
customClockGeekBinding.binding.Send().send(false)
|
||||
}
|
||||
add(customClockMode[2].toString()) {
|
||||
MIUIActivity.safeSP.putAny("custom_clock_mode", 2)
|
||||
customClockPresetBinding.binding.Send().send(false)
|
||||
customClockGeekBinding.binding.Send().send(true)
|
||||
}
|
||||
})
|
||||
|
||||
//预设模式起始
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_year),
|
||||
SwitchV("status_bar_time_year"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_month),
|
||||
SwitchV("status_bar_time_month"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_day),
|
||||
SwitchV("status_bar_time_day"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_week),
|
||||
SwitchV("status_bar_time_week"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_double_hour),
|
||||
SwitchV("status_bar_time_double_hour"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_period),
|
||||
SwitchV("status_bar_time_period", true),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_seconds),
|
||||
SwitchV("status_bar_time_seconds"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_hide_space),
|
||||
SwitchV("status_bar_time_hide_space"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_double_line),
|
||||
SwitchV("status_bar_time_double_line"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_double_line_center_align),
|
||||
SwitchV("status_bar_time_double_line_center_align"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
Text(
|
||||
textId = R.string.status_bar_clock_size,
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"status_bar_clock_size",
|
||||
0,
|
||||
18,
|
||||
0,
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
Text(
|
||||
textId = R.string.status_bar_clock_double_line_size,
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"status_bar_clock_double_line_size",
|
||||
0,
|
||||
9,
|
||||
0,
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
//预设模式结束
|
||||
|
||||
//极客模式起始
|
||||
TextSummaryWithArrow(TextSummaryV(textId = R.string.custom_clock_format_geek) {
|
||||
NewDialog(activity) {
|
||||
setTitle(R.string.custom_clock_format_geek)
|
||||
setEditText(
|
||||
MIUIActivity.safeSP.getString("custom_clock_format_geek", "HH:mm:ss"), "", isSingleLine = false
|
||||
)
|
||||
Button(getString(R.string.click_to_view_use_cases)) {
|
||||
val locale = context.resources.configuration.locale
|
||||
val language = locale.language
|
||||
if (language.endsWith("zh")) {
|
||||
val uri = Uri.parse("https://zhuti.designer.xiaomi.com/docs/grammar/#%E6%97%B6%E9%97%B4%E6%97%A5%E6%9C%9F")
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
activity.startActivity(intent)
|
||||
} else {
|
||||
val uri = Uri.parse("https://docs.google.com/spreadsheets/d/1ghkT2iFbxB3bT4TKCiKAfmEdGt6kTVKFU3dm4Nz1or8/edit?usp=sharing")
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
activity.startActivity(intent)
|
||||
}
|
||||
}
|
||||
Button(getString(R.string.Done)) {
|
||||
if (getEditText().isNotEmpty()) {
|
||||
try {
|
||||
MIUIActivity.safeSP.putAny("custom_clock_format_geek", getEditText())
|
||||
dismiss()
|
||||
return@Button
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
}
|
||||
Toast.makeText(activity, R.string.input_error, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
Button(getString(R.string.cancel), cancelStyle = true) {
|
||||
dismiss()
|
||||
}
|
||||
}.show()
|
||||
}, dataBindingRecv = customClockGeekBinding.binding.getRecv(2))
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_double_line_center_align),
|
||||
SwitchV("status_bar_time_center_align_geek"),
|
||||
dataBindingRecv = customClockGeekBinding.binding.getRecv(2)
|
||||
)
|
||||
Text(
|
||||
textId = R.string.status_bar_clock_size,
|
||||
dataBindingRecv = customClockGeekBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"status_bar_clock_size_geek",
|
||||
0,
|
||||
18,
|
||||
0,
|
||||
dataBindingRecv = customClockGeekBinding.binding.getRecv(2)
|
||||
)
|
||||
//极客模式结束
|
||||
|
||||
|
||||
Line()
|
||||
TitleText(textId = R.string.status_bar_icon)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.hide_icon,
|
||||
onClickListener = { showFragment("hide_icon") })
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.show_wifi_standard),
|
||||
SwitchV("show_wifi_standard")
|
||||
)
|
||||
val customMobileTypeTextBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"custom_mobile_type_text_switch",
|
||||
false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.custom_mobile_type_text_switch),
|
||||
SwitchV(
|
||||
"custom_mobile_type_text_switch",
|
||||
dataBindingSend = customMobileTypeTextBinding.bindingSend
|
||||
)
|
||||
)
|
||||
TextSummaryWithArrow(TextSummaryV(textId = R.string.custom_mobile_type_text) {
|
||||
MIUIDialog(activity) {
|
||||
setTitle(R.string.custom_mobile_type_text)
|
||||
setEditText(MIUIActivity.safeSP.getString("custom_mobile_type_text", "5G"), "")
|
||||
setLButton(textId = R.string.cancel) {
|
||||
dismiss()
|
||||
}
|
||||
setRButton(textId = R.string.Done) {
|
||||
if (getEditText().isNotEmpty()) {
|
||||
try {
|
||||
MIUIActivity.safeSP.putAny("custom_mobile_type_text", getEditText())
|
||||
dismiss()
|
||||
return@setRButton
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
}
|
||||
Toast.makeText(activity, R.string.input_error, Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
}.show()
|
||||
}, dataBindingRecv = customMobileTypeTextBinding.binding.getRecv(2))
|
||||
val bigMobileTypeIconBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"big_mobile_type_icon",
|
||||
false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.big_mobile_type_icon),
|
||||
SwitchV(
|
||||
"big_mobile_type_icon",
|
||||
dataBindingSend = bigMobileTypeIconBinding.bindingSend
|
||||
)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.big_mobile_type_icon_bold),
|
||||
SwitchV("big_mobile_type_icon_bold", true),
|
||||
dataBindingRecv = bigMobileTypeIconBinding.binding.getRecv(2)
|
||||
)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.big_mobile_type_icon_size,
|
||||
onClickListener = {
|
||||
MIUIDialog(activity) {
|
||||
setTitle(R.string.big_mobile_type_icon_size)
|
||||
setEditText(
|
||||
"",
|
||||
"${activity.getString(R.string.def)}12.5, ${activity.getString(R.string.current)}${
|
||||
MIUIActivity.safeSP.getFloat("big_mobile_type_icon_size", 12.5f)
|
||||
}"
|
||||
)
|
||||
setLButton(textId = R.string.cancel) {
|
||||
dismiss()
|
||||
}
|
||||
setRButton(textId = R.string.Done) {
|
||||
if (getEditText() != "") {
|
||||
MIUIActivity.safeSP.putAny(
|
||||
"big_mobile_type_icon_size",
|
||||
getEditText().toFloat()
|
||||
)
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
}.show()
|
||||
}), dataBindingRecv = bigMobileTypeIconBinding.binding.getRecv(2)
|
||||
)
|
||||
TextSummaryWithArrow(TextSummaryV(textId = R.string.big_mobile_type_icon_up_and_down_position) {
|
||||
MIUIDialog(activity) {
|
||||
setTitle(R.string.big_mobile_type_icon_up_and_down_position)
|
||||
setMessage("${activity.getString(R.string.range)} -15~15")
|
||||
setEditText(
|
||||
"",
|
||||
"${activity.getString(R.string.def)}0, ${activity.getString(R.string.current)}${
|
||||
MIUIActivity.safeSP.getInt("big_mobile_type_icon_up_and_down_position", 0)
|
||||
}"
|
||||
)
|
||||
setLButton(textId = R.string.cancel) {
|
||||
dismiss()
|
||||
}
|
||||
setRButton(textId = R.string.Done) {
|
||||
if (getEditText().isNotEmpty()) {
|
||||
try {
|
||||
val value = getEditText().toInt()
|
||||
if (value in (-15..15)) {
|
||||
MIUIActivity.safeSP.putAny(
|
||||
"big_mobile_type_icon_up_and_down_position",
|
||||
value
|
||||
)
|
||||
dismiss()
|
||||
return@setRButton
|
||||
}
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
}
|
||||
Toast.makeText(activity, R.string.input_error, Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
}.show()
|
||||
}, dataBindingRecv = bigMobileTypeIconBinding.binding.getRecv(2))
|
||||
TextSummaryWithArrow(TextSummaryV(textId = R.string.big_mobile_type_icon_left_and_right_margins) {
|
||||
MIUIDialog(activity) {
|
||||
setTitle(R.string.big_mobile_type_icon_left_and_right_margins)
|
||||
setMessage("${activity.getString(R.string.range)} 0~30")
|
||||
setEditText(
|
||||
"",
|
||||
"${activity.getString(R.string.def)}0, ${activity.getString(R.string.current)}${
|
||||
MIUIActivity.safeSP.getInt("big_mobile_type_icon_left_and_right_margins", 0)
|
||||
}"
|
||||
)
|
||||
setLButton(textId = R.string.cancel) {
|
||||
dismiss()
|
||||
}
|
||||
setRButton(textId = R.string.Done) {
|
||||
if (getEditText().isNotEmpty()) {
|
||||
try {
|
||||
val value = getEditText().toInt()
|
||||
if (value in (0..30)) {
|
||||
MIUIActivity.safeSP.putAny(
|
||||
"big_mobile_type_icon_left_and_right_margins",
|
||||
value
|
||||
)
|
||||
dismiss()
|
||||
return@setRButton
|
||||
}
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
}
|
||||
Toast.makeText(activity, R.string.input_error, Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
}.show()
|
||||
}, dataBindingRecv = bigMobileTypeIconBinding.binding.getRecv(2))
|
||||
Text(textId = R.string.maximum_number_of_notification_icons)
|
||||
SeekBarWithText("maximum_number_of_notification_icons", 1, 30, 3)
|
||||
Text(textId = R.string.maximum_number_of_notification_dots)
|
||||
SeekBarWithText("maximum_number_of_notification_dots", 0, 4, 3)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.battery_percentage_font_size,
|
||||
onClickListener = {
|
||||
MIUIDialog(activity) {
|
||||
setTitle(R.string.battery_percentage_font_size)
|
||||
setMessage(R.string.zero_do_no_change)
|
||||
setEditText(
|
||||
"", "${activity.getString(R.string.current)}${
|
||||
MIUIActivity.safeSP.getFloat("battery_percentage_font_size", 0f)
|
||||
}"
|
||||
)
|
||||
setLButton(textId = R.string.cancel) {
|
||||
dismiss()
|
||||
}
|
||||
setRButton(textId = R.string.Done) {
|
||||
if (getEditText() != "") {
|
||||
MIUIActivity.safeSP.putAny(
|
||||
"battery_percentage_font_size",
|
||||
getEditText().toFloat()
|
||||
)
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
}.show()
|
||||
})
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.hide_battery_percentage_icon,
|
||||
tipsId = R.string.hide_battery_percentage_icon_summary
|
||||
), SwitchV("hide_battery_percentage_icon")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.status_bar_network_speed)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.status_bar_network_speed_refresh_speed,
|
||||
tipsId = R.string.status_bar_network_speed_refresh_speed_summary
|
||||
), SwitchV("status_bar_network_speed_refresh_speed")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.hide_status_bar_network_speed_second,
|
||||
tipsId = R.string.hide_status_bar_network_speed_second_summary
|
||||
), SwitchV("hide_status_bar_network_speed_second")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_network_speed_splitter),
|
||||
SwitchV("hide_network_speed_splitter")
|
||||
)
|
||||
val statusBarDualRowNetworkSpeedBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"status_bar_dual_row_network_speed",
|
||||
false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.status_bar_dual_row_network_speed,
|
||||
tipsId = R.string.status_bar_dual_row_network_speed_summary
|
||||
),
|
||||
SwitchV(
|
||||
"status_bar_dual_row_network_speed",
|
||||
dataBindingSend = statusBarDualRowNetworkSpeedBinding.bindingSend
|
||||
)
|
||||
)
|
||||
val align: HashMap<Int, String> = hashMapOf()
|
||||
align[0] = getString(R.string.left)
|
||||
align[1] = getString(R.string.right)
|
||||
TextWithSpinner(
|
||||
TextV(textId = R.string.status_bar_network_speed_dual_row_gravity),
|
||||
SpinnerV(
|
||||
align[MIUIActivity.safeSP.getInt(
|
||||
"status_bar_network_speed_dual_row_gravity",
|
||||
0
|
||||
)].toString()
|
||||
) {
|
||||
add(align[0].toString()) {
|
||||
MIUIActivity.safeSP.putAny("status_bar_network_speed_dual_row_gravity", 0)
|
||||
}
|
||||
add(align[1].toString()) {
|
||||
MIUIActivity.safeSP.putAny("status_bar_network_speed_dual_row_gravity", 1)
|
||||
|
||||
}
|
||||
},
|
||||
dataBindingRecv = statusBarDualRowNetworkSpeedBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSpinner(
|
||||
TextV(textId = R.string.status_bar_network_speed_dual_row_icon),
|
||||
SpinnerV(
|
||||
MIUIActivity.safeSP.getString(
|
||||
"status_bar_network_speed_dual_row_icon",
|
||||
getString(R.string.none)
|
||||
)
|
||||
) {
|
||||
add(getString(R.string.none)) {
|
||||
MIUIActivity.safeSP.putAny(
|
||||
"status_bar_network_speed_dual_row_icon",
|
||||
getString(R.string.none)
|
||||
)
|
||||
}
|
||||
add("▲▼") {
|
||||
MIUIActivity.safeSP.putAny("status_bar_network_speed_dual_row_icon", "▲▼")
|
||||
}
|
||||
add("△▽") {
|
||||
MIUIActivity.safeSP.putAny("status_bar_network_speed_dual_row_icon", "△▽")
|
||||
}
|
||||
add("↑↓") {
|
||||
MIUIActivity.safeSP.putAny("status_bar_network_speed_dual_row_icon", "↑↓")
|
||||
}
|
||||
})
|
||||
Text(
|
||||
textId = R.string.status_bar_network_speed_dual_row_size,
|
||||
dataBindingRecv = statusBarDualRowNetworkSpeedBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"status_bar_network_speed_dual_row_size",
|
||||
0,
|
||||
9,
|
||||
0,
|
||||
dataBindingRecv = statusBarDualRowNetworkSpeedBinding.binding.getRecv(2)
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.notification_center)
|
||||
val showWeatherMainSwitchBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"notification_weather",
|
||||
false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.show_weather_main_switch,
|
||||
colorId = R.color.blue
|
||||
),
|
||||
SwitchV(
|
||||
"notification_weather",
|
||||
dataBindingSend = showWeatherMainSwitchBinding.bindingSend
|
||||
)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.show_city,
|
||||
),
|
||||
SwitchV("notification_weather_city"),
|
||||
dataBindingRecv = showWeatherMainSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.can_notification_slide,
|
||||
tipsId = R.string.can_notification_slide_summary,
|
||||
),
|
||||
SwitchV("can_notification_slide"),
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.control_center)
|
||||
val controlCenterWeatherBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"control_center_weather",
|
||||
false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.show_weather_main_switch,
|
||||
colorId = R.color.blue,
|
||||
tipsId = R.string.control_center_weather_summary
|
||||
),
|
||||
SwitchV(
|
||||
"control_center_weather",
|
||||
dataBindingSend = controlCenterWeatherBinding.bindingSend
|
||||
)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.show_city,
|
||||
),
|
||||
SwitchV("control_center_weather_city"),
|
||||
dataBindingRecv = controlCenterWeatherBinding.binding.getRecv(2)
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.lock_screen)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.lock_screen_clock_display_seconds,
|
||||
tipsId = R.string.only_official_default_themes_are_supported
|
||||
), SwitchV("lock_screen_clock_display_seconds")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.remove_the_left_side_of_the_lock_screen,
|
||||
tipsId = R.string.only_official_default_themes_are_supported
|
||||
), SwitchV("remove_the_left_side_of_the_lock_screen")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.remove_lock_screen_camera,
|
||||
tipsId = R.string.only_official_default_themes_are_supported
|
||||
), SwitchV("remove_lock_screen_camera")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.enable_wave_charge_animation),
|
||||
SwitchV("enable_wave_charge_animation")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.lock_screen_charging_current,
|
||||
tipsId = R.string.only_official_default_themes_are_supported
|
||||
), SwitchV("lock_screen_charging_current")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.double_tap_to_sleep,
|
||||
tipsId = R.string.home_double_tap_to_sleep_summary
|
||||
), SwitchV("lock_screen_double_tap_to_sleep")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.old_quick_settings_panel)
|
||||
val oldQSCustomSwitchBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"old_qs_custom_switch",
|
||||
false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.old_qs_custom_switch,
|
||||
colorId = R.color.blue
|
||||
),
|
||||
SwitchV(
|
||||
"old_qs_custom_switch",
|
||||
dataBindingSend = oldQSCustomSwitchBinding.bindingSend
|
||||
)
|
||||
)
|
||||
Text(
|
||||
textId = R.string.qs_custom_rows,
|
||||
dataBindingRecv = oldQSCustomSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"qs_custom_rows",
|
||||
1,
|
||||
6,
|
||||
3,
|
||||
dataBindingRecv = oldQSCustomSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
Text(
|
||||
textId = R.string.qs_custom_rows_horizontal,
|
||||
dataBindingRecv = oldQSCustomSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"qs_custom_rows_horizontal",
|
||||
1,
|
||||
3,
|
||||
2,
|
||||
dataBindingRecv = oldQSCustomSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
Text(
|
||||
textId = R.string.qs_custom_columns,
|
||||
dataBindingRecv = oldQSCustomSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"qs_custom_columns",
|
||||
1,
|
||||
7,
|
||||
4,
|
||||
dataBindingRecv = oldQSCustomSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
Text(
|
||||
textId = R.string.qs_custom_columns_unexpanded,
|
||||
dataBindingRecv = oldQSCustomSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"qs_custom_columns_unexpanded",
|
||||
1,
|
||||
7,
|
||||
5,
|
||||
dataBindingRecv = oldQSCustomSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package com.lt2333.simplicitytools.activity.pages.t
|
||||
|
||||
import android.view.View
|
||||
import android.widget.Switch
|
||||
import cn.fkj233.ui.activity.MIUIActivity
|
||||
import cn.fkj233.ui.activity.annotation.BMPage
|
||||
import cn.fkj233.ui.activity.data.BasePage
|
||||
import cn.fkj233.ui.activity.view.SwitchV
|
||||
import cn.fkj233.ui.activity.view.TextSummaryV
|
||||
import cn.fkj233.ui.dialog.MIUIDialog
|
||||
import com.lt2333.simplicitytools.R
|
||||
|
||||
|
||||
@BMPage("scope_android","Android", hideMenu = false)
|
||||
class AndroidPageForT : BasePage() {
|
||||
|
||||
override fun onCreate() {
|
||||
TitleText(textId = R.string.corepacth)
|
||||
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.downgr,
|
||||
tipsId = R.string.downgr_summary
|
||||
), SwitchV("downgrade")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.authcreak,
|
||||
tipsId = R.string.authcreak_summary
|
||||
), SwitchV("authcreak")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.digestCreak,
|
||||
tipsId = R.string.digestCreak_summary
|
||||
), SwitchV("digestCreak")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.UsePreSig,
|
||||
tipsId = R.string.UsePreSig_summary
|
||||
), SwitchV("UsePreSig")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.enhancedMode,
|
||||
tipsId = R.string.enhancedMode_summary
|
||||
), SwitchV("enhancedMode")
|
||||
)
|
||||
Line()
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.disable_flag_secure,
|
||||
tipsId = R.string.disable_flag_secure_summary
|
||||
), SwitchV("disable_flag_secure")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.delete_on_post_notification,
|
||||
tipsId = R.string.delete_on_post_notification_summary
|
||||
), SwitchV("delete_on_post_notification")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.remove_small_window_restrictions,
|
||||
tipsId = R.string.remove_small_window_restrictions_summary
|
||||
), SwitchV("remove_small_window_restrictions")
|
||||
)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.max_wallpaper_scale,
|
||||
onClickListener = {
|
||||
MIUIDialog(activity) {
|
||||
setTitle(R.string.max_wallpaper_scale)
|
||||
setEditText(
|
||||
"",
|
||||
"${activity.getString(R.string.def)}1.2, ${activity.getString(R.string.current)}${
|
||||
MIUIActivity.safeSP.getFloat("max_wallpaper_scale", 1.2f)
|
||||
}"
|
||||
)
|
||||
setLButton(textId = R.string.cancel) {
|
||||
dismiss()
|
||||
}
|
||||
setRButton(textId = R.string.Done) {
|
||||
if (getEditText() != "") {
|
||||
MIUIActivity.safeSP.putAny(
|
||||
"max_wallpaper_scale",
|
||||
getEditText().toFloat()
|
||||
)
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
}.show()
|
||||
})
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.allow_untrusted_touches,
|
||||
tipsId = R.string.take_effect_after_reboot
|
||||
), SwitchV("allow_untrusted_touches")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.sound)
|
||||
val mediaVolumeStepsSwitchBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"media_volume_steps_switch",
|
||||
false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.media_volume_steps_switch,
|
||||
tips = "${getString(R.string.take_effect_after_reboot)}\n${getString(R.string.media_volume_steps_summary)}"
|
||||
),
|
||||
SwitchV(
|
||||
"media_volume_steps_switch",
|
||||
dataBindingSend = mediaVolumeStepsSwitchBinding.bindingSend
|
||||
)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"media_volume_steps",
|
||||
15,
|
||||
29,
|
||||
15,
|
||||
dataBindingRecv = mediaVolumeStepsSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.lt2333.simplicitytools.activity.pages.t
|
||||
|
||||
import android.view.View
|
||||
import android.widget.Switch
|
||||
import cn.fkj233.ui.activity.MIUIActivity
|
||||
import cn.fkj233.ui.activity.annotation.BMPage
|
||||
import cn.fkj233.ui.activity.data.BasePage
|
||||
import cn.fkj233.ui.activity.view.SwitchV
|
||||
import cn.fkj233.ui.activity.view.TextSummaryV
|
||||
import cn.fkj233.ui.activity.view.TextV
|
||||
import cn.fkj233.ui.dialog.MIUIDialog
|
||||
import com.lt2333.simplicitytools.R
|
||||
|
||||
|
||||
@BMPage("hide_icon","Hide Icon", hideMenu = false)
|
||||
class HideIconPageForT : BasePage() {
|
||||
|
||||
override fun onCreate() {
|
||||
TitleText(textId = R.string.status_bar_icon)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_battery_icon),
|
||||
SwitchV("hide_battery_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_battery_charging_icon),
|
||||
SwitchV("hide_battery_charging_icon")
|
||||
)
|
||||
TextWithSwitch(TextV(textId = R.string.hide_gps_icon), SwitchV("hide_gps_icon"))
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_bluetooth_icon),
|
||||
SwitchV("hide_bluetooth_icon")
|
||||
)
|
||||
|
||||
TextWithSwitch(TextV(textId = R.string.hide_nfc_icon), SwitchV("hide_nfc_icon"))
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_bluetooth_battery_icon),
|
||||
SwitchV("hide_bluetooth_battery_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_small_hd_icon),
|
||||
SwitchV("hide_small_hd_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_big_hd_icon),
|
||||
SwitchV("hide_big_hd_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_new_hd_icon),
|
||||
SwitchV("hide_new_hd_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_hd_no_service_icon),
|
||||
SwitchV("hide_hd_no_service_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_no_sim_icon),
|
||||
SwitchV("hide_no_sim_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_sim_one_icon),
|
||||
SwitchV("hide_sim_one_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_sim_two_icon),
|
||||
SwitchV("hide_sim_two_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_mobile_activity_icon),
|
||||
SwitchV("hide_mobile_activity_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_mobile_type_icon),
|
||||
SwitchV("hide_mobile_type_icon")
|
||||
)
|
||||
TextWithSwitch(TextV(textId = R.string.hide_wifi_icon), SwitchV("hide_wifi_icon"))
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_wifi_activity_icon),
|
||||
SwitchV("hide_wifi_activity_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_wifi_standard_icon),
|
||||
SwitchV("hide_wifi_standard_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_slave_wifi_icon),
|
||||
SwitchV("hide_slave_wifi_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_hotspot_icon),
|
||||
SwitchV("hide_hotspot_icon")
|
||||
)
|
||||
TextWithSwitch(TextV(textId = R.string.hide_vpn_icon), SwitchV("hide_vpn_icon"))
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_airplane_icon),
|
||||
SwitchV("hide_airplane_icon")
|
||||
)
|
||||
TextWithSwitch(TextV(textId = R.string.hide_alarm_icon), SwitchV("hide_alarm_icon"))
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_headset_icon),
|
||||
SwitchV("hide_headset_icon")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_volume_icon),
|
||||
SwitchV("hide_volume_icon")
|
||||
)
|
||||
TextWithSwitch(TextV(textId = R.string.hide_zen_icon), SwitchV("hide_zen_icon"))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.lt2333.simplicitytools.activity.pages.t
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.pm.PackageManager
|
||||
import cn.fkj233.ui.activity.annotation.BMMainPage
|
||||
import cn.fkj233.ui.activity.data.BasePage
|
||||
import cn.fkj233.ui.activity.view.SwitchV
|
||||
import cn.fkj233.ui.activity.view.TextSummaryV
|
||||
import cn.fkj233.ui.dialog.MIUIDialog
|
||||
import com.lt2333.simplicitytools.BuildConfig
|
||||
import com.lt2333.simplicitytools.R
|
||||
|
||||
|
||||
@BMMainPage("WooBox[MIUI14]")
|
||||
class MainPageForT : BasePage() {
|
||||
|
||||
override fun onCreate() {
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.main_switch,
|
||||
colorId = R.color.blue
|
||||
), SwitchV("main_switch", true)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.HideLauncherIcon),
|
||||
SwitchV("hLauncherIcon", onClickListener = {
|
||||
activity.packageManager.setComponentEnabledSetting(
|
||||
ComponentName(activity, "${BuildConfig.APPLICATION_ID}.launcher"),
|
||||
if (it) {
|
||||
PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|
||||
} else {
|
||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED
|
||||
},
|
||||
PackageManager.DONT_KILL_APP
|
||||
)
|
||||
})
|
||||
)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.matters_needing_attention,
|
||||
colorId = R.color.red,
|
||||
onClickListener = {
|
||||
MIUIDialog(activity) {
|
||||
setTitle(R.string.matters_needing_attention)
|
||||
setMessage(R.string.matters_needing_attention_context)
|
||||
setRButton(R.string.Done) {
|
||||
dismiss()
|
||||
}
|
||||
}.show()
|
||||
})
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.scope)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.scope_systemui,
|
||||
tipsId = R.string.scope_systemui_summary,
|
||||
onClickListener = { showFragment("scope_systemui") })
|
||||
)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.scope_android,
|
||||
tipsId = R.string.scope_android_summary,
|
||||
onClickListener = { showFragment("scope_android") })
|
||||
)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.scope_other,
|
||||
tipsId = R.string.scope_other_summary,
|
||||
onClickListener = { showFragment("scope_other") })
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.about)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.about_module,
|
||||
tips = getString(R.string.about_module_summary),
|
||||
onClickListener = { showFragment("about_module") })
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
package com.lt2333.simplicitytools.activity.pages.t
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.view.View
|
||||
import android.widget.Switch
|
||||
import android.widget.Toast
|
||||
import cn.fkj233.ui.activity.MIUIActivity
|
||||
import cn.fkj233.ui.activity.annotation.BMPage
|
||||
import cn.fkj233.ui.activity.data.BasePage
|
||||
import cn.fkj233.ui.activity.view.SwitchV
|
||||
import cn.fkj233.ui.activity.view.TextSummaryV
|
||||
import com.lt2333.simplicitytools.R
|
||||
|
||||
|
||||
@BMPage("scope_other", "Other", hideMenu = false)
|
||||
class OtherPageForT : BasePage() {
|
||||
|
||||
override fun onCreate() {
|
||||
TitleText(textId = R.string.scope_miuihome)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.home_time,
|
||||
tipsId = R.string.home_time_summary
|
||||
), SwitchV("home_time")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.double_tap_to_sleep,
|
||||
tipsId = R.string.home_double_tap_to_sleep_summary
|
||||
), SwitchV("double_tap_to_sleep")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.miuihome_recentwiew_wallpaper_darkening, tipsId = R.string.miuihome_recentwiew_wallpaper_darkening_summary
|
||||
), SwitchV("miuihome_recentwiew_wallpaper_darkening", false)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.miuihome_recentview_remove_card_animation, tipsId = R.string.miuihome_recentview_remove_card_animation_summary
|
||||
), SwitchV("miuihome_recentview_remove_card_animation", false)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.miuihome_shortcut_add_small_window, tipsId = R.string.miuihome_shortcut_add_small_window_summary),
|
||||
SwitchV("miuihome_shortcut_add_small_window", false)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.miuihome_scroll_icon_name, tipsId = R.string.miuihome_scroll_icon_name_summary),
|
||||
SwitchV("miuihome_scroll_icon_name", false)
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.scope_powerkeeper)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.lock_max_fps,
|
||||
tipsId = R.string.lock_max_fps_summary
|
||||
), SwitchV("lock_max_fps")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.prevent_recovery_of_battery_optimization_white_list,
|
||||
tipsId = R.string.failed_after_restart
|
||||
), SwitchV("prevent_recovery_of_battery_optimization_white_list")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.do_not_clear_app,
|
||||
tipsId = R.string.do_not_clear_app_summary
|
||||
), SwitchV("do_not_clear_app")
|
||||
)
|
||||
val makeMilletMoreAggressiveSwitchBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"make_millet_more_aggressive",
|
||||
false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.make_millet_more_aggressive,
|
||||
tipsId = R.string.make_millet_more_aggressive_summary
|
||||
),
|
||||
SwitchV(
|
||||
"make_millet_more_aggressive",
|
||||
dataBindingSend = makeMilletMoreAggressiveSwitchBinding.bindingSend
|
||||
)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.make_millet_ignore_active,
|
||||
tipsId = R.string.make_millet_ignore_active_summary
|
||||
),
|
||||
SwitchV("make_millet_ignore_active"),
|
||||
dataBindingRecv = makeMilletMoreAggressiveSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(
|
||||
textId = R.string.battery_optimization,
|
||||
tipsId = R.string.battery_optimization_summary,
|
||||
onClickListener = {
|
||||
try {
|
||||
val intent = Intent()
|
||||
val comp = ComponentName(
|
||||
"com.android.settings",
|
||||
"com.android.settings.Settings\$HighPowerApplicationsActivity"
|
||||
)
|
||||
intent.component = comp
|
||||
activity.startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(activity, "启动失败,可能是不支持", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
})
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.scope_securitycenter)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.skip_waiting_time,
|
||||
tipsId = R.string.skip_waiting_time_summary
|
||||
), SwitchV("skip_waiting_time")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.remove_open_app_confirmation_popup,
|
||||
tipsId = R.string.remove_open_app_confirmation_popup_summary
|
||||
), SwitchV("remove_open_app_confirmation_popup")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.lock_one_hundred,
|
||||
tipsId = R.string.lock_one_hundred_summary
|
||||
), SwitchV("lock_one_hundred")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.remove_macro_blacklist),
|
||||
SwitchV("remove_macro_blacklist")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.battery_life_function),
|
||||
SwitchV("battery_life_function")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.scope_mediaeditor)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.unlock_unlimited_cropping,
|
||||
tipsId = R.string.unlock_unlimited_cropping_summary
|
||||
), SwitchV("unlock_unlimited_cropping")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.updater)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.remove_ota_validate,
|
||||
tipsId = R.string.remove_ota_validate_summary
|
||||
), SwitchV("remove_ota_validate")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.settings)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.show_notification_importance,
|
||||
tipsId = R.string.show_notification_importance_summary
|
||||
), SwitchV("show_notification_importance")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.cast)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.force_support_send_app,
|
||||
), SwitchV("force_support_send_app")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.rear_display)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.show_weather_main_switch,
|
||||
), SwitchV("rear_show_weather")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.remove_ad)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.remove_thememanager_ads),
|
||||
SwitchV("remove_thememanager_ads")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.pkg_installer)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.pkg_installer_summary),
|
||||
SwitchV("pkg_installer_count_checking")
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,680 @@
|
||||
package com.lt2333.simplicitytools.activity.pages.t
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.view.View
|
||||
import android.widget.Switch
|
||||
import android.widget.Toast
|
||||
import cn.fkj233.ui.activity.MIUIActivity
|
||||
import cn.fkj233.ui.activity.annotation.BMPage
|
||||
import cn.fkj233.ui.activity.data.BasePage
|
||||
import cn.fkj233.ui.activity.view.SpinnerV
|
||||
import cn.fkj233.ui.activity.view.SwitchV
|
||||
import cn.fkj233.ui.activity.view.TextSummaryV
|
||||
import cn.fkj233.ui.activity.view.TextV
|
||||
import cn.fkj233.ui.dialog.MIUIDialog
|
||||
import cn.fkj233.ui.dialog.NewDialog
|
||||
import com.lt2333.simplicitytools.R
|
||||
|
||||
|
||||
@BMPage("scope_systemui", "System UI", hideMenu = false) class SystemUIPageForT : BasePage() {
|
||||
|
||||
override fun onCreate() {
|
||||
TitleText(textId = R.string.statusbar)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.double_tap_to_sleep), SwitchV("status_bar_double_tap_to_sleep")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.status_bar_layout)
|
||||
val statusBarLayoutMode: HashMap<Int, String> = hashMapOf<Int, String>().also {
|
||||
it[0] = getString(R.string.default1)
|
||||
it[1] = getString(R.string.clock_center)
|
||||
it[2] = getString(R.string.clock_right)
|
||||
it[3] = getString(R.string.clock_center_and_icon_left)
|
||||
}
|
||||
TextWithSpinner(TextV(textId = R.string.status_bar_layout_mode), SpinnerV(
|
||||
statusBarLayoutMode[MIUIActivity.safeSP.getInt(
|
||||
"status_bar_layout_mode", 0
|
||||
)].toString()
|
||||
) {
|
||||
add(statusBarLayoutMode[0].toString()) {
|
||||
MIUIActivity.safeSP.putAny("status_bar_layout_mode", 0)
|
||||
}
|
||||
add(statusBarLayoutMode[1].toString()) {
|
||||
MIUIActivity.safeSP.putAny("status_bar_layout_mode", 1)
|
||||
}
|
||||
add(statusBarLayoutMode[2].toString()) {
|
||||
MIUIActivity.safeSP.putAny("status_bar_layout_mode", 2)
|
||||
}
|
||||
add(statusBarLayoutMode[3].toString()) {
|
||||
MIUIActivity.safeSP.putAny("status_bar_layout_mode", 3)
|
||||
}
|
||||
})
|
||||
|
||||
val layoutCompatibilityBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"layout_compatibility_mode", false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.layout_compatibility_mode, tipsId = R.string.layout_compatibility_mode_summary
|
||||
), SwitchV("layout_compatibility_mode", dataBindingSend = layoutCompatibilityBinding.bindingSend)
|
||||
)
|
||||
|
||||
Text(
|
||||
textId = R.string.left_margin, dataBindingRecv = layoutCompatibilityBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"status_bar_left_margin", 0, 300, 0, dataBindingRecv = layoutCompatibilityBinding.binding.getRecv(2)
|
||||
)
|
||||
Text(
|
||||
textId = R.string.right_margin, dataBindingRecv = layoutCompatibilityBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"status_bar_right_margin", 0, 300, 0, dataBindingRecv = layoutCompatibilityBinding.binding.getRecv(2)
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.status_bar_clock_format)
|
||||
|
||||
|
||||
val customClockPresetBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getInt(
|
||||
"custom_clock_mode", 0
|
||||
) == 1
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
val customClockGeekBinding = GetDataBinding({ MIUIActivity.safeSP.getInt("custom_clock_mode", 0) == 2 }
|
||||
|
||||
) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
val customClockMode: HashMap<Int, String> = hashMapOf<Int, String>().also {
|
||||
it[0] = getString(R.string.off)
|
||||
it[1] = getString(R.string.preset)
|
||||
it[2] = getString(R.string.geek)
|
||||
}
|
||||
TextWithSpinner(TextV(textId = R.string.custom_clock_mode), SpinnerV(
|
||||
customClockMode[MIUIActivity.safeSP.getInt(
|
||||
"custom_clock_mode", 0
|
||||
)].toString()
|
||||
) {
|
||||
add(customClockMode[0].toString()) {
|
||||
MIUIActivity.safeSP.putAny("custom_clock_mode", 0)
|
||||
customClockPresetBinding.binding.Send().send(false)
|
||||
customClockGeekBinding.binding.Send().send(false)
|
||||
}
|
||||
add(customClockMode[1].toString()) {
|
||||
MIUIActivity.safeSP.putAny("custom_clock_mode", 1)
|
||||
customClockPresetBinding.binding.Send().send(true)
|
||||
customClockGeekBinding.binding.Send().send(false)
|
||||
}
|
||||
add(customClockMode[2].toString()) {
|
||||
MIUIActivity.safeSP.putAny("custom_clock_mode", 2)
|
||||
customClockPresetBinding.binding.Send().send(false)
|
||||
customClockGeekBinding.binding.Send().send(true)
|
||||
}
|
||||
})
|
||||
|
||||
//预设模式起始
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_year),
|
||||
SwitchV("status_bar_time_year"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_month),
|
||||
SwitchV("status_bar_time_month"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_day),
|
||||
SwitchV("status_bar_time_day"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_week),
|
||||
SwitchV("status_bar_time_week"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_double_hour),
|
||||
SwitchV("status_bar_time_double_hour"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_period),
|
||||
SwitchV("status_bar_time_period", true),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_seconds),
|
||||
SwitchV("status_bar_time_seconds"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_hide_space),
|
||||
SwitchV("status_bar_time_hide_space"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_double_line),
|
||||
SwitchV("status_bar_time_double_line"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_double_line_center_align),
|
||||
SwitchV("status_bar_time_double_line_center_align"),
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
Text(
|
||||
textId = R.string.status_bar_clock_size, dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"status_bar_clock_size", 0, 18, 0, dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
Text(
|
||||
textId = R.string.status_bar_clock_double_line_size,
|
||||
dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"status_bar_clock_double_line_size", 0, 9, 0, dataBindingRecv = customClockPresetBinding.binding.getRecv(2)
|
||||
)
|
||||
//预设模式结束
|
||||
|
||||
//极客模式起始
|
||||
TextSummaryWithArrow(TextSummaryV(textId = R.string.custom_clock_format_geek) {
|
||||
NewDialog(activity) {
|
||||
setTitle(R.string.custom_clock_format_geek)
|
||||
setEditText(
|
||||
MIUIActivity.safeSP.getString("custom_clock_format_geek", "HH:mm:ss"), "", isSingleLine = false
|
||||
)
|
||||
Button(getString(R.string.click_to_view_use_cases)) {
|
||||
val locale = context.resources.configuration.locale
|
||||
val language = locale.language
|
||||
if (language.endsWith("zh")) {
|
||||
val uri = Uri.parse("https://zhuti.designer.xiaomi.com/docs/grammar/#%E6%97%B6%E9%97%B4%E6%97%A5%E6%9C%9F")
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
activity.startActivity(intent)
|
||||
} else {
|
||||
val uri = Uri.parse("https://docs.google.com/spreadsheets/d/1ghkT2iFbxB3bT4TKCiKAfmEdGt6kTVKFU3dm4Nz1or8/edit?usp=sharing")
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
activity.startActivity(intent)
|
||||
}
|
||||
}
|
||||
Button(getString(R.string.Done)) {
|
||||
if (getEditText().isNotEmpty()) {
|
||||
try {
|
||||
MIUIActivity.safeSP.putAny("custom_clock_format_geek", getEditText())
|
||||
dismiss()
|
||||
return@Button
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
}
|
||||
Toast.makeText(activity, R.string.input_error, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
Button(getString(R.string.cancel), cancelStyle = true) {
|
||||
dismiss()
|
||||
}
|
||||
}.show()
|
||||
}, dataBindingRecv = customClockGeekBinding.binding.getRecv(2))
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.status_bar_time_double_line_center_align),
|
||||
SwitchV("status_bar_time_center_align_geek"),
|
||||
dataBindingRecv = customClockGeekBinding.binding.getRecv(2)
|
||||
)
|
||||
Text(
|
||||
textId = R.string.status_bar_clock_size, dataBindingRecv = customClockGeekBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"status_bar_clock_size_geek", 0, 18, 0, dataBindingRecv = customClockGeekBinding.binding.getRecv(2)
|
||||
)
|
||||
//极客模式结束
|
||||
|
||||
|
||||
Line()
|
||||
TitleText(textId = R.string.status_bar_icon)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(textId = R.string.hide_icon, onClickListener = { showFragment("hide_icon") })
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.show_wifi_standard), SwitchV("show_wifi_standard")
|
||||
)
|
||||
val customMobileTypeTextBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"custom_mobile_type_text_switch", false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.custom_mobile_type_text_switch), SwitchV(
|
||||
"custom_mobile_type_text_switch", dataBindingSend = customMobileTypeTextBinding.bindingSend
|
||||
)
|
||||
)
|
||||
TextSummaryWithArrow(TextSummaryV(textId = R.string.custom_mobile_type_text) {
|
||||
MIUIDialog(activity) {
|
||||
setTitle(R.string.custom_mobile_type_text)
|
||||
setEditText(MIUIActivity.safeSP.getString("custom_mobile_type_text", "5G"), "")
|
||||
setLButton(textId = R.string.cancel) {
|
||||
dismiss()
|
||||
}
|
||||
setRButton(textId = R.string.Done) {
|
||||
if (getEditText().isNotEmpty()) {
|
||||
try {
|
||||
MIUIActivity.safeSP.putAny("custom_mobile_type_text", getEditText())
|
||||
dismiss()
|
||||
return@setRButton
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
}
|
||||
Toast.makeText(activity, R.string.input_error, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}.show()
|
||||
}, dataBindingRecv = customMobileTypeTextBinding.binding.getRecv(2))
|
||||
val bigMobileTypeIconBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"big_mobile_type_icon", false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.big_mobile_type_icon), SwitchV(
|
||||
"big_mobile_type_icon", dataBindingSend = bigMobileTypeIconBinding.bindingSend
|
||||
)
|
||||
)
|
||||
val bigMobileTypeLocation: HashMap<Int, String> = hashMapOf<Int, String>().also {
|
||||
it[0] = getString(R.string.left)
|
||||
it[1] = getString(R.string.right)
|
||||
}
|
||||
TextWithSpinner(
|
||||
TextV(textId = R.string.big_mobile_type_location), SpinnerV(
|
||||
bigMobileTypeLocation[MIUIActivity.safeSP.getInt(
|
||||
"big_mobile_type_location", 1
|
||||
)].toString()
|
||||
) {
|
||||
add(bigMobileTypeLocation[0].toString()) {
|
||||
MIUIActivity.safeSP.putAny("big_mobile_type_location", 0)
|
||||
}
|
||||
add(bigMobileTypeLocation[1].toString()) {
|
||||
MIUIActivity.safeSP.putAny("big_mobile_type_location", 1)
|
||||
}
|
||||
}, dataBindingRecv = bigMobileTypeIconBinding.binding.getRecv(2)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.big_mobile_type_only_show_network_card),
|
||||
SwitchV("big_mobile_type_only_show_network_card", false),
|
||||
dataBindingRecv = bigMobileTypeIconBinding.binding.getRecv(2)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.big_mobile_type_icon_bold),
|
||||
SwitchV("big_mobile_type_icon_bold", true),
|
||||
dataBindingRecv = bigMobileTypeIconBinding.binding.getRecv(2)
|
||||
)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(textId = R.string.big_mobile_type_icon_size, onClickListener = {
|
||||
MIUIDialog(activity) {
|
||||
setTitle(R.string.big_mobile_type_icon_size)
|
||||
setEditText(
|
||||
"", "${activity.getString(R.string.def)}12.5, ${activity.getString(R.string.current)}${
|
||||
MIUIActivity.safeSP.getFloat("big_mobile_type_icon_size", 12.5f)
|
||||
}"
|
||||
)
|
||||
setLButton(textId = R.string.cancel) {
|
||||
dismiss()
|
||||
}
|
||||
setRButton(textId = R.string.Done) {
|
||||
if (getEditText() != "") {
|
||||
MIUIActivity.safeSP.putAny(
|
||||
"big_mobile_type_icon_size", getEditText().toFloat()
|
||||
)
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
}.show()
|
||||
}), dataBindingRecv = bigMobileTypeIconBinding.binding.getRecv(2)
|
||||
)
|
||||
TextSummaryWithArrow(TextSummaryV(textId = R.string.big_mobile_type_icon_up_and_down_position) {
|
||||
MIUIDialog(activity) {
|
||||
setTitle(R.string.big_mobile_type_icon_up_and_down_position)
|
||||
setMessage("${activity.getString(R.string.range)} -15~15")
|
||||
setEditText(
|
||||
"", "${activity.getString(R.string.def)}0, ${activity.getString(R.string.current)}${
|
||||
MIUIActivity.safeSP.getInt("big_mobile_type_icon_up_and_down_position", 0)
|
||||
}"
|
||||
)
|
||||
setLButton(textId = R.string.cancel) {
|
||||
dismiss()
|
||||
}
|
||||
setRButton(textId = R.string.Done) {
|
||||
if (getEditText().isNotEmpty()) {
|
||||
try {
|
||||
val value = getEditText().toInt()
|
||||
if (value in (-15..15)) {
|
||||
MIUIActivity.safeSP.putAny(
|
||||
"big_mobile_type_icon_up_and_down_position", value
|
||||
)
|
||||
dismiss()
|
||||
return@setRButton
|
||||
}
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
}
|
||||
Toast.makeText(activity, R.string.input_error, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}.show()
|
||||
}, dataBindingRecv = bigMobileTypeIconBinding.binding.getRecv(2))
|
||||
TextSummaryWithArrow(TextSummaryV(textId = R.string.big_mobile_type_icon_left_and_right_margins) {
|
||||
MIUIDialog(activity) {
|
||||
setTitle(R.string.big_mobile_type_icon_left_and_right_margins)
|
||||
setMessage("${activity.getString(R.string.range)} 0~30")
|
||||
setEditText(
|
||||
"", "${activity.getString(R.string.def)}0, ${activity.getString(R.string.current)}${
|
||||
MIUIActivity.safeSP.getInt("big_mobile_type_icon_left_and_right_margins", 0)
|
||||
}"
|
||||
)
|
||||
setLButton(textId = R.string.cancel) {
|
||||
dismiss()
|
||||
}
|
||||
setRButton(textId = R.string.Done) {
|
||||
if (getEditText().isNotEmpty()) {
|
||||
try {
|
||||
val value = getEditText().toInt()
|
||||
if (value in (0..30)) {
|
||||
MIUIActivity.safeSP.putAny(
|
||||
"big_mobile_type_icon_left_and_right_margins", value
|
||||
)
|
||||
dismiss()
|
||||
return@setRButton
|
||||
}
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
}
|
||||
Toast.makeText(activity, R.string.input_error, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}.show()
|
||||
}, dataBindingRecv = bigMobileTypeIconBinding.binding.getRecv(2))
|
||||
Text(textId = R.string.maximum_number_of_notification_icons)
|
||||
SeekBarWithText("maximum_number_of_notification_icons", 1, 30, 3)
|
||||
Text(textId = R.string.maximum_number_of_notification_dots)
|
||||
SeekBarWithText("maximum_number_of_notification_dots", 0, 4, 3)
|
||||
TextSummaryWithArrow(
|
||||
TextSummaryV(textId = R.string.battery_percentage_font_size, onClickListener = {
|
||||
MIUIDialog(activity) {
|
||||
setTitle(R.string.battery_percentage_font_size)
|
||||
setMessage(R.string.zero_do_no_change)
|
||||
setEditText(
|
||||
"", "${activity.getString(R.string.current)}${
|
||||
MIUIActivity.safeSP.getFloat("battery_percentage_font_size", 0f)
|
||||
}"
|
||||
)
|
||||
setLButton(textId = R.string.cancel) {
|
||||
dismiss()
|
||||
}
|
||||
setRButton(textId = R.string.Done) {
|
||||
if (getEditText() != "") {
|
||||
MIUIActivity.safeSP.putAny(
|
||||
"battery_percentage_font_size", getEditText().toFloat()
|
||||
)
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
}.show()
|
||||
})
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.hide_battery_percentage_icon, tipsId = R.string.hide_battery_percentage_icon_summary
|
||||
), SwitchV("hide_battery_percentage_icon")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.status_bar_network_speed)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.status_bar_network_speed_refresh_speed,
|
||||
tipsId = R.string.status_bar_network_speed_refresh_speed_summary
|
||||
), SwitchV("status_bar_network_speed_refresh_speed")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.hide_status_bar_network_speed_second,
|
||||
tipsId = R.string.hide_status_bar_network_speed_second_summary
|
||||
), SwitchV("hide_status_bar_network_speed_second")
|
||||
)
|
||||
TextWithSwitch(
|
||||
TextV(textId = R.string.hide_network_speed_splitter), SwitchV("hide_network_speed_splitter")
|
||||
)
|
||||
val statusBarDualRowNetworkSpeedBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"status_bar_dual_row_network_speed", false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.status_bar_dual_row_network_speed,
|
||||
tipsId = R.string.status_bar_dual_row_network_speed_summary
|
||||
), SwitchV(
|
||||
"status_bar_dual_row_network_speed", dataBindingSend = statusBarDualRowNetworkSpeedBinding.bindingSend
|
||||
)
|
||||
)
|
||||
val align: HashMap<Int, String> = hashMapOf()
|
||||
align[0] = getString(R.string.left)
|
||||
align[1] = getString(R.string.right)
|
||||
TextWithSpinner(
|
||||
TextV(textId = R.string.status_bar_network_speed_dual_row_gravity), SpinnerV(
|
||||
align[MIUIActivity.safeSP.getInt(
|
||||
"status_bar_network_speed_dual_row_gravity", 0
|
||||
)].toString()
|
||||
) {
|
||||
add(align[0].toString()) {
|
||||
MIUIActivity.safeSP.putAny("status_bar_network_speed_dual_row_gravity", 0)
|
||||
}
|
||||
add(align[1].toString()) {
|
||||
MIUIActivity.safeSP.putAny("status_bar_network_speed_dual_row_gravity", 1)
|
||||
|
||||
}
|
||||
}, dataBindingRecv = statusBarDualRowNetworkSpeedBinding.binding.getRecv(2)
|
||||
)
|
||||
TextWithSpinner(TextV(textId = R.string.status_bar_network_speed_dual_row_icon), SpinnerV(
|
||||
MIUIActivity.safeSP.getString(
|
||||
"status_bar_network_speed_dual_row_icon", getString(R.string.none)
|
||||
)
|
||||
) {
|
||||
add(getString(R.string.none)) {
|
||||
MIUIActivity.safeSP.putAny(
|
||||
"status_bar_network_speed_dual_row_icon", getString(R.string.none)
|
||||
)
|
||||
}
|
||||
add("▲▼") {
|
||||
MIUIActivity.safeSP.putAny("status_bar_network_speed_dual_row_icon", "▲▼")
|
||||
}
|
||||
add("△▽") {
|
||||
MIUIActivity.safeSP.putAny("status_bar_network_speed_dual_row_icon", "△▽")
|
||||
}
|
||||
add("↑↓") {
|
||||
MIUIActivity.safeSP.putAny("status_bar_network_speed_dual_row_icon", "↑↓")
|
||||
}
|
||||
})
|
||||
Text(
|
||||
textId = R.string.status_bar_network_speed_dual_row_size,
|
||||
dataBindingRecv = statusBarDualRowNetworkSpeedBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"status_bar_network_speed_dual_row_size",
|
||||
0,
|
||||
9,
|
||||
0,
|
||||
dataBindingRecv = statusBarDualRowNetworkSpeedBinding.binding.getRecv(2)
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.notification_center)
|
||||
val showWeatherMainSwitchBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"notification_weather", false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.show_weather_main_switch, colorId = R.color.blue
|
||||
), SwitchV(
|
||||
"notification_weather", dataBindingSend = showWeatherMainSwitchBinding.bindingSend
|
||||
)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.show_city,
|
||||
), SwitchV("notification_weather_city"), dataBindingRecv = showWeatherMainSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.can_notification_slide,
|
||||
tipsId = R.string.can_notification_slide_summary,
|
||||
),
|
||||
SwitchV("can_notification_slide"),
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.control_center)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.disable_bluetooth_temporarily_off
|
||||
), SwitchV(
|
||||
"disable_bluetooth_temporarily_off"
|
||||
)
|
||||
)
|
||||
val controlCenterWeatherBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"control_center_weather", false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.show_weather_main_switch,
|
||||
colorId = R.color.blue,
|
||||
tipsId = R.string.control_center_weather_summary
|
||||
), SwitchV(
|
||||
"control_center_weather", dataBindingSend = controlCenterWeatherBinding.bindingSend
|
||||
)
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.show_city,
|
||||
), SwitchV("control_center_weather_city"), dataBindingRecv = controlCenterWeatherBinding.binding.getRecv(2)
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.lock_screen)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.lock_screen_clock_display_seconds,
|
||||
tipsId = R.string.only_official_default_themes_are_supported
|
||||
), SwitchV("lock_screen_clock_display_seconds")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.remove_the_left_side_of_the_lock_screen,
|
||||
tipsId = R.string.only_official_default_themes_are_supported
|
||||
), SwitchV("remove_the_left_side_of_the_lock_screen")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.remove_lock_screen_camera,
|
||||
tipsId = R.string.only_official_default_themes_are_supported
|
||||
), SwitchV("remove_lock_screen_camera")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(textId = R.string.enable_wave_charge_animation), SwitchV("enable_wave_charge_animation")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.lock_screen_charging_current,
|
||||
tipsId = R.string.only_official_default_themes_are_supported
|
||||
), SwitchV("lock_screen_charging_current")
|
||||
)
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.double_tap_to_sleep, tipsId = R.string.home_double_tap_to_sleep_summary
|
||||
), SwitchV("lock_screen_double_tap_to_sleep")
|
||||
)
|
||||
Line()
|
||||
TitleText(textId = R.string.old_quick_settings_panel)
|
||||
val oldQSCustomSwitchBinding = GetDataBinding({
|
||||
MIUIActivity.safeSP.getBoolean(
|
||||
"old_qs_custom_switch", false
|
||||
)
|
||||
}) { view, flags, data ->
|
||||
when (flags) {
|
||||
1 -> (view as Switch).isEnabled = data as Boolean
|
||||
2 -> view.visibility = if (data as Boolean) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
TextSummaryWithSwitch(
|
||||
TextSummaryV(
|
||||
textId = R.string.old_qs_custom_switch, colorId = R.color.blue
|
||||
), SwitchV(
|
||||
"old_qs_custom_switch", dataBindingSend = oldQSCustomSwitchBinding.bindingSend
|
||||
)
|
||||
)
|
||||
Text(
|
||||
textId = R.string.qs_custom_rows, dataBindingRecv = oldQSCustomSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"qs_custom_rows", 1, 6, 3, dataBindingRecv = oldQSCustomSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
Text(
|
||||
textId = R.string.qs_custom_rows_horizontal, dataBindingRecv = oldQSCustomSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"qs_custom_rows_horizontal", 1, 3, 2, dataBindingRecv = oldQSCustomSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
Text(
|
||||
textId = R.string.qs_custom_columns, dataBindingRecv = oldQSCustomSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"qs_custom_columns", 1, 7, 4, dataBindingRecv = oldQSCustomSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
Text(
|
||||
textId = R.string.qs_custom_columns_unexpanded,
|
||||
dataBindingRecv = oldQSCustomSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
SeekBarWithText(
|
||||
"qs_custom_columns_unexpanded", 1, 7, 5, dataBindingRecv = oldQSCustomSwitchBinding.binding.getRecv(2)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.lt2333.simplicitytools.application
|
||||
|
||||
import com.highcapable.yukihookapi.hook.xposed.application.ModuleApplication
|
||||
|
||||
class DefaultApplication : ModuleApplication() {
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
// Your code here.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.lt2333.simplicitytools.hooks
|
||||
|
||||
import com.highcapable.yukihookapi.annotation.xposed.InjectYukiHookWithXposed
|
||||
import com.highcapable.yukihookapi.hook.factory.configs
|
||||
import com.highcapable.yukihookapi.hook.factory.encase
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.event.YukiXposedEvent
|
||||
import com.highcapable.yukihookapi.hook.xposed.proxy.IYukiHookXposedInit
|
||||
import com.lt2333.simplicitytools.hooks.apps.*
|
||||
import com.lt2333.simplicitytools.hooks.rules.all.corepatch.CorePatchMainHook
|
||||
import de.robv.android.xposed.IXposedHookZygoteInit
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||
|
||||
@InjectYukiHookWithXposed
|
||||
class MainHook : IYukiHookXposedInit {
|
||||
|
||||
override fun onInit() = configs {
|
||||
debugLog {
|
||||
tag = "WooBoxForMIUI-Debug"
|
||||
}
|
||||
}
|
||||
|
||||
override fun onHook() = encase {
|
||||
loadSystem(AndroidHooker) //Andorid
|
||||
loadApp("com.android.systemui", SystemUIHooker) //系统界面
|
||||
loadApp("com.milink.service", CastHooker) //投屏
|
||||
loadApp("com.miui.mediaeditor", MediaEditorHooker) //相册编辑
|
||||
loadApp("com.miui.home", MiuiHomeHooker) //桌面
|
||||
loadApp("com.miui.packageinstaller", PackageInstallerHooker) //安装包管理组件
|
||||
loadApp("com.miui.powerkeeper", PowerKeepcerHooker) //电量与性能
|
||||
loadApp("com.xiaomi.misubscreenui", RearDisplayHooker) //背屏显示
|
||||
loadApp("com.miui.screenshot", ScreenShotHooker) //截屏
|
||||
loadApp("com.miui.securitycenter", SecurityCenterHooker) //手机管家
|
||||
loadApp("com.android.settings", SettingsHooker) //设置
|
||||
loadApp("com.android.thememanager", ThemeManagerHooker) //主题管理
|
||||
loadApp("com.android.updater", UpdaterHooker) //系统更新
|
||||
}
|
||||
|
||||
override fun onXposedEvent() {
|
||||
YukiXposedEvent.onHandleLoadPackage {
|
||||
if (it.packageName == "android") CorePatchMainHook().handleLoadPackage(it)
|
||||
}
|
||||
YukiXposedEvent.onInitZygote {
|
||||
CorePatchMainHook().initZygote(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.lt2333.simplicitytools.hooks.apps
|
||||
|
||||
import android.os.Build
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
import com.lt2333.simplicitytools.hooks.rules.all.android.DisableFlagSecureForAll
|
||||
import com.lt2333.simplicitytools.hooks.rules.all.corepatch.CorePatchMainHook
|
||||
|
||||
object AndroidHooker: YukiBaseHooker() {
|
||||
override fun onHook() {
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
Build.VERSION_CODES.TIRAMISU -> {
|
||||
loadHooker(DisableFlagSecureForAll) //允许截图
|
||||
}
|
||||
|
||||
Build.VERSION_CODES.S -> {
|
||||
loadHooker(DisableFlagSecureForAll) //允许截图
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.lt2333.simplicitytools.hooks.apps
|
||||
|
||||
import android.os.Build
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
import com.lt2333.simplicitytools.hooks.rules.all.android.DisableFlagSecureForAll
|
||||
|
||||
object CastHooker: YukiBaseHooker() {
|
||||
override fun onHook() {
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
Build.VERSION_CODES.TIRAMISU -> {
|
||||
}
|
||||
|
||||
Build.VERSION_CODES.S -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.lt2333.simplicitytools.hooks.apps
|
||||
|
||||
import android.os.Build
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
|
||||
object MediaEditorHooker: YukiBaseHooker() {
|
||||
override fun onHook() {
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
Build.VERSION_CODES.TIRAMISU -> {
|
||||
}
|
||||
|
||||
Build.VERSION_CODES.S -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.lt2333.simplicitytools.hooks.apps
|
||||
|
||||
import android.os.Build
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
|
||||
object MiuiHomeHooker: YukiBaseHooker() {
|
||||
override fun onHook() {
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
Build.VERSION_CODES.TIRAMISU -> {
|
||||
}
|
||||
|
||||
Build.VERSION_CODES.S -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.lt2333.simplicitytools.hooks.apps
|
||||
|
||||
import android.os.Build
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
|
||||
object PackageInstallerHooker: YukiBaseHooker() {
|
||||
override fun onHook() {
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
Build.VERSION_CODES.TIRAMISU -> {
|
||||
}
|
||||
|
||||
Build.VERSION_CODES.S -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.lt2333.simplicitytools.hooks.apps
|
||||
|
||||
import android.os.Build
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
|
||||
object PowerKeepcerHooker: YukiBaseHooker() {
|
||||
override fun onHook() {
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
Build.VERSION_CODES.TIRAMISU -> {
|
||||
}
|
||||
|
||||
Build.VERSION_CODES.S -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.lt2333.simplicitytools.hooks.apps
|
||||
|
||||
import android.os.Build
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
|
||||
object RearDisplayHooker: YukiBaseHooker() {
|
||||
override fun onHook() {
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
Build.VERSION_CODES.TIRAMISU -> {
|
||||
}
|
||||
|
||||
Build.VERSION_CODES.S -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.lt2333.simplicitytools.hooks.apps
|
||||
|
||||
import android.os.Build
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
|
||||
object ScreenShotHooker: YukiBaseHooker() {
|
||||
override fun onHook() {
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
Build.VERSION_CODES.TIRAMISU -> {
|
||||
}
|
||||
|
||||
Build.VERSION_CODES.S -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.lt2333.simplicitytools.hooks.apps
|
||||
|
||||
import android.os.Build
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
|
||||
object SecurityCenterHooker: YukiBaseHooker() {
|
||||
override fun onHook() {
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
Build.VERSION_CODES.TIRAMISU -> {
|
||||
}
|
||||
|
||||
Build.VERSION_CODES.S -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.lt2333.simplicitytools.hooks.apps
|
||||
|
||||
import android.os.Build
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
|
||||
object SettingsHooker: YukiBaseHooker() {
|
||||
override fun onHook() {
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
Build.VERSION_CODES.TIRAMISU -> {
|
||||
}
|
||||
|
||||
Build.VERSION_CODES.S -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.lt2333.simplicitytools.hooks.apps
|
||||
|
||||
import android.os.Build
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
import com.lt2333.simplicitytools.hooks.rules.all.android.DisableFlagSecureForAll
|
||||
|
||||
object SystemUIHooker : YukiBaseHooker() {
|
||||
override fun onHook() {
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
Build.VERSION_CODES.TIRAMISU -> {
|
||||
}
|
||||
|
||||
Build.VERSION_CODES.S -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.lt2333.simplicitytools.hooks.apps
|
||||
|
||||
import android.os.Build
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
|
||||
object ThemeManagerHooker: YukiBaseHooker() {
|
||||
override fun onHook() {
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
Build.VERSION_CODES.TIRAMISU -> {
|
||||
}
|
||||
|
||||
Build.VERSION_CODES.S -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.lt2333.simplicitytools.hooks.apps
|
||||
|
||||
import android.os.Build
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
|
||||
object UpdaterHooker: YukiBaseHooker() {
|
||||
override fun onHook() {
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
Build.VERSION_CODES.TIRAMISU -> {
|
||||
}
|
||||
|
||||
Build.VERSION_CODES.S -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.lt2333.simplicitytools.hooks.rules.all.android
|
||||
|
||||
import android.os.Build
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
import com.highcapable.yukihookapi.hook.factory.MembersType
|
||||
import com.lt2333.simplicitytools.utils.hasEnable
|
||||
|
||||
object DisableFlagSecureForAll : YukiBaseHooker() {
|
||||
override fun onHook() {
|
||||
"com.android.server.wm.WindowState".hook {
|
||||
injectMember {
|
||||
method { name = "isSecureLocked" }
|
||||
beforeHook {
|
||||
hasEnable("disable_flag_secure") {
|
||||
this.result = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//Android13 额外Hook
|
||||
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.TIRAMISU) {
|
||||
"com.android.server.wm.WindowSurfaceController".hook {
|
||||
injectMember {
|
||||
method { name = "setSecure" }
|
||||
beforeHook {
|
||||
hasEnable("disable_flag_secure") {
|
||||
this.args[0] = false
|
||||
}
|
||||
}
|
||||
}
|
||||
injectMember {
|
||||
allMembers(MembersType.CONSTRUCTOR)
|
||||
beforeHook {
|
||||
hasEnable("disable_flag_secure") {
|
||||
var flags = this.args[2] as Int
|
||||
val secureFlag = 128
|
||||
flags = flags and secureFlag.inv()
|
||||
this.args[2] = flags
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package com.lt2333.simplicitytools.hooks.rules.all.corepatch;
|
||||
|
||||
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.Signature;
|
||||
|
||||
import com.lt2333.simplicitytools.BuildConfig;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage;
|
||||
import de.robv.android.xposed.IXposedHookZygoteInit;
|
||||
import de.robv.android.xposed.XC_MethodHook;
|
||||
import de.robv.android.xposed.XC_MethodReplacement;
|
||||
import de.robv.android.xposed.XSharedPreferences;
|
||||
import de.robv.android.xposed.XposedHelpers;
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||
|
||||
public class CorePatchForQ extends XposedHelper implements IXposedHookLoadPackage, IXposedHookZygoteInit {
|
||||
XSharedPreferences prefs = new XSharedPreferences(BuildConfig.APPLICATION_ID, "config");
|
||||
|
||||
@Override
|
||||
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
// 允许降级
|
||||
Class<?> packageClazz = XposedHelpers.findClass("android.content.pm.PackageParser.Package", loadPackageParam.classLoader);
|
||||
hookAllMethods("com.android.server.pm.PackageManagerService", loadPackageParam.classLoader, "checkDowngrade", new XC_MethodHook() {
|
||||
public void beforeHookedMethod(MethodHookParam methodHookParam) throws Throwable {
|
||||
super.beforeHookedMethod(methodHookParam);
|
||||
if (prefs.getBoolean("downgrade", true)) {
|
||||
Object packageInfoLite = methodHookParam.args[0];
|
||||
|
||||
if (prefs.getBoolean("downgrade", true)) {
|
||||
Field field = packageClazz.getField("mVersionCode");
|
||||
field.setAccessible(true);
|
||||
field.set(packageInfoLite, 0);
|
||||
field = packageClazz.getField("mVersionCodeMajor");
|
||||
field.setAccessible(true);
|
||||
field.set(packageInfoLite, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
hookAllMethods("android.util.jar.StrictJarVerifier", loadPackageParam.classLoader, "verifyMessageDigest",
|
||||
new ReturnConstant(prefs, "authcreak", true));
|
||||
hookAllMethods("android.util.jar.StrictJarVerifier", loadPackageParam.classLoader, "verify",
|
||||
new ReturnConstant(prefs, "authcreak", true));
|
||||
hookAllMethods("java.security.MessageDigest", loadPackageParam.classLoader, "isEqual",
|
||||
new ReturnConstant(prefs, "authcreak", true));
|
||||
hookAllMethods("com.android.server.pm.PackageManagerServiceUtils", loadPackageParam.classLoader, "verifySignatures",
|
||||
new ReturnConstant(prefs, "authcreak", false));
|
||||
|
||||
Class<?> signingDetails = XposedHelpers.findClass("android.content.pm.PackageParser.SigningDetails", loadPackageParam.classLoader);
|
||||
Constructor<?> findConstructorExact = XposedHelpers.findConstructorExact(signingDetails, Signature[].class, Integer.TYPE);
|
||||
findConstructorExact.setAccessible(true);
|
||||
Class<?> packageParserException = XposedHelpers.findClass("android.content.pm.PackageParser.PackageParserException", loadPackageParam.classLoader);
|
||||
Field error = XposedHelpers.findField(packageParserException, "error");
|
||||
error.setAccessible(true);
|
||||
Object[] signingDetailsArgs = new Object[2];
|
||||
signingDetailsArgs[0] = new Signature[]{new Signature(SIGNATURE)};
|
||||
signingDetailsArgs[1] = 1;
|
||||
final Object newInstance = findConstructorExact.newInstance(signingDetailsArgs);
|
||||
hookAllMethods("android.util.apk.ApkSignatureVerifier", loadPackageParam.classLoader, "verifyV1Signature", new XC_MethodHook() {
|
||||
public void afterHookedMethod(MethodHookParam methodHookParam) throws Throwable {
|
||||
super.afterHookedMethod(methodHookParam);
|
||||
if (prefs.getBoolean("authcreak", true)) {
|
||||
Throwable throwable = methodHookParam.getThrowable();
|
||||
if (throwable != null) {
|
||||
Throwable cause = throwable.getCause();
|
||||
if (throwable.getClass() == packageParserException) {
|
||||
if (error.getInt(throwable) == -103) {
|
||||
methodHookParam.setResult(newInstance);
|
||||
}
|
||||
}
|
||||
if (cause != null && cause.getClass() == packageParserException) {
|
||||
if (error.getInt(cause) == -103) {
|
||||
methodHookParam.setResult(newInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//New package has a different signature
|
||||
//处理覆盖安装但签名不一致
|
||||
hookAllMethods(signingDetails, "checkCapability", new XC_MethodHook() {
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
|
||||
super.beforeHookedMethod(param);
|
||||
if (prefs.getBoolean("digestCreak", true)) {
|
||||
if ((Integer) param.args[1] != 4 && prefs.getBoolean("authcreak", true)) {
|
||||
param.setResult(Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
hookAllMethods(signingDetails, "checkCapabilityRecover",
|
||||
new XC_MethodHook() {
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
|
||||
super.beforeHookedMethod(param);
|
||||
if (prefs.getBoolean("digestCreak", true)) {
|
||||
if ((Integer) param.args[1] != 4 && prefs.getBoolean("authcreak", true)) {
|
||||
param.setResult(Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// if app is system app, allow to use hidden api, even if app not using a system signature
|
||||
findAndHookMethod("android.content.pm.ApplicationInfo", loadPackageParam.classLoader, "isPackageWhitelistedForHiddenApis", new XC_MethodHook() {
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
|
||||
super.beforeHookedMethod(param);
|
||||
if (prefs.getBoolean("digestCreak", true)) {
|
||||
ApplicationInfo info = (ApplicationInfo) param.thisObject;
|
||||
if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0
|
||||
|| (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
|
||||
param.setResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initZygote(StartupParam startupParam) {
|
||||
hookAllMethods("android.content.pm.PackageParser", null, "getApkSigningVersion", XC_MethodReplacement.returnConstant(1));
|
||||
hookAllConstructors("android.util.jar.StrictJarVerifier", new XC_MethodHook() {
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
|
||||
super.beforeHookedMethod(param);
|
||||
if (prefs.getBoolean("enhancedMode", false)) {
|
||||
param.args[3] = Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
package com.lt2333.simplicitytools.hooks.rules.all.corepatch;
|
||||
|
||||
|
||||
import android.app.AndroidAppHelper;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.Signature;
|
||||
import android.util.Log;
|
||||
|
||||
import com.lt2333.simplicitytools.BuildConfig;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage;
|
||||
import de.robv.android.xposed.IXposedHookZygoteInit;
|
||||
import de.robv.android.xposed.XC_MethodHook;
|
||||
import de.robv.android.xposed.XC_MethodReplacement;
|
||||
import de.robv.android.xposed.XSharedPreferences;
|
||||
import de.robv.android.xposed.XposedBridge;
|
||||
import de.robv.android.xposed.XposedHelpers;
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||
|
||||
public class CorePatchForR extends XposedHelper implements IXposedHookLoadPackage, IXposedHookZygoteInit {
|
||||
XSharedPreferences prefs = new XSharedPreferences(BuildConfig.APPLICATION_ID, "config");
|
||||
|
||||
@Override
|
||||
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
|
||||
Log.d(CorePatchMainHook.TAG, "downgrade" + prefs.getBoolean("downgrade->", true));
|
||||
Log.d(CorePatchMainHook.TAG, "authcreak" + prefs.getBoolean("authcreak->", true));
|
||||
Log.d(CorePatchMainHook.TAG, "digestCreak" + prefs.getBoolean("digestCreak->", true));
|
||||
Log.d(CorePatchMainHook.TAG, "UsePreSig" + prefs.getBoolean("UsePreSig->", false));
|
||||
|
||||
// 允许降级
|
||||
findAndHookMethod("com.android.server.pm.PackageManagerService", loadPackageParam.classLoader,
|
||||
"checkDowngrade",
|
||||
"com.android.server.pm.parsing.pkg.AndroidPackage",
|
||||
"android.content.pm.PackageInfoLite",
|
||||
new ReturnConstant(prefs, "downgrade", null));
|
||||
|
||||
// exists on flyme 9(Android 11) only
|
||||
findAndHookMethod("com.android.server.pm.PackageManagerService", loadPackageParam.classLoader,
|
||||
"checkDowngrade",
|
||||
"android.content.pm.PackageInfoLite",
|
||||
"android.content.pm.PackageInfoLite",
|
||||
new ReturnConstant(prefs, "downgrade", true));
|
||||
|
||||
|
||||
// apk内文件修改后 digest校验会失败
|
||||
hookAllMethods("android.util.jar.StrictJarVerifier", loadPackageParam.classLoader, "verifyMessageDigest",
|
||||
new ReturnConstant(prefs, "authcreak", true));
|
||||
hookAllMethods("android.util.jar.StrictJarVerifier", loadPackageParam.classLoader, "verify",
|
||||
new ReturnConstant(prefs, "authcreak", true));
|
||||
hookAllMethods("java.security.MessageDigest", loadPackageParam.classLoader, "isEqual",
|
||||
new ReturnConstant(prefs, "authcreak", true));
|
||||
|
||||
// Targeting R+ (version " + Build.VERSION_CODES.R + " and above) requires"
|
||||
// + " the resources.arsc of installed APKs to be stored uncompressed"
|
||||
// + " and aligned on a 4-byte boundary
|
||||
// target >=30 的情况下 resources.arsc 必须是未压缩的且4K对齐
|
||||
hookAllMethods("android.content.res.AssetManager", loadPackageParam.classLoader, "containsAllocatedTable",
|
||||
new ReturnConstant(prefs, "authcreak", false));
|
||||
|
||||
// No signature found in package of version " + minSignatureSchemeVersion
|
||||
// + " or newer for package " + apkPath
|
||||
findAndHookMethod("android.util.apk.ApkSignatureVerifier", loadPackageParam.classLoader, "getMinimumSignatureSchemeVersionForTargetSdk", int.class,
|
||||
new ReturnConstant(prefs, "authcreak", 0));
|
||||
findAndHookMethod("com.android.apksig.ApkVerifier", loadPackageParam.classLoader, "getMinimumSignatureSchemeVersionForTargetSdk", int.class,
|
||||
new ReturnConstant(prefs, "authcreak", 0));
|
||||
|
||||
// Package " + packageName + " signatures do not match previously installed version; ignoring!"
|
||||
// public boolean checkCapability(String sha256String, @CertCapabilities int flags) {
|
||||
// public boolean checkCapability(SigningDetails oldDetails, @CertCapabilities int flags)
|
||||
hookAllMethods("android.content.pm.PackageParser", loadPackageParam.classLoader, "checkCapability", new XC_MethodHook() {
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) {
|
||||
// Don't handle PERMISSION (grant SIGNATURE permissions to pkgs with this cert)
|
||||
// Or applications will have all privileged permissions
|
||||
// https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/content/pm/PackageParser.java;l=5947?q=CertCapabilities
|
||||
if (prefs.getBoolean("authcreak", true)) {
|
||||
if ((Integer) param.args[1] != 4) {
|
||||
param.setResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 当verifyV1Signature抛出转换异常时,替换一个签名作为返回值
|
||||
// 如果用户已安装apk,并且其定义了私有权限,则安装时会因签名与模块内硬编码的不一致而被拒绝。尝试从待安装apk中获取签名。如果其中apk的签名和已安装的一致(只动了内容)就没有问题。此策略可能有潜在的安全隐患。
|
||||
Class<?> pkc = XposedHelpers.findClass("sun.security.pkcs.PKCS7", loadPackageParam.classLoader);
|
||||
Constructor<?> constructor = XposedHelpers.findConstructorExact(pkc, byte[].class);
|
||||
constructor.setAccessible(true);
|
||||
Class<?> ASV = XposedHelpers.findClass("android.util.apk.ApkSignatureVerifier", loadPackageParam.classLoader);
|
||||
Class<?> sJarClass = XposedHelpers.findClass("android.util.jar.StrictJarFile", loadPackageParam.classLoader);
|
||||
Constructor<?> constructorExact = XposedHelpers.findConstructorExact(sJarClass, String.class, boolean.class, boolean.class);
|
||||
constructorExact.setAccessible(true);
|
||||
Class<?> signingDetails = getSigningDetails(loadPackageParam.classLoader);
|
||||
Constructor<?> findConstructorExact = XposedHelpers.findConstructorExact(signingDetails, Signature[].class, Integer.TYPE);
|
||||
findConstructorExact.setAccessible(true);
|
||||
Class<?> packageParserException = XposedHelpers.findClass("android.content.pm.PackageParser.PackageParserException", loadPackageParam.classLoader);
|
||||
Field error = XposedHelpers.findField(packageParserException, "error");
|
||||
error.setAccessible(true);
|
||||
Object[] signingDetailsArgs = new Object[2];
|
||||
signingDetailsArgs[1] = 1;
|
||||
Class<?> parseResult = XposedHelpers.findClassIfExists("android.content.pm.parsing.result.ParseResult", loadPackageParam.classLoader);
|
||||
hookAllMethods("android.util.jar.StrictJarVerifier", loadPackageParam.classLoader, "verifyBytes", new XC_MethodHook() {
|
||||
public void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||
super.afterHookedMethod(param);
|
||||
if (prefs.getBoolean("digestCreak", true)) {
|
||||
if (!prefs.getBoolean("UsePreSig", false)) {
|
||||
final Object block = constructor.newInstance(param.args[0]);
|
||||
Object[] infos = (Object[]) XposedHelpers.callMethod(block, "getSignerInfos");
|
||||
Object info = infos[0];
|
||||
List<X509Certificate> verifiedSignerCertChain = (List<X509Certificate>) XposedHelpers.callMethod(info, "getCertificateChain", block);
|
||||
param.setResult(verifiedSignerCertChain.toArray(
|
||||
new X509Certificate[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
hookAllMethods("android.util.apk.ApkSignatureVerifier", loadPackageParam.classLoader, "verifyV1Signature", new XC_MethodHook() {
|
||||
public void afterHookedMethod(MethodHookParam methodHookParam) throws Throwable {
|
||||
if (prefs.getBoolean("authcreak", true)) {
|
||||
Throwable throwable = methodHookParam.getThrowable();
|
||||
Integer parseErr = null;
|
||||
if (parseResult != null && ((Method) methodHookParam.method).getReturnType() == parseResult) {
|
||||
Object result = methodHookParam.getResult();
|
||||
if ((boolean) XposedHelpers.callMethod(result, "isError")) {
|
||||
parseErr = (int) XposedHelpers.callMethod(result, "getErrorCode");
|
||||
}
|
||||
}
|
||||
if (throwable != null || parseErr != null) {
|
||||
Signature[] lastSigs = null;
|
||||
try {
|
||||
if (prefs.getBoolean("UsePreSig", false)) {
|
||||
PackageManager PM = AndroidAppHelper.currentApplication().getPackageManager();
|
||||
if (PM == null) {
|
||||
XposedBridge.log("E: " + BuildConfig.APPLICATION_ID + " Cannot get the Package Manager... Are you using MiUI?");
|
||||
} else {
|
||||
PackageInfo pI;
|
||||
if (parseErr != null) {
|
||||
pI = PM.getPackageArchiveInfo((String) methodHookParam.args[1], 0);
|
||||
} else {
|
||||
pI = PM.getPackageArchiveInfo((String) methodHookParam.args[0], 0);
|
||||
}
|
||||
PackageInfo InstpI = PM.getPackageInfo(pI.packageName, PackageManager.GET_SIGNATURES);
|
||||
lastSigs = InstpI.signatures;
|
||||
}
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
|
||||
}
|
||||
try {
|
||||
if (lastSigs == null && prefs.getBoolean("digestCreak", true)) {
|
||||
final Object origJarFile = constructorExact.newInstance(methodHookParam.args[parseErr == null ? 0 : 1], true, false);
|
||||
final ZipEntry manifestEntry = (ZipEntry) XposedHelpers.callMethod(origJarFile, "findEntry", "AndroidManifest.xml");
|
||||
final Certificate[][] lastCerts;
|
||||
if (parseErr != null) {
|
||||
lastCerts = (Certificate[][]) XposedHelpers.callMethod(XposedHelpers.callStaticMethod(ASV, "loadCertificates", methodHookParam.args[0], origJarFile, manifestEntry), "getResult");
|
||||
} else {
|
||||
lastCerts = (Certificate[][]) XposedHelpers.callStaticMethod(ASV, "loadCertificates", origJarFile, manifestEntry);
|
||||
}
|
||||
lastSigs = (Signature[]) XposedHelpers.callStaticMethod(ASV, "convertToSignatures", (Object) lastCerts);
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
if (lastSigs != null) {
|
||||
signingDetailsArgs[0] = lastSigs;
|
||||
} else {
|
||||
signingDetailsArgs[0] = new Signature[]{new Signature(SIGNATURE)};
|
||||
}
|
||||
Object newInstance = findConstructorExact.newInstance(signingDetailsArgs);
|
||||
|
||||
//修复 java.lang.ClassCastException: Cannot cast android.content.pm.PackageParser$SigningDetails to android.util.apk.ApkSignatureVerifier$SigningDetailsWithDigests
|
||||
Class<?> signingDetailsWithDigests = XposedHelpers.findClassIfExists("android.util.apk.ApkSignatureVerifier.SigningDetailsWithDigests", loadPackageParam.classLoader);
|
||||
if (signingDetailsWithDigests != null) {
|
||||
Constructor<?> signingDetailsWithDigestsConstructorExact = XposedHelpers.findConstructorExact(signingDetailsWithDigests, signingDetails, Map.class);
|
||||
signingDetailsWithDigestsConstructorExact.setAccessible(true);
|
||||
newInstance = signingDetailsWithDigestsConstructorExact.newInstance(new Object[]{newInstance, null});
|
||||
}
|
||||
if (throwable != null) {
|
||||
Throwable cause = throwable.getCause();
|
||||
if (throwable.getClass() == packageParserException) {
|
||||
if (error.getInt(throwable) == -103) {
|
||||
methodHookParam.setResult(newInstance);
|
||||
}
|
||||
}
|
||||
if (cause != null && cause.getClass() == packageParserException) {
|
||||
if (error.getInt(cause) == -103) {
|
||||
methodHookParam.setResult(newInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parseErr != null && parseErr == -103) {
|
||||
Object input = methodHookParam.args[0];
|
||||
XposedHelpers.callMethod(input, "reset");
|
||||
methodHookParam.setResult(XposedHelpers.callMethod(input, "success", newInstance));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//New package has a different signature
|
||||
//处理覆盖安装但签名不一致
|
||||
hookAllMethods(signingDetails, "checkCapability", new XC_MethodHook() {
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) {
|
||||
// Don't handle PERMISSION (grant SIGNATURE permissions to pkgs with this cert)
|
||||
// Or applications will have all privileged permissions
|
||||
// https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/content/pm/PackageParser.java;l=5947?q=CertCapabilities
|
||||
if (((Integer) param.args[1] != 4) && prefs.getBoolean("digestCreak", true)) {
|
||||
param.setResult(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
// if app is system app, allow to use hidden api, even if app not using a system signature
|
||||
findAndHookMethod("android.content.pm.ApplicationInfo", loadPackageParam.classLoader, "isPackageWhitelistedForHiddenApis", new XC_MethodHook() {
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
|
||||
super.beforeHookedMethod(param);
|
||||
if (prefs.getBoolean("digestCreak", true)) {
|
||||
ApplicationInfo info = (ApplicationInfo) param.thisObject;
|
||||
if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0
|
||||
|| (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
|
||||
param.setResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var utilClass = findClass("com.android.server.pm.PackageManagerServiceUtils", loadPackageParam.classLoader);
|
||||
if (utilClass != null) {
|
||||
for (var m : utilClass.getDeclaredMethods()) {
|
||||
if ("verifySignatures".equals(m.getName())) {
|
||||
try {
|
||||
XposedBridge.class.getDeclaredMethod("deoptimizeMethod", Member.class).invoke(null, m);
|
||||
} catch (Throwable e) {
|
||||
Log.e("CorePatch", "deoptimizing failed", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Class<?> getSigningDetails(ClassLoader classLoader) {
|
||||
return XposedHelpers.findClass("android.content.pm.PackageParser.SigningDetails", classLoader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initZygote(StartupParam startupParam) {
|
||||
|
||||
hookAllMethods("android.content.pm.PackageParser", null, "getApkSigningVersion", XC_MethodReplacement.returnConstant(1));
|
||||
hookAllConstructors("android.util.jar.StrictJarVerifier", new XC_MethodHook() {
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
|
||||
if (prefs.getBoolean("enhancedMode", false)) {
|
||||
super.beforeHookedMethod(param);
|
||||
param.args[3] = Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.lt2333.simplicitytools.hooks.rules.all.corepatch;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import de.robv.android.xposed.XC_MethodHook;
|
||||
import de.robv.android.xposed.XposedHelpers;
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||
|
||||
public class CorePatchForS extends CorePatchForR {
|
||||
@Override
|
||||
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
super.handleLoadPackage(loadPackageParam);
|
||||
if (prefs.getBoolean("digestCreak", true) && prefs.getBoolean("UsePreSig", false)) {
|
||||
findAndHookMethod("com.android.server.pm.PackageManagerService", loadPackageParam.classLoader, "doesSignatureMatchForPermissions", String.class, "com.android.server.pm.parsing.pkg.ParsedPackage", int.class, new XC_MethodHook() {
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||
//If we decide to crack this then at least make sure they are same apks, avoid another one that tries to impersonate.
|
||||
if (param.getResult().equals(false)) {
|
||||
String pPname = (String) XposedHelpers.callMethod(param.args[1], "getPackageName");
|
||||
if (pPname.contentEquals((String) param.args[0])) {
|
||||
param.setResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.lt2333.simplicitytools.hooks.rules.all.corepatch;
|
||||
|
||||
public class CorePatchForSv2 extends CorePatchForS{
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.lt2333.simplicitytools.hooks.rules.all.corepatch;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import de.robv.android.xposed.XC_MethodHook;
|
||||
import de.robv.android.xposed.XposedBridge;
|
||||
import de.robv.android.xposed.XposedHelpers;
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||
|
||||
public class CorePatchForT extends CorePatchForSv2 {
|
||||
@Override
|
||||
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
super.handleLoadPackage(loadPackageParam);
|
||||
|
||||
findAndHookMethod("com.android.server.pm.PackageManagerServiceUtils", loadPackageParam.classLoader,
|
||||
"checkDowngrade",
|
||||
"com.android.server.pm.parsing.pkg.AndroidPackage",
|
||||
"android.content.pm.PackageInfoLite",
|
||||
new ReturnConstant(prefs, "downgrade", null));
|
||||
|
||||
Class<?> signingDetails = getSigningDetails(loadPackageParam.classLoader);
|
||||
//New package has a different signature
|
||||
//处理覆盖安装但签名不一致
|
||||
hookAllMethods(signingDetails, "checkCapability", new XC_MethodHook() {
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) {
|
||||
// Don't handle PERMISSION (grant SIGNATURE permissions to pkgs with this cert)
|
||||
// Or applications will have all privileged permissions
|
||||
// https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/content/pm/PackageParser.java;l=5947?q=CertCapabilities
|
||||
if (((Integer) param.args[1] != 4) && prefs.getBoolean("digestCreak", true)) {
|
||||
param.setResult(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Package " + packageName + " signatures do not match previously installed version; ignoring!"
|
||||
// public boolean checkCapability(String sha256String, @CertCapabilities int flags) {
|
||||
// public boolean checkCapability(SigningDetails oldDetails, @CertCapabilities int flags)
|
||||
hookAllMethods("android.content.pm.PackageParser", loadPackageParam.classLoader, "checkCapability", new XC_MethodHook() {
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) {
|
||||
Log.e("CorePatch", "checkCapability");
|
||||
// Don't handle PERMISSION (grant SIGNATURE permissions to pkgs with this cert)
|
||||
// Or applications will have all privileged permissions
|
||||
// https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/content/pm/PackageParser.java;l=5947?q=CertCapabilities
|
||||
if (prefs.getBoolean("authcreak", true)) {
|
||||
if ((Integer) param.args[1] != 4) {
|
||||
param.setResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (prefs.getBoolean("digestCreak", true) && prefs.getBoolean("UsePreSig", false)) {
|
||||
findAndHookMethod("com.android.server.pm.InstallPackageHelper", loadPackageParam.classLoader, "doesSignatureMatchForPermissions", String.class, "com.android.server.pm.parsing.pkg.ParsedPackage", int.class, new XC_MethodHook() {
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) {
|
||||
//If we decide to crack this then at least make sure they are same apks, avoid another one that tries to impersonate.
|
||||
if (param.getResult().equals(false)) {
|
||||
String pPname = (String) XposedHelpers.callMethod(param.args[1], "getPackageName");
|
||||
if (pPname.contentEquals((String) param.args[0])) {
|
||||
param.setResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
findAndHookMethod("com.android.server.pm.ScanPackageUtils", loadPackageParam.classLoader, "assertMinSignatureSchemeIsValid", "com.android.server.pm.parsing.pkg.AndroidPackage", int.class, new XC_MethodHook() {
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||
if (prefs.getBoolean("authcreak", true)) {
|
||||
param.setResult(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
Class<?> strictJarVerifier = findClass("android.util.jar.StrictJarVerifier", loadPackageParam.classLoader);
|
||||
if (strictJarVerifier != null) {
|
||||
XposedBridge.hookAllConstructors(strictJarVerifier, new XC_MethodHook() {
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) {
|
||||
if (prefs.getBoolean("authcreak", true)) {
|
||||
XposedHelpers.setBooleanField(param.thisObject, "signatureSchemeRollbackProtectionsEnforced", false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
Class<?> getSigningDetails(ClassLoader classLoader) {
|
||||
return XposedHelpers.findClassIfExists("android.content.pm.SigningDetails", classLoader);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.lt2333.simplicitytools.hooks.rules.all.corepatch;
|
||||
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage;
|
||||
import de.robv.android.xposed.IXposedHookZygoteInit;
|
||||
import de.robv.android.xposed.XposedBridge;
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||
|
||||
public class CorePatchMainHook implements IXposedHookLoadPackage, IXposedHookZygoteInit {
|
||||
public static final String TAG = "WooBox: CorePatch";
|
||||
|
||||
@Override
|
||||
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
|
||||
if (("android".equals(lpparam.packageName)) && (lpparam.processName.equals("android"))) {
|
||||
Log.d(TAG, "Current sdk version " + Build.VERSION.SDK_INT);
|
||||
switch (Build.VERSION.SDK_INT) {
|
||||
case Build.VERSION_CODES.TIRAMISU: // 33
|
||||
new CorePatchForT().handleLoadPackage(lpparam);
|
||||
break;
|
||||
case Build.VERSION_CODES.S_V2: // 32
|
||||
new CorePatchForSv2().handleLoadPackage(lpparam);
|
||||
break;
|
||||
case Build.VERSION_CODES.S: // 31
|
||||
new CorePatchForS().handleLoadPackage(lpparam);
|
||||
break;
|
||||
case Build.VERSION_CODES.R: // 30
|
||||
new CorePatchForR().handleLoadPackage(lpparam);
|
||||
break;
|
||||
case Build.VERSION_CODES.Q: // 29
|
||||
new CorePatchForQ().handleLoadPackage(lpparam);
|
||||
break;
|
||||
default:
|
||||
XposedBridge.log(TAG + ": Warning: Unsupported Version of Android " + Build.VERSION.SDK_INT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initZygote(StartupParam startupParam) throws Throwable {
|
||||
if (startupParam.startsSystemServer) {
|
||||
Log.d(TAG, "Current sdk version " + Build.VERSION.SDK_INT);
|
||||
switch (Build.VERSION.SDK_INT) {
|
||||
case Build.VERSION_CODES.TIRAMISU: // 33
|
||||
new CorePatchForT().initZygote(startupParam);
|
||||
break;
|
||||
case Build.VERSION_CODES.S_V2: // 32
|
||||
new CorePatchForSv2().initZygote(startupParam);
|
||||
break;
|
||||
case Build.VERSION_CODES.S: // 31
|
||||
new CorePatchForS().initZygote(startupParam);
|
||||
break;
|
||||
case Build.VERSION_CODES.R: // 30
|
||||
new CorePatchForR().initZygote(startupParam);
|
||||
break;
|
||||
case Build.VERSION_CODES.Q: // 29
|
||||
new CorePatchForQ().initZygote(startupParam);
|
||||
break;
|
||||
default:
|
||||
XposedBridge.log(TAG + ": Warning: Unsupported Version of Android " + Build.VERSION.SDK_INT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.lt2333.simplicitytools.hooks.rules.all.corepatch;
|
||||
|
||||
import de.robv.android.xposed.XC_MethodHook;
|
||||
import de.robv.android.xposed.XSharedPreferences;
|
||||
|
||||
public class ReturnConstant extends XC_MethodHook {
|
||||
private final XSharedPreferences prefs;
|
||||
private final String prefsKey;
|
||||
private final Object value;
|
||||
|
||||
public ReturnConstant(XSharedPreferences prefs, String prefsKey, Object value) {
|
||||
this.prefs = prefs;
|
||||
this.prefsKey = prefsKey;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
|
||||
super.beforeHookedMethod(param);
|
||||
prefs.reload();
|
||||
if (prefs.getBoolean(prefsKey, false)) {
|
||||
param.setResult(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.lt2333.simplicitytools.hooks.rules.all.corepatch;
|
||||
|
||||
import com.lt2333.simplicitytools.BuildConfig;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import de.robv.android.xposed.XC_MethodHook;
|
||||
import de.robv.android.xposed.XposedBridge;
|
||||
import de.robv.android.xposed.XposedHelpers;
|
||||
|
||||
public class XposedHelper {
|
||||
public String SIGNATURE = "308203c6308202aea003020102021426d148b7c65944abcf3a683b4c3dd3b139c4ec85300d06092a864886f70d01010b05003074310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e205669657731143012060355040a130b476f6f676c6520496e632e3110300e060355040b1307416e64726f69643110300e06035504031307416e64726f6964301e170d3139303130323138353233385a170d3439303130323138353233385a3074310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e205669657731143012060355040a130b476f6f676c6520496e632e3110300e060355040b1307416e64726f69643110300e06035504031307416e64726f696430820122300d06092a864886f70d01010105000382010f003082010a028201010087fcde48d9beaeba37b733a397ae586fb42b6c3f4ce758dc3ef1327754a049b58f738664ece587994f1c6362f98c9be5fe82c72177260c390781f74a10a8a6f05a6b5ca0c7c5826e15526d8d7f0e74f2170064896b0cf32634a388e1a975ed6bab10744d9b371cba85069834bf098f1de0205cdee8e715759d302a64d248067a15b9beea11b61305e367ac71b1a898bf2eec7342109c9c5813a579d8a1b3e6a3fe290ea82e27fdba748a663f73cca5807cff1e4ad6f3ccca7c02945926a47279d1159599d4ecf01c9d0b62e385c6320a7a1e4ddc9833f237e814b34024b9ad108a5b00786ea15593a50ca7987cbbdc203c096eed5ff4bf8a63d27d33ecc963990203010001a350304e300c0603551d13040530030101ff301d0603551d0e04160414a361efb002034d596c3a60ad7b0332012a16aee3301f0603551d23041830168014a361efb002034d596c3a60ad7b0332012a16aee3300d06092a864886f70d01010b0500038201010022ccb684a7a8706f3ee7c81d6750fd662bf39f84805862040b625ddf378eeefae5a4f1f283deea61a3c7f8e7963fd745415153a531912b82b596e7409287ba26fb80cedba18f22ae3d987466e1fdd88e440402b2ea2819db5392cadee501350e81b8791675ea1a2ed7ef7696dff273f13fb742bb9625fa12ce9c2cb0b7b3d94b21792f1252b1d9e4f7012cb341b62ff556e6864b40927e942065d8f0f51273fcda979b8832dd5562c79acf719de6be5aee2a85f89265b071bf38339e2d31041bc501d5e0c034ab1cd9c64353b10ee70b49274093d13f733eb9d3543140814c72f8e003f301c7a00b1872cc008ad55e26df2e8f07441002c4bcb7dc746745f0db";
|
||||
|
||||
public static void findAndHookMethod(String p1, ClassLoader lpparam, String p2, Object... parameterTypesAndCallback) {
|
||||
try {
|
||||
if (findClass(p1, lpparam) != null) {
|
||||
XposedHelpers.findAndHookMethod(p1, lpparam, p2, parameterTypesAndCallback);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (BuildConfig.DEBUG)
|
||||
XposedBridge.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void hookAllMethods(String p1, ClassLoader lpparam, String methodName, XC_MethodHook parameterTypesAndCallback) {
|
||||
try {
|
||||
Class<?> packageParser = findClass(p1, lpparam);
|
||||
XposedBridge.hookAllMethods(packageParser, methodName, parameterTypesAndCallback);
|
||||
} catch (Throwable e) {
|
||||
if (BuildConfig.DEBUG)
|
||||
XposedBridge.log(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void hookAllMethods(Class<?> packageManagerServiceUtils, String verifySignatures, XC_MethodHook methodHook) {
|
||||
try {
|
||||
XposedBridge.hookAllMethods(packageManagerServiceUtils, verifySignatures, methodHook);
|
||||
} catch (Throwable e) {
|
||||
if (BuildConfig.DEBUG)
|
||||
XposedBridge.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> findClass(String className, ClassLoader classLoader) {
|
||||
try {
|
||||
return Class.forName(className, false, classLoader);
|
||||
} catch (Throwable e) {
|
||||
if (BuildConfig.DEBUG)
|
||||
XposedBridge.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void hookAllConstructors(String p1, XC_MethodHook parameterTypesAndCallback) {
|
||||
try {
|
||||
Class<?> packageParser = findClass(p1, null);
|
||||
hookAllConstructors(packageParser, parameterTypesAndCallback);
|
||||
} catch (Throwable e) {
|
||||
if (BuildConfig.DEBUG)
|
||||
XposedBridge.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<XC_MethodHook.Unhook> hookAllConstructors(Class<?> hookClass, XC_MethodHook callback) {
|
||||
try {
|
||||
return XposedBridge.hookAllConstructors(hookClass, callback);
|
||||
} catch (Throwable e) {
|
||||
if (BuildConfig.DEBUG)
|
||||
XposedBridge.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.lt2333.simplicitytools.tiles
|
||||
|
||||
import android.service.quicksettings.Tile
|
||||
import android.service.quicksettings.TileService
|
||||
|
||||
class AllowScreenshots : TileService() {
|
||||
private val key = "disable_flag_secure"
|
||||
|
||||
override fun onClick() {
|
||||
super.onClick()
|
||||
try {
|
||||
val pref = getSharedPreferences("config", MODE_WORLD_READABLE)
|
||||
val prefEditor = pref.edit()
|
||||
if (pref.getBoolean(key, false)) {
|
||||
prefEditor.putBoolean(key, false)
|
||||
qsTile.state = Tile.STATE_INACTIVE
|
||||
} else {
|
||||
prefEditor.putBoolean(key, true)
|
||||
qsTile.state = Tile.STATE_ACTIVE
|
||||
}
|
||||
prefEditor.commit()
|
||||
qsTile.updateTile()
|
||||
} catch (e: SecurityException) {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStartListening() {
|
||||
super.onStartListening()
|
||||
try {
|
||||
val pref = getSharedPreferences("config", MODE_WORLD_READABLE)
|
||||
if (pref.getBoolean(key, false)) {
|
||||
qsTile.state = Tile.STATE_ACTIVE
|
||||
} else {
|
||||
qsTile.state = Tile.STATE_INACTIVE
|
||||
}
|
||||
qsTile.updateTile()
|
||||
} catch (e: SecurityException) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.lt2333.simplicitytools.tiles
|
||||
|
||||
import android.service.quicksettings.Tile
|
||||
import android.service.quicksettings.TileService
|
||||
|
||||
class LockMaxFpsTile : TileService() {
|
||||
|
||||
private val key = "lock_max_fps"
|
||||
|
||||
override fun onClick() {
|
||||
super.onClick()
|
||||
try {
|
||||
val pref = getSharedPreferences("config", MODE_WORLD_READABLE)
|
||||
val prefEditor = pref.edit()
|
||||
if (pref.getBoolean(key, false)) {
|
||||
prefEditor.putBoolean(key, false)
|
||||
qsTile.state = Tile.STATE_INACTIVE
|
||||
} else {
|
||||
prefEditor.putBoolean(key, true)
|
||||
qsTile.state = Tile.STATE_ACTIVE
|
||||
}
|
||||
prefEditor.commit()
|
||||
qsTile.updateTile()
|
||||
} catch (e: SecurityException) {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStartListening() {
|
||||
super.onStartListening()
|
||||
try {
|
||||
val pref = getSharedPreferences("config", MODE_WORLD_READABLE)
|
||||
if (pref.getBoolean(key, false)) {
|
||||
qsTile.state = Tile.STATE_ACTIVE
|
||||
} else {
|
||||
qsTile.state = Tile.STATE_INACTIVE
|
||||
}
|
||||
qsTile.updateTile()
|
||||
} catch (e: SecurityException) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
package com.lt2333.simplicitytools.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
|
||||
public class ShellUtils {
|
||||
|
||||
public static final String COMMAND_SU = "su";
|
||||
public static final String COMMAND_SH = "sh";
|
||||
public static final String COMMAND_EXIT = "exit\n";
|
||||
public static final String COMMAND_LINE_END = "\n";
|
||||
|
||||
private ShellUtils() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether has root permission
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static boolean checkRootPermission() {
|
||||
return execCommand("echo root", true, false).result == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* execute shell command, default return result msg
|
||||
*
|
||||
* @param command command
|
||||
* @param isRoot whether need to run with root
|
||||
* @return
|
||||
* @see ShellUtils#execCommand(String[], boolean, boolean)
|
||||
*/
|
||||
public static CommandResult execCommand(String command, boolean isRoot) {
|
||||
return execCommand(new String[]{command}, isRoot, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* execute shell commands, default return result msg
|
||||
*
|
||||
* @param commands command activity_wifi
|
||||
* @param isRoot whether need to run with root
|
||||
* @return
|
||||
* @see ShellUtils#execCommand(String[], boolean, boolean)
|
||||
*/
|
||||
public static CommandResult execCommand(List<String> commands, boolean isRoot) {
|
||||
return execCommand(commands == null ? null : commands.toArray(new String[]{}), isRoot, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* execute shell commands, default return result msg
|
||||
*
|
||||
* @param commands command array
|
||||
* @param isRoot whether need to run with root
|
||||
* @return
|
||||
* @see ShellUtils#execCommand(String[], boolean, boolean)
|
||||
*/
|
||||
public static CommandResult execCommand(String[] commands, boolean isRoot) {
|
||||
return execCommand(commands, isRoot, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* execute shell command
|
||||
*
|
||||
* @param command command
|
||||
* @param isRoot whether need to run with root
|
||||
* @param isNeedResultMsg whether need result msg
|
||||
* @return
|
||||
* @see ShellUtils#execCommand(String[], boolean, boolean)
|
||||
*/
|
||||
public static CommandResult execCommand(String command, boolean isRoot, boolean isNeedResultMsg) {
|
||||
return execCommand(new String[]{command}, isRoot, isNeedResultMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* execute shell commands
|
||||
*
|
||||
* @param commands command activity_wifi
|
||||
* @param isRoot whether need to run with root
|
||||
* @param isNeedResultMsg whether need result msg
|
||||
* @return
|
||||
* @see ShellUtils#execCommand(String[], boolean, boolean)
|
||||
*/
|
||||
public static CommandResult execCommand(List<String> commands, boolean isRoot, boolean isNeedResultMsg) {
|
||||
return execCommand(commands == null ? null : commands.toArray(new String[]{}), isRoot, isNeedResultMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* execute shell commands
|
||||
*
|
||||
* @param commands command array
|
||||
* @param isRoot whether need to run with root
|
||||
* @param isNeedResultMsg whether need result msg
|
||||
* @return <ul>
|
||||
* <li>if isNeedResultMsg is false, {@link CommandResult#successMsg} is null and
|
||||
* {@link CommandResult#errorMsg} is null.</li>
|
||||
* <li>if {@link CommandResult#result} is -1, there maybe some excepiton.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static CommandResult execCommand(String[] commands, boolean isRoot, boolean isNeedResultMsg) {
|
||||
int result = -1;
|
||||
if (commands == null || commands.length == 0) {
|
||||
return new CommandResult(result, null, null);
|
||||
}
|
||||
|
||||
Process process = null;
|
||||
BufferedReader successResult = null;
|
||||
BufferedReader errorResult = null;
|
||||
StringBuilder successMsg = null;
|
||||
StringBuilder errorMsg = null;
|
||||
|
||||
DataOutputStream os = null;
|
||||
try {
|
||||
process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);
|
||||
os = new DataOutputStream(process.getOutputStream());
|
||||
for (String command : commands) {
|
||||
if (command == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// donnot use os.writeBytes(commmand), avoid chinese charset error
|
||||
os.write(command.getBytes());
|
||||
os.writeBytes(COMMAND_LINE_END);
|
||||
os.flush();
|
||||
}
|
||||
os.writeBytes(COMMAND_EXIT);
|
||||
os.flush();
|
||||
|
||||
result = process.waitFor();
|
||||
// get command result
|
||||
if (isNeedResultMsg) {
|
||||
successMsg = new StringBuilder();
|
||||
errorMsg = new StringBuilder();
|
||||
successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
|
||||
String s;
|
||||
while ((s = successResult.readLine()) != null) {
|
||||
successMsg.append(s);
|
||||
}
|
||||
while ((s = errorResult.readLine()) != null) {
|
||||
errorMsg.append(s);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (os != null) {
|
||||
os.close();
|
||||
}
|
||||
if (successResult != null) {
|
||||
successResult.close();
|
||||
}
|
||||
if (errorResult != null) {
|
||||
errorResult.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
return new CommandResult(result, successMsg == null ? null : successMsg.toString(), errorMsg == null ? null
|
||||
: errorMsg.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* result of command
|
||||
* <ul>
|
||||
* <li>{@link CommandResult#result} means result of command, 0 means normal, else means error, same to excute in
|
||||
* linux shell</li>
|
||||
* <li>{@link CommandResult#successMsg} means success message of command result</li>
|
||||
* <li>{@link CommandResult#errorMsg} means error message of command result</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author <main href="http://www.trinea.cn" target="_blank">Trinea</main> 2013-5-16
|
||||
*/
|
||||
public static class CommandResult {
|
||||
|
||||
/**
|
||||
* result of command
|
||||
**/
|
||||
public int result;
|
||||
/**
|
||||
* success message of command result
|
||||
**/
|
||||
public String successMsg;
|
||||
/**
|
||||
* error message of command result
|
||||
**/
|
||||
public String errorMsg;
|
||||
|
||||
public CommandResult(int result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public CommandResult(int result, String successMsg, String errorMsg) {
|
||||
this.result = result;
|
||||
this.successMsg = successMsg;
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.lt2333.simplicitytools.utils
|
||||
|
||||
import com.lt2333.simplicitytools.BuildConfig
|
||||
import de.robv.android.xposed.XSharedPreferences
|
||||
|
||||
object XSPUtils {
|
||||
private var prefs = XSharedPreferences(BuildConfig.APPLICATION_ID, "config")
|
||||
|
||||
fun getBoolean(key: String, defValue: Boolean): Boolean {
|
||||
if (prefs.hasFileChanged()) {
|
||||
prefs.reload()
|
||||
}
|
||||
return prefs.getBoolean(key, defValue)
|
||||
}
|
||||
|
||||
fun getInt(key: String, defValue: Int): Int {
|
||||
if (prefs.hasFileChanged()) {
|
||||
prefs.reload()
|
||||
}
|
||||
return prefs.getInt(key, defValue)
|
||||
}
|
||||
|
||||
fun getFloat(key: String, defValue: Float): Float {
|
||||
if (prefs.hasFileChanged()) {
|
||||
prefs.reload()
|
||||
}
|
||||
return prefs.getFloat(key, defValue)
|
||||
}
|
||||
|
||||
fun getString(key: String, defValue: String): String? {
|
||||
if (prefs.hasFileChanged()) {
|
||||
prefs.reload()
|
||||
}
|
||||
return prefs.getString(key, defValue)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun hasEnable(
|
||||
key: String,
|
||||
default: Boolean = false,
|
||||
noinline extraCondition: (() -> Boolean)? = null,
|
||||
crossinline block: () -> Unit
|
||||
) {
|
||||
val conditionResult = if (extraCondition != null) extraCondition() else true
|
||||
if (XSPUtils.getBoolean(key, default) && conditionResult) {
|
||||
block()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
@file:Suppress("unused")
|
||||
|
||||
package com.lt2333.simplicitytools.utils.factory
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
|
||||
/**
|
||||
* System dark mode is enabled or not
|
||||
*
|
||||
* 系统深色模式是否开启
|
||||
* @return [Boolean] Whether to enable / 是否开启
|
||||
*/
|
||||
val Context.isSystemInDarkMode get() = (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
|
||||
|
||||
/**
|
||||
* System dark mode is disable or not
|
||||
*
|
||||
* 系统深色模式是否没开启
|
||||
* @return [Boolean] Whether to enable / 是否开启
|
||||
*/
|
||||
inline val Context.isNotSystemInDarkMode get() = isSystemInDarkMode.not()
|
||||
|
||||
/**
|
||||
* dp to pxInt
|
||||
*
|
||||
* dp 转换为 pxInt
|
||||
* @param context using instance / 使用的实例
|
||||
* @return [Int]
|
||||
*/
|
||||
fun Number.dp(context: Context) = dpFloat(context).toInt()
|
||||
|
||||
/**
|
||||
* dp to pxFloat
|
||||
*
|
||||
* dp 转换为 pxFloat
|
||||
* @param context using instance / 使用的实例
|
||||
* @return [Float]
|
||||
*/
|
||||
fun Number.dpFloat(context: Context) = toFloat() * context.resources.displayMetrics.density
|
||||
Reference in New Issue
Block a user