mirror of
https://github.com/LittleTurtle2333/SimplicityTools.git
synced 2026-07-12 11:21:18 +08:00
KotlinXposedHelper 化
This commit is contained in:
@@ -206,7 +206,7 @@ class SettingsActivity : MIUIActivity() {
|
||||
}
|
||||
|
||||
//关于页面
|
||||
fun aboutItems(): ArrayList<BaseView> {
|
||||
private fun aboutItems(): ArrayList<BaseView> {
|
||||
return ArrayList<BaseView>().apply {
|
||||
add(
|
||||
AuthorV(
|
||||
@@ -894,7 +894,7 @@ class SettingsActivity : MIUIActivity() {
|
||||
}
|
||||
|
||||
//其他页面
|
||||
fun otherItems(): ArrayList<BaseView> {
|
||||
private fun otherItems(): ArrayList<BaseView> {
|
||||
return ArrayList<BaseView>().apply {
|
||||
add(TitleTextV(resId = R.string.scope_miuihome))
|
||||
add(
|
||||
|
||||
@@ -15,41 +15,23 @@ class MainHook : IXposedHookLoadPackage {
|
||||
EzXHelperInit.setEzClassLoader(lpparam.classLoader)
|
||||
when (lpparam.packageName) {
|
||||
//Android
|
||||
"android" -> {
|
||||
Android().handleLoadPackage(lpparam)
|
||||
}
|
||||
"android" -> Android().handleLoadPackage(lpparam)
|
||||
//系统界面
|
||||
"com.android.systemui" -> {
|
||||
SystemUI().handleLoadPackage(lpparam)
|
||||
}
|
||||
"com.android.systemui" -> SystemUI().handleLoadPackage(lpparam)
|
||||
//电量与性能
|
||||
"com.miui.powerkeeper" -> {
|
||||
PowerKeeper().handleLoadPackage(lpparam)
|
||||
}
|
||||
"com.miui.powerkeeper" -> PowerKeeper().handleLoadPackage(lpparam)
|
||||
//桌面
|
||||
"com.miui.home" -> {
|
||||
MiuiHome().handleLoadPackage(lpparam)
|
||||
}
|
||||
"com.miui.home" -> MiuiHome().handleLoadPackage(lpparam)
|
||||
//手机管家
|
||||
"com.miui.securitycenter" -> {
|
||||
SecurityCenter().handleLoadPackage(lpparam)
|
||||
}
|
||||
"com.miui.securitycenter" -> SecurityCenter().handleLoadPackage(lpparam)
|
||||
//相册编辑
|
||||
"com.miui.mediaeditor" -> {
|
||||
MediaEditor().handleLoadPackage(lpparam)
|
||||
}
|
||||
"com.miui.mediaeditor" -> MediaEditor().handleLoadPackage(lpparam)
|
||||
//系统更新
|
||||
"com.android.updater" -> {
|
||||
Updater().handleLoadPackage(lpparam)
|
||||
}
|
||||
"com.android.updater" -> Updater().handleLoadPackage(lpparam)
|
||||
//设置
|
||||
"com.android.settings" -> {
|
||||
Settings().handleLoadPackage(lpparam)
|
||||
}
|
||||
"com.android.settings" -> Settings().handleLoadPackage(lpparam)
|
||||
//主题壁纸
|
||||
"com.android.thememanager" -> {
|
||||
ThemeManager().handleLoadPackage(lpparam)
|
||||
}
|
||||
"com.android.thememanager" -> ThemeManager().handleLoadPackage(lpparam)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,46 +2,28 @@ package com.lt2333.simplicitytools.hook.app.securitycenter
|
||||
|
||||
import android.view.View
|
||||
import com.lt2333.simplicitytools.util.XSPUtils
|
||||
import com.lt2333.simplicitytools.util.findClass
|
||||
import com.lt2333.simplicitytools.util.hookBeforeMethod
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage
|
||||
import de.robv.android.xposed.XC_MethodHook
|
||||
import de.robv.android.xposed.XposedHelpers
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||
|
||||
class LockOneHundred : IXposedHookLoadPackage {
|
||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
||||
|
||||
//防止点击重新检测
|
||||
var classIfExists = XposedHelpers.findClassIfExists(
|
||||
"com.miui.securityscan.ui.main.MainContentFrame",
|
||||
lpparam.classLoader
|
||||
)
|
||||
XposedHelpers.findAndHookMethod(
|
||||
classIfExists,
|
||||
"onClick",
|
||||
View::class.java,
|
||||
object : XC_MethodHook() {
|
||||
override fun beforeHookedMethod(param: MethodHookParam) {
|
||||
if (XSPUtils.getBoolean("lock_one_hundred", false)) {
|
||||
param.result = null
|
||||
}
|
||||
}
|
||||
})
|
||||
val mainContentFrameClass = "com.miui.securityscan.ui.main.MainContentFrame".findClass(lpparam.classLoader)
|
||||
mainContentFrameClass.hookBeforeMethod("onClick", View::class.java) {
|
||||
if (XSPUtils.getBoolean("lock_one_hundred", false)) {
|
||||
it.result = null
|
||||
}
|
||||
}
|
||||
|
||||
//锁定100分
|
||||
var classIfExists2 = XposedHelpers.findClassIfExists(
|
||||
"com.miui.securityscan.scanner.ScoreManager",
|
||||
lpparam.classLoader
|
||||
)
|
||||
XposedHelpers.findAndHookMethod(
|
||||
classIfExists2,
|
||||
"B",
|
||||
object : XC_MethodHook() {
|
||||
override fun beforeHookedMethod(param: MethodHookParam) {
|
||||
if (XSPUtils.getBoolean("lock_one_hundred", false)) {
|
||||
param.result = 0
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
var scoreManagerClass = "com.miui.securityscan.scanner.ScoreManager".findClass(lpparam.classLoader)
|
||||
scoreManagerClass.hookBeforeMethod("B") {
|
||||
if (XSPUtils.getBoolean("lock_one_hundred", false)) {
|
||||
it.result = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,51 +2,37 @@ package com.lt2333.simplicitytools.hook.app.securitycenter
|
||||
|
||||
import android.widget.TextView
|
||||
import com.lt2333.simplicitytools.util.XSPUtils
|
||||
import com.lt2333.simplicitytools.util.findClass
|
||||
import com.lt2333.simplicitytools.util.hookBeforeMethod
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage
|
||||
import de.robv.android.xposed.XC_MethodHook
|
||||
import de.robv.android.xposed.XposedHelpers
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||
|
||||
class SkipWaitingTime : IXposedHookLoadPackage {
|
||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
||||
|
||||
var classIfExists = XposedHelpers.findClassIfExists(
|
||||
"android.widget.TextView",
|
||||
lpparam.classLoader
|
||||
)
|
||||
XposedHelpers.findAndHookMethod(
|
||||
classIfExists,
|
||||
val textViewClass = "android.widget.TextView".findClass(lpparam.classLoader)
|
||||
textViewClass.hookBeforeMethod(
|
||||
"setText",
|
||||
CharSequence::class.java,
|
||||
TextView.BufferType::class.java,
|
||||
Boolean::class.java,
|
||||
Int::class.java,
|
||||
object : XC_MethodHook() {
|
||||
override fun beforeHookedMethod(param: MethodHookParam) {
|
||||
if (XSPUtils.getBoolean("skip_waiting_time", false)) {
|
||||
if (param.args.isNotEmpty() && param.args[0]?.toString()
|
||||
?.startsWith("确定(") == true
|
||||
) {
|
||||
param.args[0] = "确定"
|
||||
}
|
||||
}
|
||||
Int::class.java
|
||||
) {
|
||||
if (XSPUtils.getBoolean("skip_waiting_time", false)) {
|
||||
if (it.args.isNotEmpty() && it.args[0]?.toString()?.startsWith("确定(") == true
|
||||
) {
|
||||
it.args[0] = "确定"
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
val classIfExists2 = XposedHelpers.findClassIfExists(
|
||||
"android.widget.TextView",
|
||||
lpparam.classLoader
|
||||
)
|
||||
XposedHelpers.findAndHookMethod(
|
||||
classIfExists2,
|
||||
textViewClass.hookBeforeMethod(
|
||||
"setEnabled",
|
||||
Boolean::class.java,
|
||||
object : XC_MethodHook() {
|
||||
override fun beforeHookedMethod(param: MethodHookParam) {
|
||||
if (XSPUtils.getBoolean("skip_waiting_time", false)) {
|
||||
param.args[0] = true
|
||||
}
|
||||
}
|
||||
})
|
||||
Boolean::class.java
|
||||
) {
|
||||
if (XSPUtils.getBoolean("skip_waiting_time", false)) {
|
||||
it.args[0] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,71 +3,32 @@ package com.lt2333.simplicitytools.hook.app.settings
|
||||
import android.app.NotificationChannel
|
||||
import com.lt2333.simplicitytools.util.*
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage
|
||||
import de.robv.android.xposed.XC_MethodHook
|
||||
import de.robv.android.xposed.XposedHelpers
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||
|
||||
class ShowNotificationImportance : IXposedHookLoadPackage {
|
||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
||||
val channelNotificationSettingsClass = XposedHelpers.findClass(
|
||||
"com.android.settings.notification.ChannelNotificationSettings",
|
||||
lpparam.classLoader
|
||||
)
|
||||
val channelNotificationSettingsClass = "com.android.settings.notification.ChannelNotificationSettings".findClass(lpparam.classLoader)
|
||||
channelNotificationSettingsClass.hookBeforeMethod("removeDefaultPrefs") {
|
||||
if (!XSPUtils.getBoolean("show_notification_importance", false)) return@hookBeforeMethod
|
||||
val importance = it.thisObject.callMethod("findPreference", "importance") ?: return@hookBeforeMethod
|
||||
val mChannel = it.thisObject.getObjectField("mChannel") as NotificationChannel
|
||||
val index = importance.callMethod("findSpinnerIndexOfValue", mChannel.importance.toString()) as Int
|
||||
if (index < 0) return@hookBeforeMethod
|
||||
importance.callMethod("setValueIndex", index)
|
||||
XposedHelpers.setAdditionalInstanceField(importance, "channelNotificationSettings", it.thisObject)
|
||||
it.result = null
|
||||
}
|
||||
|
||||
channelNotificationSettingsClass.hookMethod("removeDefaultPrefs",
|
||||
object : XC_MethodHook() {
|
||||
override fun beforeHookedMethod(param: MethodHookParam) {
|
||||
if (!XSPUtils.getBoolean("show_notification_importance", false)) return
|
||||
|
||||
val importance =
|
||||
param.thisObject.callMethod("findPreference", "importance") ?: return
|
||||
val mChannel =
|
||||
param.thisObject.getObjectField("mChannel") as NotificationChannel
|
||||
val index = importance.callMethod(
|
||||
"findSpinnerIndexOfValue",
|
||||
mChannel.importance.toString()
|
||||
) as Int
|
||||
if (index < 0) return
|
||||
|
||||
importance.callMethod("setValueIndex", index)
|
||||
|
||||
XposedHelpers.setAdditionalInstanceField(
|
||||
importance,
|
||||
"channelNotificationSettings",
|
||||
param.thisObject
|
||||
)
|
||||
|
||||
param.result = null
|
||||
}
|
||||
})
|
||||
|
||||
val dropDownPreferenceClass = XposedHelpers.findClass(
|
||||
"androidx.preference.Preference",
|
||||
lpparam.classLoader
|
||||
)
|
||||
|
||||
dropDownPreferenceClass.hookMethod("callChangeListener",
|
||||
Any::class.java, object : XC_MethodHook() {
|
||||
override fun afterHookedMethod(param: MethodHookParam) {
|
||||
val channelNotificationSettings = XposedHelpers.getAdditionalInstanceField(
|
||||
param.thisObject,
|
||||
"channelNotificationSettings"
|
||||
) ?: return@afterHookedMethod
|
||||
|
||||
val mChannel = XposedHelpers.getObjectField(
|
||||
channelNotificationSettings,
|
||||
"mChannel"
|
||||
) as NotificationChannel
|
||||
|
||||
mChannel.callMethod(
|
||||
"setImportance", (param.args[0] as String).toInt()
|
||||
)
|
||||
|
||||
val mBackend = channelNotificationSettings.getObjectField("mBackend") ?: return
|
||||
val mPkg = channelNotificationSettings.getObjectField("mPkg") as String
|
||||
val mUid = channelNotificationSettings.getIntField("mUid")
|
||||
mBackend.callMethod("updateChannel", mPkg, mUid, mChannel)
|
||||
}
|
||||
})
|
||||
val dropDownPreferenceClass = XposedHelpers.findClass("androidx.preference.Preference", lpparam.classLoader)
|
||||
dropDownPreferenceClass.hookAfterMethod("callChangeListener", Any::class.java) {
|
||||
val channelNotificationSettings = XposedHelpers.getAdditionalInstanceField(it.thisObject, "channelNotificationSettings") ?: return@hookAfterMethod
|
||||
val mChannel = channelNotificationSettings.getObjectField("mChannel") as NotificationChannel
|
||||
mChannel.callMethod("setImportance", (it.args[0] as String).toInt())
|
||||
val mBackend = channelNotificationSettings.getObjectField("mBackend") ?: return@hookAfterMethod
|
||||
val mPkg = channelNotificationSettings.getObjectField("mPkg") as String
|
||||
val mUid = channelNotificationSettings.getIntField("mUid")
|
||||
mBackend.callMethod("updateChannel", mPkg, mUid, mChannel)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,25 +2,19 @@ package com.lt2333.simplicitytools.hook.app.systemui
|
||||
|
||||
import android.widget.TextView
|
||||
import com.lt2333.simplicitytools.util.XSPUtils
|
||||
import com.lt2333.simplicitytools.util.findClass
|
||||
import com.lt2333.simplicitytools.util.hookAfterMethod
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage
|
||||
import de.robv.android.xposed.XC_MethodHook
|
||||
import de.robv.android.xposed.XposedHelpers
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||
|
||||
class HideNetworkSpeedSplitter : IXposedHookLoadPackage {
|
||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
||||
val classIfExists = XposedHelpers.findClassIfExists(
|
||||
"com.android.systemui.statusbar.views.NetworkSpeedSplitter",
|
||||
lpparam.classLoader
|
||||
)
|
||||
|
||||
XposedHelpers.findAndHookMethod(classIfExists, "init", object : XC_MethodHook() {
|
||||
override fun afterHookedMethod(param: MethodHookParam) {
|
||||
if (XSPUtils.getBoolean("hide_network_speed_splitter", false)) {
|
||||
val textView = param.thisObject as TextView
|
||||
textView.text = " "
|
||||
}
|
||||
val networkSpeedSplitterClass = "com.android.systemui.statusbar.views.NetworkSpeedSplitter".findClass(lpparam.classLoader)
|
||||
networkSpeedSplitterClass.hookAfterMethod("init") {
|
||||
if (XSPUtils.getBoolean("hide_network_speed_splitter", false)) {
|
||||
val textView = it.thisObject as TextView
|
||||
textView.text = " "
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,24 +20,15 @@ class NotificationWeather : IXposedHookLoadPackage {
|
||||
"com.android.systemui.qs.MiuiNotificationHeaderView".hookAfterMethod(lpparam.classLoader, "onFinishInflate") {
|
||||
val viewGroup = it.thisObject as ViewGroup
|
||||
val context = viewGroup.context
|
||||
val layoutParam = loadClass("androidx.constraintlayout.widget.ConstraintLayout\$LayoutParams")
|
||||
.getConstructor(Int::class.java, Int::class.java).newInstance(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
) as ViewGroup.MarginLayoutParams
|
||||
val layoutParam = loadClass("androidx.constraintlayout.widget.ConstraintLayout\$LayoutParams").getConstructor(Int::class.java, Int::class.java).newInstance(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) as ViewGroup.MarginLayoutParams
|
||||
layoutParam.setObjectField("bottomToTop", context.resources.getIdentifier("date_time", "id", context.packageName))
|
||||
layoutParam.setObjectField("startToEnd", context.resources.getIdentifier("big_time", "id", context.packageName))
|
||||
|
||||
layoutParam.marginStart = context.resources.getDimensionPixelSize(
|
||||
context.resources.getIdentifier("notification_panel_time_date_space", "dimen", context.packageName)
|
||||
)
|
||||
|
||||
layoutParam.marginStart = context.resources.getDimensionPixelSize(context.resources.getIdentifier("notification_panel_time_date_space", "dimen", context.packageName))
|
||||
mWeatherView = WeatherView(context, isDisplayCity).apply {
|
||||
setTextAppearance(context.resources.getIdentifier("TextAppearance.QSControl.Date", "style", context.packageName))
|
||||
layoutParams = layoutParam
|
||||
}
|
||||
viewGroup.addView(mWeatherView)
|
||||
|
||||
(mWeatherView as WeatherView).setOnClickListener {
|
||||
try {
|
||||
val intent = Intent().apply {
|
||||
|
||||
@@ -2,27 +2,22 @@ package com.lt2333.simplicitytools.hook.app.systemui
|
||||
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import com.lt2333.simplicitytools.util.findClass
|
||||
import com.lt2333.simplicitytools.util.hookAfterMethod
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage
|
||||
import de.robv.android.xposed.XC_MethodHook
|
||||
import de.robv.android.xposed.XposedHelpers
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||
|
||||
class StatusBarCurrent :IXposedHookLoadPackage {
|
||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
||||
val classIfExists = XposedHelpers.findClassIfExists(
|
||||
"com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView",
|
||||
lpparam.classLoader
|
||||
)
|
||||
XposedHelpers.findAndHookMethod(classIfExists, "onFinishInflate", object : XC_MethodHook() {
|
||||
override fun afterHookedMethod(param: MethodHookParam) {
|
||||
val viewGroup = param.thisObject as ViewGroup
|
||||
|
||||
val textView = TextView(viewGroup.context).also {
|
||||
it.text = "Text"
|
||||
it.textSize=14F
|
||||
}
|
||||
viewGroup.addView(textView)
|
||||
val miuiPhoneStatusBarViewClass =
|
||||
"com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView".findClass(lpparam.classLoader)
|
||||
miuiPhoneStatusBarViewClass.hookAfterMethod("onFinishInflate") { param ->
|
||||
val viewGroup = param.thisObject as ViewGroup
|
||||
val textView = TextView(viewGroup.context).also {
|
||||
it.text = "Text"
|
||||
it.textSize = 14F
|
||||
}
|
||||
})
|
||||
viewGroup.addView(textView)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,9 +11,10 @@ import android.widget.FrameLayout
|
||||
import android.widget.LinearLayout
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.lt2333.simplicitytools.util.XSPUtils
|
||||
import com.lt2333.simplicitytools.util.findClass
|
||||
import com.lt2333.simplicitytools.util.getObjectField
|
||||
import com.lt2333.simplicitytools.util.hookAfterMethod
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage
|
||||
import de.robv.android.xposed.XC_MethodHook
|
||||
import de.robv.android.xposed.XposedHelpers
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||
|
||||
class StatusBarLayout : IXposedHookLoadPackage {
|
||||
@@ -31,164 +32,125 @@ class StatusBarLayout : IXposedHookLoadPackage {
|
||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
||||
if (!XSPUtils.getBoolean("status_bar_time_center", false)) return
|
||||
|
||||
val classIfExists = XposedHelpers.findClassIfExists(
|
||||
"com.android.systemui.statusbar.phone.CollapsedStatusBarFragment",
|
||||
lpparam.classLoader
|
||||
)
|
||||
val collapsedStatusBarFragmentClass =
|
||||
"com.android.systemui.statusbar.phone.CollapsedStatusBarFragment".findClass(lpparam.classLoader)
|
||||
|
||||
XposedHelpers.findAndHookMethod(
|
||||
classIfExists,
|
||||
collapsedStatusBarFragmentClass.hookAfterMethod(
|
||||
"onViewCreated",
|
||||
View::class.java,
|
||||
Bundle::class.java,
|
||||
object : XC_MethodHook() {
|
||||
@Throws(Throwable::class)
|
||||
override fun afterHookedMethod(param: MethodHookParam) {
|
||||
super.afterHookedMethod(param)
|
||||
val MiuiPhoneStatusBarView: ViewGroup =
|
||||
XposedHelpers.getObjectField(
|
||||
param.thisObject,
|
||||
"mStatusBar"
|
||||
) as ViewGroup
|
||||
val context: Context = MiuiPhoneStatusBarView.context
|
||||
val res: Resources = MiuiPhoneStatusBarView.resources
|
||||
val status_bar_ID: Int =
|
||||
res.getIdentifier("status_bar", "id", "com.android.systemui")
|
||||
val status_bar_contents_ID: Int =
|
||||
res.getIdentifier("status_bar_contents", "id", "com.android.systemui")
|
||||
val system_icon_area_ID: Int =
|
||||
res.getIdentifier("system_icon_area", "id", "com.android.systemui")
|
||||
Bundle::class.java
|
||||
) { param ->
|
||||
val MiuiPhoneStatusBarView: ViewGroup =
|
||||
param.thisObject.getObjectField("mStatusBar") as ViewGroup
|
||||
val context: Context = MiuiPhoneStatusBarView.context
|
||||
val res: Resources = MiuiPhoneStatusBarView.resources
|
||||
val status_bar_ID: Int = res.getIdentifier("status_bar", "id", "com.android.systemui")
|
||||
val status_bar_contents_ID: Int =
|
||||
res.getIdentifier("status_bar_contents", "id", "com.android.systemui")
|
||||
val system_icon_area_ID: Int =
|
||||
res.getIdentifier("system_icon_area", "id", "com.android.systemui")
|
||||
val clock_ID: Int = res.getIdentifier("clock", "id", "com.android.systemui")
|
||||
val phone_status_bar_left_container_ID: Int =
|
||||
res.getIdentifier("phone_status_bar_left_container", "id", "com.android.systemui")
|
||||
val fullscreen_notification_icon_area_ID: Int =
|
||||
res.getIdentifier("fullscreen_notification_icon_area", "id", "com.android.systemui")
|
||||
status_bar = MiuiPhoneStatusBarView.findViewById(status_bar_ID)
|
||||
val status_bar_contents: ViewGroup =
|
||||
MiuiPhoneStatusBarView.findViewById(status_bar_contents_ID)
|
||||
if (status_bar == null) return@hookAfterMethod
|
||||
val Clock: View = MiuiPhoneStatusBarView.findViewById(clock_ID)
|
||||
val phone_status_bar_left_container: ViewGroup =
|
||||
MiuiPhoneStatusBarView.findViewById(phone_status_bar_left_container_ID)
|
||||
val fullscreen_notification_icon_area: ViewGroup =
|
||||
MiuiPhoneStatusBarView.findViewById(fullscreen_notification_icon_area_ID)
|
||||
val system_icon_area: ViewGroup =
|
||||
MiuiPhoneStatusBarView.findViewById(system_icon_area_ID)
|
||||
|
||||
val clock_ID: Int = res.getIdentifier("clock", "id", "com.android.systemui")
|
||||
val phone_status_bar_left_container_ID: Int = res.getIdentifier(
|
||||
"phone_status_bar_left_container",
|
||||
"id",
|
||||
"com.android.systemui"
|
||||
)
|
||||
val fullscreen_notification_icon_area_ID: Int = res.getIdentifier(
|
||||
"fullscreen_notification_icon_area",
|
||||
"id",
|
||||
"com.android.systemui"
|
||||
)
|
||||
status_bar =
|
||||
MiuiPhoneStatusBarView.findViewById(status_bar_ID)
|
||||
val status_bar_contents: ViewGroup =
|
||||
MiuiPhoneStatusBarView.findViewById(status_bar_contents_ID)
|
||||
if (status_bar == null) return
|
||||
val Clock: View = MiuiPhoneStatusBarView.findViewById(clock_ID)
|
||||
val phone_status_bar_left_container: ViewGroup =
|
||||
MiuiPhoneStatusBarView.findViewById(phone_status_bar_left_container_ID)
|
||||
val fullscreen_notification_icon_area: ViewGroup =
|
||||
MiuiPhoneStatusBarView.findViewById(fullscreen_notification_icon_area_ID)
|
||||
val system_icon_area: ViewGroup =
|
||||
MiuiPhoneStatusBarView.findViewById(system_icon_area_ID)
|
||||
(Clock.parent as ViewGroup).removeView(Clock)
|
||||
(phone_status_bar_left_container.parent as ViewGroup).removeView(
|
||||
phone_status_bar_left_container
|
||||
)
|
||||
(fullscreen_notification_icon_area.parent as ViewGroup).removeView(
|
||||
fullscreen_notification_icon_area
|
||||
)
|
||||
(system_icon_area.parent as ViewGroup).removeView(system_icon_area)
|
||||
|
||||
val mConstraintLayoutLp = ConstraintLayout.LayoutParams(
|
||||
ConstraintLayout.LayoutParams.MATCH_PARENT,
|
||||
ConstraintLayout.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
|
||||
val mConstraintLayout =
|
||||
ConstraintLayout(context).also { it.layoutParams = mConstraintLayoutLp }
|
||||
|
||||
mConstraintLayout.addView(fullscreen_notification_icon_area)
|
||||
|
||||
val fullscreen_notification_icon_area_lp = FrameLayout.LayoutParams(
|
||||
ConstraintLayout.LayoutParams.MATCH_PARENT,
|
||||
ConstraintLayout.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
|
||||
fullscreen_notification_icon_area.layoutParams = fullscreen_notification_icon_area_lp
|
||||
|
||||
//增加一个左对齐布局
|
||||
mLeftLayout = LinearLayout(context)
|
||||
val LeftLp: LinearLayout.LayoutParams =
|
||||
LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1.0f)
|
||||
mLeftLayout!!.layoutParams = LeftLp
|
||||
mLeftLayout!!.gravity = Gravity.START or Gravity.CENTER_VERTICAL
|
||||
|
||||
//增加一个居中布局
|
||||
mCenterLayout = LinearLayout(context)
|
||||
val CenterLp: LinearLayout.LayoutParams = LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
mCenterLayout!!.layoutParams = CenterLp
|
||||
mCenterLayout!!.gravity = Gravity.CENTER or Gravity.CENTER_VERTICAL
|
||||
mRightLayout = LinearLayout(context)
|
||||
val RightLp: LinearLayout.LayoutParams =
|
||||
LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1.0f)
|
||||
mRightLayout!!.layoutParams = RightLp
|
||||
mRightLayout!!.gravity = Gravity.END or Gravity.CENTER_VERTICAL
|
||||
mLeftLayout!!.addView(phone_status_bar_left_container)
|
||||
mLeftLayout!!.addView(mConstraintLayout)
|
||||
|
||||
mCenterLayout!!.addView(Clock)
|
||||
mRightLayout!!.addView(system_icon_area)
|
||||
status_bar_contents.addView(mLeftLayout, 0)
|
||||
status_bar_contents.addView(mCenterLayout)
|
||||
status_bar_contents.addView(mRightLayout)
|
||||
|
||||
status_bar_left = status_bar!!.paddingLeft
|
||||
status_bar_top = status_bar!!.paddingTop
|
||||
status_bar_right = status_bar!!.paddingRight
|
||||
status_bar_bottom = status_bar!!.paddingBottom
|
||||
|
||||
|
||||
(Clock.parent as ViewGroup).removeView(Clock)
|
||||
(phone_status_bar_left_container.parent as ViewGroup).removeView(
|
||||
phone_status_bar_left_container
|
||||
)
|
||||
(fullscreen_notification_icon_area.parent as ViewGroup).removeView(
|
||||
fullscreen_notification_icon_area
|
||||
)
|
||||
(system_icon_area.parent as ViewGroup).removeView(system_icon_area)
|
||||
|
||||
|
||||
val mConstraintLayoutLp = ConstraintLayout.LayoutParams(
|
||||
ConstraintLayout.LayoutParams.MATCH_PARENT,
|
||||
ConstraintLayout.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
|
||||
val mConstraintLayout = ConstraintLayout(context).also {
|
||||
it.layoutParams = mConstraintLayoutLp
|
||||
}
|
||||
|
||||
mConstraintLayout.addView(fullscreen_notification_icon_area)
|
||||
|
||||
val fullscreen_notification_icon_area_lp = FrameLayout.LayoutParams(
|
||||
ConstraintLayout.LayoutParams.MATCH_PARENT,
|
||||
ConstraintLayout.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
|
||||
fullscreen_notification_icon_area.layoutParams =
|
||||
fullscreen_notification_icon_area_lp
|
||||
|
||||
//增加一个左对齐布局
|
||||
mLeftLayout = LinearLayout(context)
|
||||
val LeftLp: LinearLayout.LayoutParams =
|
||||
LinearLayout.LayoutParams(
|
||||
0,
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
1.0f
|
||||
)
|
||||
mLeftLayout!!.layoutParams = LeftLp
|
||||
mLeftLayout!!.gravity = Gravity.START or Gravity.CENTER_VERTICAL
|
||||
|
||||
//增加一个居中布局
|
||||
mCenterLayout = LinearLayout(context)
|
||||
val CenterLp: LinearLayout.LayoutParams = LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
mCenterLayout!!.layoutParams = CenterLp
|
||||
mCenterLayout!!.gravity = Gravity.CENTER or Gravity.CENTER_VERTICAL
|
||||
mRightLayout = LinearLayout(context)
|
||||
val RightLp: LinearLayout.LayoutParams =
|
||||
LinearLayout.LayoutParams(
|
||||
0,
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
1.0f
|
||||
)
|
||||
mRightLayout!!.layoutParams = RightLp
|
||||
mRightLayout!!.gravity = Gravity.END or Gravity.CENTER_VERTICAL
|
||||
mLeftLayout!!.addView(phone_status_bar_left_container)
|
||||
mLeftLayout!!.addView(mConstraintLayout)
|
||||
|
||||
mCenterLayout!!.addView(Clock)
|
||||
mRightLayout!!.addView(system_icon_area)
|
||||
status_bar_contents.addView(mLeftLayout, 0)
|
||||
status_bar_contents.addView(mCenterLayout)
|
||||
status_bar_contents.addView(mRightLayout)
|
||||
|
||||
status_bar_left = status_bar!!.paddingLeft
|
||||
status_bar_top = status_bar!!.paddingTop
|
||||
status_bar_right = status_bar!!.paddingRight
|
||||
status_bar_bottom = status_bar!!.paddingBottom
|
||||
|
||||
|
||||
if (XSPUtils.getBoolean("layout_compatibility_mode", false)) {
|
||||
val custom_left_margin = XSPUtils.getInt("status_bar_left_margin", 0)
|
||||
if (custom_left_margin != 0) {
|
||||
status_bar_left = custom_left_margin
|
||||
}
|
||||
|
||||
val custom_right_margin = XSPUtils.getInt("status_bar_right_margin", 0)
|
||||
if (custom_right_margin != 0) {
|
||||
status_bar_right = custom_right_margin
|
||||
}
|
||||
updateLayout(context)
|
||||
}
|
||||
|
||||
if (XSPUtils.getBoolean("layout_compatibility_mode", false)) {
|
||||
val custom_left_margin = XSPUtils.getInt("status_bar_left_margin", 0)
|
||||
if (custom_left_margin != 0) {
|
||||
status_bar_left = custom_left_margin
|
||||
}
|
||||
})
|
||||
|
||||
val classIfExists2 = XposedHelpers.findClassIfExists(
|
||||
"com.android.systemui.statusbar.phone.PhoneStatusBarView",
|
||||
lpparam.classLoader
|
||||
)
|
||||
|
||||
XposedHelpers.findAndHookMethod(
|
||||
classIfExists2,
|
||||
"updateLayoutForCutout",
|
||||
object : XC_MethodHook() {
|
||||
override fun afterHookedMethod(param: MethodHookParam) {
|
||||
if (XSPUtils.getBoolean("layout_compatibility_mode", false)) {
|
||||
val context = (param.thisObject as ViewGroup).context
|
||||
updateLayout(context)
|
||||
}
|
||||
val custom_right_margin = XSPUtils.getInt("status_bar_right_margin", 0)
|
||||
if (custom_right_margin != 0) {
|
||||
status_bar_right = custom_right_margin
|
||||
}
|
||||
updateLayout(context)
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
val phoneStatusBarViewClass =
|
||||
"com.android.systemui.statusbar.phone.PhoneStatusBarView".findClass(lpparam.classLoader)
|
||||
|
||||
phoneStatusBarViewClass.hookAfterMethod("updateLayoutForCutout") {
|
||||
if (XSPUtils.getBoolean("layout_compatibility_mode", false)) {
|
||||
val context = (it.thisObject as ViewGroup).context
|
||||
updateLayout(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -8,9 +8,10 @@ import android.util.AttributeSet
|
||||
import android.util.TypedValue
|
||||
import android.widget.TextView
|
||||
import com.lt2333.simplicitytools.util.XSPUtils
|
||||
import com.lt2333.simplicitytools.util.findClass
|
||||
import com.lt2333.simplicitytools.util.hookAfterConstructor
|
||||
import com.lt2333.simplicitytools.util.hookAfterMethod
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage
|
||||
import de.robv.android.xposed.XC_MethodHook
|
||||
import de.robv.android.xposed.XposedHelpers
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||
import java.lang.reflect.Method
|
||||
import java.text.SimpleDateFormat
|
||||
@@ -18,151 +19,113 @@ import java.util.*
|
||||
|
||||
class StatusBarTimeCustomization : IXposedHookLoadPackage {
|
||||
|
||||
private val isYear = XSPUtils.getBoolean("status_bar_time_year", false)
|
||||
private val isMonth = XSPUtils.getBoolean("status_bar_time_month", false)
|
||||
private val isDay = XSPUtils.getBoolean("status_bar_time_day", false)
|
||||
private val isWeek = XSPUtils.getBoolean("status_bar_time_week", false)
|
||||
private val isHideSpace = XSPUtils.getBoolean("status_bar_time_hide_space", false)
|
||||
private val isDoubleLine = XSPUtils.getBoolean("status_bar_time_double_line", false)
|
||||
private val isSecond = XSPUtils.getBoolean("status_bar_time_seconds", false)
|
||||
private val isDoubleHour = XSPUtils.getBoolean("status_bar_time_double_hour", false)
|
||||
private val isPeriod = XSPUtils.getBoolean("status_bar_time_period", true)
|
||||
private val getClockSize = XSPUtils.getInt("status_bar_clock_size", 0)
|
||||
private val isOpen = XSPUtils.getBoolean("custom_clock_switch", false)
|
||||
private val getClockDoubleSize = XSPUtils.getInt("status_bar_clock_double_line_size", 0)
|
||||
private var now_time: Date? = null
|
||||
private var str = ""
|
||||
|
||||
val isYear = XSPUtils.getBoolean("status_bar_time_year", false)
|
||||
val isMonth = XSPUtils.getBoolean("status_bar_time_month", false)
|
||||
val isDay = XSPUtils.getBoolean("status_bar_time_day", false)
|
||||
val isWeek = XSPUtils.getBoolean("status_bar_time_week", false)
|
||||
val isHideSpace = XSPUtils.getBoolean("status_bar_time_hide_space", false)
|
||||
val isDoubleLine = XSPUtils.getBoolean("status_bar_time_double_line", false)
|
||||
val isSecond = XSPUtils.getBoolean("status_bar_time_seconds", false)
|
||||
val isDoubleHour = XSPUtils.getBoolean("status_bar_time_double_hour", false)
|
||||
val isPeriod = XSPUtils.getBoolean("status_bar_time_period", true)
|
||||
val getClockSize = XSPUtils.getInt("status_bar_clock_size", 0)
|
||||
val isOpen = XSPUtils.getBoolean("custom_clock_switch", false)
|
||||
val getClockDoubleSize = XSPUtils.getInt("status_bar_clock_double_line_size", 0)
|
||||
|
||||
|
||||
var now_time: Date? = null
|
||||
var str = ""
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
||||
if (isOpen) {
|
||||
var c: Context? = null
|
||||
val classIfExists = XposedHelpers.findClassIfExists(
|
||||
"com.android.systemui.statusbar.views.MiuiClock",
|
||||
lpparam.classLoader
|
||||
)
|
||||
XposedHelpers.findAndHookConstructor(classIfExists,
|
||||
Context::class.java,
|
||||
AttributeSet::class.java,
|
||||
Integer.TYPE,
|
||||
object : XC_MethodHook() {
|
||||
override fun afterHookedMethod(param: MethodHookParam) {
|
||||
try {
|
||||
c = param.args[0] as Context
|
||||
val textV = param.thisObject as TextView
|
||||
textV.isSingleLine = false
|
||||
|
||||
if (isDoubleLine) {
|
||||
str = "\n"
|
||||
var clock_double_line_size = 7F
|
||||
if (getClockDoubleSize != 0) {
|
||||
clock_double_line_size =
|
||||
getClockDoubleSize
|
||||
.toFloat()
|
||||
}
|
||||
textV.setTextSize(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
clock_double_line_size
|
||||
)
|
||||
} else {
|
||||
if (getClockSize != 0) {
|
||||
val clock_size =
|
||||
getClockSize.toFloat()
|
||||
textV.setTextSize(TypedValue.COMPLEX_UNIT_DIP, clock_size)
|
||||
}
|
||||
}
|
||||
|
||||
val d: Method = textV.javaClass.getDeclaredMethod("updateTime")
|
||||
val r = Runnable {
|
||||
d.isAccessible = true
|
||||
d.invoke(textV)
|
||||
}
|
||||
|
||||
class T : TimerTask() {
|
||||
override fun run() {
|
||||
Handler(textV.context.mainLooper).post(r)
|
||||
}
|
||||
}
|
||||
if (textV.resources.getResourceEntryName(textV.id) == "clock")
|
||||
Timer().scheduleAtFixedRate(
|
||||
T(),
|
||||
1000 - System.currentTimeMillis() % 1000,
|
||||
1000
|
||||
)
|
||||
|
||||
} catch (e: java.lang.Exception) {
|
||||
val miuiClockClass = "com.android.systemui.statusbar.views.MiuiClock".findClass(lpparam.classLoader)
|
||||
miuiClockClass.hookAfterConstructor(Context::class.java, AttributeSet::class.java, Integer.TYPE) {
|
||||
try {
|
||||
c = it.args[0] as Context
|
||||
val textV = it.thisObject as TextView
|
||||
textV.isSingleLine = false
|
||||
if (isDoubleLine) {
|
||||
str = "\n"
|
||||
var clock_double_line_size = 7F
|
||||
if (getClockDoubleSize != 0) {
|
||||
clock_double_line_size = getClockDoubleSize.toFloat()
|
||||
}
|
||||
textV.setTextSize(TypedValue.COMPLEX_UNIT_DIP, clock_double_line_size)
|
||||
} else {
|
||||
if (getClockSize != 0) {
|
||||
val clock_size = getClockSize.toFloat()
|
||||
textV.setTextSize(TypedValue.COMPLEX_UNIT_DIP, clock_size)
|
||||
}
|
||||
}
|
||||
val d: Method = textV.javaClass.getDeclaredMethod("updateTime")
|
||||
val r = Runnable {
|
||||
d.isAccessible = true
|
||||
d.invoke(textV)
|
||||
}
|
||||
class T : TimerTask() {
|
||||
override fun run() {
|
||||
Handler(textV.context.mainLooper).post(r)
|
||||
}
|
||||
}
|
||||
if (textV.resources.getResourceEntryName(textV.id) == "clock")
|
||||
Timer().scheduleAtFixedRate(T(), 1000 - System.currentTimeMillis() % 1000, 1000)
|
||||
} catch (e: java.lang.Exception) {
|
||||
}
|
||||
)
|
||||
XposedHelpers.findAndHookMethod(classIfExists, "updateTime",
|
||||
object : XC_MethodHook() {
|
||||
@SuppressLint("SetTextI18n", "SimpleDateFormat")
|
||||
override fun afterHookedMethod(param: MethodHookParam) {
|
||||
try {
|
||||
val textV = param.thisObject as TextView
|
||||
if (textV.resources.getResourceEntryName(textV.id) == "clock") {
|
||||
val t = Settings.System.getString(
|
||||
c!!.contentResolver,
|
||||
Settings.System.TIME_12_24
|
||||
)
|
||||
now_time = Calendar.getInstance().time
|
||||
|
||||
textV.text = getDate(c!!, t) + str + getTime(c!!, t)
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
}
|
||||
miuiClockClass.hookAfterMethod("updateTime") {
|
||||
try {
|
||||
val textV = it.thisObject as TextView
|
||||
if (textV.resources.getResourceEntryName(textV.id) == "clock") {
|
||||
val t = Settings.System.getString(c!!.contentResolver, Settings.System.TIME_12_24)
|
||||
now_time = Calendar.getInstance().time
|
||||
textV.text = getDate(c!!, t) + str + getTime(c!!, t)
|
||||
}
|
||||
})
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
private fun getDate(context: Context, t: String): String {
|
||||
var DatePattern = ""
|
||||
var datePattern = ""
|
||||
val isZh = isZh(context)
|
||||
|
||||
if (isYear) {
|
||||
if (isZh) {
|
||||
DatePattern += "YY年"
|
||||
// if (!isHideSpace) DatePattern = "$DatePattern "
|
||||
datePattern += "YY年"
|
||||
// if (!isHideSpace) datePattern = "$datePattern "
|
||||
} else {
|
||||
DatePattern += "YY"
|
||||
if (isMonth || isDay) DatePattern += "/"
|
||||
datePattern += "YY"
|
||||
if (isMonth || isDay) datePattern += "/"
|
||||
}
|
||||
}
|
||||
if (isMonth) {
|
||||
if (isZh) {
|
||||
DatePattern += "M月"
|
||||
// if (!isHideSpace) DatePattern = "$DatePattern "
|
||||
datePattern += "M月"
|
||||
// if (!isHideSpace) datePattern = "$datePattern "
|
||||
} else {
|
||||
DatePattern += "M"
|
||||
if (isDay) DatePattern += "/"
|
||||
datePattern += "M"
|
||||
if (isDay) datePattern += "/"
|
||||
}
|
||||
}
|
||||
if (isDay) {
|
||||
if (isZh) {
|
||||
DatePattern += "d日"
|
||||
datePattern += if (isZh) {
|
||||
"d日"
|
||||
} else {
|
||||
DatePattern += "d"
|
||||
"d"
|
||||
}
|
||||
}
|
||||
|
||||
if (isWeek) {
|
||||
if (!isHideSpace) DatePattern = "$DatePattern "
|
||||
DatePattern += "E"
|
||||
if (!isHideSpace) datePattern = "$datePattern "
|
||||
datePattern += "E"
|
||||
if (!isDoubleLine) {
|
||||
if (!isHideSpace) DatePattern = "$DatePattern "
|
||||
if (!isHideSpace) datePattern = "$datePattern "
|
||||
}
|
||||
}
|
||||
|
||||
DatePattern = SimpleDateFormat(DatePattern).format(now_time)
|
||||
|
||||
return DatePattern
|
||||
datePattern = SimpleDateFormat(datePattern).format(now_time)
|
||||
return datePattern
|
||||
}
|
||||
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
@@ -171,13 +134,9 @@ class StatusBarTimeCustomization : IXposedHookLoadPackage {
|
||||
val isZh = isZh(context)
|
||||
timePattern += if (t == "24") "HH:mm" else "h:mm"
|
||||
if (isSecond) timePattern += ":ss"
|
||||
|
||||
timePattern = SimpleDateFormat(timePattern).format(now_time)
|
||||
|
||||
if (isZh) timePattern = getPeriod(isZh) + timePattern else timePattern += getPeriod(isZh)
|
||||
|
||||
timePattern = getDoubleHour() + timePattern
|
||||
|
||||
return timePattern
|
||||
}
|
||||
|
||||
@@ -186,8 +145,7 @@ class StatusBarTimeCustomization : IXposedHookLoadPackage {
|
||||
var period = ""
|
||||
if (isPeriod) {
|
||||
if (isZh) {
|
||||
val now = SimpleDateFormat("HH").format(now_time)
|
||||
when (now) {
|
||||
when (SimpleDateFormat("HH").format(now_time)) {
|
||||
"00", "01", "02", "03", "04", "05" -> {
|
||||
period = "凌晨"
|
||||
}
|
||||
@@ -222,8 +180,7 @@ class StatusBarTimeCustomization : IXposedHookLoadPackage {
|
||||
private fun getDoubleHour(): String {
|
||||
var doubleHour = ""
|
||||
if (isDoubleHour) {
|
||||
val now = SimpleDateFormat("HH").format(now_time)
|
||||
when (now) {
|
||||
when (SimpleDateFormat("HH").format(now_time)) {
|
||||
"23", "00" -> {
|
||||
doubleHour = "子时"
|
||||
}
|
||||
@@ -268,7 +225,7 @@ class StatusBarTimeCustomization : IXposedHookLoadPackage {
|
||||
return doubleHour
|
||||
}
|
||||
|
||||
fun isZh(context: Context): Boolean {
|
||||
private fun isZh(context: Context): Boolean {
|
||||
val locale = context.resources.configuration.locale
|
||||
val language = locale.language
|
||||
return language.endsWith("zh")
|
||||
|
||||
Reference in New Issue
Block a user