feat: lots of changes

- add BuildConfigWrapper
- merge to new project promote
- add ci version tag support
- add open parasitic from Host App
This commit is contained in:
2023-09-16 01:10:27 +08:00
parent bd027b37f5
commit c9d49a398f
8 changed files with 166 additions and 98 deletions

View File

@@ -19,8 +19,13 @@
* *
* This file is Created by fankes on 2022/9/29. * This file is Created by fankes on 2022/9/29.
*/ */
@file:Suppress("MemberVisibilityCanBePrivate")
package com.fankes.tsbattery.const package com.fankes.tsbattery.const
import com.fankes.tsbattery.generated.AppProperties
import com.fankes.tsbattery.wrapper.BuildConfigWrapper
/** /**
* 包名常量定义类 * 包名常量定义类
*/ */
@@ -43,4 +48,27 @@ object JumpEvent {
/** 启动模块设置 */ /** 启动模块设置 */
const val OPEN_MODULE_SETTING = "tsbattery_open_module_settings" const val OPEN_MODULE_SETTING = "tsbattery_open_module_settings"
}
/**
* 模块版本常量定义类
*/
object ModuleVersion {
/** 当前 GitHub 提交的 ID (CI 自动构建) */
const val GITHUB_COMMIT_ID = AppProperties.GITHUB_CI_COMMIT_ID
/** 版本名称 */
const val NAME = BuildConfigWrapper.VERSION_NAME
/** 版本号 */
const val CODE = BuildConfigWrapper.VERSION_CODE
/** 是否为 CI 自动构建版本 */
val isCiMode = GITHUB_COMMIT_ID.isNotBlank()
/** 当前版本名称后缀 */
val suffix = GITHUB_COMMIT_ID.let { if (it.isNotBlank()) "-$it" else "" }
override fun toString() = "$NAME$suffix($CODE)"
} }

View File

@@ -19,6 +19,8 @@
* *
* This file is Created by fankes on 2022/9/29. * This file is Created by fankes on 2022/9/29.
*/ */
@file:Suppress("ConstPropertyName")
package com.fankes.tsbattery.hook.entity package com.fankes.tsbattery.hook.entity
import android.app.Activity import android.app.Activity
@@ -30,8 +32,8 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.app.ServiceCompat import androidx.core.app.ServiceCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.fankes.tsbattery.BuildConfig
import com.fankes.tsbattery.R import com.fankes.tsbattery.R
import com.fankes.tsbattery.const.ModuleVersion
import com.fankes.tsbattery.const.PackageName import com.fankes.tsbattery.const.PackageName
import com.fankes.tsbattery.data.ConfigData import com.fankes.tsbattery.data.ConfigData
import com.fankes.tsbattery.hook.HookEntry import com.fankes.tsbattery.hook.HookEntry
@@ -43,13 +45,31 @@ import com.fankes.tsbattery.utils.factory.appVersionName
import com.fankes.tsbattery.utils.factory.dp import com.fankes.tsbattery.utils.factory.dp
import com.highcapable.yukihookapi.hook.bean.VariousClass import com.highcapable.yukihookapi.hook.bean.VariousClass
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
import com.highcapable.yukihookapi.hook.factory.* import com.highcapable.yukihookapi.hook.factory.buildOf
import com.highcapable.yukihookapi.hook.factory.current
import com.highcapable.yukihookapi.hook.factory.field
import com.highcapable.yukihookapi.hook.factory.injectModuleAppResources
import com.highcapable.yukihookapi.hook.factory.method
import com.highcapable.yukihookapi.hook.factory.processName
import com.highcapable.yukihookapi.hook.factory.registerModuleAppActivities
import com.highcapable.yukihookapi.hook.log.loggerD import com.highcapable.yukihookapi.hook.log.loggerD
import com.highcapable.yukihookapi.hook.log.loggerE import com.highcapable.yukihookapi.hook.log.loggerE
import com.highcapable.yukihookapi.hook.log.loggerI import com.highcapable.yukihookapi.hook.log.loggerI
import com.highcapable.yukihookapi.hook.log.loggerW import com.highcapable.yukihookapi.hook.log.loggerW
import com.highcapable.yukihookapi.hook.type.android.* import com.highcapable.yukihookapi.hook.type.android.BuildClass
import com.highcapable.yukihookapi.hook.type.java.* import com.highcapable.yukihookapi.hook.type.android.BundleClass
import com.highcapable.yukihookapi.hook.type.android.ContextClass
import com.highcapable.yukihookapi.hook.type.android.IntentClass
import com.highcapable.yukihookapi.hook.type.android.MessageClass
import com.highcapable.yukihookapi.hook.type.java.AnyArrayClass
import com.highcapable.yukihookapi.hook.type.java.AnyClass
import com.highcapable.yukihookapi.hook.type.java.BooleanType
import com.highcapable.yukihookapi.hook.type.java.CharSequenceClass
import com.highcapable.yukihookapi.hook.type.java.IntType
import com.highcapable.yukihookapi.hook.type.java.ListClass
import com.highcapable.yukihookapi.hook.type.java.LongType
import com.highcapable.yukihookapi.hook.type.java.StringClass
import com.highcapable.yukihookapi.hook.type.java.UnitType
import java.lang.reflect.Proxy import java.lang.reflect.Proxy
/** /**
@@ -647,7 +667,7 @@ object QQTIMHooker : YukiBaseHooker() {
method { method {
name = "setRightText" name = "setRightText"
param(CharSequenceClass) param(CharSequenceClass)
}.call("${BuildConfig.VERSION_NAME}(${BuildConfig.VERSION_CODE})") }.call(ModuleVersion.toString())
method { method {
name = "setBgType" name = "setBgType"
param(IntType) param(IntType)
@@ -676,9 +696,10 @@ object QQTIMHooker : YukiBaseHooker() {
/** 不注入此进程防止部分系统发生 X5 浏览器内核崩溃问题 */ /** 不注入此进程防止部分系统发生 X5 浏览器内核崩溃问题 */
if (processName.startsWith(privilegedProcessName)) return@onCreate if (processName.startsWith(privilegedProcessName)) return@onCreate
ConfigData.init(context = this) ConfigData.init(context = this)
if (isQQNTVersion) registerModuleAppActivities(when {
registerModuleAppActivities(GeneralSettingActivityClass) isQQNTVersion -> GeneralSettingActivityClass
else registerModuleAppActivities(AboutActivityClass) else -> AboutActivityClass
})
if (ConfigData.isDisableAllHook) return@onCreate if (ConfigData.isDisableAllHook) return@onCreate
hookSystemWakeLock() hookSystemWakeLock()
hookQQBaseChatPie() hookQQBaseChatPie()

