From d2ff9d61e73380b1419efe816b88d6ce81ebf7fd Mon Sep 17 00:00:00 2001 From: YuKongA <70465933+YuKongA@users.noreply.github.com> Date: Sun, 13 Mar 2022 20:50:07 +0800 Subject: [PATCH] =?UTF-8?q?Feature:=20=E9=94=81=E5=B1=8F=E7=94=B5=E6=B5=81?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E5=B1=95=E7=A4=BA=20(#65)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/proguard-rules.pro | 4 + .../activity/SettingsActivity.kt | 8 + .../lt2333/simplicitytools/hook/MainHook.kt | 8 +- .../simplicitytools/hook/app/SystemUI.kt | 2 + .../hook/app/systemui/LockScreenCurrent.kt | 140 ++++++++++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 3 + app/src/main/res/values-zh-rHK/strings.xml | 3 + app/src/main/res/values-zh-rTW/strings.xml | 3 + app/src/main/res/values/strings.xml | 3 + 9 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/lt2333/simplicitytools/hook/app/systemui/LockScreenCurrent.kt diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 50e3228e..e20ed21e 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -23,6 +23,10 @@ public void *(de.robv.android.xposed.callbacks.XC_LoadPackage$LoadPackageParam); } +-keep class * implements de.robv.android.xposed.IXposedHookZygoteInit { + public void *(de.robv.android.xposed.IXposedHookZygoteInit$StartupParam); +} + -assumenosideeffects class kotlin.jvm.internal.Intrinsics { public static void check*(...); public static void throw*(...); diff --git a/app/src/main/java/com/lt2333/simplicitytools/activity/SettingsActivity.kt b/app/src/main/java/com/lt2333/simplicitytools/activity/SettingsActivity.kt index 3f304037..b4f12978 100644 --- a/app/src/main/java/com/lt2333/simplicitytools/activity/SettingsActivity.kt +++ b/app/src/main/java/com/lt2333/simplicitytools/activity/SettingsActivity.kt @@ -942,6 +942,14 @@ class SettingsActivity : MIUIActivity() { SwitchV("enable_wave_charge_animation") ) ) + add( + TextSummaryWithSwitchV( + TextSummaryV( + textId = R.string.lock_screen_current, + ), + SwitchV("lock_screen_current") + ) + ) } } diff --git a/app/src/main/java/com/lt2333/simplicitytools/hook/MainHook.kt b/app/src/main/java/com/lt2333/simplicitytools/hook/MainHook.kt index 89998371..4c1be34e 100644 --- a/app/src/main/java/com/lt2333/simplicitytools/hook/MainHook.kt +++ b/app/src/main/java/com/lt2333/simplicitytools/hook/MainHook.kt @@ -4,11 +4,17 @@ import com.github.kyuubiran.ezxhelper.init.EzXHelperInit import com.lt2333.simplicitytools.BuildConfig import com.lt2333.simplicitytools.hook.app.* import de.robv.android.xposed.IXposedHookLoadPackage +import de.robv.android.xposed.IXposedHookZygoteInit import de.robv.android.xposed.XSharedPreferences import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam -class MainHook : IXposedHookLoadPackage { +class MainHook : IXposedHookLoadPackage,IXposedHookZygoteInit { private var prefs = XSharedPreferences(BuildConfig.APPLICATION_ID, "config") + + override fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam) { + EzXHelperInit.initZygote(startupParam) + } + override fun handleLoadPackage(lpparam: LoadPackageParam) { if (prefs.getBoolean("main_switch", true)) { EzXHelperInit.initHandleLoadPackage(lpparam) diff --git a/app/src/main/java/com/lt2333/simplicitytools/hook/app/SystemUI.kt b/app/src/main/java/com/lt2333/simplicitytools/hook/app/SystemUI.kt index cd867782..cb6d3c84 100644 --- a/app/src/main/java/com/lt2333/simplicitytools/hook/app/SystemUI.kt +++ b/app/src/main/java/com/lt2333/simplicitytools/hook/app/SystemUI.kt @@ -70,6 +70,8 @@ class SystemUI : IXposedHookLoadPackage { HideNetworkSpeedSplitter().handleLoadPackage(lpparam) //Alpha充电动画 WaveCharge().handleLoadPackage(lpparam) + //锁屏电流 + LockScreenCurrent().handleLoadPackage(lpparam) } } diff --git a/app/src/main/java/com/lt2333/simplicitytools/hook/app/systemui/LockScreenCurrent.kt b/app/src/main/java/com/lt2333/simplicitytools/hook/app/systemui/LockScreenCurrent.kt new file mode 100644 index 00000000..0c6081af --- /dev/null +++ b/app/src/main/java/com/lt2333/simplicitytools/hook/app/systemui/LockScreenCurrent.kt @@ -0,0 +1,140 @@ +package com.lt2333.simplicitytools.hook.app.systemui + +import android.annotation.SuppressLint +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.graphics.Typeface +import android.view.Gravity +import android.view.ViewGroup +import android.widget.TextView +import cn.fkj233.ui.activity.dp2px +import com.github.kyuubiran.ezxhelper.init.InitFields +import com.lt2333.simplicitytools.R +import com.lt2333.simplicitytools.util.findClass +import com.lt2333.simplicitytools.util.hasEnable +import com.lt2333.simplicitytools.util.hookAfterAllMethods +import com.lt2333.simplicitytools.util.hookAfterMethod +import com.microsoft.appcenter.utils.HandlerUtils.runOnUiThread +import de.robv.android.xposed.IXposedHookLoadPackage +import de.robv.android.xposed.callbacks.XC_LoadPackage +import java.io.BufferedReader +import java.io.FileReader +import java.lang.reflect.Method +import java.util.* +import kotlin.math.roundToInt + +class LockScreenCurrent(private var battery: String = "") : IXposedHookLoadPackage { + + override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) { + hasEnable("lock_screen_current") { + val miuiPhoneStatusBarViewClass = + "com.android.systemui.statusbar.phone.KeyguardBottomAreaView".findClass(lpparam.classLoader) + miuiPhoneStatusBarViewClass.hookAfterMethod("onFinishInflate") { param -> + val viewGroup = param.thisObject as ViewGroup + battery = getSystemBattery(viewGroup.context) + val textView = TextView(viewGroup.context).also { + it.typeface = Typeface.defaultFromStyle(Typeface.BOLD) + it.textSize = dp2px(viewGroup.context, 5f).toFloat() + } + textView.gravity = Gravity.CENTER or Gravity.BOTTOM + textView.setPadding(0, 0, 0, dp2px(viewGroup.context, 5f)) + Timer().schedule(object : TimerTask() { + override fun run() { + runOnUiThread { + textView.text = getCurrent() + } + } + + }, 0, 1000) + val darkIconDispatcherClass = + "com.android.systemui.plugins.DarkIconDispatcher".findClass(lpparam.classLoader) + darkIconDispatcherClass.hookAfterAllMethods("getTint") { + val areaTint = it.args[2] as Int + textView.setTextColor(areaTint) + } + viewGroup.addView(textView) + } + } + } + + /** + * 原始代码来自 CSDN + * https://blog.csdn.net/zhangyongfeiyong/article/details/53641809 + */ + @SuppressLint("PrivateApi") + private fun getCurrent(): String { + var result = "" + try { + val systemProperties = Class.forName("android.os.SystemProperties") + val get = systemProperties.getDeclaredMethod("get", String::class.java) as Method + val platName = get.invoke(null, "ro.hardware") as String + if (platName.startsWith("mt") || platName.startsWith("MT")) { + val filePath = + "/sys/class/power_supply/battery/device/FG_Battery_CurrentConsumption" + result = "${(getMeanCurrentVal(filePath, 5, 0) / 1000.0f).roundToInt()} mA" + } else if (platName.startsWith("qcom")) { + val filePath = "/sys/class/power_supply/battery/current_now" + val current = (getMeanCurrentVal(filePath, 5, 0) / 1000.0f).roundToInt() + result = if (current < 0) { + "${InitFields.moduleRes.getString(R.string.current_current)}$current mA,${InitFields.moduleRes.getString(R.string.charging)}$battery%".replace("-", "") + } else { + "${InitFields.moduleRes.getString(R.string.current_current)}-$current mA" + } + } + } catch (e: Exception) { + e.printStackTrace() + } + return result + } + + /** + * 获取平均电流值 + * 获取 filePath 文件 totalCount 次数的平均值,每次采样间隔 intervalMs 时间 + */ + private fun getMeanCurrentVal(filePath: String, totalCount: Int, intervalMs: Int): Float { + var meanVal = 0.0f + if (totalCount <= 0) { + return 0.0f + } + for (i in 0 until totalCount) { + try { + val f: Float = readFile(filePath, 0).toFloat() + meanVal += f / totalCount + } catch (e: Exception) { + e.printStackTrace() + } + if (intervalMs <= 0) { + continue + } + try { + Thread.sleep(intervalMs.toLong()) + } catch (e: Exception) { + e.printStackTrace() + } + } + return meanVal + } + + private fun readFile(path: String, defaultValue: Int): Int { + try { + val bufferedReader = BufferedReader(FileReader(path)) + val i: Int = bufferedReader.readLine().toInt(10) + bufferedReader.close() + return i + } catch (localException: java.lang.Exception) { + } + return defaultValue + } + + private fun getSystemBattery(context: Context): String { + val batteryInfoIntent: Intent? = context.applicationContext.registerReceiver( + null, + IntentFilter(Intent.ACTION_BATTERY_CHANGED) + ) + val level: Int = batteryInfoIntent!!.getIntExtra("level", 0) + val batterySum = batteryInfoIntent.getIntExtra("scale", 100) + val percentBattery = 100 * level / batterySum + return percentBattery.toString() + } +} \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 81728b18..747e7025 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -152,4 +152,7 @@ 当前值: 参与翻译 帮助我们将应用翻译成您的语言 + 锁屏显示电流信息 + 当前电流: + 充电中: diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index c5e12d82..65b9e930 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -152,4 +152,7 @@ 當前值: 參與翻譯 幫助我們將這個APP翻譯成您的語言 + 锁屏显示电流信息 + 當前電流: + 充電中: diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 9844e0ae..828e7850 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -152,4 +152,7 @@ 當前值: 參與評估 幫助我們將這個APP翻譯成您的語言 + 锁屏显示电流信息 + 當前電流: + 充電中: diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bb25da1d..8a0c5247 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -156,4 +156,7 @@ Current: Participate in translation Help us translate the app into your language + Lock screen displays current information + current: + charging: