mirror of
https://github.com/fankes/TSBattery.git
synced 2025-09-04 09:45:41 +08:00
Compare commits
89 Commits
Author | SHA1 | Date | |
---|---|---|---|
b7015f8a69
|
|||
d39f50642a
|
|||
5a6a61b4be
|
|||
114ec89764
|
|||
476b6d6be6
|
|||
53249108d1
|
|||
147e4c117e
|
|||
276820fdc5
|
|||
0b7ade9076
|
|||
6c26a8b0cd
|
|||
d925873c4c
|
|||
9fb52332d5
|
|||
bf92f0241c
|
|||
7ec8de4be0
|
|||
df949cf56b
|
|||
f1061b27fa
|
|||
b8543130cc
|
|||
9ae395ecee
|
|||
8d2d233b93
|
|||
70757b1594
|
|||
a14a38e00f
|
|||
910c67a943
|
|||
6a31eef23e
|
|||
0517df5dc4
|
|||
f25472b124
|
|||
ebb68c69b4
|
|||
c89eb39a75
|
|||
43e0dff6cb
|
|||
215d680955
|
|||
c25f316512
|
|||
798a55a328
|
|||
3dea65c4c6
|
|||
46efaf7083
|
|||
760b7a42cd
|
|||
6be267f74d
|
|||
7d1dbbbf44
|
|||
fb0182f075
|
|||
80e89d087f
|
|||
c5711338e3
|
|||
2fac3c2709
|
|||
7b65ca01fb
|
|||
4d75fb9e8c
|
|||
13d25dcafd
|
|||
1298077c9f
|
|||
374ffaab4f
|
|||
76904665cc
|
|||
dfdb18dcb7
|
|||
d1fb794284
|
|||
3adaad1040
|
|||
39b132cc1a
|
|||
13837b3b33
|
|||
4405808ff3
|
|||
7c66519e2d
|
|||
9b620d7688
|
|||
cde830b804
|
|||
884a743338
|
|||
e9aa721902
|
|||
fa967c8dfb
|
|||
7fe6bd91f0
|
|||
8025b45b06
|
|||
d8b3884cb0
|
|||
1a3c8d9bcb
|
|||
b6d8040bfa
|
|||
d4f8d7d3fd
|
|||
a4970747c0
|
|||
4a8816de37
|
|||
6969d7b2c6
|
|||
ea0b46020f
|
|||
4436815525
|
|||
e96b6a5d2a
|
|||
576c8574c8
|
|||
94d425fcf7
|
|||
58510cef52
|
|||
efe000d690
|
|||
c9d49a398f
|
|||
bd027b37f5
|
|||
2e56baa6c7
|
|||
147b7fa6f5
|
|||
6bd906a51e
|
|||
5c92671ae2
|
|||
b5bb7eb892
|
|||
3361284f16
|
|||
5b4da6df45
|
|||
f520983d32
|
|||
1e67116f0a
|
|||
7257127c0f
|
|||
63d5043f31
|
|||
64c4c282b2
|
|||
89cbc49287
|
35
.editorconfig
Normal file
35
.editorconfig
Normal file
@@ -0,0 +1,35 @@
|
||||
# noinspection EditorConfigKeyCorrectness
|
||||
[{*.kt,*.kts}]
|
||||
ktlint_standard_annotation = disabled
|
||||
ktlint_standard_filename = disabled
|
||||
ktlint_standard_wrapping = disabled
|
||||
ktlint_standard_import-ordering = enabled
|
||||
ktlint_standard_max-line-length = disabled
|
||||
ktlint_standard_multiline-if-else = disabled
|
||||
ktlint_standard_argument-list-wrapping = disabled
|
||||
ktlint_standard_parameter-list-wrapping = disabled
|
||||
ktlint_standard_trailing-comma-on-declaration-site = disabled
|
||||
ktlint_function_signature_body_expression_wrapping = multiline
|
||||
ktlint_standard_string-template-indent = disabled
|
||||
ktlint_standard_function-signature = disabled
|
||||
ktlint_standard_trailing-comma-on-call-site = disabled
|
||||
ktlint_standard_multiline-expression-wrapping = disabled
|
||||
ktlint_standard_no-empty-first-line-in-class-body = disabled
|
||||
ktlint_standard_if-else-wrapping = disabled
|
||||
ktlint_standard_if-else-bracing = disabled
|
||||
ktlint_standard_statement-wrapping = disabled
|
||||
ktlint_standard_blank-line-before-declaration = disabled
|
||||
ktlint_standard_no-empty-file = disabled
|
||||
ktlint_standard_property-naming = disabled
|
||||
ktlint_standard_function-naming = disabled
|
||||
ktlint_standard_chain-method-continuation = disabled
|
||||
ktlint_standard_class-signature = disabled
|
||||
ktlint_standard_condition-wrapping = disabled
|
||||
ktlint_standard_class-signature = disabled
|
||||
ktlint_standard_no-trailing-spaces = disabled
|
||||
ktlint_standard_multiline-loop = disabled
|
||||
ij_continuation_indent_size = 2
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = false
|
||||
max_line_length = 150
|
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -42,6 +42,7 @@ body:
|
||||
attributes:
|
||||
label: Android 版本
|
||||
options:
|
||||
- 14
|
||||
- 13
|
||||
- 12L/12.1
|
||||
- 12
|
||||
|
55
.github/workflows/commit_ci.yml
vendored
55
.github/workflows/commit_ci.yml
vendored
@@ -13,17 +13,34 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
name: Build CI
|
||||
if: ${{ success() }}
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
APK_OUTPUT_PATH: 'app/build/outputs/apk'
|
||||
TG_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
|
||||
TG_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
|
||||
COMMIT_MESSAGE: |+
|
||||
New push to GitHub\!
|
||||
```
|
||||
${{ github.event.head_commit.message }}
|
||||
```by `${{ github.event.head_commit.author.name }}`
|
||||
See commit detail [here](${{ github.event.head_commit.url }})
|
||||
COMMIT_URL: ${{ github.event.head_commit.url }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Prepare GitHub Env
|
||||
run: |
|
||||
GITHUB_SHA=${{ github.sha }}
|
||||
GITHUB_CI_COMMIT_ID=${GITHUB_SHA:0:7}
|
||||
echo "GITHUB_CI_COMMIT_ID=$GITHUB_CI_COMMIT_ID" >> $GITHUB_ENV
|
||||
- name: Setup cmake
|
||||
uses: jwlawson/actions-setup-cmake@v1
|
||||
with:
|
||||
cmake-version: '3.22.1'
|
||||
- name: Prepare Java 11
|
||||
uses: actions/setup-java@v3
|
||||
- name: Prepare Java 21
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 11
|
||||
java-version: 21
|
||||
java-package: jdk
|
||||
distribution: 'temurin'
|
||||
cache: 'gradle'
|
||||
@@ -34,7 +51,7 @@ jobs:
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
!~/.gradle/caches/build-cache-*
|
||||
key: gradle-deps-core-${{ hashFiles('**/build.gradle') }}
|
||||
key: gradle-deps-core-${{ hashFiles('**/build.gradle.kts') }}
|
||||
restore-keys: |
|
||||
gradle-deps
|
||||
- name: Cache Gradle Build
|
||||
@@ -49,15 +66,23 @@ jobs:
|
||||
run: |
|
||||
./gradlew :app:assembleDebug
|
||||
./gradlew :app:assembleRelease
|
||||
echo "DEBUG_APK_FILE=$(find app/build/outputs/apk/debug -name '*.apk')" >> $GITHUB_ENV
|
||||
echo "RELEASE_APK_FILE=$(find app/build/outputs/apk/release -name '*.apk')" >> $GITHUB_ENV
|
||||
- name: Upload Artifacts(debug)
|
||||
uses: actions/upload-artifact@v3
|
||||
echo "DEBUG_APK_PATH=$(find ${{ env.APK_OUTPUT_PATH }}/debug -name '*.apk')" >> $GITHUB_ENV
|
||||
echo "RELEASE_APK_PATH=$(find ${{ env.APK_OUTPUT_PATH }}/release -name '*.apk')" >> $GITHUB_ENV
|
||||
- name: Upload Artifacts (Debug)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: ${{ env.DEBUG_APK_FILE }}
|
||||
name: app-debug
|
||||
- name: Upload Artifacts(release)
|
||||
uses: actions/upload-artifact@v3
|
||||
path: ${{ env.DEBUG_APK_PATH }}
|
||||
name: TSBattery-debug-${{ github.event.head_commit.id }}
|
||||
- name: Upload Artifacts (Release)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: ${{ env.RELEASE_APK_FILE }}
|
||||
name: app-release
|
||||
path: ${{ env.RELEASE_APK_PATH }}
|
||||
name: TSBattery-release-${{ github.event.head_commit.id }}
|
||||
- name: Post Artifacts to Telegram
|
||||
run: |
|
||||
export debug=$(find ${{ env.APK_OUTPUT_PATH }}/debug -name "*.apk")
|
||||
export release=$(find ${{ env.APK_OUTPUT_PATH }}/release -name "*.apk")
|
||||
ESCAPED=`python3 -c 'import json,os,urllib.parse; msg = json.dumps(os.environ["COMMIT_MESSAGE"]); print(urllib.parse.quote(msg if len(msg) <= 1024 else json.dumps(os.environ["COMMIT_URL"])))'`
|
||||
curl -v "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMediaGroup?chat_id=${TG_CHAT_ID}&media=%5B%7B%22type%22%3A%22document%22%2C%20%22media%22%3A%22attach%3A%2F%2Fdebug%22%7D%2C%7B%22type%22%3A%22document%22%2C%20%22media%22%3A%22attach%3A%2F%2Frelease%22%2C%22parse_mode%22%3A%22MarkdownV2%22%2C%22caption%22:${ESCAPED}%7D%5D" \
|
||||
-F debug="@$debug" \
|
||||
-F release="@$release"
|
40
.github/workflows/pull_request_ci.yml
vendored
40
.github/workflows/pull_request_ci.yml
vendored
@@ -11,18 +11,26 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Pull request check
|
||||
name: Pull Request Check
|
||||
if: ${{ success() }}
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
APK_OUTPUT_PATH: 'app/build/outputs/apk'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Prepare GitHub Env
|
||||
run: |
|
||||
GITHUB_SHA=${{ github.sha }}
|
||||
GITHUB_CI_COMMIT_ID=${GITHUB_SHA:0:7}
|
||||
echo "GITHUB_CI_COMMIT_ID=$GITHUB_CI_COMMIT_ID" >> $GITHUB_ENV
|
||||
- name: Setup cmake
|
||||
uses: jwlawson/actions-setup-cmake@v1
|
||||
with:
|
||||
cmake-version: '3.22.1'
|
||||
- name: Prepare Java 11
|
||||
uses: actions/setup-java@v3
|
||||
- name: Prepare Java 21
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 11
|
||||
java-version: 21
|
||||
java-package: jdk
|
||||
distribution: 'temurin'
|
||||
cache: 'gradle'
|
||||
@@ -33,7 +41,7 @@ jobs:
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
!~/.gradle/caches/build-cache-*
|
||||
key: gradle-deps-core-${{ hashFiles('**/build.gradle') }}
|
||||
key: gradle-deps-core-${{ hashFiles('**/build.gradle.kts') }}
|
||||
restore-keys: |
|
||||
gradle-deps
|
||||
- name: Cache Gradle Build
|
||||
@@ -48,15 +56,15 @@ jobs:
|
||||
run: |
|
||||
./gradlew :app:assembleDebug
|
||||
./gradlew :app:assembleRelease
|
||||
echo "DEBUG_APK_FILE=$(find app/build/outputs/apk/debug -name '*.apk')" >> $GITHUB_ENV
|
||||
echo "RELEASE_APK_FILE=$(find app/build/outputs/apk/release -name '*.apk')" >> $GITHUB_ENV
|
||||
- name: Upload Artifacts(debug)
|
||||
uses: actions/upload-artifact@v3
|
||||
echo "DEBUG_APK_PATH=$(find ${{ env.APK_OUTPUT_PATH }}/debug -name '*.apk')" >> $GITHUB_ENV
|
||||
echo "RELEASE_APK_PATH=$(find ${{ env.APK_OUTPUT_PATH }}/release -name '*.apk')" >> $GITHUB_ENV
|
||||
- name: Upload Artifacts (Debug)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: ${{ env.DEBUG_APK_FILE }}
|
||||
name: app-debug
|
||||
- name: Upload Artifacts(release)
|
||||
uses: actions/upload-artifact@v3
|
||||
path: ${{ env.DEBUG_APK_PATH }}
|
||||
name: TSBattery-debug-${{ github.event.head_commit.id }}
|
||||
- name: Upload Artifacts (Release)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: ${{ env.RELEASE_APK_FILE }}
|
||||
name: app-release
|
||||
path: ${{ env.RELEASE_APK_PATH }}
|
||||
name: TSBattery-release-${{ github.event.head_commit.id }}
|
117
.gitignore
vendored
117
.gitignore
vendored
@@ -1,15 +1,110 @@
|
||||
## Fully .gtignore for IntelliJ, Android Studio and Gradle based Java projects
|
||||
## References:
|
||||
## - https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
## - https://github.com/android/platform-samples/blob/main/.gitignore
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
.idea/.name
|
||||
.idea/artifacts
|
||||
.idea/compiler.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/modules.xml
|
||||
.idea/*.iml
|
||||
.idea/modules
|
||||
.idea/caches
|
||||
.idea/material_theme**
|
||||
.idea/other.xml
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
/build
|
||||
*.ipr
|
||||
|
||||
# Kotlin
|
||||
.kotlin
|
||||
|
||||
# Misc
|
||||
.idea/misc.xml
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
# Android studio 3.1+ additional
|
||||
.idea/deployment*.xml
|
||||
.idea/assetWizardSettings.xml
|
||||
.idea/androidTestResultsUserPreferences.xml
|
||||
|
||||
# Android projects
|
||||
**/local.properties
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
||||
|
||||
# Gradle projects
|
||||
.gradle
|
||||
build/
|
||||
|
||||
# Mkdocs temporary serving folder
|
||||
docs-gen
|
||||
site
|
||||
*.bak
|
||||
.idea/appInsightsSettings.xml
|
||||
|
||||
# Mac OS
|
||||
.DS_Store
|
3
.idea/.gitignore
generated
vendored
3
.idea/.gitignore
generated
vendored
@@ -1,3 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
6
.idea/AndroidProjectSystem.xml
generated
Normal file
6
.idea/AndroidProjectSystem.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AndroidProjectSystem">
|
||||
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
|
||||
</component>
|
||||
</project>
|
117
.idea/codeStyles/Project.xml
generated
Normal file
117
.idea/codeStyles/Project.xml
generated
Normal file
@@ -0,0 +1,117 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<codeStyleSettings language="XML">
|
||||
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
6
.idea/compiler.xml
generated
6
.idea/compiler.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="11" />
|
||||
</component>
|
||||
</project>
|
20
.idea/gradle.xml
generated
20
.idea/gradle.xml
generated
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="GRADLE" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="11" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
1
.idea/inspectionProfiles/Project_Default.xml
generated
1
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -7,5 +7,6 @@
|
||||
<option name="processLiterals" value="true" />
|
||||
<option name="processComments" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="YAMLSchemaValidation" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
</profile>
|
||||
</component>
|
45
.idea/jarRepositories.xml
generated
45
.idea/jarRepositories.xml
generated
@@ -1,45 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="MavenRepo" />
|
||||
<option name="name" value="MavenRepo" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="BintrayJCenter" />
|
||||
<option name="name" value="BintrayJCenter" />
|
||||
<option name="url" value="https://jcenter.bintray.com/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="Google" />
|
||||
<option name="name" value="Google" />
|
||||
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven3" />
|
||||
<option name="name" value="maven3" />
|
||||
<option name="url" value="https://www.jitpack.io" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven" />
|
||||
<option name="name" value="maven" />
|
||||
<option name="url" value="https://maven.aliyun.com/nexus/content/groups/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven2" />
|
||||
<option name="name" value="maven2" />
|
||||
<option name="url" value="https://maven.aliyun.com/nexus/content/repositories/jcenter" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
2
.idea/kotlinc.xml
generated
2
.idea/kotlinc.xml
generated
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="KotlinJpsPluginSettings">
|
||||
<option name="version" value="1.7.20" />
|
||||
<option name="version" value="2.1.10" />
|
||||
</component>
|
||||
</project>
|
7
.idea/ktlint-plugin.xml
generated
Normal file
7
.idea/ktlint-plugin.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="KtLint plugin">
|
||||
<ktlintMode>MANUAL</ktlintMode>
|
||||
<formatOnSave>false</formatOnSave>
|
||||
</component>
|
||||
</project>
|
6
.idea/ktlint.xml
generated
Normal file
6
.idea/ktlint.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="KtlintProjectConfiguration">
|
||||
<treatAsErrors>false</treatAsErrors>
|
||||
</component>
|
||||
</project>
|
10
.idea/migrations.xml
generated
Normal file
10
.idea/migrations.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectMigrations">
|
||||
<option name="MigrateToGradleLocalJavaHome">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
24
.idea/misc.xml
generated
24
.idea/misc.xml
generated
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DesignSurface">
|
||||
<option name="filePathToZoomLevelMap">
|
||||
<map>
|
||||
<entry key="app/src/main/res/drawable-v24/dark_round.xml" value="0.4482051282051282" />
|
||||
<entry key="app/src/main/res/drawable/bg_orange_round.xml" value="0.229" />
|
||||
<entry key="app/src/main/res/drawable/bg_permotion_round.xml" value="0.2495" />
|
||||
<entry key="app/src/main/res/drawable/button_round.xml" value="0.44871794871794873" />
|
||||
<entry key="app/src/main/res/drawable/dark_round.xml" value="0.4482051282051282" />
|
||||
<entry key="app/src/main/res/drawable/permotion_round.xml" value="0.4482051282051282" />
|
||||
<entry key="app/src/main/res/drawable/red_round.xml" value="0.4482051282051282" />
|
||||
<entry key="app/src/main/res/layout/activity_main.xml" value="0.3413246647704185" />
|
||||
<entry key="app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml" value="0.2495" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
17
.idea/runConfigurations.xml
generated
Normal file
17
.idea/runConfigurations.xml
generated
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"keyAlias": "public",
|
||||
"keyPassword": "123456",
|
||||
"storeFileName": "universal.p12",
|
||||
"storePassword": "123456"
|
||||
}
|
93
README.md
93
README.md
@@ -1,70 +1,81 @@
|
||||
# TSBattery
|
||||
|
||||
[](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/Xposed-Modules-Repo/com.fankes.tsbattery/releases)
|
||||
[](https://t.me/XiaofangInternet)
|
||||
<br/><br/>
|
||||
<br/>
|
||||
[](https://github.com/fankes/TSBattery/blob/master/LICENSE)
|
||||
[](https://github.com/fankes/TSBattery/actions/workflows/commit_ci.yml)
|
||||
[](https://github.com/fankes/TSBattery/releases)
|
||||

|
||||

|
||||
|
||||
[](https://t.me/TSBattery_CI)
|
||||
[](https://t.me/XiaofangInternet)
|
||||
[](https://qm.qq.com/cgi-bin/qm/qr?k=dp2h5YhWiga9WWb_Oh7kSHmx01X8I8ii&jump_from=webapi&authKey=Za5CaFP0lk7+Zgsk2KpoBD7sSaYbeXbsDgFjiWelOeH4VSionpxFJ7V0qQBSqvFM)
|
||||
[](https://pd.qq.com/s/44gcy28h)
|
||||
|
||||
<img src="app/src/main/ic_launcher-playstore.png" width = "100" height = "100" alt="LOGO"/>
|
||||
|
||||
A new way to save your battery avoid cancer apps hacker it.
|
||||
|
||||
TSBattery 是一个旨在使 QQ、TIM、微信 变得更省电的开源 Xposed 模块。
|
||||
|
||||
## Developer
|
||||
## For Non-Chinese Users
|
||||
|
||||
[酷安 @星夜不荟](http://www.coolapk.com/u/876977)
|
||||
This Xposed Module is for use by specific apps for users in mainland China, you should not need it.
|
||||
|
||||
## 适配说明
|
||||
|
||||
- 解锁 BL 并安装 **Magisk** 的设备建议使用 [LSPosed](https://github.com/LSPosed/LSPosed)
|
||||
- 解锁 BootLoader 并安装 **KernelSU**、**Magisk** 的设备建议使用 [LSPosed](https://github.com/LSPosed/LSPosed)
|
||||
|
||||
- 可以使用 **~~EdXposed~~**,但随时停止支持
|
||||
- **太极 (无极)** 支持性不是很好,建议使用 [LSPatch](https://github.com/LSPosed/LSPatch)
|
||||
|
||||
- **太极无极 · 阴** 支持性不是很好,建议使用 [LSPatch](https://github.com/LSPosed/LSPatch)
|
||||
- 支持一些第三方 Xposed 框架,但是不保证其稳定性
|
||||
|
||||
- 支持一些第三方免 Root 框架例如**应用转生**、**SandVXposed**,但是不推荐使用,可能会造成封号风险
|
||||
|
||||
- 如果在微信设置界面右上角你无法找到 **TSBattery** 的图标,请尝试同时激活 [WeXposed (微X模块)](https://github.com/Xposed-Modules-Repo/com.fkzhang.wechatxposed)
|
||||
- 如果在微信设置界面右上角你无法找到 **TSBattery**
|
||||
的图标,请尝试同时激活 [WeXposed (微X模块)](https://github.com/Xposed-Modules-Repo/com.fkzhang.wechatxposed)
|
||||
|
||||
## 请勿用于非法用途
|
||||
## 发行渠道
|
||||
|
||||
本模块完全开源免费,如果好用你可以打赏支持开发,但是请不要用于非法用途。
|
||||
| <img src="https://avatars.githubusercontent.com/in/15368?s=64&v=4" width = "30" height = "30" alt="LOGO"/> | [GitHub CI](https://github.com/fankes/TSBattery/actions/workflows/commit_ci.yml) | CI 自动构建 (测试版) |
|
||||
|------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------|---------------|
|
||||
|
||||
## 发行渠道说明
|
||||
| <img src="https://github.com/peter-iakovlev/Telegram/blob/public/Icon.png?raw=true" width = "30" height = "30" alt="LOGO"/> | [Telegram CI 频道](https://t.me/TSBattery_CI) | CI 自动构建 (测试版) |
|
||||
|-----------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|---------------|
|
||||
|
||||
- [Automatic Build on Commit](https://github.com/fankes/TSBattery/actions/workflows/commit_ci.yml)
|
||||
| <img src="https://avatars.githubusercontent.com/in/15368?s=64&v=4" width = "30" height = "30" alt="LOGO"/> | [GitHub Releases](https://github.com/fankes/TSBattery/releases) | 正式版 (稳定版) |
|
||||
|------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------|-----------|
|
||||
|
||||
上述更新为代码 `commit` 后自动触发,具体更新内容可点击上方的文字前往 **GitHub Actions** 进行查看,本更新由开源的流程自动编译发布,**不保证其稳定性**,所发布的版本**仅供测试**,且不会特殊说明甚至可能会变更版本号或保持与当前稳定版相同的版本号。
|
||||
| <img src="https://avatars.githubusercontent.com/u/78217009?s=200&v=4?raw=true" width = "30" height = "30" alt="LOGO"/> | [Xposed-Modules-Repo](https://github.com/Xposed-Modules-Repo/com.fankes.tsbattery/releases) | 正式版 (稳定版) |
|
||||
|------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|-----------|
|
||||
|
||||
- [Release](https://github.com/fankes/TSBattery/releases)
|
||||
- [Xposed-Modules-Repo](https://github.com/Xposed-Modules-Repo/com.fankes.tsbattery/releases)
|
||||
- [蓝奏云 **密码:tsbt**](https://fankes.lanzouy.com/b02zfz3sj)
|
||||
|
||||
上述更新为手动发布的稳定版,具体更新内容可点击上方的文字前往指定的发布页面查看,稳定版的更新将会同时发布到上述地址中,同步更新。
|
||||
| <img src="https://github.com/fankes/fankes/assets/37344460/82113d3c-aa7b-4dd1-95c7-cda650065c12" width = "30" height = "30" alt="LOGO"/> | [123 云盘 **(密码:tsbt)**](https://www.123pan.com/s/5SlUVv-N8DBh.html) | 正式版 (稳定版) |
|
||||
|------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------|-----------|
|
||||
|
||||
本模块发布地址仅限于上述所列出的地址,从其他非正规渠道下载到的版本或对您造成任何影响均与我们无关。
|
||||
|
||||
## 发行状态说明
|
||||
## 注意事项
|
||||
|
||||

|
||||
<h3>1. 本软件免费、由兴趣驱动开发,仅供学习交流使用。如果你是从其他非官方渠道付费获得本软件,可能已遭遇欺诈,欢迎向我们举报可疑行为。</h3>
|
||||
|
||||
上述状态为当前稳定版与自动构建版本一致或当前代码改动与稳定版无功能差异。
|
||||
<h3>2. 本软件采用 <strong>GNU Affero General Public License (AGPL 3.0)</strong> 许可证。根据该许可证的要求:</h3>
|
||||
|
||||

|
||||
- 任何衍生作品必须采用相同的 AGPL 许可证
|
||||
- 分发本软件或其修改版本时,必须提供完整的源代码
|
||||
- 必须保留原始的版权声明及许可证信息
|
||||
- 不得额外施加限制来限制他人对本软件的自由使用
|
||||
|
||||
上述状态为存在自动构建版本和新功能的更新但当前并未发布稳定版,处于预发行状态。
|
||||
<h3>3. 我们鼓励在遵守 AGPL 3.0 条款的前提下进行自由传播和改进,但请尊重作者署名权,勿冒用原作者名义。</h3>
|
||||
|
||||

|
||||
## 项目推广
|
||||
|
||||
上述状态为当前发行的稳定版可能存在严重问题但并未及时进行修复且并未发布稳定版。
|
||||
|
||||
## 开始贡献
|
||||
|
||||
欢迎为此项目进行新版本的适配代码贡献!<br/>
|
||||
|
||||
- [CONTRIBUTING](https://github.com/fankes/TSBattery/blob/master/CONTRIBUTING.md)
|
||||
<!--suppress HtmlDeprecatedAttribute -->
|
||||
<div align="center">
|
||||
<h2>嘿,还请君留步!👋</h2>
|
||||
<h3>这里有 Android 开发工具、UI 设计、Gradle 插件、Xposed 模块和实用软件等相关项目。</h3>
|
||||
<h3>如果下方的项目能为你提供帮助,不妨为我点个 star 吧!</h3>
|
||||
<h3>所有项目免费、开源,遵循对应开源许可协议。</h3>
|
||||
<h1><a href="https://github.com/fankes/fankes/blob/main/project-promote/README-zh-CN.md">→ 查看更多关于我的项目,请点击这里 ←</a></h1>
|
||||
</div>
|
||||
|
||||
## Star History
|
||||
|
||||
@@ -75,7 +86,7 @@ TSBattery 是一个旨在使 QQ、TIM、微信 变得更省电的开源 Xposed
|
||||
- [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.html)
|
||||
|
||||
```
|
||||
Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
@@ -88,9 +99,9 @@ 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
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
```
|
||||
|
||||
Powered by [YukiHookAPI](https://github.com/fankes/YukiHookAPI)
|
||||
Powered by [YukiHookAPI](https://github.com/HighCapable/YukiHookAPI)
|
||||
|
||||
版权所有 © 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
版权所有 © 2017 Fankes Studio(qzmmcn@163.com)
|
2
app/.gitignore
vendored
2
app/.gitignore
vendored
@@ -1,4 +1,2 @@
|
||||
/build
|
||||
/release
|
||||
/src/main/assets/xposed_init
|
||||
/src/main/resources/META-INF/yukihookapi_init
|
@@ -1,86 +0,0 @@
|
||||
import groovy.json.JsonSlurper
|
||||
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'org.jetbrains.kotlin.android'
|
||||
id 'com.google.devtools.ksp'
|
||||
}
|
||||
|
||||
android {
|
||||
signingConfigs {
|
||||
universal {
|
||||
def dirPath = rootProject.ext.app.signingConfigs.secretConfigsDirPath
|
||||
def fileName = rootProject.ext.app.signingConfigs.secretConfigsFileName
|
||||
def configs = new JsonSlurper().parse(file("${dirPath}/${fileName}"))
|
||||
keyAlias configs.keyAlias
|
||||
keyPassword configs.keyPassword
|
||||
storeFile file("${dirPath}/${configs.storeFileName}")
|
||||
storePassword configs.storePassword
|
||||
v1SigningEnabled true
|
||||
v2SigningEnabled true
|
||||
}
|
||||
}
|
||||
|
||||
namespace 'com.fankes.tsbattery'
|
||||
compileSdk rootProject.ext.android.compileSdk
|
||||
|
||||
defaultConfig {
|
||||
applicationId 'com.fankes.tsbattery'
|
||||
|
||||
minSdk rootProject.ext.android.minSdk
|
||||
targetSdk rootProject.ext.android.targetSdk
|
||||
|
||||
versionCode rootProject.ext.app.versionCode
|
||||
versionName rootProject.ext.app.versionName
|
||||
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
minifyEnabled false
|
||||
signingConfig signingConfigs.universal
|
||||
}
|
||||
release {
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
zipAlignEnabled true
|
||||
signingConfig signingConfigs.universal
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '11'
|
||||
freeCompilerArgs = [
|
||||
'-Xno-param-assertions',
|
||||
'-Xno-call-assertions',
|
||||
'-Xno-receiver-assertions'
|
||||
]
|
||||
}
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
lintOptions {
|
||||
checkReleaseBuilds false
|
||||
}
|
||||
aaptOptions.additionalParameters '--allow-reserved-package-id', '--package-id', '0x37'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly 'de.robv.android.xposed:api:82'
|
||||
implementation 'com.highcapable.yukihookapi:api:1.1.11'
|
||||
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.1.11'
|
||||
implementation 'com.github.duanhong169:drawabletoolbox:1.0.7'
|
||||
implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.7'
|
||||
implementation 'androidx.core:core-ktx:1.10.1'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'com.google.android.material:material:1.9.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
}
|
94
app/build.gradle.kts
Normal file
94
app/build.gradle.kts
Normal file
@@ -0,0 +1,94 @@
|
||||
plugins {
|
||||
autowire(libs.plugins.android.application)
|
||||
autowire(libs.plugins.kotlin.android)
|
||||
autowire(libs.plugins.kotlin.ksp)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = property.project.app.packageName
|
||||
compileSdk = property.project.android.compileSdk
|
||||
|
||||
signingConfigs {
|
||||
create("universal") {
|
||||
keyAlias = property.project.app.signing.keyAlias
|
||||
keyPassword = property.project.app.signing.keyPassword
|
||||
storeFile = rootProject.file(property.project.app.signing.storeFilePath)
|
||||
storePassword = property.project.app.signing.storePassword
|
||||
enableV1Signing = true
|
||||
enableV2Signing = true
|
||||
}
|
||||
}
|
||||
defaultConfig {
|
||||
applicationId = property.project.app.packageName
|
||||
minSdk = property.project.android.minSdk
|
||||
targetSdk = property.project.android.targetSdk
|
||||
versionName = property.project.app.versionName
|
||||
versionCode = property.project.app.versionCode
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
buildTypes {
|
||||
all { signingConfig = signingConfigs.getByName("universal") }
|
||||
release {
|
||||
isMinifyEnabled = true
|
||||
isShrinkResources = true
|
||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
buildFeatures {
|
||||
buildConfig = true
|
||||
viewBinding = true
|
||||
}
|
||||
lint { checkReleaseBuilds = false }
|
||||
androidResources.additionalParameters += listOf("--allow-reserved-package-id", "--package-id", "0x37")
|
||||
}
|
||||
|
||||
androidComponents {
|
||||
onVariants(selector().all()) {
|
||||
it.outputs.forEach { output ->
|
||||
val currentType = it.buildType
|
||||
|
||||
// Workaround for GitHub Actions.
|
||||
// Why? I don't know, but it works.
|
||||
// Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
|
||||
// public inline fun CharSequence.isNotBlank(): Boolean defined in kotlin.text.
|
||||
@Suppress("UNNECESSARY_SAFE_CALL", "RemoveRedundantCallsOfConversionMethods")
|
||||
val currentSuffix = property.github.ci.commit.id?.let { suffix ->
|
||||
// Workaround for GitHub Actions.
|
||||
// Strongly transfer type to [String].
|
||||
val sSuffix = suffix.toString()
|
||||
if (sSuffix.isNotBlank()) "-$sSuffix" else ""
|
||||
}
|
||||
val currentVersion = "${output.versionName.get()}$currentSuffix(${output.versionCode.get()})"
|
||||
if (output is com.android.build.api.variant.impl.VariantOutputImpl)
|
||||
output.outputFileName.set("${property.project.name}-v$currentVersion-$currentType.apk")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(de.robv.android.xposed.api)
|
||||
implementation(com.highcapable.yukihookapi.api)
|
||||
ksp(com.highcapable.yukihookapi.ksp.xposed)
|
||||
ksp(com.highcapable.hikage.hikage.compiler)
|
||||
implementation(com.highcapable.kavaref.kavaref.core)
|
||||
implementation(com.highcapable.kavaref.kavaref.extension)
|
||||
implementation(com.highcapable.hikage.hikage.core)
|
||||
implementation(com.highcapable.hikage.hikage.extension)
|
||||
implementation(com.highcapable.hikage.hikage.widget.androidx)
|
||||
implementation(com.highcapable.hikage.hikage.widget.material)
|
||||
implementation(com.fankes.projectpromote.project.promote)
|
||||
implementation(org.luckypray.dexkit)
|
||||
implementation(com.github.duanhong169.drawabletoolbox)
|
||||
implementation(com.squareup.okhttp3.okhttp)
|
||||
implementation(androidx.core.core.ktx)
|
||||
implementation(androidx.appcompat.appcompat)
|
||||
implementation(com.google.android.material.material)
|
||||
implementation(androidx.constraintlayout.constraintlayout)
|
||||
testImplementation(junit.junit)
|
||||
androidTestImplementation(androidx.test.ext.junit)
|
||||
androidTestImplementation(androidx.test.espresso.espresso.core)
|
||||
}
|
11
app/proguard-rules.pro
vendored
11
app/proguard-rules.pro
vendored
@@ -32,11 +32,16 @@
|
||||
-adaptresourcefilecontents
|
||||
|
||||
-renamesourcefileattribute P
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
-keepattributes SourceFile,Signature,LineNumberTable
|
||||
|
||||
# 排除注入的 Activity
|
||||
-keep class com.fankes.tsbattery.ui.activity.parasitic.ConfigActivity
|
||||
|
||||
# DexKit
|
||||
-keep class org.luckypray.dexkit.DexKitBridge {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
# 防止某些类被 R8 混淆 (可能是 BUG)
|
||||
# FIXME: 已知问题字符串类名 (即使是常量) 也会被 R8 处理为混淆后的类名
|
||||
# FIXME: 所以目前只能把不允许 R8 处理的类 keep 掉,同时在当前模块中也不会被混淆就是了
|
||||
@@ -48,6 +53,8 @@
|
||||
public static *** throwUninitializedPropertyAccessException(...);
|
||||
}
|
||||
|
||||
-keepclassmembers class * implements androidx.viewbinding.ViewBinding {
|
||||
-keep class * extends android.app.Activity
|
||||
-keep class * implements androidx.viewbinding.ViewBinding {
|
||||
<init>();
|
||||
*** inflate(android.view.LayoutInflater);
|
||||
}
|
@@ -1,11 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.fankes.tsbattery">
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<uses-permission
|
||||
android:name="${applicationId}.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"
|
||||
tools:node="remove" />
|
||||
<permission
|
||||
android:name="${applicationId}.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"
|
||||
tools:node="remove" />
|
||||
|
||||
<!-- 作用域 APP -->
|
||||
<queries>
|
||||
<package android:name="com.tencent.mobileqq" />
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
* Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
|
||||
* https://github.com/fankes/TSBattery
|
||||
*
|
||||
* This software is non-free but opensource software: you can redistribute it
|
||||
@@ -17,7 +17,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2021/11/9.
|
||||
* This file is created by fankes on 2021/11/9.
|
||||
*/
|
||||
package com.fankes.tsbattery.application
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
* Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
|
||||
* https://github.com/fankes/TSBattery
|
||||
*
|
||||
* This software is non-free but opensource software: you can redistribute it
|
||||
@@ -17,10 +17,15 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* 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
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
/**
|
||||
* 模块版本常量定义类
|
||||
*/
|
||||
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)"
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
* Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
|
||||
* https://github.com/fankes/TSBattery
|
||||
*
|
||||
* This software is non-free but opensource software: you can redistribute it
|
||||
@@ -17,7 +17,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/9/28.
|
||||
* This file is created by fankes on 2022/9/28.
|
||||
*/
|
||||
@file:Suppress("StaticFieldLeak")
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
* Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
|
||||
* https://github.com/fankes/TSBattery
|
||||
*
|
||||
* This software is non-free but opensource software: you can redistribute it
|
||||
@@ -17,10 +17,8 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/2/15.
|
||||
* This file is created by fankes on 2022/2/15.
|
||||
*/
|
||||
@file:Suppress("IMPLICIT_CAST_TO_ANY")
|
||||
|
||||
package com.fankes.tsbattery.hook
|
||||
|
||||
import com.fankes.tsbattery.const.PackageName
|
||||
@@ -31,7 +29,7 @@ import com.highcapable.yukihookapi.hook.factory.configs
|
||||
import com.highcapable.yukihookapi.hook.factory.encase
|
||||
import com.highcapable.yukihookapi.hook.xposed.proxy.IYukiHookXposedInit
|
||||
|
||||
@InjectYukiHookWithXposed(isUsingResourcesHook = false)
|
||||
@InjectYukiHookWithXposed
|
||||
object HookEntry : IYukiHookXposedInit {
|
||||
|
||||
/** 是否完全支持当前版本 */
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
* Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
|
||||
* https://github.com/fankes/TSBattery
|
||||
*
|
||||
* This software is non-free but opensource software: you can redistribute it
|
||||
@@ -17,8 +17,10 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* 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
|
||||
|
||||
import android.app.Activity
|
||||
@@ -40,13 +42,13 @@ import com.fankes.tsbattery.utils.factory.absoluteStatusBarHeight
|
||||
import com.fankes.tsbattery.utils.factory.appVersionCode
|
||||
import com.fankes.tsbattery.utils.factory.appVersionName
|
||||
import com.fankes.tsbattery.utils.factory.dp
|
||||
import com.highcapable.kavaref.KavaRef.Companion.asResolver
|
||||
import com.highcapable.kavaref.KavaRef.Companion.resolve
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
import com.highcapable.yukihookapi.hook.factory.current
|
||||
import com.highcapable.yukihookapi.hook.factory.injectModuleAppResources
|
||||
import com.highcapable.yukihookapi.hook.factory.processName
|
||||
import com.highcapable.yukihookapi.hook.factory.registerModuleAppActivities
|
||||
import com.highcapable.yukihookapi.hook.log.loggerI
|
||||
import com.highcapable.yukihookapi.hook.type.android.ViewClass
|
||||
import com.highcapable.yukihookapi.hook.log.YLog
|
||||
|
||||
/**
|
||||
* Hook 微信
|
||||
@@ -56,16 +58,19 @@ import com.highcapable.yukihookapi.hook.type.android.ViewClass
|
||||
object WeChatHooker : YukiBaseHooker() {
|
||||
|
||||
/** 微信存在的类 - 未测试每个版本是否都存在 */
|
||||
const val LauncherUIClass = "${PackageName.WECHAT}.ui.LauncherUI"
|
||||
const val LauncherUIClassName = "${PackageName.WECHAT}.ui.LauncherUI"
|
||||
|
||||
/** 微信存在的类 - 未测试每个版本是否都存在 */
|
||||
private const val EmptyActivityClass = "${PackageName.WECHAT}.ui.EmptyActivity"
|
||||
private val LauncherUIClass by lazyClassOrNull("${PackageName.WECHAT}.ui.LauncherUI")
|
||||
|
||||
/** 微信存在的类 - 未测试每个版本是否都存在 */
|
||||
private const val WelabMainUIClass = "${PackageName.WECHAT}.plugin.welab.ui.WelabMainUI"
|
||||
private val EmptyActivityClass by lazyClassOrNull("${PackageName.WECHAT}.ui.EmptyActivity")
|
||||
|
||||
/** 微信存在的类 - 未测试每个版本是否都存在 */
|
||||
private const val SettingsUIClass = "${PackageName.WECHAT}.plugin.setting.ui.setting.SettingsUI"
|
||||
private val WelabMainUIClass by lazyClassOrNull("${PackageName.WECHAT}.plugin.welab.ui.WelabMainUI")
|
||||
|
||||
/** 微信存在的类 - 未测试每个版本是否都存在 */
|
||||
private val SettingsUIClass by lazyClassOrNull("${PackageName.WECHAT}.plugin.setting.ui.setting.SettingsUI")
|
||||
|
||||
/** TSBattery 图标 TAG 名称 */
|
||||
private const val TSBARRERY_ICON_TAG = "tsbattery_icon"
|
||||
@@ -95,54 +100,42 @@ object WeChatHooker : YukiBaseHooker() {
|
||||
onAppLifecycle {
|
||||
onCreate {
|
||||
ConfigData.init(context = this)
|
||||
registerModuleAppActivities(
|
||||
when {
|
||||
EmptyActivityClass.hasClass() -> EmptyActivityClass
|
||||
WelabMainUIClass.hasClass() -> WelabMainUIClass
|
||||
else -> error("Inject WeChat Activity Proxy failed, unsupport version $appVersionName($appVersionCode)")
|
||||
}
|
||||
)
|
||||
registerModuleAppActivities(when {
|
||||
EmptyActivityClass != null -> EmptyActivityClass
|
||||
WelabMainUIClass != null -> WelabMainUIClass
|
||||
else -> error("Inject WeChat Activity Proxy failed, unsupport version $appVersionName($appVersionCode)")
|
||||
})
|
||||
if (ConfigData.isDisableAllHook) return@onCreate
|
||||
hookSystemWakeLock()
|
||||
loggerI(msg = "All processes are completed for \"${processName.takeIf { it != packageName } ?: packageName}\"")
|
||||
YLog.info("All processes are completed for \"${processName.takeIf { it != packageName } ?: packageName}\"")
|
||||
}
|
||||
}
|
||||
/** 仅注入主进程 */
|
||||
withProcess(mainProcessName) {
|
||||
/** Hook 跳转事件 */
|
||||
LauncherUIClass.hook {
|
||||
injectMember {
|
||||
method {
|
||||
name = "onResume"
|
||||
emptyParam()
|
||||
}
|
||||
afterHook { instance<Activity>().jumpToModuleSettings(isFinish = false) }
|
||||
}
|
||||
}
|
||||
LauncherUIClass?.resolve()?.optional()?.firstMethodOrNull {
|
||||
name = "onResume"
|
||||
emptyParameters()
|
||||
}?.hook()?.after { instance<Activity>().jumpToModuleSettings(isFinish = false) }
|
||||
/** 向设置界面右上角添加按钮 */
|
||||
SettingsUIClass.hook {
|
||||
injectMember {
|
||||
method {
|
||||
name = "onResume"
|
||||
emptyParam()
|
||||
}
|
||||
afterHook {
|
||||
method {
|
||||
name = "get_fragment"
|
||||
emptyParam()
|
||||
superClass(isOnlySuperClass = true)
|
||||
}.get(instance).call()?.current()?.method {
|
||||
name = "getView"
|
||||
emptyParam()
|
||||
returnType = ViewClass
|
||||
superClass(isOnlySuperClass = true)
|
||||
}?.invoke<ViewGroup?>()?.also {
|
||||
it.context?.injectModuleAppResources()
|
||||
runCatching { it.getChildAt(0) as? ViewGroup? }.getOrNull()?.also { rootView ->
|
||||
if (rootView.findViewWithTag<View>(TSBARRERY_ICON_TAG) == null)
|
||||
rootView.addView(createPreferenceIcon(it.context))
|
||||
}
|
||||
}
|
||||
SettingsUIClass?.resolve()?.optional()?.firstMethodOrNull {
|
||||
name = "onResume"
|
||||
emptyParameters()
|
||||
}?.hook()?.after {
|
||||
SettingsUIClass?.resolve()?.optional()?.firstMethodOrNull {
|
||||
name = "get_fragment"
|
||||
emptyParameters()
|
||||
superclass()
|
||||
}?.of(instance)?.invoke()?.asResolver()?.optional()?.firstMethodOrNull {
|
||||
name = "getView"
|
||||
emptyParameters()
|
||||
returnType = View::class
|
||||
superclass()
|
||||
}?.invoke<ViewGroup?>()?.also {
|
||||
it.context?.injectModuleAppResources()
|
||||
runCatching { it.getChildAt(0) as? ViewGroup? }.getOrNull()?.also { rootView ->
|
||||
if (rootView.findViewWithTag<View>(TSBARRERY_ICON_TAG) == null)
|
||||
rootView.addView(createPreferenceIcon(it.context))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
* Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
|
||||
* https://github.com/fankes/TSBattery
|
||||
*
|
||||
* This software is non-free but opensource software: you can redistribute it
|
||||
@@ -17,24 +17,24 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/9/29.
|
||||
* This file is created by fankes on 2022/9/29.
|
||||
*/
|
||||
package com.fankes.tsbattery.hook.factory
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.PowerManager
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import com.fankes.tsbattery.const.JumpEvent
|
||||
import com.fankes.tsbattery.const.PackageName
|
||||
import com.fankes.tsbattery.hook.entity.QQTIMHooker.toClass
|
||||
import com.fankes.tsbattery.ui.activity.parasitic.ConfigActivity
|
||||
import com.highcapable.kavaref.KavaRef.Companion.asResolver
|
||||
import com.highcapable.kavaref.KavaRef.Companion.resolve
|
||||
import com.highcapable.kavaref.extension.VariousClass
|
||||
import com.highcapable.yukihookapi.YukiHookAPI
|
||||
import com.highcapable.yukihookapi.hook.bean.VariousClass
|
||||
import com.highcapable.yukihookapi.hook.factory.field
|
||||
import com.highcapable.yukihookapi.hook.factory.method
|
||||
import com.highcapable.yukihookapi.hook.param.PackageParam
|
||||
import com.highcapable.yukihookapi.hook.type.android.PowerManager_WakeLockClass
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
/** QQ、TIM 存在的类 */
|
||||
@@ -47,14 +47,27 @@ private val ThemeUtilClass = VariousClass("${PackageName.QQ}.theme.ThemeUtil", "
|
||||
* QQ、TIM 主题是否为夜间模式
|
||||
* @return [Boolean]
|
||||
*/
|
||||
fun Context.isQQNightMode() = runCatching {
|
||||
ThemeUtilClass.get(classLoader).method {
|
||||
name = "getUserCurrentThemeId"
|
||||
paramCount = 1
|
||||
}.get().string(MobileQQClass.toClass(classLoader)
|
||||
.field { name = "sMobileQQ" }.ignored().get().current(ignored = true)?.field { name = "mAppRuntime" }?.any()
|
||||
).let { it.endsWith("1103") || it.endsWith("2920") }
|
||||
}.getOrNull() ?: false
|
||||
fun Context.isQQNightMode(): Boolean {
|
||||
val sMobileQQ = MobileQQClass.toClass(classLoader).resolve()
|
||||
.optional()
|
||||
.firstFieldOrNull {
|
||||
name = "sMobileQQ"
|
||||
superclass()
|
||||
}?.get()
|
||||
val mAppRuntime = sMobileQQ?.asResolver()
|
||||
?.optional()
|
||||
?.firstFieldOrNull {
|
||||
name = "mAppRuntime"
|
||||
superclass()
|
||||
}?.get()
|
||||
val currentThemeId = ThemeUtilClass.load(classLoader).resolve()
|
||||
.optional()
|
||||
.firstMethodOrNull {
|
||||
name = "getUserCurrentThemeId"
|
||||
parameterCount = 1
|
||||
}?.invokeQuietly<String>(mAppRuntime)
|
||||
return currentThemeId?.let { it.endsWith("1103") || it.endsWith("2920") } == true
|
||||
}
|
||||
|
||||
/** 启动模块设置 [Activity] */
|
||||
fun Context.startModuleSettings() {
|
||||
@@ -81,13 +94,14 @@ fun Activity.jumpToModuleSettings(isFinish: Boolean = true) {
|
||||
|
||||
/** Hook 系统电源锁 */
|
||||
fun PackageParam.hookSystemWakeLock() {
|
||||
PowerManager_WakeLockClass.hook {
|
||||
injectMember {
|
||||
method {
|
||||
name = "acquireLocked"
|
||||
emptyParam()
|
||||
}
|
||||
intercept()
|
||||
}
|
||||
PowerManager.WakeLock::class.resolve().apply {
|
||||
firstMethod {
|
||||
name = "acquireLocked"
|
||||
emptyParameters()
|
||||
}.hook().intercept()
|
||||
firstMethod {
|
||||
name = "release"
|
||||
parameters(Int::class)
|
||||
}.hook().intercept()
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2017 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/10/8.
|
||||
*/
|
||||
@file:Suppress("MemberVisibilityCanBePrivate")
|
||||
|
||||
package com.fankes.tsbattery.hook.helper
|
||||
|
||||
import com.highcapable.yukihookapi.hook.log.YLog
|
||||
import com.highcapable.yukihookapi.hook.param.PackageParam
|
||||
import org.luckypray.dexkit.DexKitBridge
|
||||
|
||||
/**
|
||||
* DexKit 工具类
|
||||
*/
|
||||
object DexKitHelper {
|
||||
|
||||
/** 是否已装载 */
|
||||
private var isLoaded = false
|
||||
|
||||
/** 装载 */
|
||||
fun load() {
|
||||
if (isLoaded) return
|
||||
runCatching {
|
||||
System.loadLibrary("dexkit")
|
||||
isLoaded = true
|
||||
}.onFailure { YLog.error("Load DexKit failed!", it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 [DexKitBridge]
|
||||
* @param param 当前实例
|
||||
* @param initiate 方法体
|
||||
*/
|
||||
fun create(param: PackageParam, initiate: DexKitBridge.() -> Unit) {
|
||||
load()
|
||||
runCatching { DexKitBridge.create(param.appInfo.sourceDir).use { initiate(it) } }
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
* Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
|
||||
* https://github.com/fankes/TSBattery
|
||||
*
|
||||
* This software is non-free but opensource software: you can redistribute it
|
||||
@@ -17,7 +17,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2021/9/4.
|
||||
* This file is created by fankes on 2021/9/4.
|
||||
*/
|
||||
@file:Suppress("SetTextI18n", "LocalVariableName", "SameParameterValue")
|
||||
|
||||
@@ -27,54 +27,37 @@ import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.view.HapticFeedbackConstants
|
||||
import androidx.core.view.isVisible
|
||||
import com.fankes.tsbattery.BuildConfig
|
||||
import com.fankes.projectpromote.ProjectPromote
|
||||
import com.fankes.tsbattery.R
|
||||
import com.fankes.tsbattery.const.JumpEvent
|
||||
import com.fankes.tsbattery.const.ModuleVersion
|
||||
import com.fankes.tsbattery.const.PackageName
|
||||
import com.fankes.tsbattery.databinding.ActivityMainBinding
|
||||
import com.fankes.tsbattery.hook.entity.QQTIMHooker
|
||||
import com.fankes.tsbattery.hook.entity.WeChatHooker
|
||||
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.YukiPromoteTool
|
||||
import com.fankes.tsbattery.wrapper.BuildConfigWrapper
|
||||
import com.highcapable.yukihookapi.YukiHookAPI
|
||||
|
||||
class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
|
||||
companion object {
|
||||
|
||||
private val qqSupportVersions = arrayOf(
|
||||
"8.0.0", "8.0.5", "8.0.7", "8.1.0", "8.1.3", "8.1.5", "8.1.8",
|
||||
"8.2.0", "8.2.6", "8.2.7", "8.2.8", "8.2.11", "8.3.0", "8.3.5",
|
||||
"8.3.6", "8.3.9", "8.4.1", "8.4.5", "8.4.8", "8.4.10", "8.4.17",
|
||||
"8.4.18", "8.5.0", "8.5.5", "8.6.0", "8.6.5", "8.7.0", "8.7.5",
|
||||
"8.7.8", "8.8.0", "8.8.3", "8.8.5", "8.8.11", "8.8.12", "8.8.17",
|
||||
"8.8.20", "8.8.23", "8.8.28", "8.8.33", "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.8.93", "8.8.95", "8.8.98", "8.9.0", "8.9.1", "8.9.2", "8.9.3",
|
||||
"8.9.5", "8.9.8", "8.9.10", "8.9.13", "8.9.15", "8.9.18", "8.9.19",
|
||||
"8.9.20", "8.9.23", "8.9.25", "8.9.28", "8.9.30", "8.9.33",
|
||||
"8.9.35", "8.9.38", "8.9.50", "8.9.53", "8.9.55", "8.9.58",
|
||||
"8.9.63", "8.9.68", "8.9.70"
|
||||
)
|
||||
private val qqSupportVersion by lazy {
|
||||
if (qqSupportVersions.isNotEmpty()) {
|
||||
var value = ""
|
||||
qqSupportVersions.forEach { value += "$it、" }
|
||||
"${value.trim().let { it.substring(0, it.lastIndex) }}\n\n其余版本请自行测试是否有效。"
|
||||
} else "empty"
|
||||
}
|
||||
private const val timSupportVersion = "2+、3+ (并未完全测试每个版本)。"
|
||||
private const val wechatSupportVersion = "全版本仅支持基础省电,更多功能依然画饼。"
|
||||
|
||||
/** 预发布的版本标识 */
|
||||
private const val pendingFlag = ""
|
||||
private const val QQ_SUPPORT_VERSION = "理论支持 8.0.0+ 及以上版本。"
|
||||
private const val TIM_SUPPORT_VERSION = "2+、3+ (并未完全测试每个版本)。"
|
||||
private const val WECHAT_SUPPORT_VERSION = "全版本仅支持基础省电,更多功能依然画饼。"
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
/** 检查更新 */
|
||||
GithubReleaseTool.checkingForUpdate(context = this, BuildConfig.VERSION_NAME) { version, function ->
|
||||
GithubReleaseTool.checkingForUpdate(context = this, ModuleVersion.NAME) { version, function ->
|
||||
binding.mainTextReleaseVersion.apply {
|
||||
text = "点击更新 $version"
|
||||
isVisible = true
|
||||
@@ -89,7 +72,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
binding.mainTextApiWay.isVisible = true
|
||||
refreshActivateExecutor()
|
||||
/** 推广、恰饭 */
|
||||
YukiPromoteTool.promote(context = this)
|
||||
ProjectPromote.show(activity = this, ModuleVersion.toString())
|
||||
} else
|
||||
showDialog {
|
||||
title = "模块没有激活"
|
||||
@@ -102,11 +85,31 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
binding.mainTextTimVer.text = PackageName.TIM.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 {
|
||||
showDialog {
|
||||
title = "兼容的 QQ 版本"
|
||||
msg = qqSupportVersion
|
||||
msg = QQ_SUPPORT_VERSION
|
||||
confirmButton(text = "我知道了")
|
||||
}
|
||||
/** 振动提醒 */
|
||||
@@ -115,7 +118,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
binding.mainTimItem.setOnClickListener {
|
||||
showDialog {
|
||||
title = "兼容的 TIM 版本"
|
||||
msg = timSupportVersion
|
||||
msg = TIM_SUPPORT_VERSION
|
||||
confirmButton(text = "我知道了")
|
||||
}
|
||||
/** 振动提醒 */
|
||||
@@ -124,7 +127,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
binding.mainWechatItem.setOnClickListener {
|
||||
showDialog {
|
||||
title = "兼容的微信版本"
|
||||
msg = wechatSupportVersion
|
||||
msg = WECHAT_SUPPORT_VERSION
|
||||
confirmButton(text = "我知道了")
|
||||
}
|
||||
/** 振动提醒 */
|
||||
@@ -148,6 +151,11 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
if (btn.isPressed.not()) return@setOnCheckedChangeListener
|
||||
hideOrShowLauncherIcon(b)
|
||||
}
|
||||
/** 判断当前启动模式 */
|
||||
if (packageName != BuildConfigWrapper.APPLICATION_ID) {
|
||||
binding.quickActionItem.isVisible = false
|
||||
binding.displaySettingItem.isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,7 +167,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
startActivity(Intent().apply {
|
||||
component = ComponentName(
|
||||
packageName,
|
||||
if (packageName != PackageName.WECHAT) QQTIMHooker.JumpActivityClass else WeChatHooker.LauncherUIClass
|
||||
if (packageName != PackageName.WECHAT) QQTIMHooker.JumpActivityClassName else WeChatHooker.LauncherUIClassName
|
||||
)
|
||||
putExtra(JumpEvent.OPEN_MODULE_SETTING, YukiHookAPI.Status.compiledTimestamp)
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
* Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
|
||||
* https://github.com/fankes/TSBattery
|
||||
*
|
||||
* This software is non-free but opensource software: you can redistribute it
|
||||
@@ -17,25 +17,26 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/1/30.
|
||||
* This file is created by fankes on 2022/1/30.
|
||||
*/
|
||||
@file:Suppress("UNCHECKED_CAST")
|
||||
|
||||
package com.fankes.tsbattery.ui.activity.base
|
||||
|
||||
import android.content.res.Configuration
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.fankes.tsbattery.R
|
||||
import com.fankes.tsbattery.utils.factory.isNotSystemInDarkMode
|
||||
import com.highcapable.yukihookapi.hook.factory.current
|
||||
import com.highcapable.yukihookapi.hook.factory.method
|
||||
import com.highcapable.yukihookapi.hook.type.android.LayoutInflaterClass
|
||||
import com.highcapable.yukihookapi.hook.xposed.parasitic.activity.base.ModuleAppCompatActivity
|
||||
import com.highcapable.kavaref.KavaRef.Companion.resolve
|
||||
import com.highcapable.kavaref.extension.genericSuperclassTypeArguments
|
||||
import com.highcapable.kavaref.extension.toClassOrNull
|
||||
import com.highcapable.yukihookapi.hook.xposed.parasitic.activity.proxy.ModuleActivity
|
||||
|
||||
abstract class BaseActivity<VB : ViewBinding> : ModuleAppCompatActivity() {
|
||||
abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity(), ModuleActivity {
|
||||
|
||||
override val moduleTheme get() = R.style.Theme_TSBattery
|
||||
|
||||
@@ -43,11 +44,14 @@ abstract class BaseActivity<VB : ViewBinding> : ModuleAppCompatActivity() {
|
||||
lateinit var binding: VB
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
delegate.onCreate(savedInstanceState)
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = current().generic()?.argument()?.method {
|
||||
val bindingClass = javaClass.genericSuperclassTypeArguments().firstOrNull()?.toClassOrNull()
|
||||
binding = bindingClass?.resolve()?.optional()?.firstMethodOrNull {
|
||||
name = "inflate"
|
||||
param(LayoutInflaterClass)
|
||||
}?.get()?.invoke<VB>(layoutInflater) ?: error("binding failed")
|
||||
parameters(LayoutInflater::class)
|
||||
}?.invoke<VB>(layoutInflater) ?: error("binding failed")
|
||||
if (Build.VERSION.SDK_INT >= 35) binding.root.fitsSystemWindows = true
|
||||
setContentView(binding.root)
|
||||
/** 隐藏系统的标题栏 */
|
||||
supportActionBar?.hide()
|
||||
@@ -56,6 +60,7 @@ abstract class BaseActivity<VB : ViewBinding> : ModuleAppCompatActivity() {
|
||||
isAppearanceLightStatusBars = isNotSystemInDarkMode
|
||||
isAppearanceLightNavigationBars = isNotSystemInDarkMode
|
||||
}
|
||||
@Suppress("DEPRECATION")
|
||||
ResourcesCompat.getColor(resources, R.color.colorThemeBackground, null).also {
|
||||
window?.statusBarColor = it
|
||||
window?.navigationBarColor = it
|
||||
@@ -67,4 +72,16 @@ abstract class BaseActivity<VB : ViewBinding> : ModuleAppCompatActivity() {
|
||||
|
||||
/** 回调 [onCreate] 方法 */
|
||||
abstract fun onCreate()
|
||||
|
||||
override fun getClassLoader() = delegate.getClassLoader()
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
delegate.onConfigurationChanged(newConfig)
|
||||
super.onConfigurationChanged(newConfig)
|
||||
}
|
||||
|
||||
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
|
||||
delegate.onRestoreInstanceState(savedInstanceState)
|
||||
super.onRestoreInstanceState(savedInstanceState)
|
||||
}
|
||||
}
|
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2017 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 2025/4/21.
|
||||
*/
|
||||
@file:Suppress("DEPRECATION")
|
||||
|
||||
package com.fankes.tsbattery.ui.activity.base
|
||||
|
||||
import android.content.res.Configuration
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.widget.FrameLayout
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.view.WindowCompat
|
||||
import com.fankes.tsbattery.R
|
||||
import com.fankes.tsbattery.utils.factory.isNotSystemInDarkMode
|
||||
import com.highcapable.yukihookapi.hook.xposed.parasitic.activity.proxy.ModuleActivity
|
||||
import android.R as Android_R
|
||||
|
||||
abstract class BaseActivity2 : AppCompatActivity(), ModuleActivity {
|
||||
|
||||
override val moduleTheme get() = R.style.Theme_TSBattery
|
||||
|
||||
@CallSuper
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
delegate.onCreate(savedInstanceState)
|
||||
super.onCreate(savedInstanceState)
|
||||
/** 隐藏系统的标题栏 */
|
||||
supportActionBar?.hide()
|
||||
/** 初始化沉浸状态栏 */
|
||||
WindowCompat.getInsetsController(window, 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()
|
||||
if (Build.VERSION.SDK_INT >= 35) findViewById<FrameLayout>(Android_R.id.content).getChildAt(0)?.fitsSystemWindows = true
|
||||
}
|
||||
|
||||
/** 回调 [onCreate] 方法 */
|
||||
abstract fun onCreate()
|
||||
|
||||
override fun getClassLoader() = delegate.getClassLoader()
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
delegate.onConfigurationChanged(newConfig)
|
||||
super.onConfigurationChanged(newConfig)
|
||||
}
|
||||
|
||||
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
|
||||
delegate.onRestoreInstanceState(savedInstanceState)
|
||||
super.onRestoreInstanceState(savedInstanceState)
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
* Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
|
||||
* https://github.com/fankes/TSBattery
|
||||
*
|
||||
* This software is non-free but opensource software: you can redistribute it
|
||||
@@ -17,115 +17,545 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/9/28.
|
||||
* This file is created by fankes on 2022/9/28.
|
||||
*/
|
||||
@file:Suppress("SetTextI18n", "DEPRECATION")
|
||||
|
||||
package com.fankes.tsbattery.ui.activity.parasitic
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.animation.LayoutTransition
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Typeface
|
||||
import android.view.Gravity
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import com.fankes.tsbattery.BuildConfig
|
||||
import androidx.core.view.setPadding
|
||||
import androidx.core.view.updateMargins
|
||||
import androidx.core.view.updateMarginsRelative
|
||||
import androidx.core.view.updatePadding
|
||||
import com.fankes.projectpromote.ProjectPromote
|
||||
import com.fankes.tsbattery.R
|
||||
import com.fankes.tsbattery.const.ModuleVersion
|
||||
import com.fankes.tsbattery.const.PackageName
|
||||
import com.fankes.tsbattery.data.ConfigData
|
||||
import com.fankes.tsbattery.data.ConfigData.bind
|
||||
import com.fankes.tsbattery.databinding.ActivityConfigBinding
|
||||
import com.fankes.tsbattery.hook.HookEntry
|
||||
import com.fankes.tsbattery.hook.entity.QQTIMHooker
|
||||
import com.fankes.tsbattery.ui.activity.MainActivity
|
||||
import com.fankes.tsbattery.ui.activity.base.BaseActivity
|
||||
import com.fankes.tsbattery.utils.factory.*
|
||||
import com.fankes.tsbattery.ui.activity.base.BaseActivity2
|
||||
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.wrapper.BuildConfigWrapper
|
||||
import com.highcapable.betterandroid.ui.extension.component.base.getThemeAttrsDrawable
|
||||
import com.highcapable.betterandroid.ui.extension.component.startActivity
|
||||
import com.highcapable.betterandroid.ui.extension.graphics.toNormalColorStateList
|
||||
import com.highcapable.betterandroid.ui.extension.view.textColor
|
||||
import com.highcapable.betterandroid.ui.extension.view.tooltipTextCompat
|
||||
import com.highcapable.betterandroid.ui.extension.view.updateMargins
|
||||
import com.highcapable.betterandroid.ui.extension.view.updatePadding
|
||||
import com.highcapable.betterandroid.ui.extension.view.updateTypeface
|
||||
import com.highcapable.hikage.extension.setContentView
|
||||
import com.highcapable.hikage.widget.android.widget.ImageView
|
||||
import com.highcapable.hikage.widget.android.widget.LinearLayout
|
||||
import com.highcapable.hikage.widget.android.widget.TextView
|
||||
import com.highcapable.hikage.widget.androidx.cardview.widget.CardView
|
||||
import com.highcapable.hikage.widget.androidx.core.widget.NestedScrollView
|
||||
import com.highcapable.hikage.widget.com.fankes.tsbattery.ui.widget.MaterialSwitch
|
||||
import com.highcapable.yukihookapi.YukiHookAPI
|
||||
import com.highcapable.yukihookapi.hook.factory.classOf
|
||||
import kotlin.system.exitProcess
|
||||
import android.R as Android_R
|
||||
|
||||
class ConfigActivity : BaseActivity<ActivityConfigBinding>() {
|
||||
class ConfigActivity : BaseActivity2() {
|
||||
|
||||
private lateinit var updateVersionText: TextView
|
||||
private lateinit var needRestartTipText: TextView
|
||||
private lateinit var currentModeText: TextView
|
||||
private lateinit var itemQQTimConfig: LinearLayout
|
||||
|
||||
override fun onCreate() {
|
||||
setContentView {
|
||||
LinearLayout(
|
||||
lparams = LayoutParams(matchParent = true),
|
||||
init = {
|
||||
orientation = LinearLayout.VERTICAL
|
||||
setBackgroundResource(R.color.colorThemeBackground)
|
||||
}
|
||||
) {
|
||||
LinearLayout(
|
||||
lparams = LayoutParams(widthMatchParent = true),
|
||||
init = {
|
||||
gravity = Gravity.CENTER or Gravity.START
|
||||
setPadding(15.dp)
|
||||
}
|
||||
) {
|
||||
ImageView(
|
||||
lparams = LayoutParams(20.dp, 20.dp) {
|
||||
marginStart = 10.dp
|
||||
marginEnd = 20.dp
|
||||
}
|
||||
) {
|
||||
imageTintList = stateColorResource(R.color.colorTextGray)
|
||||
tooltipTextCompat = "返回"
|
||||
setImageResource(R.drawable.ic_back)
|
||||
background = getThemeAttrsDrawable(Android_R.attr.selectableItemBackgroundBorderless)
|
||||
setOnClickListener { finish() }
|
||||
}
|
||||
TextView(
|
||||
lparams = LayoutParams(width = 0) {
|
||||
marginEnd = 2.dp
|
||||
weight = 1f
|
||||
}
|
||||
) {
|
||||
isSingleLine = true
|
||||
textSize = 19f
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
text = "TSBattery 设置 (${appName.trim()})"
|
||||
updateTypeface(Typeface.BOLD)
|
||||
}
|
||||
ImageView(
|
||||
lparams = LayoutParams(23.dp, 23.dp) {
|
||||
marginEnd = 10.dp
|
||||
}
|
||||
) {
|
||||
setPadding(1.dp)
|
||||
imageTintList = stateColorResource(R.color.colorTextGray)
|
||||
tooltipTextCompat = "打开模块主界面"
|
||||
setImageResource(R.drawable.ic_icon)
|
||||
background = getThemeAttrsDrawable(Android_R.attr.selectableItemBackgroundBorderless)
|
||||
setOnClickListener {
|
||||
showDialog {
|
||||
title = "打开模块主界面"
|
||||
msg = "点击确定后将打开模块主界面,如果未安装模块本体将尝试打开寄生界面。"
|
||||
confirmButton {
|
||||
runCatching {
|
||||
startActivity(
|
||||
packageName = BuildConfigWrapper.APPLICATION_ID,
|
||||
activityClass = classOf<MainActivity>().name
|
||||
)
|
||||
}.onFailure {
|
||||
runCatching {
|
||||
startActivity<MainActivity>()
|
||||
}.onFailure { snake(msg = "打开失败,请确认你已安装模块 APP 或在模块更新后重启过$appName\n$it") }
|
||||
}
|
||||
}
|
||||
cancelButton()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NestedScrollView(
|
||||
lparams = LayoutParams(matchParent = true),
|
||||
init = {
|
||||
setFadingEdgeLength(10.dp)
|
||||
isVerticalFadingEdgeEnabled = true
|
||||
isVerticalScrollBarEnabled = false
|
||||
isHorizontalScrollBarEnabled = false
|
||||
}
|
||||
) {
|
||||
LinearLayout(
|
||||
lparams = LayoutParams(widthMatchParent = true),
|
||||
init = {
|
||||
orientation = LinearLayout.VERTICAL
|
||||
layoutTransition = LayoutTransition()
|
||||
updatePadding(bottom = 15.dp)
|
||||
}
|
||||
) {
|
||||
repeat(2) { index ->
|
||||
TextView(
|
||||
lparams = LayoutParams(widthMatchParent = true) {
|
||||
updateMargins(horizontal = 15.dp)
|
||||
updateMargins(bottom = 5.dp)
|
||||
}
|
||||
) {
|
||||
setBackgroundResource(R.drawable.bg_orange_round)
|
||||
setPadding(5.dp)
|
||||
gravity = Gravity.CENTER
|
||||
textSize = 13f
|
||||
textColor = colorResource(R.color.white)
|
||||
text = when (index) {
|
||||
0 -> "点击更新 %1"
|
||||
else -> "新的设置需要重新启动${appName}才能生效"
|
||||
}
|
||||
isVisible = false
|
||||
when (index) {
|
||||
0 -> updateVersionText = this
|
||||
else -> {
|
||||
needRestartTipText = this
|
||||
setOnClickListener {
|
||||
showDialog {
|
||||
title = "需要重新启动"
|
||||
msg = "你必须重新启动${appName}才能使当前更改生效,现在重新启动吗?"
|
||||
confirmButton {
|
||||
cancel()
|
||||
finish()
|
||||
exitProcess(status = 0)
|
||||
}
|
||||
cancelButton(text = "稍后再说") {
|
||||
cancel()
|
||||
it.isVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LinearLayout(
|
||||
lparams = LayoutParams(widthMatchParent = true) {
|
||||
updateMargins(horizontal = 15.dp)
|
||||
updateMargins(top = 5.dp)
|
||||
},
|
||||
init = {
|
||||
setBackgroundResource(R.drawable.bg_permotion_round)
|
||||
setPadding(15.dp)
|
||||
gravity = Gravity.CENTER
|
||||
}
|
||||
) {
|
||||
ImageView(
|
||||
lparams = LayoutParams(45.dp, 45.dp) {
|
||||
marginEnd = 15.dp
|
||||
}
|
||||
) {
|
||||
setImageDrawable(appIconOf())
|
||||
}
|
||||
LinearLayout(
|
||||
lparams = LayoutParams(widthMatchParent = true),
|
||||
init = {
|
||||
orientation = LinearLayout.VERTICAL
|
||||
}
|
||||
) {
|
||||
LinearLayout(
|
||||
lparams = LayoutParams(widthMatchParent = true) {
|
||||
bottomMargin = 5.dp
|
||||
gravity = Gravity.CENTER or Gravity.START
|
||||
}
|
||||
) {
|
||||
TextView(
|
||||
lparams = LayoutParams {
|
||||
marginEnd = 7.dp
|
||||
}
|
||||
) {
|
||||
isSingleLine = true
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
textSize = 15f
|
||||
text = appName.trim()
|
||||
}
|
||||
TextView {
|
||||
isSingleLine = true
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
textSize = 12f
|
||||
text = "$appVersionName($appVersionCode)"
|
||||
alpha = 0.85f
|
||||
}
|
||||
TextView(
|
||||
lparams = LayoutParams {
|
||||
updateMargins(horizontal = 6.dp)
|
||||
}
|
||||
) {
|
||||
isSingleLine = true
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
textSize = 12f
|
||||
text = "|"
|
||||
alpha = 0.85f
|
||||
}
|
||||
TextView {
|
||||
isSingleLine = true
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
textSize = 12f
|
||||
text = "模块版本:$ModuleVersion"
|
||||
alpha = 0.85f
|
||||
}
|
||||
}
|
||||
LinearLayout(
|
||||
lparams = LayoutParams(widthMatchParent = true),
|
||||
init = {
|
||||
gravity = Gravity.CENTER or Gravity.START
|
||||
}
|
||||
) {
|
||||
CardView(
|
||||
lparams = LayoutParams(13.dp, 13.dp) {
|
||||
marginEnd = 6.dp
|
||||
},
|
||||
init = {
|
||||
setCardBackgroundColor(colorResource(R.color.colorThemeBackground))
|
||||
radius = 50f.dp
|
||||
elevation = 0f
|
||||
}
|
||||
) {
|
||||
ImageView(
|
||||
lparams = LayoutParams(13.dp, 13.dp)
|
||||
) {
|
||||
setImageResource(if (HookEntry.isHookClientSupport)
|
||||
R.drawable.ic_success
|
||||
else R.drawable.ic_error)
|
||||
imageTintList = (if (HookEntry.isHookClientSupport)
|
||||
0xFF26A69A
|
||||
else 0xFFFF7043).toInt().toNormalColorStateList()
|
||||
}
|
||||
}
|
||||
if (!HookEntry.isHookClientSupport)
|
||||
LinearLayout(
|
||||
lparams = LayoutParams {
|
||||
marginEnd = 6.dp
|
||||
},
|
||||
init = {
|
||||
gravity = Gravity.CENTER or Gravity.START
|
||||
}
|
||||
) {
|
||||
TextView {
|
||||
isSingleLine = true
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
textSize = 12f
|
||||
alpha = 0.85f
|
||||
text = "未适配"
|
||||
}
|
||||
TextView(
|
||||
lparams = LayoutParams {
|
||||
updateMarginsRelative(start = 6.dp)
|
||||
}
|
||||
) {
|
||||
isSingleLine = true
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
textSize = 12f
|
||||
text = "|"
|
||||
alpha = 0.85f
|
||||
}
|
||||
}
|
||||
TextView {
|
||||
isSingleLine = true
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
textSize = 12f
|
||||
alpha = 0.85f
|
||||
currentModeText = this
|
||||
}
|
||||
TextView(
|
||||
lparams = LayoutParams {
|
||||
updateMarginsRelative(start = 6.dp)
|
||||
}
|
||||
) {
|
||||
isSingleLine = true
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
textSize = 12f
|
||||
text = "|"
|
||||
alpha = 0.85f
|
||||
}
|
||||
TextView(
|
||||
lparams = LayoutParams {
|
||||
updateMarginsRelative(start = 6.dp)
|
||||
}
|
||||
) {
|
||||
isSingleLine = true
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
textSize = 12f
|
||||
text = "${YukiHookAPI.Status.Executor.name} API ${YukiHookAPI.Status.Executor.apiLevel}"
|
||||
alpha = 0.85f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TextView(
|
||||
lparams = LayoutParams(widthMatchParent = true) {
|
||||
updateMargins(horizontal = 15.dp)
|
||||
updateMargins(top = 15.dp)
|
||||
}
|
||||
) {
|
||||
setBackgroundResource(R.drawable.bg_permotion_round)
|
||||
setPadding(15.dp)
|
||||
textSize = 12f
|
||||
textColor = colorResource(R.color.colorTextDark)
|
||||
setLineSpacing(10f.dp, 1f)
|
||||
text = "模块只对挂后台锁屏情况下有省电效果,请不要将过多的群提醒,消息通知打开,这样子在使用过程时照样会极其耗电。\n" +
|
||||
"持续常驻使用${appName}依然会耗电,任何软件都是如此,模块是无法帮你做到前台不耗电的。"
|
||||
}
|
||||
LinearLayout(
|
||||
lparams = LayoutParams(widthMatchParent = true) {
|
||||
updateMargins(horizontal = 15.dp)
|
||||
updateMargins(top = 15.dp)
|
||||
},
|
||||
init = {
|
||||
orientation = LinearLayout.VERTICAL
|
||||
}
|
||||
) {
|
||||
LinearLayout(
|
||||
lparams = LayoutParams(widthMatchParent = true),
|
||||
init = {
|
||||
orientation = LinearLayout.VERTICAL
|
||||
gravity = Gravity.CENTER
|
||||
setBackgroundResource(R.drawable.bg_permotion_round)
|
||||
updatePadding(horizontal = 15.dp)
|
||||
updatePadding(top = 10.dp, bottom = 15.dp)
|
||||
}
|
||||
) {
|
||||
MaterialSwitch(
|
||||
lparams = LayoutParams(widthMatchParent = true, height = 35.dp) {
|
||||
bottomMargin = 5.dp
|
||||
}
|
||||
) {
|
||||
text = "停用省电策略"
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
textSize = 15f
|
||||
bind(ConfigData.DISABLE_ALL_HOOK) {
|
||||
refreshConfigItems()
|
||||
refreshCurrentModeText()
|
||||
showNeedRestartTip()
|
||||
}
|
||||
}
|
||||
TextView(
|
||||
lparams = LayoutParams(widthMatchParent = true)
|
||||
) {
|
||||
isSingleLine = true
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
textSize = 12f
|
||||
alpha = 0.6f
|
||||
setLineSpacing(6f.dp, 1f)
|
||||
text = "选择停用后模块将关闭所有省电功能,模块停止使用。"
|
||||
}
|
||||
}
|
||||
}
|
||||
LinearLayout(
|
||||
lparams = LayoutParams(widthMatchParent = true) {
|
||||
updateMargins(horizontal = 15.dp)
|
||||
updateMargins(top = 15.dp)
|
||||
},
|
||||
init = {
|
||||
orientation = LinearLayout.VERTICAL
|
||||
itemQQTimConfig = this
|
||||
}
|
||||
) {
|
||||
LinearLayout(
|
||||
lparams = LayoutParams(widthMatchParent = true),
|
||||
init = {
|
||||
orientation = LinearLayout.VERTICAL
|
||||
gravity = Gravity.CENTER
|
||||
setBackgroundResource(R.drawable.bg_permotion_round)
|
||||
updatePadding(horizontal = 15.dp)
|
||||
updatePadding(top = 10.dp, bottom = 15.dp)
|
||||
}
|
||||
) {
|
||||
MaterialSwitch(
|
||||
lparams = LayoutParams(widthMatchParent = true, height = 35.dp) {
|
||||
bottomMargin = 5.dp
|
||||
}
|
||||
) {
|
||||
text = "启用保守模式"
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
textSize = 15f
|
||||
bind(ConfigData.ENABLE_QQ_TIM_PROTECT_MODE) {
|
||||
refreshCurrentModeText()
|
||||
showNeedRestartTip()
|
||||
}
|
||||
}
|
||||
TextView(
|
||||
lparams = LayoutParams(widthMatchParent = true)
|
||||
) {
|
||||
isSingleLine = true
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
textSize = 12f
|
||||
alpha = 0.6f
|
||||
setLineSpacing(6f.dp, 1f)
|
||||
text = "此选项默认关闭,默认情况下模块将会干掉${appName}自身的电源锁控制类,开启后模块将只对系统电源锁生效," +
|
||||
"如果你的${appName}视频通话等设置发生了故障,可以尝试开启这个功能。"
|
||||
}
|
||||
}
|
||||
LinearLayout(
|
||||
lparams = LayoutParams(widthMatchParent = true) {
|
||||
topMargin = 15.dp
|
||||
},
|
||||
init = {
|
||||
orientation = LinearLayout.VERTICAL
|
||||
gravity = Gravity.CENTER
|
||||
setBackgroundResource(R.drawable.bg_permotion_round)
|
||||
updatePadding(horizontal = 15.dp)
|
||||
updatePadding(top = 10.dp, bottom = 15.dp)
|
||||
}
|
||||
) {
|
||||
MaterialSwitch(
|
||||
lparams = LayoutParams(widthMatchParent = true, height = 35.dp) {
|
||||
bottomMargin = 5.dp
|
||||
}
|
||||
) {
|
||||
text = "关闭 CoreService"
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
textSize = 15f
|
||||
bind(ConfigData.ENABLE_KILL_QQ_TIM_CORESERVICE) { showNeedRestartTip() }
|
||||
}
|
||||
TextView(
|
||||
lparams = LayoutParams(widthMatchParent = true) {
|
||||
bottomMargin = 10.dp
|
||||
}
|
||||
) {
|
||||
isSingleLine = true
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
textSize = 12f
|
||||
alpha = 0.6f
|
||||
setLineSpacing(6f.dp, 1f)
|
||||
text = "关闭后可能会影响消息接收与视频通话,但是会达到省电效果,如果你的系统拥有推送服务 (HMS) 或 (MIPUSH) 可以尝试关闭。"
|
||||
}
|
||||
MaterialSwitch(
|
||||
lparams = LayoutParams(widthMatchParent = true, height = 35.dp) {
|
||||
bottomMargin = 5.dp
|
||||
}
|
||||
) {
|
||||
text = "关闭 CoreService\$KernelService"
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
textSize = 15f
|
||||
bind(ConfigData.ENABLE_KILLE_QQ_TIM_CORESERVICE_CHILD) { showNeedRestartTip() }
|
||||
}
|
||||
TextView(
|
||||
lparams = LayoutParams(widthMatchParent = true)
|
||||
) {
|
||||
isSingleLine = true
|
||||
textColor = colorResource(R.color.colorTextGray)
|
||||
textSize = 12f
|
||||
alpha = 0.6f
|
||||
setLineSpacing(6f.dp, 1f)
|
||||
text = "这是一个辅助子服务,理论主服务关闭后子服务同样不会被启动,建议在保证消息接收的前提下可以尝试关闭子服务。"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 检查更新 */
|
||||
GithubReleaseTool.checkingForUpdate(context = this, BuildConfig.VERSION_NAME) { version, function ->
|
||||
binding.updateVersionText.apply {
|
||||
GithubReleaseTool.checkingForUpdate(context = this, ModuleVersion.NAME) { version, function ->
|
||||
updateVersionText.apply {
|
||||
text = "点击更新 $version"
|
||||
isVisible = true
|
||||
setOnClickListener { function() }
|
||||
}
|
||||
}
|
||||
binding.titleBackIcon.setOnClickListener { finish() }
|
||||
binding.titleModuleIcon.setOnClickListener {
|
||||
showDialog {
|
||||
title = "打开模块主界面"
|
||||
msg = "点击确定后将打开模块主界面,如果未安装模块本体将会无法打开。"
|
||||
confirmButton {
|
||||
runCatching {
|
||||
startActivity(Intent().apply {
|
||||
component = ComponentName(BuildConfig.APPLICATION_ID, MainActivity::class.java.name)
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
})
|
||||
}.onFailure { snake(msg = "打开失败,请确认你已安装模块 APP\n$it") }
|
||||
}
|
||||
cancelButton()
|
||||
}
|
||||
}
|
||||
binding.titleNameText.text = "TSBattery 设置 (${appName.trim()})"
|
||||
binding.appIcon.setImageDrawable(appIconOf())
|
||||
binding.appName.text = appName.trim()
|
||||
binding.appVersion.text = "${appVersionName}($appVersionCode)"
|
||||
binding.moduleVersion.text = "${BuildConfig.VERSION_NAME}(${BuildConfig.VERSION_CODE})"
|
||||
binding.activeModeIcon.isVisible = HookEntry.isHookClientSupport
|
||||
binding.inactiveModeIcon.isGone = HookEntry.isHookClientSupport
|
||||
binding.unsupportItem.isGone = HookEntry.isHookClientSupport
|
||||
binding.executorInfoText.text = "${YukiHookAPI.Status.Executor.name} API ${YukiHookAPI.Status.Executor.apiLevel}"
|
||||
binding.needRestartTipText.replaceToAppName()
|
||||
binding.needRestartTipText.setOnClickListener {
|
||||
showDialog {
|
||||
title = "需要重新启动"
|
||||
msg = "你必须重新启动${appName}才能使当前更改生效,现在重新启动吗?"
|
||||
confirmButton {
|
||||
cancel()
|
||||
finish()
|
||||
exitProcess(status = 0)
|
||||
}
|
||||
cancelButton(text = "稍后再说") {
|
||||
cancel()
|
||||
it.isVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 刷新当前模式文本 */
|
||||
fun refreshCurrentModeText() {
|
||||
binding.currentModeText.text = when {
|
||||
ConfigData.isDisableAllHook -> "模块已停用"
|
||||
packageName == PackageName.WECHAT -> "基础省电模式"
|
||||
ConfigData.isEnableQQTimProtectMode -> "保守模式"
|
||||
else -> "完全模式"
|
||||
}
|
||||
}
|
||||
refreshCurrentModeText()
|
||||
/** 刷新配置条目显示隐藏状态 */
|
||||
fun refreshConfigItems() {
|
||||
binding.itemQqTimConfig.isVisible = packageName != PackageName.WECHAT && ConfigData.isDisableAllHook.not()
|
||||
}
|
||||
refreshConfigItems()
|
||||
binding.infoTipText.replaceToAppName()
|
||||
binding.qqTimProtectTipText.replaceToAppName()
|
||||
binding.disableAllHookSwitch.bind(ConfigData.DISABLE_ALL_HOOK) { refreshConfigItems(); refreshCurrentModeText(); showNeedRestartTip() }
|
||||
binding.qqTimProtectModeSwitch.bind(ConfigData.ENABLE_QQ_TIM_PROTECT_MODE) { refreshCurrentModeText(); showNeedRestartTip() }
|
||||
binding.qqTimCoreServiceSwitch.bind(ConfigData.ENABLE_KILL_QQ_TIM_CORESERVICE) { showNeedRestartTip() }
|
||||
binding.qqTimCoreServiceChildSwitch.bind(ConfigData.ENABLE_KILLE_QQ_TIM_CORESERVICE_CHILD) { showNeedRestartTip() }
|
||||
/** 推广、恰饭 */
|
||||
ProjectPromote.show(activity = this, ModuleVersion.toString())
|
||||
}
|
||||
|
||||
/** 显示需要重新启动提示 */
|
||||
private fun showNeedRestartTip() {
|
||||
binding.needRestartTipText.isVisible = true
|
||||
needRestartTipText.isVisible = true
|
||||
}
|
||||
|
||||
/** 替换占位符到当前 APP 名称 */
|
||||
private fun TextView.replaceToAppName() {
|
||||
text = text.toString().replace("{APP_NAME}", appName)
|
||||
/** 刷新配置条目显示隐藏状态 */
|
||||
private fun refreshConfigItems() {
|
||||
itemQQTimConfig.isVisible = packageName != PackageName.WECHAT && ConfigData.isDisableAllHook.not()
|
||||
}
|
||||
|
||||
/** 刷新当前模式文本 */
|
||||
private fun refreshCurrentModeText() {
|
||||
currentModeText.text = when {
|
||||
ConfigData.isDisableAllHook -> "模块已停用"
|
||||
packageName == PackageName.WECHAT -> "基础省电模式"
|
||||
ConfigData.isEnableQQTimProtectMode -> "保守模式"
|
||||
else -> "完全模式"
|
||||
}
|
||||
}
|
||||
|
||||
/** 重新设置 DPI 防止 QQ、TIM 修改它 */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
* Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
|
||||
* https://github.com/fankes/TSBattery
|
||||
*
|
||||
* This software is non-free but opensource software: you can redistribute it
|
||||
@@ -17,7 +17,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/1/8.
|
||||
* This file is created by fankes on 2022/1/8.
|
||||
*/
|
||||
@file:Suppress("SameParameterValue")
|
||||
|
||||
@@ -31,8 +31,10 @@ import android.util.AttributeSet
|
||||
import androidx.appcompat.widget.SwitchCompat
|
||||
import com.fankes.tsbattery.utils.factory.dp
|
||||
import com.fankes.tsbattery.utils.factory.isSystemInDarkMode
|
||||
import com.highcapable.hikage.annotation.HikageView
|
||||
import top.defaults.drawabletoolbox.DrawableBuilder
|
||||
|
||||
@HikageView
|
||||
class MaterialSwitch(context: Context, attrs: AttributeSet?) : SwitchCompat(context, attrs) {
|
||||
|
||||
private fun toColors(selected: Int, pressed: Int, normal: Int): ColorStateList {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
* Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
|
||||
* https://github.com/fankes/TSBattery
|
||||
*
|
||||
* This software is non-free but opensource software: you can redistribute it
|
||||
@@ -17,9 +17,9 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/1/7.
|
||||
* This file is created by fankes on 2022/1/7.
|
||||
*/
|
||||
@file:Suppress("unused", "OPT_IN_USAGE", "EXPERIMENTAL_API_USAGE")
|
||||
@file:Suppress("unused")
|
||||
|
||||
package com.fankes.tsbattery.utils.factory
|
||||
|
||||
@@ -34,7 +34,6 @@ import androidx.appcompat.app.AlertDialog
|
||||
import com.fankes.tsbattery.R
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
import com.highcapable.yukihookapi.annotation.CauseProblemsApi
|
||||
import com.highcapable.yukihookapi.hook.factory.applyModuleTheme
|
||||
|
||||
/**
|
||||
@@ -134,7 +133,6 @@ class DialogBuilder(val context: Context) {
|
||||
fun cancel() = dialogInstance?.cancel()
|
||||
|
||||
/** 显示对话框 */
|
||||
@CauseProblemsApi
|
||||
fun show() = runInSafe {
|
||||
instance?.create()?.apply {
|
||||
customLayoutView?.let { setView(it) }
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
* Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
|
||||
* https://github.com/fankes/TSBattery
|
||||
*
|
||||
* This software is non-free but opensource software: you can redistribute it
|
||||
@@ -17,13 +17,13 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/3/13.
|
||||
* This file is created by fankes on 2022/3/13.
|
||||
*/
|
||||
@file:Suppress("unused")
|
||||
@file:Suppress("unused", "UnusedReceiverParameter")
|
||||
|
||||
package com.fankes.tsbattery.utils.factory
|
||||
|
||||
import com.highcapable.yukihookapi.hook.log.loggerE
|
||||
import com.highcapable.yukihookapi.hook.log.YLog
|
||||
|
||||
/**
|
||||
* 忽略异常返回值
|
||||
@@ -78,5 +78,5 @@ inline fun <T> safeOf(default: T, result: () -> T) = try {
|
||||
* @param block 正常回调
|
||||
*/
|
||||
inline fun <T> T.runInSafe(msg: String = "", block: () -> Unit) {
|
||||
runCatching(block).onFailure { if (msg.isNotBlank()) loggerE(msg = msg, e = it) }
|
||||
runCatching(block).onFailure { if (msg.isNotBlank()) YLog.error(msg, it) }
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
* Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
|
||||
* https://github.com/fankes/TSBattery
|
||||
*
|
||||
* This software is non-free but opensource software: you can redistribute it
|
||||
@@ -17,7 +17,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/1/7.
|
||||
* This file is created by fankes on 2022/1/7.
|
||||
*/
|
||||
@file:Suppress("unused", "DiscouragedApi", "InternalInsetResource")
|
||||
|
||||
@@ -40,7 +40,7 @@ import android.provider.Settings
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.getSystemService
|
||||
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.highcapable.yukihookapi.hook.xposed.application.ModuleApplication.Companion.appContext
|
||||
|
||||
@@ -75,7 +75,7 @@ inline val Context.isNotSystemInDarkMode get() = !isSystemInDarkMode
|
||||
* @return [PackageInfo] or null
|
||||
*/
|
||||
private fun Context.getPackageInfoCompat(packageName: String, flag: Number = 0) = runCatching {
|
||||
@Suppress("DEPRECATION")
|
||||
@Suppress("DEPRECATION", "KotlinRedundantDiagnosticSuppress")
|
||||
if (Build.VERSION.SDK_INT >= 33)
|
||||
packageManager?.getPackageInfo(packageName, PackageInfoFlags.of(flag.toLong()))
|
||||
else packageManager?.getPackageInfo(packageName, flag.toInt())
|
||||
@@ -227,7 +227,7 @@ fun Context.openBrowser(url: String, packageName: String = "") = runCatching {
|
||||
*/
|
||||
fun Context.hideOrShowLauncherIcon(isShow: Boolean) {
|
||||
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,
|
||||
PackageManager.DONT_KILL_APP
|
||||
)
|
||||
@@ -239,5 +239,5 @@ fun Context.hideOrShowLauncherIcon(isShow: Boolean) {
|
||||
*/
|
||||
val Context.isLauncherIconShowing
|
||||
get() = packageManager?.getComponentEnabledSetting(
|
||||
ComponentName(packageName, "${BuildConfig.APPLICATION_ID}.Home")
|
||||
ComponentName(packageName, "${BuildConfigWrapper.APPLICATION_ID}.Home")
|
||||
) != PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
* Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
|
||||
* https://github.com/fankes/TSBattery
|
||||
*
|
||||
* This software is non-free but opensource software: you can redistribute it
|
||||
@@ -17,7 +17,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/3/20.
|
||||
* This file is created by fankes on 2022/3/20.
|
||||
*/
|
||||
@file:Suppress("NewApi")
|
||||
|
||||
@@ -28,12 +28,20 @@ import android.content.Context
|
||||
import android.icu.text.SimpleDateFormat
|
||||
import android.icu.util.Calendar
|
||||
import android.icu.util.TimeZone
|
||||
import com.fankes.tsbattery.utils.factory.*
|
||||
import okhttp3.*
|
||||
import com.fankes.tsbattery.utils.factory.isNetWorkSuccess
|
||||
import com.fankes.tsbattery.utils.factory.openBrowser
|
||||
import com.fankes.tsbattery.utils.factory.openSelfSetting
|
||||
import com.fankes.tsbattery.utils.factory.runInSafe
|
||||
import com.fankes.tsbattery.utils.factory.showDialog
|
||||
import okhttp3.Call
|
||||
import okhttp3.Callback
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.json.JSONObject
|
||||
import java.io.IOException
|
||||
import java.io.Serializable
|
||||
import java.util.*
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* 获取 GitHub Release 最新版本工具类
|
||||
@@ -60,7 +68,6 @@ object GithubReleaseTool {
|
||||
.build()
|
||||
).enqueue(object : Callback {
|
||||
override fun onFailure(call: Call, e: IOException) {}
|
||||
|
||||
override fun onResponse(call: Call, response: Response) = runInSafe {
|
||||
JSONObject(response.body.string()).apply {
|
||||
GithubReleaseBean(
|
||||
@@ -72,7 +79,7 @@ object GithubReleaseTool {
|
||||
fun showUpdate() = context.showDialog {
|
||||
title = "最新版本 $name"
|
||||
msg = "发布于 $date\n\n" +
|
||||
"更新日志\n\n" + content
|
||||
"更新日志\n\n" + content
|
||||
confirmButton(text = "更新") { context.openBrowser(htmlUrl) }
|
||||
cancelButton()
|
||||
}
|
||||
|
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* TSBattery - A new way to save your battery avoid cancer apps hacker it.
|
||||
* Copyright (C) 2017 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
|
||||
}
|
@@ -1,418 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/colorThemeBackground"
|
||||
android:orientation="vertical"
|
||||
tools:context=".ui.activity.parasitic.ConfigActivity"
|
||||
tools:ignore="HardcodedText,ContentDescription,UnusedAttribute,UselessParent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="0dp"
|
||||
android:gravity="center|start"
|
||||
android:paddingLeft="15dp"
|
||||
android:paddingTop="15dp"
|
||||
android:paddingRight="15dp"
|
||||
android:paddingBottom="15dp">
|
||||
|
||||
<androidx.constraintlayout.utils.widget.ImageFilterView
|
||||
android:id="@+id/title_back_icon"
|
||||
style="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:src="@drawable/ic_back"
|
||||
android:tint="@color/colorTextGray"
|
||||
android:tooltipText="返回" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title_name_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="2.5dp"
|
||||
android:layout_weight="1"
|
||||
android:singleLine="true"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="19sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<androidx.constraintlayout.utils.widget.ImageFilterView
|
||||
android:id="@+id/title_module_icon"
|
||||
android:layout_width="23dp"
|
||||
android:layout_height="23dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:padding="1.5dp"
|
||||
android:src="@drawable/ic_icon"
|
||||
android:tint="@color/colorTextGray"
|
||||
android:tooltipText="打开模块主界面" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fadingEdgeLength="10dp"
|
||||
android:orientation="vertical"
|
||||
android:requiresFadingEdge="vertical"
|
||||
android:scrollbars="none">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:animateLayoutChanges="true"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="15dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/update_version_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@drawable/bg_orange_round"
|
||||
android:gravity="center"
|
||||
android:padding="5dp"
|
||||
android:text="点击更新 %1"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="13sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/need_restart_tip_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@drawable/bg_orange_round"
|
||||
android:gravity="center"
|
||||
android:padding="5dp"
|
||||
android:text="新的设置需要重新启动{APP_NAME}才能生效"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="13sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:background="@drawable/bg_permotion_round"
|
||||
android:elevation="0dp"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:padding="15dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/app_icon"
|
||||
android:layout_width="45dp"
|
||||
android:layout_height="45dp"
|
||||
android:layout_marginEnd="15dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:gravity="center|start">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/app_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="7.5dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/app_version"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0.85"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_marginRight="6dp"
|
||||
android:alpha="0.85"
|
||||
android:singleLine="true"
|
||||
android:text="|"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0.85"
|
||||
android:singleLine="true"
|
||||
android:text="模块版本:"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/module_version"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0.85"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center|start"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="13dp"
|
||||
android:layout_height="13dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
app:cardBackgroundColor="@color/colorThemeBackground"
|
||||
app:cardCornerRadius="50dp"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<androidx.constraintlayout.utils.widget.ImageFilterView
|
||||
android:id="@+id/active_mode_icon"
|
||||
android:layout_width="13dp"
|
||||
android:layout_height="13dp"
|
||||
android:src="@drawable/ic_success"
|
||||
android:tint="#FF26A69A"
|
||||
android:visibility="gone" />
|
||||
|
||||
<androidx.constraintlayout.utils.widget.ImageFilterView
|
||||
android:id="@+id/inactive_mode_icon"
|
||||
android:layout_width="13dp"
|
||||
android:layout_height="13dp"
|
||||
android:src="@drawable/ic_error"
|
||||
android:tint="#FF7043"
|
||||
android:visibility="gone" />
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/unsupport_item"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:gravity="center|start"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0.85"
|
||||
android:singleLine="true"
|
||||
android:text="未适配"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:alpha="0.85"
|
||||
android:singleLine="true"
|
||||
android:text="|"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/current_mode_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0.85"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:alpha="0.85"
|
||||
android:singleLine="true"
|
||||
android:text="|"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/executor_info_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:alpha="0.85"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/info_tip_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginTop="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:alpha="0.8"
|
||||
android:background="@drawable/bg_permotion_round"
|
||||
android:lineSpacingExtra="10dp"
|
||||
android:padding="15dp"
|
||||
android:text="模块只对挂后台锁屏情况下有省电效果,请不要将过多的群提醒,消息通知打开,这样子在使用过程时照样会极其耗电。\n持续常驻使用{APP_NAME}依然会耗电,任何软件都是如此,模块是无法帮你做到前台不耗电的。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginTop="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_permotion_round"
|
||||
android:elevation="0dp"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="15dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingRight="15dp"
|
||||
android:paddingBottom="15dp">
|
||||
|
||||
<com.fankes.tsbattery.ui.widget.MaterialSwitch
|
||||
android:id="@+id/disable_all_hook_switch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:text="停用省电策略"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0.6"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:text="选择停用后模块将关闭所有省电功能,模块停止使用。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/item_qq_tim_config"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginTop="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_permotion_round"
|
||||
android:elevation="0dp"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="15dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingRight="15dp">
|
||||
|
||||
<com.fankes.tsbattery.ui.widget.MaterialSwitch
|
||||
android:id="@+id/qq_tim_protect_mode_switch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:text="启用保守模式"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/qq_tim_protect_tip_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:alpha="0.6"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:text="此选项默认关闭,默认情况下模块将会干掉{APP_NAME}自身的电源锁控制类,开启后模块将只对系统电源锁生效,如果你的{APP_NAME}视频通话等设置发生了故障,可以尝试开启这个功能。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="15dp"
|
||||
android:background="@drawable/bg_permotion_round"
|
||||
android:elevation="0dp"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="15dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingRight="15dp"
|
||||
android:paddingBottom="15dp">
|
||||
|
||||
<com.fankes.tsbattery.ui.widget.MaterialSwitch
|
||||
android:id="@+id/qq_tim_core_service_switch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:text="关闭 CoreService"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:alpha="0.6"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:text="关闭后可能会影响消息接收与视频通话,但是会达到省电效果,如果你的系统拥有推送服务 (HMS) 或 (MIPUSH) 可以尝试关闭。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<com.fankes.tsbattery.ui.widget.MaterialSwitch
|
||||
android:id="@+id/qq_tim_core_service_child_switch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:text="关闭 CoreService$KernelService"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0.6"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:text="这是一个辅助子服务,理论主服务关闭后子服务同样不会被启动,建议在保证消息接收的前提下可以尝试关闭子服务。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</LinearLayout>
|
@@ -265,6 +265,7 @@
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/quick_action_item"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
@@ -356,6 +357,7 @@
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/display_setting_item"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
@@ -590,7 +592,8 @@
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@mipmap/bg_qr_pay" />
|
||||
android:adjustViewBounds="true"
|
||||
android:src="@mipmap/bg_payment_code" />
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<TextView
|
||||
@@ -628,7 +631,36 @@
|
||||
android:ellipsize="end"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:maxLines="2"
|
||||
android:text="此模块使用 YukiHookAPI 构建。\n了解更多 https://github.com/fankes/YukiHookAPI"
|
||||
android:text="此模块使用 YukiHookAPI 构建。\n了解更多 https://github.com/HighCapable/YukiHookAPI"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="11sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="@drawable/bg_permotion_round"
|
||||
android:gravity="center|start"
|
||||
android:orientation="horizontal"
|
||||
android:padding="10dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:src="@mipmap/ic_kavaref" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autoLink="web"
|
||||
android:ellipsize="end"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:maxLines="2"
|
||||
android:text="此模块使用 KavaRef 强力驱动。\n了解更多 https://github.com/HighCapable/KavaRef"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="11sp" />
|
||||
</LinearLayout>
|
||||
|
BIN
app/src/main/res/mipmap-xxhdpi/bg_payment_code.jpg
Normal file
BIN
app/src/main/res/mipmap-xxhdpi/bg_payment_code.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 122 KiB |
Binary file not shown.
Before Width: | Height: | Size: 201 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_kavaref.png
Normal file
BIN
app/src/main/res/mipmap-xxhdpi/ic_kavaref.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
26
build.gradle
26
build.gradle
@@ -1,26 +0,0 @@
|
||||
plugins {
|
||||
id 'com.android.application' version '7.4.1' apply false
|
||||
id 'com.android.library' version '7.4.1' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.8.20' apply false
|
||||
id 'com.google.devtools.ksp' version '1.8.20-1.0.10' apply false
|
||||
}
|
||||
|
||||
ext {
|
||||
android = [
|
||||
compileSdk: 33,
|
||||
minSdk : 21,
|
||||
targetSdk : 33
|
||||
]
|
||||
app = [
|
||||
versionName : '4.3',
|
||||
versionCode : 29,
|
||||
signingConfigs: [
|
||||
secretConfigsDirPath : "${projectDir.getAbsolutePath()}/.secret",
|
||||
secretConfigsFileName: "key_store_secret.json"
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
21
build.gradle.kts
Normal file
21
build.gradle.kts
Normal file
@@ -0,0 +1,21 @@
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
|
||||
|
||||
plugins {
|
||||
autowire(libs.plugins.android.application) apply false
|
||||
autowire(libs.plugins.kotlin.android) apply false
|
||||
autowire(libs.plugins.kotlin.ksp) apply false
|
||||
}
|
||||
|
||||
allprojects {
|
||||
tasks.withType<KotlinJvmCompile>().configureEach {
|
||||
compilerOptions {
|
||||
jvmTarget = JvmTarget.JVM_17
|
||||
freeCompilerArgs.addAll(
|
||||
"-Xno-param-assertions",
|
||||
"-Xno-call-assertions",
|
||||
"-Xno-receiver-assertions"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,23 +1,17 @@
|
||||
# Project-wide Gradle settings.
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-XX:+UseParallelGC
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||
# Android operating system, and which are packaged with your app"s APK
|
||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
# Compiler Configuration
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
android.useAndroidX=true
|
||||
# Automatically convert third-party libraries to use AndroidX
|
||||
android.enableJetifier=true
|
||||
# Kotlin code style for this project: "official" or "obsolete":
|
||||
android.nonTransitiveRClass=true
|
||||
kotlin.code.style=official
|
||||
# Incremental
|
||||
kotlin.incremental.useClasspathSnapshot=true
|
||||
# Project Configuration
|
||||
project.name=TSBattery
|
||||
project.android.compileSdk=36
|
||||
project.android.minSdk=24
|
||||
project.android.targetSdk=36
|
||||
project.app.packageName=com.fankes.tsbattery
|
||||
project.app.versionName="4.4"
|
||||
project.app.versionCode=30
|
||||
project.app.signing.keyAlias=public
|
||||
project.app.signing.keyPassword="123456"
|
||||
project.app.signing.storePassword="123456"
|
||||
project.app.signing.storeFilePath=.secret/universal.p12
|
94
gradle/sweet-dependency/sweet-dependency-config.yaml
Normal file
94
gradle/sweet-dependency/sweet-dependency-config.yaml
Normal file
@@ -0,0 +1,94 @@
|
||||
preferences:
|
||||
autowire-on-sync-mode: UPDATE_OPTIONAL_DEPENDENCIES
|
||||
repositories-mode: FAIL_ON_PROJECT_REPOS
|
||||
|
||||
repositories:
|
||||
gradle-plugin-portal:
|
||||
scope: PLUGINS
|
||||
google:
|
||||
maven-central:
|
||||
jit-pack:
|
||||
sonatype-oss-releases:
|
||||
rovo89-xposed-api:
|
||||
scope: LIBRARIES
|
||||
url: https://api.xposed.info/
|
||||
content:
|
||||
include:
|
||||
group:
|
||||
de.robv.android.xposed
|
||||
fankes-maven-releases:
|
||||
url: https://raw.githubusercontent.com/fankes/maven-repository/main/repository/releases
|
||||
|
||||
plugins:
|
||||
com.android.application:
|
||||
alias: android-application
|
||||
version: 8.12.1
|
||||
org.jetbrains.kotlin.android:
|
||||
alias: kotlin-android
|
||||
version: 2.2.10
|
||||
com.google.devtools.ksp:
|
||||
alias: kotlin-ksp
|
||||
version: 2.2.10-2.0.2
|
||||
|
||||
libraries:
|
||||
com.fankes.projectpromote:
|
||||
project-promote:
|
||||
version: 1.0.0
|
||||
repositories:
|
||||
fankes-maven-releases
|
||||
de.robv.android.xposed:
|
||||
api:
|
||||
version: 82
|
||||
repositories:
|
||||
rovo89-xposed-api
|
||||
com.highcapable.yukihookapi:
|
||||
api:
|
||||
version: 1.3.0
|
||||
ksp-xposed:
|
||||
version-ref: <this>::api
|
||||
com.highcapable.kavaref:
|
||||
kavaref-core:
|
||||
version: 1.0.1
|
||||
kavaref-extension:
|
||||
version: 1.0.1
|
||||
com.highcapable.hikage:
|
||||
hikage-core:
|
||||
version: 1.0.2
|
||||
hikage-compiler:
|
||||
version: 1.0.1
|
||||
hikage-extension:
|
||||
version: 1.0.1
|
||||
hikage-widget-androidx:
|
||||
version: 1.0.1
|
||||
hikage-widget-material:
|
||||
version: 1.0.1
|
||||
org.luckypray:
|
||||
dexkit:
|
||||
version: 2.0.6
|
||||
com.github.duanhong169:
|
||||
drawabletoolbox:
|
||||
version: 1.0.7
|
||||
com.squareup.okhttp3:
|
||||
okhttp:
|
||||
version: 5.1.0
|
||||
androidx.core:
|
||||
core-ktx:
|
||||
version: 1.17.0
|
||||
androidx.appcompat:
|
||||
appcompat:
|
||||
version: 1.7.1
|
||||
com.google.android.material:
|
||||
material:
|
||||
version: 1.12.0
|
||||
androidx.constraintlayout:
|
||||
constraintlayout:
|
||||
version: 2.2.1
|
||||
androidx.test.ext:
|
||||
junit:
|
||||
version: 1.3.0
|
||||
androidx.test.espresso:
|
||||
espresso-core:
|
||||
version: 3.7.0
|
||||
junit:
|
||||
junit:
|
||||
version: 4.13.2
|
5
gradle/wrapper/gradle-wrapper.properties
vendored
5
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,5 @@
|
||||
#Wed May 25 04:34:58 CST 2022
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStoreBase=GRADLE_USER_HOME
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
@@ -1,19 +0,0 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
repositories {
|
||||
google()
|
||||
maven { url "https://api.xposed.info/" }
|
||||
maven { url "https://www.jitpack.io" }
|
||||
maven { url "https://s01.oss.sonatype.org/content/repositories/releases" }
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
rootProject.name = "TSBattery"
|
||||
include ':app'
|
27
settings.gradle.kts
Normal file
27
settings.gradle.kts
Normal file
@@ -0,0 +1,27 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
plugins {
|
||||
id("com.highcapable.sweetdependency") version "1.0.4"
|
||||
id("com.highcapable.sweetproperty") version "1.0.8"
|
||||
}
|
||||
sweetProperty {
|
||||
global {
|
||||
all {
|
||||
permanentKeyValues("GITHUB_CI_COMMIT_ID" to "")
|
||||
generateFrom(ROOT_PROJECT, SYSTEM_ENV)
|
||||
}
|
||||
sourcesCode {
|
||||
includeKeys("GITHUB_CI_COMMIT_ID")
|
||||
// 关闭类型自动转换功能,防止一些特殊 "COMMIT ID" 被生成为数值
|
||||
isEnableTypeAutoConversion = false
|
||||
}
|
||||
}
|
||||
rootProject { all { isEnable = false } }
|
||||
}
|
||||
rootProject.name = "TSBattery"
|
||||
include(":app")
|
Reference in New Issue
Block a user