mirror of
https://github.com/fankes/TSBattery.git
synced 2025-09-04 17:55:30 +08:00
Compare commits
20 Commits
Author | SHA1 | Date | |
---|---|---|---|
2be9a3d934
|
|||
d7dbecb65c
|
|||
6c2b3f12b3
|
|||
f1c520586a
|
|||
e9c99343c3
|
|||
20de713ffd
|
|||
3b78e8a515
|
|||
cf898092bd
|
|||
251a5151df
|
|||
59e93bc040
|
|||
d440e85be4
|
|||
e1dc99de01
|
|||
4eab1f7046
|
|||
3fc294dd8d
|
|||
a2c06cc201 | |||
6f39d5fdab | |||
5ada7585e3 | |||
31b8f157e5 | |||
e71f137f74 | |||
9e9bbcc8ca |
@@ -2,7 +2,7 @@
|
||||
|
||||
[](https://github.com/fankes/TSBattery)
|
||||
[](https://github.com/fankes/TSBattery/blob/master/LICENSE)
|
||||
[](https://github.com/fankes/TSBattery/releases)
|
||||
[](https://github.com/fankes/TSBattery/releases)
|
||||
[](https://github.com/fankes/TSBattery/releases)
|
||||
[](https://github.com/Xposed-Modules-Repo/com.fankes.tsbattery/releases)
|
||||
[](https://t.me/XiaofangInternet)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'kotlin-android'
|
||||
id 'com.google.devtools.ksp' version '1.6.20-1.0.5'
|
||||
id 'com.google.devtools.ksp' version '1.6.21-1.0.5'
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -31,6 +31,8 @@ android {
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled rootProject.ext.enableR8
|
||||
shrinkResources rootProject.ext.enableR8
|
||||
zipAlignEnabled rootProject.ext.enableR8
|
||||
signingConfig signingConfigs.debug
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
@@ -50,34 +52,20 @@ android {
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
}
|
||||
|
||||
/** 移除无效耗时 lint Task */
|
||||
tasks.whenTaskAdded {
|
||||
task -> if (task.name == "lintVitalRelease") task.enabled = false
|
||||
}
|
||||
|
||||
/** 移除无效耗时 lint Task */
|
||||
tasks.whenTaskAdded {
|
||||
task -> if (task.name == "lintVitalAnalyzeRelease") task.enabled = false
|
||||
}
|
||||
|
||||
/** 移除无效耗时 lint Task */
|
||||
tasks.whenTaskAdded {
|
||||
task -> if (task.name == "lintVitalReportRelease") task.enabled = false
|
||||
lintOptions {
|
||||
checkReleaseBuilds false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly 'de.robv.android.xposed:api:82'
|
||||
implementation 'com.highcapable.yukihookapi:api:1.0.80'
|
||||
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.0.80'
|
||||
implementation 'com.highcapable.yukihookapi:api:1.0.92'
|
||||
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.0.92'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
|
||||
implementation 'com.geyifeng.immersionbar:immersionbar:3.2.0'
|
||||
implementation 'com.geyifeng.immersionbar:immersionbar-ktx:3.2.0'
|
||||
implementation 'androidx.core:core-ktx:1.7.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||
implementation 'com.google.android.material:material:1.5.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
||||
implementation 'com.google.android.material:material:1.6.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
|
@@ -54,7 +54,7 @@ import com.highcapable.yukihookapi.hook.type.android.*
|
||||
import com.highcapable.yukihookapi.hook.type.java.*
|
||||
import com.highcapable.yukihookapi.hook.xposed.proxy.IYukiHookXposedInit
|
||||
|
||||
@InjectYukiHookWithXposed
|
||||
@InjectYukiHookWithXposed(isUsingResourcesHook = false)
|
||||
class HookEntry : IYukiHookXposedInit {
|
||||
|
||||
companion object {
|
||||
@@ -130,7 +130,7 @@ class HookEntry : IYukiHookXposedInit {
|
||||
interceptBaseChatPie(methodName = "bk")
|
||||
interceptBaseChatPie(methodName = "bl")
|
||||
}
|
||||
"8.8.83", "8.8.85", "8.8.88" -> {
|
||||
"8.8.83", "8.8.85", "8.8.88", "8.8.90" -> {
|
||||
interceptBaseChatPie(methodName = "bl")
|
||||
interceptBaseChatPie(methodName = "bm")
|
||||
}
|
||||
@@ -400,6 +400,7 @@ class HookEntry : IYukiHookXposedInit {
|
||||
debugTag = "TSBattery"
|
||||
isDebug = false
|
||||
isEnableModulePrefsCache = false
|
||||
isEnableDataChannel = false
|
||||
}
|
||||
|
||||
override fun onHook() = encase {
|
||||
|
@@ -37,10 +37,9 @@ import com.fankes.tsbattery.hook.HookConst.WECHAT_PACKAGE_NAME
|
||||
import com.fankes.tsbattery.ui.activity.base.BaseActivity
|
||||
import com.fankes.tsbattery.utils.factory.*
|
||||
import com.fankes.tsbattery.utils.tool.GithubReleaseTool
|
||||
import com.highcapable.yukihookapi.hook.factory.isModuleActive
|
||||
import com.highcapable.yukihookapi.hook.factory.isTaiChiModuleActive
|
||||
import com.fankes.tsbattery.utils.tool.YukiPromoteTool
|
||||
import com.highcapable.yukihookapi.YukiHookAPI
|
||||
import com.highcapable.yukihookapi.hook.factory.modulePrefs
|
||||
import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus
|
||||
|
||||
class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
|
||||
@@ -48,7 +47,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
|
||||
private const val moduleVersion = BuildConfig.VERSION_NAME
|
||||
private const val qqSupportVersion =
|
||||
"8.2.11(Play)、8.8.17、8.8.23、8.8.35、8.8.38、8.8.50、8.8.55、8.8.68、8.8.80、8.8.83、8.8.85、8.8.88 (8.2.11、8.5.5~8.8.88)"
|
||||
"8.2.11(Play)、8.8.17、8.8.23、8.8.35、8.8.38、8.8.50、8.8.55、8.8.68、8.8.80、8.8.83、8.8.85、8.8.88、8.8.90 (8.2.11、8.5.5~8.8.90)"
|
||||
private const val timSupportVersion = "2+、3+ (并未完全测试每个版本)"
|
||||
private const val wechatSupportVersion = "全版本仅支持基础省电,更多功能依然画饼"
|
||||
|
||||
@@ -66,7 +65,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
}
|
||||
}
|
||||
/** 判断 Hook 状态 */
|
||||
if (isModuleActive) {
|
||||
if (YukiHookAPI.Status.isModuleActive) {
|
||||
binding.mainLinStatus.setBackgroundResource(R.drawable.bg_green_round)
|
||||
binding.mainImgStatus.setImageResource(R.mipmap.ic_success)
|
||||
binding.mainTextStatus.text = "模块已激活"
|
||||
@@ -74,6 +73,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
refreshActivateExecutor()
|
||||
/** 写入激活的模块版本 */
|
||||
modulePrefs.put(DataConst.ENABLE_MODULE_VERSION, moduleVersion)
|
||||
/** 推广、恰饭 */
|
||||
YukiPromoteTool.promote(context = this)
|
||||
} else
|
||||
showDialog {
|
||||
title = "模块没有激活"
|
||||
@@ -89,7 +90,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
noCancelable()
|
||||
}
|
||||
/** 推荐使用 LSPosed */
|
||||
if (isTaiChiModuleActive)
|
||||
if (YukiHookAPI.Status.isTaiChiModuleActive)
|
||||
showDialog {
|
||||
title = "兼容性提示"
|
||||
msg = "若你的设备已 Root,推荐使用 LSPosed 激活模块,太极可能会出现模块设置无法保存的问题。"
|
||||
@@ -201,10 +202,10 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
/** 刷新模块激活使用的方式 */
|
||||
private fun refreshActivateExecutor() {
|
||||
when {
|
||||
YukiHookModuleStatus.executorVersion > 0 ->
|
||||
YukiHookAPI.Status.executorVersion > 0 ->
|
||||
binding.mainTextApiWay.text =
|
||||
"Activated by ${YukiHookModuleStatus.executorName} API ${YukiHookModuleStatus.executorVersion}"
|
||||
isTaiChiModuleActive -> binding.mainTextApiWay.text = "Activated by TaiChi"
|
||||
"Activated by ${YukiHookAPI.Status.executorName} API ${YukiHookAPI.Status.executorVersion}"
|
||||
YukiHookAPI.Status.isTaiChiModuleActive -> binding.mainTextApiWay.text = "Activated by TaiChi"
|
||||
else -> binding.mainTextApiWay.text = "Activated by anonymous"
|
||||
}
|
||||
}
|
||||
|
@@ -23,12 +23,14 @@
|
||||
|
||||
package com.fankes.tsbattery.ui.activity.base
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.fankes.tsbattery.R
|
||||
import com.fankes.tsbattery.utils.factory.isNotSystemInDarkMode
|
||||
import com.gyf.immersionbar.ktx.immersionBar
|
||||
import com.highcapable.yukihookapi.hook.factory.method
|
||||
import com.highcapable.yukihookapi.hook.type.android.LayoutInflaterClass
|
||||
import java.lang.reflect.ParameterizedType
|
||||
@@ -52,13 +54,14 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
||||
/** 隐藏系统的标题栏 */
|
||||
supportActionBar?.hide()
|
||||
/** 初始化沉浸状态栏 */
|
||||
immersionBar {
|
||||
statusBarColor(R.color.colorThemeBackground)
|
||||
autoDarkModeEnable(true)
|
||||
statusBarDarkFont(isNotSystemInDarkMode)
|
||||
navigationBarColor(R.color.colorThemeBackground)
|
||||
navigationBarDarkIcon(isNotSystemInDarkMode)
|
||||
fitsSystemWindows(true)
|
||||
ViewCompat.getWindowInsetsController(window.decorView)?.apply {
|
||||
isAppearanceLightStatusBars = isNotSystemInDarkMode
|
||||
isAppearanceLightNavigationBars = isNotSystemInDarkMode
|
||||
}
|
||||
ResourcesCompat.getColor(resources, R.color.colorThemeBackground, null).also {
|
||||
window?.statusBarColor = it
|
||||
window?.navigationBarColor = it
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) window?.navigationBarDividerColor = it
|
||||
}
|
||||
/** 装载子类 */
|
||||
onCreate()
|
||||
|
@@ -44,10 +44,10 @@ import com.highcapable.yukihookapi.hook.type.android.LayoutInflaterClass
|
||||
/**
|
||||
* 构造对话框
|
||||
* @param isUseBlackTheme 是否使用深色主题
|
||||
* @param it 对话框方法体
|
||||
* @param initiate 对话框方法体
|
||||
*/
|
||||
fun Context.showDialog(isUseBlackTheme: Boolean = false, it: DialogBuilder.() -> Unit) =
|
||||
DialogBuilder(this, isUseBlackTheme).apply(it).show()
|
||||
fun Context.showDialog(isUseBlackTheme: Boolean = false, initiate: DialogBuilder.() -> Unit) =
|
||||
DialogBuilder(context = this, isUseBlackTheme).apply(initiate).show()
|
||||
|
||||
/**
|
||||
* 对话框构造器
|
||||
@@ -140,34 +140,34 @@ class DialogBuilder(val context: Context, private val isUseBlackTheme: Boolean)
|
||||
/**
|
||||
* 设置对话框确定按钮
|
||||
* @param text 按钮文本内容
|
||||
* @param it 点击事件
|
||||
* @param callback 点击事件
|
||||
*/
|
||||
fun confirmButton(text: String = "确定", it: () -> Unit = {}) {
|
||||
fun confirmButton(text: String = "确定", callback: () -> Unit = {}) {
|
||||
if (isUsingAndroidX)
|
||||
runInSafe { instanceAndroidX?.setPositiveButton(text) { _, _ -> it() } }
|
||||
else runInSafe { instanceAndroid?.setPositiveButton(text) { _, _ -> it() } }
|
||||
runInSafe { instanceAndroidX?.setPositiveButton(text) { _, _ -> callback() } }
|
||||
else runInSafe { instanceAndroid?.setPositiveButton(text) { _, _ -> callback() } }
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置对话框取消按钮
|
||||
* @param text 按钮文本内容
|
||||
* @param it 点击事件
|
||||
* @param callback 点击事件
|
||||
*/
|
||||
fun cancelButton(text: String = "取消", it: () -> Unit = {}) {
|
||||
fun cancelButton(text: String = "取消", callback: () -> Unit = {}) {
|
||||
if (isUsingAndroidX)
|
||||
runInSafe { instanceAndroidX?.setNegativeButton(text) { _, _ -> it() } }
|
||||
else runInSafe { instanceAndroid?.setNegativeButton(text) { _, _ -> it() } }
|
||||
runInSafe { instanceAndroidX?.setNegativeButton(text) { _, _ -> callback() } }
|
||||
else runInSafe { instanceAndroid?.setNegativeButton(text) { _, _ -> callback() } }
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置对话框第三个按钮
|
||||
* @param text 按钮文本内容
|
||||
* @param it 点击事件
|
||||
* @param callback 点击事件
|
||||
*/
|
||||
fun neutralButton(text: String = "更多", it: () -> Unit = {}) {
|
||||
fun neutralButton(text: String = "更多", callback: () -> Unit = {}) {
|
||||
if (isUsingAndroidX)
|
||||
runInSafe { instanceAndroidX?.setNeutralButton(text) { _, _ -> it() } }
|
||||
else runInSafe { instanceAndroid?.setNeutralButton(text) { _, _ -> it() } }
|
||||
runInSafe { instanceAndroidX?.setNeutralButton(text) { _, _ -> callback() } }
|
||||
else runInSafe { instanceAndroid?.setNeutralButton(text) { _, _ -> callback() } }
|
||||
}
|
||||
|
||||
/** 取消对话框 */
|
||||
|
@@ -137,13 +137,13 @@ fun toast(msg: String) = Toast.makeText(appContext, msg, Toast.LENGTH_SHORT).sho
|
||||
* 弹出 [Snackbar]
|
||||
* @param msg 提示内容
|
||||
* @param actionText 按钮文本 - 不写默认取消按钮
|
||||
* @param it 按钮事件回调
|
||||
* @param callback 按钮事件回调
|
||||
*/
|
||||
fun Context.snake(msg: String, actionText: String = "", it: () -> Unit = {}) =
|
||||
fun Context.snake(msg: String, actionText: String = "", callback: () -> Unit = {}) =
|
||||
Snackbar.make((this as Activity).findViewById(android.R.id.content), msg, Snackbar.LENGTH_LONG).apply {
|
||||
if (actionText.isBlank()) return@apply
|
||||
setActionTextColor(if (isSystemInDarkMode) Color.BLACK else Color.WHITE)
|
||||
setAction(actionText) { it() }
|
||||
setAction(actionText) { callback() }
|
||||
}.show()
|
||||
|
||||
/**
|
||||
|
@@ -44,9 +44,9 @@ object GithubReleaseTool {
|
||||
* 获取最新版本信息
|
||||
* @param context 实例
|
||||
* @param version 当前版本
|
||||
* @param it 成功后回调 - ([String] 最新版本,[Function] 更新对话框方法体)
|
||||
* @param result 成功后回调 - ([String] 最新版本,[Function] 更新对话框方法体)
|
||||
*/
|
||||
fun checkingForUpdate(context: Context, version: String, it: (String, () -> Unit) -> Unit) = checkingInternetConnect(context) {
|
||||
fun checkingForUpdate(context: Context, version: String, result: (String, () -> Unit) -> Unit) = checkingInternetConnect(context) {
|
||||
OkHttpClient().newBuilder().build().newCall(
|
||||
Request.Builder()
|
||||
.url("https://api.github.com/repos/$REPO_AUTHOR/$REPO_NAME/releases/latest")
|
||||
@@ -72,7 +72,7 @@ object GithubReleaseTool {
|
||||
}
|
||||
if (name != version) (context as? Activity?)?.runOnUiThread {
|
||||
showUpdate()
|
||||
it(name) { showUpdate() }
|
||||
result(name) { showUpdate() }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,9 +83,9 @@ object GithubReleaseTool {
|
||||
/**
|
||||
* 检查网络连接情况
|
||||
* @param context 实例
|
||||
* @param it 已连接回调
|
||||
* @param callback 已连接回调
|
||||
*/
|
||||
private fun checkingInternetConnect(context: Context, it: () -> Unit) = runInSafe {
|
||||
private fun checkingInternetConnect(context: Context, callback: () -> Unit) = runInSafe {
|
||||
if (isNetWorkSuccess)
|
||||
OkHttpClient().newBuilder().build().newCall(
|
||||
Request.Builder()
|
||||
@@ -106,7 +106,7 @@ object GithubReleaseTool {
|
||||
}
|
||||
|
||||
override fun onResponse(call: Call, response: Response) = runInSafe {
|
||||
(context as? Activity?)?.runOnUiThread { runInSafe { it() } }
|
||||
(context as? Activity?)?.runOnUiThread { runInSafe { callback() } }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com)
|
||||
* https://github.com/fankes/TSBattery
|
||||
*
|
||||
* This software is non-free but opensource software: you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/5/30.
|
||||
*/
|
||||
package com.fankes.tsbattery.utils.tool
|
||||
|
||||
import android.content.Context
|
||||
import com.fankes.tsbattery.utils.factory.openBrowser
|
||||
import com.fankes.tsbattery.utils.factory.showDialog
|
||||
import com.highcapable.yukihookapi.YukiHookAPI
|
||||
import com.highcapable.yukihookapi.hook.factory.modulePrefs
|
||||
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
|
||||
|
||||
/**
|
||||
* [YukiHookAPI] 的自动推广工具类
|
||||
*/
|
||||
object YukiPromoteTool {
|
||||
|
||||
/** 推广已读存储键值 */
|
||||
private val YUKI_PROMOTE_READED = PrefsData("yuki_promote_readed", false)
|
||||
|
||||
/**
|
||||
* 显示推广对话框
|
||||
* @param context 实例
|
||||
*/
|
||||
fun promote(context: Context) {
|
||||
fun saveReaded() = context.modulePrefs.put(YUKI_PROMOTE_READED, value = true)
|
||||
if (context.modulePrefs.get(YUKI_PROMOTE_READED).not())
|
||||
context.showDialog {
|
||||
title = "面向开发者的推广"
|
||||
msg = "你想快速拥有一个自己的 Xposed 模块吗,你只需要拥有基础的 Android 开发经验以及使用 Kotlin 编程语言即可。\n\n" +
|
||||
"快来体验 YukiHookAPI,这是一个使用 Kotlin 重新构建的高效 Xposed Hook API,助你的开发变得更轻松。"
|
||||
confirmButton(text = "去看看") {
|
||||
context.openBrowser(url = "https://github.com/fankes/YukiHookAPI")
|
||||
saveReaded()
|
||||
}
|
||||
cancelButton(text = "我不是开发者") { saveReaded() }
|
||||
noCancelable()
|
||||
}
|
||||
}
|
||||
}
|
10
build.gradle
10
build.gradle
@@ -1,12 +1,12 @@
|
||||
plugins {
|
||||
id 'com.android.application' version '7.1.3' apply false
|
||||
id 'com.android.library' version '7.1.3' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.6.20' apply false
|
||||
id 'com.android.application' version '7.2.0' apply false
|
||||
id 'com.android.library' version '7.2.0' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.6.21' apply false
|
||||
}
|
||||
|
||||
ext {
|
||||
appVersionName = "3.8"
|
||||
appVersionCode = 16
|
||||
appVersionName = "3.95"
|
||||
appVersionCode = 18
|
||||
enableR8 = true
|
||||
}
|
||||
|
||||
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
#Mon Feb 14 23:27:58 CST 2022
|
||||
#Wed May 25 04:34:58 CST 2022
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
Reference in New Issue
Block a user