View File

@@ -19,6 +19,8 @@
* *
* This file is Created by fankes on 2022/9/29. * This file is Created by fankes on 2022/9/29.
*/ */
@file:Suppress("ConstPropertyName")
package com.fankes.tsbattery.hook.entity package com.fankes.tsbattery.hook.entity
import android.app.Activity import android.app.Activity
@@ -95,13 +97,11 @@ object WeChatHooker : YukiBaseHooker() {
onAppLifecycle { onAppLifecycle {
onCreate { onCreate {
ConfigData.init(context = this) ConfigData.init(context = this)
registerModuleAppActivities( registerModuleAppActivities(when {
when { EmptyActivityClass.hasClass() -> EmptyActivityClass
EmptyActivityClass.hasClass() -> EmptyActivityClass WelabMainUIClass.hasClass() -> WelabMainUIClass
WelabMainUIClass.hasClass() -> WelabMainUIClass else -> error("Inject WeChat Activity Proxy failed, unsupport version $appVersionName($appVersionCode)")
else -> error("Inject WeChat Activity Proxy failed, unsupport version $appVersionName($appVersionCode)") })
}
)
if (ConfigData.isDisableAllHook) return@onCreate if (ConfigData.isDisableAllHook) return@onCreate
hookSystemWakeLock() hookSystemWakeLock()
loggerI(msg = "All processes are completed for \"${processName.takeIf { it != packageName } ?: packageName}\"") loggerI(msg = "All processes are completed for \"${processName.takeIf { it != packageName } ?: packageName}\"")

View File

@@ -27,17 +27,24 @@ import android.content.ComponentName
import android.content.Intent import android.content.Intent
import android.view.HapticFeedbackConstants import android.view.HapticFeedbackConstants
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.fankes.tsbattery.BuildConfig import com.fankes.projectpromote.ProjectPromote
import com.fankes.tsbattery.R import com.fankes.tsbattery.R
import com.fankes.tsbattery.const.JumpEvent import com.fankes.tsbattery.const.JumpEvent
import com.fankes.tsbattery.const.ModuleVersion
import com.fankes.tsbattery.const.PackageName import com.fankes.tsbattery.const.PackageName
import com.fankes.tsbattery.databinding.ActivityMainBinding import com.fankes.tsbattery.databinding.ActivityMainBinding
import com.fankes.tsbattery.hook.entity.QQTIMHooker import com.fankes.tsbattery.hook.entity.QQTIMHooker
import com.fankes.tsbattery.hook.entity.WeChatHooker import com.fankes.tsbattery.hook.entity.WeChatHooker
import com.fankes.tsbattery.ui.activity.base.BaseActivity import com.fankes.tsbattery.ui.activity.base.BaseActivity
import com.fankes.tsbattery.utils.factory.* import com.fankes.tsbattery.utils.factory.appVersionBrandOf
import com.fankes.tsbattery.utils.factory.hideOrShowLauncherIcon
import com.fankes.tsbattery.utils.factory.isInstall
import com.fankes.tsbattery.utils.factory.isLauncherIconShowing
import com.fankes.tsbattery.utils.factory.openBrowser
import com.fankes.tsbattery.utils.factory.showDialog
import com.fankes.tsbattery.utils.factory.snake
import com.fankes.tsbattery.utils.tool.GithubReleaseTool import com.fankes.tsbattery.utils.tool.GithubReleaseTool
import com.fankes.tsbattery.utils.tool.YukiPromoteTool import com.fankes.tsbattery.wrapper.BuildConfigWrapper
import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.YukiHookAPI
class MainActivity : BaseActivity<ActivityMainBinding>() { class MainActivity : BaseActivity<ActivityMainBinding>() {
@@ -65,16 +72,13 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
"${value.trim().let { it.substring(0, it.lastIndex) }}\n\n其余版本请自行测试是否有效。" "${value.trim().let { it.substring(0, it.lastIndex) }}\n\n其余版本请自行测试是否有效。"
} else "empty" } else "empty"
} }
private const val timSupportVersion = "2+、3+ (并未完全测试每个版本)。" private const val TIM_SUPPORT_VERSION = "2+、3+ (并未完全测试每个版本)。"
private const val wechatSupportVersion = "全版本仅支持基础省电,更多功能依然画饼。" private const val WECHAT_SUPPORT_VERSION = "全版本仅支持基础省电,更多功能依然画饼。"
/** 预发布的版本标识 */
private const val pendingFlag = ""
} }
override fun onCreate() { override fun onCreate() {
/** 检查更新 */ /** 检查更新 */
GithubReleaseTool.checkingForUpdate(context = this, BuildConfig.VERSION_NAME) { version, function -> GithubReleaseTool.checkingForUpdate(context = this, ModuleVersion.NAME) { version, function ->
binding.mainTextReleaseVersion.apply { binding.mainTextReleaseVersion.apply {
text = "点击更新 $version" text = "点击更新 $version"
isVisible = true isVisible = true
@@ -89,7 +93,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
binding.mainTextApiWay.isVisible = true binding.mainTextApiWay.isVisible = true
refreshActivateExecutor() refreshActivateExecutor()
/** 推广、恰饭 */ /** 推广、恰饭 */
YukiPromoteTool.promote(context = this) ProjectPromote.show(activity = this, ModuleVersion.toString())
} else } else
showDialog { showDialog {
title = "模块没有激活" title = "模块没有激活"
@@ -102,7 +106,27 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
binding.mainTextTimVer.text = PackageName.TIM.takeIf { isInstall(it) }?.let { appVersionBrandOf(it) } ?: "未安装" binding.mainTextTimVer.text = PackageName.TIM.takeIf { isInstall(it) }?.let { appVersionBrandOf(it) } ?: "未安装"
binding.mainTextWechatVer.text = PackageName.WECHAT.takeIf { isInstall(it) }?.let { appVersionBrandOf(it) } ?: "未安装" binding.mainTextWechatVer.text = PackageName.WECHAT.takeIf { isInstall(it) }?.let { appVersionBrandOf(it) } ?: "未安装"
/** 设置文本 */ /** 设置文本 */
binding.mainTextVersion.text = "模块版本:${BuildConfig.VERSION_NAME} $pendingFlag" binding.mainTextVersion.text = "模块版本:${ModuleVersion.NAME}"
/** 设置 CI 自动构建标识 */
if (ModuleVersion.isCiMode)
binding.mainTextReleaseVersion.apply {
text = "CI ${ModuleVersion.GITHUB_COMMIT_ID}"
isVisible = true
setOnClickListener {
showDialog {
title = "CI 自动构建说明"
msg = """
你正在使用的是 CI 自动构建版本Commit ID 为 ${ModuleVersion.GITHUB_COMMIT_ID}
它是由代码提交后自动触发并构建、自动编译发布的,并未经任何稳定性测试,使用风险自负。
CI 构建的版本不支持太极 (也请不要提交 CI 版本的适配,因为它们是不稳定的),你可以使用 LSPosed / LSPatch。
""".trimIndent()
confirmButton(text = "我知道了")
noCancelable()
}
}
}
binding.mainQqItem.setOnClickListener { binding.mainQqItem.setOnClickListener {
showDialog { showDialog {
title = "兼容的 QQ 版本" title = "兼容的 QQ 版本"
@@ -115,7 +139,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
binding.mainTimItem.setOnClickListener { binding.mainTimItem.setOnClickListener {
showDialog { showDialog {
title = "兼容的 TIM 版本" title = "兼容的 TIM 版本"
msg = timSupportVersion msg = TIM_SUPPORT_VERSION
confirmButton(text = "我知道了") confirmButton(text = "我知道了")
} }
/** 振动提醒 */ /** 振动提醒 */
@@ -124,7 +148,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
binding.mainWechatItem.setOnClickListener { binding.mainWechatItem.setOnClickListener {
showDialog { showDialog {
title = "兼容的微信版本" title = "兼容的微信版本"
msg = wechatSupportVersion msg = WECHAT_SUPPORT_VERSION
confirmButton(text = "我知道了") confirmButton(text = "我知道了")
} }
/** 振动提醒 */ /** 振动提醒 */
@@ -148,6 +172,11 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
if (btn.isPressed.not()) return@setOnCheckedChangeListener if (btn.isPressed.not()) return@setOnCheckedChangeListener
hideOrShowLauncherIcon(b) hideOrShowLauncherIcon(b)
} }
/** 判断当前启动模式 */
if (packageName != BuildConfigWrapper.APPLICATION_ID) {
binding.quickActionItem.isVisible = false
binding.displaySettingItem.isVisible = false
}
} }
/** /**

View File

@@ -29,7 +29,8 @@ import android.content.res.Resources
import android.widget.TextView import android.widget.TextView
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.fankes.tsbattery.BuildConfig import com.fankes.projectpromote.ProjectPromote
import com.fankes.tsbattery.const.ModuleVersion
import com.fankes.tsbattery.const.PackageName import com.fankes.tsbattery.const.PackageName
import com.fankes.tsbattery.data.ConfigData import com.fankes.tsbattery.data.ConfigData
import com.fankes.tsbattery.data.ConfigData.bind import com.fankes.tsbattery.data.ConfigData.bind
@@ -38,8 +39,14 @@ import com.fankes.tsbattery.hook.HookEntry
import com.fankes.tsbattery.hook.entity.QQTIMHooker import com.fankes.tsbattery.hook.entity.QQTIMHooker
import com.fankes.tsbattery.ui.activity.MainActivity import com.fankes.tsbattery.ui.activity.MainActivity
import com.fankes.tsbattery.ui.activity.base.BaseActivity import com.fankes.tsbattery.ui.activity.base.BaseActivity
import com.fankes.tsbattery.utils.factory.* import com.fankes.tsbattery.utils.factory.appIconOf
import com.fankes.tsbattery.utils.factory.appNameOf
import com.fankes.tsbattery.utils.factory.appVersionCode
import com.fankes.tsbattery.utils.factory.appVersionName
import com.fankes.tsbattery.utils.factory.showDialog
import com.fankes.tsbattery.utils.factory.snake
import com.fankes.tsbattery.utils.tool.GithubReleaseTool import com.fankes.tsbattery.utils.tool.GithubReleaseTool
import com.fankes.tsbattery.wrapper.BuildConfigWrapper
import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.YukiHookAPI
import kotlin.system.exitProcess import kotlin.system.exitProcess
@@ -47,7 +54,7 @@ class ConfigActivity : BaseActivity<ActivityConfigBinding>() {
override fun onCreate() { override fun onCreate() {
/** 检查更新 */ /** 检查更新 */
GithubReleaseTool.checkingForUpdate(context = this, BuildConfig.VERSION_NAME) { version, function -> GithubReleaseTool.checkingForUpdate(context = this, ModuleVersion.NAME) { version, function ->
binding.updateVersionText.apply { binding.updateVersionText.apply {
text = "点击更新 $version" text = "点击更新 $version"
isVisible = true isVisible = true
@@ -58,14 +65,18 @@ class ConfigActivity : BaseActivity<ActivityConfigBinding>() {
binding.titleModuleIcon.setOnClickListener { binding.titleModuleIcon.setOnClickListener {
showDialog { showDialog {
title = "打开模块主界面" title = "打开模块主界面"
msg = "点击确定后将打开模块主界面,如果未安装模块本体将会无法打开" msg = "点击确定后将打开模块主界面,如果未安装模块本体将尝试打开寄生界面"
confirmButton { confirmButton {
runCatching { runCatching {
startActivity(Intent().apply { startActivity(Intent().apply {
component = ComponentName(BuildConfig.APPLICATION_ID, MainActivity::class.java.name) component = ComponentName(BuildConfigWrapper.APPLICATION_ID, MainActivity::class.java.name)
flags = Intent.FLAG_ACTIVITY_NEW_TASK flags = Intent.FLAG_ACTIVITY_NEW_TASK
}) })
}.onFailure { snake(msg = "打开失败,请确认你已安装模块 APP\n$it") } }.onFailure {
runCatching {
startActivity(Intent(this@ConfigActivity, MainActivity::class.java))
}.onFailure { snake(msg = "打开失败,请确认你已安装模块 APP 或在模块更新后重启过$appName\n$it") }
}
} }
cancelButton() cancelButton()
} }
@@ -73,8 +84,8 @@ class ConfigActivity : BaseActivity<ActivityConfigBinding>() {
binding.titleNameText.text = "TSBattery 设置 (${appName.trim()})" binding.titleNameText.text = "TSBattery 设置 (${appName.trim()})"
binding.appIcon.setImageDrawable(appIconOf()) binding.appIcon.setImageDrawable(appIconOf())
binding.appName.text = appName.trim() binding.appName.text = appName.trim()
binding.appVersion.text = "${appVersionName}($appVersionCode)" binding.appVersion.text = "$appVersionName($appVersionCode)"
binding.moduleVersion.text = "${BuildConfig.VERSION_NAME}(${BuildConfig.VERSION_CODE})" binding.moduleVersion.text = ModuleVersion.toString()
binding.activeModeIcon.isVisible = HookEntry.isHookClientSupport binding.activeModeIcon.isVisible = HookEntry.isHookClientSupport
binding.inactiveModeIcon.isGone = HookEntry.isHookClientSupport binding.inactiveModeIcon.isGone = HookEntry.isHookClientSupport
binding.unsupportItem.isGone = HookEntry.isHookClientSupport binding.unsupportItem.isGone = HookEntry.isHookClientSupport
@@ -116,6 +127,8 @@ class ConfigActivity : BaseActivity<ActivityConfigBinding>() {
binding.qqTimProtectModeSwitch.bind(ConfigData.ENABLE_QQ_TIM_PROTECT_MODE) { refreshCurrentModeText(); showNeedRestartTip() } binding.qqTimProtectModeSwitch.bind(ConfigData.ENABLE_QQ_TIM_PROTECT_MODE) { refreshCurrentModeText(); showNeedRestartTip() }
binding.qqTimCoreServiceSwitch.bind(ConfigData.ENABLE_KILL_QQ_TIM_CORESERVICE) { showNeedRestartTip() } binding.qqTimCoreServiceSwitch.bind(ConfigData.ENABLE_KILL_QQ_TIM_CORESERVICE) { showNeedRestartTip() }
binding.qqTimCoreServiceChildSwitch.bind(ConfigData.ENABLE_KILLE_QQ_TIM_CORESERVICE_CHILD) { showNeedRestartTip() } binding.qqTimCoreServiceChildSwitch.bind(ConfigData.ENABLE_KILLE_QQ_TIM_CORESERVICE_CHILD) { showNeedRestartTip() }
/** 推广、恰饭 */
ProjectPromote.show(activity = this, ModuleVersion.toString())
} }
/** 显示需要重新启动提示 */ /** 显示需要重新启动提示 */

View File

@@ -40,7 +40,7 @@ import android.provider.Settings
import android.widget.Toast import android.widget.Toast
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import androidx.core.content.pm.PackageInfoCompat import androidx.core.content.pm.PackageInfoCompat
import com.fankes.tsbattery.BuildConfig import com.fankes.tsbattery.wrapper.BuildConfigWrapper
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.highcapable.yukihookapi.hook.xposed.application.ModuleApplication.Companion.appContext import com.highcapable.yukihookapi.hook.xposed.application.ModuleApplication.Companion.appContext
@@ -227,7 +227,7 @@ fun Context.openBrowser(url: String, packageName: String = "") = runCatching {
*/ */
fun Context.hideOrShowLauncherIcon(isShow: Boolean) { fun Context.hideOrShowLauncherIcon(isShow: Boolean) {
packageManager?.setComponentEnabledSetting( packageManager?.setComponentEnabledSetting(
ComponentName(packageName, "${BuildConfig.APPLICATION_ID}.Home"), ComponentName(packageName, "${BuildConfigWrapper.APPLICATION_ID}.Home"),
if (isShow) PackageManager.COMPONENT_ENABLED_STATE_DISABLED else PackageManager.COMPONENT_ENABLED_STATE_ENABLED, if (isShow) PackageManager.COMPONENT_ENABLED_STATE_DISABLED else PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP PackageManager.DONT_KILL_APP
) )
@@ -239,5 +239,5 @@ fun Context.hideOrShowLauncherIcon(isShow: Boolean) {
*/ */
val Context.isLauncherIconShowing val Context.isLauncherIconShowing
get() = packageManager?.getComponentEnabledSetting( get() = packageManager?.getComponentEnabledSetting(
ComponentName(packageName, "${BuildConfig.APPLICATION_ID}.Home") ComponentName(packageName, "${BuildConfigWrapper.APPLICATION_ID}.Home")
) != PackageManager.COMPONENT_ENABLED_STATE_DISABLED ) != PackageManager.COMPONENT_ENABLED_STATE_DISABLED

View File

@@ -1,59 +0,0 @@
/*
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
* Copyright (C) 2017-2023 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.BuildConfig
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.prefs
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
/**
* [YukiHookAPI] 的自动推广工具类
*/
object YukiPromoteTool {
/** 推广已读存储键值 */
private val YUKI_PROMOTE_READED = PrefsData("yuki_promote_readed_${BuildConfig.VERSION_NAME}", false)
/**
* 显示推广对话框
* @param context 实例
*/
fun promote(context: Context) {
fun saveReaded() = context.prefs().edit { put(YUKI_PROMOTE_READED, value = true) }
if (context.prefs().get(YUKI_PROMOTE_READED).not())
context.showDialog {
title = "面向开发者的推广"
msg = "你想快速拥有一个自己的 Xposed 模块吗,你只需要拥有基础的 Android 开发经验以及使用 Kotlin 编程语言即可。\n\n" +
"快来体验 YukiHookAPI这是一个使用 Kotlin 构建的高效 Hook API 与 Xposed 模块解决方案,助你的开发变得更轻松。"
confirmButton(text = "去看看") {
context.openBrowser(url = "https://github.com/fankes/YukiHookAPI")
saveReaded()
}
cancelButton(text = "我不是开发者") { saveReaded() }
noCancelable()
}
}
}

View File

@@ -0,0 +1,36 @@
/*
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
* Copyright (C) 2017-2023 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 2023/9/16.
*/
@file:Suppress("unused")
package com.fankes.tsbattery.wrapper
import com.fankes.tsbattery.BuildConfig
/**
* 对 [BuildConfig] 的包装
*/
object BuildConfigWrapper {
const val APPLICATION_ID = BuildConfig.APPLICATION_ID
const val VERSION_NAME = BuildConfig.VERSION_NAME
const val VERSION_CODE = BuildConfig.VERSION_CODE
val isDebug = BuildConfig.DEBUG
}