Compare commits
52 Commits
Author | SHA1 | Date | |
---|---|---|---|
9465286ce1
|
|||
61849cebe0
|
|||
1f71fbda9a
|
|||
8f01e649fe
|
|||
ae15d72923
|
|||
3b82c33c2e
|
|||
621f973a2f
|
|||
ef2c8afe3f
|
|||
3d7e4d8825
|
|||
19b2efbb83
|
|||
d330510788
|
|||
25a23d7e1a
|
|||
db4b418ed4
|
|||
8a97e38d20
|
|||
|
f294120fa8 | ||
|
d244658aa6 | ||
|
445ac85d8d | ||
|
e3b22671c1 | ||
d574449e4a
|
|||
85a2e730e0
|
|||
ca367bde9e
|
|||
03ce7fbbe6
|
|||
88e3f79878
|
|||
ba67bd0a62
|
|||
0c0cf9bfba
|
|||
0e98ec16c7
|
|||
f1fd3f2679
|
|||
97065494b0
|
|||
b172d7a090
|
|||
b86988a310
|
|||
32f8ca9d63
|
|||
3cf67eb7fc
|
|||
9f39f297f9
|
|||
7feab98a1e
|
|||
b297b43dfb
|
|||
c7c03e891f
|
|||
5ddc5de475
|
|||
d09c11f026
|
|||
bf22cae957
|
|||
a08e085b2b
|
|||
9690e27511
|
|||
f9dde5f549
|
|||
8ddb938883
|
|||
8664d7b285
|
|||
d70d01cf6c
|
|||
4703d339b7
|
|||
76b1cc2f0b
|
|||
62ec1d16ae
|
|||
7db010c9a1
|
|||
e6fa34d7fd
|
|||
d4661abb71
|
|||
744d028160
|
17
.editorconfig
Normal file
@@ -0,0 +1,17 @@
|
||||
# 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
|
||||
ij_continuation_indent_size = 2
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = false
|
||||
max_line_length = 150
|
15
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,6 +1,6 @@
|
||||
name: 问题与 BUG 反馈
|
||||
description: 问题反馈必须使用此模板进行提交
|
||||
labels: [bug]
|
||||
labels: [ bug ]
|
||||
title: "[问题与 BUG 反馈] (在这里简要描述问题原因)"
|
||||
body:
|
||||
- type: markdown
|
||||
@@ -8,7 +8,7 @@ body:
|
||||
value: |
|
||||
### 请在下方填写问题发生的具体原因和复现步骤。
|
||||
|
||||
我们只接受 MIUI 正规官方版本系统,如果你正在使用 MIUI 官改(第三方修改版)请不要提交任何 BUG 与问题,我们无义务去解决,请自求多福。
|
||||
我们只接受 MIUI 或 HyperOS 正规官方版本系统,如果你正在使用官改 (第三方修改版) 请不要提交任何 BUG 与问题,我们无义务去解决,请自求多福。
|
||||
|
||||
发生异常、崩溃、闪退或功能性问题,必须提交问题 Log (日志),没有 Log 的 issues 将直接被关闭。
|
||||
- type: input
|
||||
@@ -19,16 +19,16 @@ body:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: MIUI 版本
|
||||
label: 系统版本
|
||||
description: |
|
||||
这里填写当前的 MIUI 版本,例如:**13.0.1**
|
||||
开发版需要标注具体的版本号,例如:**13 22.9.27**
|
||||
这里填写当前的系统,例如:**MIUI 13.0.1** 或 **HyperOS 1.0**
|
||||
开发版需要标注具体的版本号,例如:**MIUI 13 22.9.27** 或 **HyperOS 1.0 22.9.27**
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: MIUI 版本类型
|
||||
description: 请选择你使用的 MIUI 版本类型。
|
||||
label: 系统版本类型
|
||||
description: 请选择你使用的系统版本类型。
|
||||
options:
|
||||
- 稳定版
|
||||
- 稳定内测版
|
||||
@@ -41,6 +41,7 @@ body:
|
||||
attributes:
|
||||
label: Android 版本
|
||||
options:
|
||||
- 14
|
||||
- 13
|
||||
- 12L/12.1
|
||||
- 12
|
||||
|
47
.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
|
||||
- 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
|
||||
- name: Prepare Java 17
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: 11
|
||||
java-version: 17
|
||||
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)
|
||||
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@v3
|
||||
with:
|
||||
path: ${{ env.DEBUG_APK_FILE }}
|
||||
name: app-debug
|
||||
- name: Upload Artifacts(release)
|
||||
path: ${{ env.DEBUG_APK_PATH }}
|
||||
name: MIUINativeNotifyIcon-debug-${{ github.event.head_commit.id }}
|
||||
- name: Upload Artifacts (Release)
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
path: ${{ env.RELEASE_APK_FILE }}
|
||||
name: app-release
|
||||
path: ${{ env.RELEASE_APK_PATH }}
|
||||
name: MIUINativeNotifyIcon-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"
|
32
.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
|
||||
- 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
|
||||
- name: Prepare Java 17
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: 11
|
||||
java-version: 17
|
||||
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)
|
||||
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@v3
|
||||
with:
|
||||
path: ${{ env.DEBUG_APK_FILE }}
|
||||
name: app-debug
|
||||
- name: Upload Artifacts(release)
|
||||
path: ${{ env.DEBUG_APK_PATH }}
|
||||
name: MIUINativeNotifyIcon-debug-${{ github.event.head_commit.id }}
|
||||
- name: Upload Artifacts (Release)
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
path: ${{ env.RELEASE_APK_FILE }}
|
||||
name: app-release
|
||||
path: ${{ env.RELEASE_APK_PATH }}
|
||||
name: MIUINativeNotifyIcon-release-${{ github.event.head_commit.id }}
|
2
.idea/.gitignore
generated
vendored
@@ -1,3 +1,5 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
/gradle.xml
|
||||
/misc.xml
|
1
.idea/.name
generated
@@ -1 +0,0 @@
|
||||
MIUINativeNotifyIcon
|
26
.idea/appInsightsSettings.xml
generated
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AppInsightsSettings">
|
||||
<option name="tabSettings">
|
||||
<map>
|
||||
<entry key="Firebase Crashlytics">
|
||||
<value>
|
||||
<InsightsFilterSettings>
|
||||
<option name="connection">
|
||||
<ConnectionSetting>
|
||||
<option name="appId" value="PLACEHOLDER" />
|
||||
<option name="mobileSdkAppId" value="" />
|
||||
<option name="projectId" value="" />
|
||||
<option name="projectNumber" value="" />
|
||||
</ConnectionSetting>
|
||||
</option>
|
||||
<option name="signal" value="SIGNAL_UNSPECIFIED" />
|
||||
<option name="timeIntervalDays" value="THIRTY_DAYS" />
|
||||
<option name="visibilityType" value="ALL" />
|
||||
</InsightsFilterSettings>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
2
.idea/compiler.xml
generated
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="11" />
|
||||
<bytecodeTargetLevel target="17" />
|
||||
</component>
|
||||
</project>
|
10
.idea/deploymentTargetDropDown.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetDropDown">
|
||||
<value>
|
||||
<entry key="app">
|
||||
<State />
|
||||
</entry>
|
||||
</value>
|
||||
</component>
|
||||
</project>
|
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
@@ -6,5 +6,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>
|
6
.idea/kotlinc.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="KotlinJpsPluginSettings">
|
||||
<option name="version" value="1.9.10" />
|
||||
</component>
|
||||
</project>
|
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
@@ -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>
|
43
.idea/misc.xml
generated
@@ -1,43 +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-night/dark_round.xml" value="0.256" />
|
||||
<entry key="app/src/main/res/drawable-night/permotion_round.xml" value="0.256" />
|
||||
<entry key="app/src/main/res/drawable-v24/ic_launcher_foreground.xml" value="0.44871794871794873" />
|
||||
<entry key="app/src/main/res/drawable/bg_dark_round.xml" value="0.2325" />
|
||||
<entry key="app/src/main/res/drawable/bg_dialog_background.xml" value="0.2325" />
|
||||
<entry key="app/src/main/res/drawable/bg_green_round.xml" value="0.255" />
|
||||
<entry key="app/src/main/res/drawable/bg_orange_round.xml" value="0.2325" />
|
||||
<entry key="app/src/main/res/drawable/bg_warn_round.xml" value="0.2325" />
|
||||
<entry key="app/src/main/res/drawable/bg_yellow_round.xml" value="0.255" />
|
||||
<entry key="app/src/main/res/drawable/ic_nf_icon_refresh.xml" value="0.2325" />
|
||||
<entry key="app/src/main/res/drawable/ic_nf_icon_update.xml" value="0.2325" />
|
||||
<entry key="app/src/main/res/drawable/ic_notify_icon.xml" value="0.2325" />
|
||||
<entry key="app/src/main/res/drawable/ic_system_clock.xml" value="0.2325" />
|
||||
<entry key="app/src/main/res/drawable/permotion_round.xml" value="0.256" />
|
||||
<entry key="app/src/main/res/drawable/white_round.xml" value="0.256" />
|
||||
<entry key="app/src/main/res/layout-w1240dp/dia_source_from.xml" value="0.36484375" />
|
||||
<entry key="app/src/main/res/layout-w1240dp/dia_source_from_string.xml" value="0.36484375" />
|
||||
<entry key="app/src/main/res/layout-w936dp/dia_status_icon_cout.xml" value="0.935546875" />
|
||||
<entry key="app/src/main/res/layout/activity_config.xml" value="0.42168674698795183" />
|
||||
<entry key="app/src/main/res/layout/activity_login.xml" value="0.4375" />
|
||||
<entry key="app/src/main/res/layout/activity_main.xml" value="0.30387540746106484" />
|
||||
<entry key="app/src/main/res/layout/adapter_config.xml" value="0.375" />
|
||||
<entry key="app/src/main/res/layout/dia_icon_filter.xml" value="0.4307692307692308" />
|
||||
<entry key="app/src/main/res/layout/dia_icon_search.xml" value="0.4307692307692308" />
|
||||
<entry key="app/src/main/res/layout/dia_source_from.xml" value="0.3591278324070115" />
|
||||
<entry key="app/src/main/res/layout/dia_source_from_string.xml" value="0.4307692307692308" />
|
||||
<entry key="app/src/main/res/layout/dia_status_icon_count.xml" value="0.45" />
|
||||
<entry key="app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml" value="0.44871794871794873" />
|
||||
</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>
|
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"keyAlias": "public",
|
||||
"keyPassword": "123456",
|
||||
"storeFileName": "universal.p12",
|
||||
"storePassword": "123456"
|
||||
}
|
@@ -12,22 +12,34 @@
|
||||
|
||||
但是,这个模块就是为了修复被 MIUI 开发组忽略的图标问题才诞生的,并完美地给 MIUI 修复了黑白块图标的问题。
|
||||
|
||||
补充:现在这个 [开发文档](https://dev.mi.com/distribute/doc/details?pId=1582) 竟然还在,那就放在这里鞭个尸吧。
|
||||
|
||||
## 效果展示
|
||||
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/style.png?raw=true"/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/img-src/style.png?raw=true" alt="Screenshot"/>
|
||||
|
||||
## 探索历程
|
||||
|
||||
原生 Android 的小图标和通知图标具有状态性。<br/><br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/native.jpg?raw=true" height = "35"/><br/><br/>
|
||||
而 MIUI 最近的版本直接破坏了这一状态性,全部设置为 APP 的图标,不仅难看而且你无法下拉通知栏区别这些图标代表什么。<br/><br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/miui.jpg?raw=true" height = "40"/><br/><br/>
|
||||
同样地,通知面板的图标同样遵守这一状态性。<br/><br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/native_n_1.jpg?raw=true" height = "100"/><br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/native_n_2.jpg?raw=true" height = "100"/><br/><br/>
|
||||
而 MIUI 做了什么呢?<br/><br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/miui_n_1.jpg?raw=true" height = "100"/><br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/miui_n_2.jpg?raw=true" height = "100"/><br/><br/>
|
||||
原生 Android 的小图标和通知图标具有状态性。
|
||||
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/img-src/native.jpg?raw=true" height = "35" alt="Screenshot"/>
|
||||
|
||||
而 MIUI 最近的版本直接破坏了这一状态性,全部设置为 APP 的图标,不仅难看而且你无法下拉通知栏区别这些图标代表什么。
|
||||
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/img-src/miui.jpg?raw=true" height = "40" alt="Screenshot"/>
|
||||
|
||||
同样地,通知面板的图标同样遵守这一状态性。
|
||||
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/img-src/native_n_1.jpg?raw=true" height = "100" alt="Screenshot"/>
|
||||
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/img-src/native_n_2.jpg?raw=true" height = "100" alt="Screenshot"/>
|
||||
|
||||
而 MIUI 做了什么呢?
|
||||
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/img-src/miui_n_1.jpg?raw=true" height = "100" alt="Screenshot"/>
|
||||
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/img-src/miui_n_2.jpg?raw=true" height = "100" alt="Screenshot"/>
|
||||
|
||||
不曾记得是什么版本开始,MIUI 把通知图标改成了这个鬼样子,寻找开发组提案也是无人问津,最后转念一想,自己干吧。
|
||||
|
||||
由于目前大量通知图标都来自 `MIPUSH` 发出的营销通知,而 `MIPUSH` 的图标都是统一的彩色应用图标,很多应用也没有适配这一特性, 在通知栏广告满天飞的情况下,MIUI
|
||||
|
97
README.md
@@ -1,20 +1,25 @@
|
||||
# MIUI 原生通知图标
|
||||
|
||||
[](https://github.com/fankes/MIUINativeNotifyIcon)
|
||||
[](https://github.com/fankes/MIUINativeNotifyIcon/blob/master/LICENSE)
|
||||
[](https://github.com/fankes/MIUINativeNotifyIcon/releases)
|
||||
[](https://github.com/fankes/MIUINativeNotifyIcon/releases)
|
||||
[](https://github.com/Xposed-Modules-Repo/com.fankes.miui.notify/releases)
|
||||
[](https://t.me/XiaofangInternet)
|
||||
<br/><br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/app/src/main/ic_launcher-playstore.png?raw=true" width = "100" height = "100"/>
|
||||
<br/>
|
||||
Fix the native notification bar icon function abandoned by the MIUI development team.<br/>
|
||||
修复被 MIUI 开发组丢弃的原生通知图标,支持 MIUI 11、12、12.5、13、14 以及最新版本。
|
||||
[](https://github.com/fankes/MIUINativeNotifyIcon/blob/master/LICENSE)
|
||||
[](https://github.com/fankes/MIUINativeNotifyIcon/actions/workflows/commit_ci.yml)
|
||||
[](https://github.com/fankes/MIUINativeNotifyIcon/releases)
|
||||

|
||||

|
||||
|
||||
## Developer
|
||||
[](https://t.me/MIUINativeNotifyIcon_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)
|
||||
|
||||
[酷安 @星夜不荟](http://www.coolapk.com/u/876977)
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/img-src/icon.png?raw=true" width = "100" height = "100" alt="LOGO"/>
|
||||
|
||||
Fix the native notification bar icon function abandoned by the MIUI development team.
|
||||
|
||||
修复被 MIUI 开发组丢弃的原生通知图标,支持 MIUI 11~14 以及 HyperOS 1.0。
|
||||
|
||||
## For Non-Chinese Users
|
||||
|
||||
This project will not be adapted i18n, please stay tuned for my new projects in the future.
|
||||
|
||||
## 项目迁移公告
|
||||
|
||||
@@ -24,7 +29,7 @@ Fix the native notification bar icon function abandoned by the MIUI development
|
||||
|
||||
## 适配说明
|
||||
|
||||
- 此模块仅支持 <b>LSPosed</b>(作用域“系统界面”)、<b>~~EdXposed(随时停止支持)~~</b>、不支持<b>太极、无极</b>
|
||||
- 此模块仅支持 **LSPosed** (作用域“系统界面”)、**~~EdXposed(随时停止支持)~~**、不支持**太极、无极**
|
||||
|
||||
- 请确保你使用的是 MIUI 官方版本,任何第三方官改包发生的问题,开发者没有义务去解决和修复,请自求多福
|
||||
|
||||
@@ -32,7 +37,7 @@ Fix the native notification bar icon function abandoned by the MIUI development
|
||||
|
||||
- 建议最低从 MIUI 12.5 `2021-5-18` 开发版以后开始使用模块,之前的版本可能或多或少存在 MIUI 自身 BUG 不生效、图标黑白块的问题
|
||||
|
||||
- 请始终保持最新版本的 LSPosed,旧版本可能会出现 Hook 不生效的问题,若最新版本依然不生效请在作用域中长按“系统界面”(“系统 UI”)选择重新优化
|
||||
- 请始终保持最新版本的 **LSPosed**,旧版本可能会出现 Hook 不生效的问题,若最新版本依然不生效请在作用域中长按“系统界面” (“系统 UI”) 选择重新优化
|
||||
|
||||
## 历史背景
|
||||
|
||||
@@ -46,41 +51,49 @@ Fix the native notification bar icon function abandoned by the MIUI development
|
||||
|
||||
- [Android 通知图标规范适配计划](https://github.com/fankes/AndroidNotifyIconAdapt)
|
||||
|
||||
## 发行渠道
|
||||
|
||||
| <img src="https://avatars.githubusercontent.com/in/15368?s=64&v=4" width = "30" height = "30" alt="LOGO"/> | [GitHub CI](https://github.com/fankes/MIUINativeNotifyIcon/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/MIUINativeNotifyIcon_CI) | CI 自动构建 (测试版) |
|
||||
|-----------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------|---------------|
|
||||
|
||||
| <img src="https://avatars.githubusercontent.com/in/15368?s=64&v=4" width = "30" height = "30" alt="LOGO"/> | [GitHub Releases](https://github.com/fankes/MIUINativeNotifyIcon/releases) | 正式版 (稳定版) |
|
||||
|------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------|-----------|
|
||||
|
||||
| <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.miui.notify/releases) | 正式版 (稳定版) |
|
||||
|------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------|-----------|
|
||||
|
||||
| <img src="https://github.com/fankes/fankes/assets/37344460/82113d3c-aa7b-4dd1-95c7-cda650065c12" width = "30" height = "30" alt="LOGO"/> | [123 云盘 **(密码:62ll)**](https://www.123pan.com/s/5SlUVv-W8DBh.html) | 正式版 (稳定版) |
|
||||
|------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------|-----------|
|
||||
|
||||
| <img src="https://github.com/fankes/fankes/assets/37344460/3cd43efd-785e-411d-a5c3-a8c9dc02308a" width = "30" height = "30" alt="LOGO"/> | [酷安应用市场](https://www.coolapk.com/apk/com.fankes.miui.notify) | 正式版 (稳定版) |
|
||||
|------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------|-----------|
|
||||
|
||||
本模块发布地址仅限于上述所列出的地址,从其他非正规渠道下载到的版本或对您造成任何影响均与我们无关。
|
||||
|
||||
## 请勿用于非法用途
|
||||
|
||||
- 本模块完全开源免费,如果好用你可以打赏支持开发,但是请不要用于非法用途。
|
||||
|
||||
## 发行渠道说明
|
||||
## 项目推广
|
||||
|
||||
- [Automatic Build on Commit](https://github.com/fankes/MIUINativeNotifyIcon/actions/workflows/commit_ci.yml)
|
||||
如果你正在寻找一个可以自动管理 Gradle 项目依赖的 Gradle 插件,你可以了解一下 [SweetDependency](https://github.com/HighCapable/SweetDependency) 项目。
|
||||
|
||||
上述更新为代码 `commit` 后自动触发,具体更新内容可点击上方的文字前往 **GitHub Actions** 进行查看,本更新由开源的流程自动编译发布,**不保证其稳定性**,所发布的版本**仅供测试**,且不会特殊说明甚至可能会变更版本号或保持与当前稳定版相同的版本号。
|
||||
如果你正在寻找一个可以自动生成属性键值的 Gradle 插件,你可以了解一下 [SweetProperty](https://github.com/HighCapable/SweetProperty) 项目。
|
||||
|
||||
- [Release](https://github.com/fankes/MIUINativeNotifyIcon/releases)
|
||||
- [Xposed-Modules-Repo](https://github.com/Xposed-Modules-Repo/com.fankes.miui.notify/releases)
|
||||
- [蓝奏云 **密码:62ll**](https://fankes.lanzouy.com/b030o2e8h)
|
||||
- [酷安应用市场](https://www.coolapk.com/apk/com.fankes.miui.notify)
|
||||
|
||||
上述更新为手动发布的稳定版,具体更新内容可点击上方的文字前往指定的发布页面查看,稳定版的更新将会同时发布到上述地址中,同步更新。
|
||||
|
||||
## 发行状态说明
|
||||
|
||||

|
||||
|
||||
上述状态为当前稳定版与自动构建版本一致或当前代码改动与稳定版无功能差异。
|
||||
|
||||

|
||||
|
||||
上述状态为存在自动构建版本和新功能的更新但当前并未发布稳定版,处于预发行状态。
|
||||
|
||||

|
||||
|
||||
上述状态为当前发行的稳定版可能存在严重问题但并未及时进行修复且并未发布稳定版。
|
||||
本项目同样使用了 **SweetDependency** 和 **SweetProperty**。
|
||||
|
||||
## 捐赠支持
|
||||
|
||||
- 工作不易,无意外情况此项目将继续维护下去,提供更多可能,欢迎打赏。<br/><br/>
|
||||
<img src="https://github.com/fankes/YuKiHookAPI/blob/master/img-src/wechat_code.jpg?raw=true" width = "200" height = "200"/>
|
||||
工作不易,无意外情况此项目将继续维护下去,提供更多可能,欢迎打赏。
|
||||
|
||||
<img src="https://github.com/fankes/fankes/blob/main/img-src/payment_code.jpg?raw=true" width = "500" alt="Payment Code"/>
|
||||
|
||||
## Star History
|
||||
|
||||

|
||||
|
||||
## 隐私政策
|
||||
|
||||
@@ -104,9 +117,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)
|
@@ -1,88 +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.miui.notify'
|
||||
compileSdk rootProject.ext.android.compileSdk
|
||||
|
||||
defaultConfig {
|
||||
applicationId 'com.fankes.miui.notify'
|
||||
|
||||
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', '0x64'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly 'de.robv.android.xposed:api:82'
|
||||
implementation 'com.highcapable.yukihookapi:api:1.1.10'
|
||||
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.1.10'
|
||||
implementation 'com.github.duanhong169:drawabletoolbox:1.0.7'
|
||||
implementation "com.github.topjohnwu.libsu:core:5.0.4"
|
||||
implementation 'androidx.annotation:annotation:1.6.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.7'
|
||||
implementation 'androidx.core:core-ktx:1.10.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'com.google.android.material:material:1.8.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'
|
||||
}
|
84
app/build.gradle.kts
Normal file
@@ -0,0 +1,84 @@
|
||||
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
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = "17"
|
||||
freeCompilerArgs = listOf(
|
||||
"-Xno-param-assertions",
|
||||
"-Xno-call-assertions",
|
||||
"-Xno-receiver-assertions"
|
||||
)
|
||||
}
|
||||
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
|
||||
val currentSuffix = property.github.ci.commit.id.let { suffix -> if (suffix.isNotBlank()) "-$suffix" 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)
|
||||
implementation(com.fankes.projectpromote.project.promote)
|
||||
implementation(com.github.topjohnwu.libsu.core)
|
||||
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)
|
||||
}
|
6
app/proguard-rules.pro
vendored
@@ -32,13 +32,15 @@
|
||||
-adaptresourcefilecontents
|
||||
|
||||
-renamesourcefileattribute P
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
-keepattributes SourceFile,Signature,LineNumberTable
|
||||
|
||||
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
|
||||
public static *** throwUninitializedProperty(...);
|
||||
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,12 +1,18 @@
|
||||
<?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.miui.notify">
|
||||
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="android.permission.POST_NOTIFICATIONS" />
|
||||
|
||||
<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" />
|
||||
|
||||
<application
|
||||
android:name=".application.MNNApplication"
|
||||
android:allowBackup="true"
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/1/24.
|
||||
* This file is created by fankes on 2022/1/24.
|
||||
*/
|
||||
@file:Suppress("unused")
|
||||
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* 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.
|
||||
*/
|
||||
package com.fankes.miui.notify.bean
|
||||
|
||||
@@ -47,13 +47,15 @@ data class IconDataBean(
|
||||
) : Serializable {
|
||||
fun toEnabledName() = ("$appName$packageName").base64 + "_enable"
|
||||
fun toEnabledAllName() = ("$appName$packageName").base64 + "_enable_all"
|
||||
override fun toString() = "{\n" +
|
||||
" \"appName\": \"$appName\",\n" +
|
||||
" \"packageName\": \"$packageName\",\n" +
|
||||
" \"iconBitmap\": \"${iconBitmap.base64}\",\n" +
|
||||
" \"iconColor\": \"#${Integer.toHexString(iconColor)}\",\n" +
|
||||
" \"contributorName\": \"$contributorName\",\n" +
|
||||
" \"isEnabled\": $isEnabled,\n" +
|
||||
" \"isEnabledAll\": $isEnabledAll\n" +
|
||||
" }"
|
||||
override fun toString() = """
|
||||
{
|
||||
"appName": "$appName",
|
||||
"packageName": "$packageName",
|
||||
"iconBitmap": "${iconBitmap.base64}",
|
||||
"iconColor": "#${Integer.toHexString(iconColor)}",
|
||||
"contributorName": "$contributorName",
|
||||
"isEnabled": $isEnabled,
|
||||
"isEnabledAll": $isEnabledAll
|
||||
}
|
||||
""".trimIndent()
|
||||
}
|
@@ -18,10 +18,15 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2023/2/2.
|
||||
* This file is created by fankes on 2023/2/2.
|
||||
*/
|
||||
@file:Suppress("MemberVisibilityCanBePrivate")
|
||||
|
||||
package com.fankes.miui.notify.const
|
||||
|
||||
import com.fankes.miui.notify.generated.AppProperties
|
||||
import com.fankes.miui.notify.wrapper.BuildConfigWrapper
|
||||
|
||||
/**
|
||||
* 包名常量定义类
|
||||
*/
|
||||
@@ -47,4 +52,27 @@ object IconRuleSourceSyncType {
|
||||
|
||||
/** 自定义地址 */
|
||||
const val CUSTOM_URL = 3000
|
||||
}
|
||||
|
||||
/**
|
||||
* 模块版本常量定义类
|
||||
*/
|
||||
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)"
|
||||
}
|
@@ -18,7 +18,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2023/2/2.
|
||||
* This file is created by fankes on 2023/2/2.
|
||||
*/
|
||||
@file:Suppress("MemberVisibilityCanBePrivate")
|
||||
|
||||
@@ -26,9 +26,8 @@ package com.fankes.miui.notify.data
|
||||
|
||||
import android.content.Context
|
||||
import com.fankes.miui.notify.const.IconRuleSourceSyncType
|
||||
import com.highcapable.yukihookapi.YukiHookAPI
|
||||
import com.highcapable.yukihookapi.hook.factory.prefs
|
||||
import com.highcapable.yukihookapi.hook.log.loggerW
|
||||
import com.highcapable.yukihookapi.hook.log.YLog
|
||||
import com.highcapable.yukihookapi.hook.param.PackageParam
|
||||
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
|
||||
|
||||
@@ -40,9 +39,6 @@ object ConfigData {
|
||||
/** 启用模块 */
|
||||
val ENABLE_MODULE = PrefsData("_enable_module", true)
|
||||
|
||||
/** 启用数据缓存 */
|
||||
val ENABLE_PREFS_CACHE = PrefsData("_enable_prefs_cache", true)
|
||||
|
||||
/** 启用模块日志 */
|
||||
val ENABLE_MODULE_LOG = PrefsData("_enable_module_log", false)
|
||||
|
||||
@@ -64,6 +60,9 @@ object ConfigData {
|
||||
/** 通知栏中的通知图标圆角程度 */
|
||||
val NOTIFY_ICON_CORNER_SIZE = PrefsData("_notify_icon_corner", 15)
|
||||
|
||||
/** 替换 MIUI 样式通知栏的通知图标 */
|
||||
val ENABLE_REPLACE_MIUI_STYLE_NOTIFY_ICON = PrefsData("_replace_miui_style_notify_icon", true)
|
||||
|
||||
/** 强制通知栏中的通知图标使用系统着色 */
|
||||
val ENABLE_NOTIFY_ICON_FORCE_SYSTEM_COLOR = PrefsData("_notify_icon_force_system_color", false)
|
||||
|
||||
@@ -110,8 +109,6 @@ object ConfigData {
|
||||
is Context, is PackageParam -> this.instance = instance
|
||||
else -> error("Unknown type for init ConfigData")
|
||||
}
|
||||
/** 设置是否启用数据缓存 */
|
||||
YukiHookAPI.Configs.isEnablePrefsBridgeCache = isEnablePrefsCache
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,7 +130,7 @@ object ConfigData {
|
||||
private fun putString(data: PrefsData<String>, value: String) {
|
||||
when (instance) {
|
||||
is Context -> (instance as Context).prefs().edit { put(data, value) }
|
||||
is PackageParam -> loggerW(msg = "Not support for this method")
|
||||
is PackageParam -> YLog.warn("Not support for this method")
|
||||
else -> error("Unknown type for put prefs data")
|
||||
}
|
||||
}
|
||||
@@ -157,7 +154,7 @@ object ConfigData {
|
||||
internal fun putInt(data: PrefsData<Int>, value: Int) {
|
||||
when (instance) {
|
||||
is Context -> (instance as Context).prefs().edit { put(data, value) }
|
||||
is PackageParam -> loggerW(msg = "Not support for this method")
|
||||
is PackageParam -> YLog.warn("Not support for this method")
|
||||
else -> error("Unknown type for put prefs data")
|
||||
}
|
||||
}
|
||||
@@ -181,7 +178,7 @@ object ConfigData {
|
||||
internal fun putBoolean(data: PrefsData<Boolean>, value: Boolean) {
|
||||
when (instance) {
|
||||
is Context -> (instance as Context).prefs().edit { put(data, value) }
|
||||
is PackageParam -> loggerW(msg = "Not support for this method")
|
||||
is PackageParam -> YLog.warn("Not support for this method")
|
||||
else -> error("Unknown type for put prefs data")
|
||||
}
|
||||
}
|
||||
@@ -196,16 +193,6 @@ object ConfigData {
|
||||
putBoolean(ENABLE_MODULE, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否启用数据缓存
|
||||
* @return [Boolean]
|
||||
*/
|
||||
var isEnablePrefsCache
|
||||
get() = getBoolean(ENABLE_PREFS_CACHE)
|
||||
set(value) {
|
||||
putBoolean(ENABLE_PREFS_CACHE, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否启用模块日志
|
||||
* @return [Boolean]
|
||||
@@ -276,6 +263,16 @@ object ConfigData {
|
||||
putInt(NOTIFY_ICON_CORNER_SIZE, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否替换 MIUI 样式通知栏的通知图标
|
||||
* @return [Boolean]
|
||||
*/
|
||||
var isEnableReplaceMiuiStyleNotifyIcon
|
||||
get() = getBoolean(ENABLE_REPLACE_MIUI_STYLE_NOTIFY_ICON)
|
||||
set(value) {
|
||||
putBoolean(ENABLE_REPLACE_MIUI_STYLE_NOTIFY_ICON, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否强制通知栏中的通知图标使用系统着色
|
||||
* @return [Boolean]
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2023/2/3.
|
||||
* This file is created by fankes on 2023/2/3.
|
||||
*/
|
||||
@file:Suppress("unused", "MemberVisibilityCanBePrivate")
|
||||
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2023/2/4.
|
||||
* This file is created by fankes on 2023/2/4.
|
||||
*/
|
||||
@file:Suppress("SetTextI18n")
|
||||
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* 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.
|
||||
*/
|
||||
package com.fankes.miui.notify.hook
|
||||
|
||||
@@ -26,16 +26,16 @@ import com.fankes.miui.notify.const.PackageName
|
||||
import com.fankes.miui.notify.data.ConfigData
|
||||
import com.fankes.miui.notify.hook.entity.SystemUIHooker
|
||||
import com.fankes.miui.notify.utils.factory.isLowerAndroidP
|
||||
import com.fankes.miui.notify.utils.factory.isNotMIUI
|
||||
import com.fankes.miui.notify.utils.factory.isNotSupportMiuiVersion
|
||||
import com.fankes.miui.notify.utils.factory.miuiVersion
|
||||
import com.fankes.miui.notify.utils.factory.isNotMiSystem
|
||||
import com.fankes.miui.notify.utils.factory.isNotSupportMiSystemVersion
|
||||
import com.fankes.miui.notify.utils.factory.miSystemVersion
|
||||
import com.highcapable.yukihookapi.annotation.xposed.InjectYukiHookWithXposed
|
||||
import com.highcapable.yukihookapi.hook.factory.configs
|
||||
import com.highcapable.yukihookapi.hook.factory.encase
|
||||
import com.highcapable.yukihookapi.hook.log.loggerW
|
||||
import com.highcapable.yukihookapi.hook.log.YLog
|
||||
import com.highcapable.yukihookapi.hook.xposed.proxy.IYukiHookXposedInit
|
||||
|
||||
@InjectYukiHookWithXposed(isUsingResourcesHook = false)
|
||||
@InjectYukiHookWithXposed
|
||||
object HookEntry : IYukiHookXposedInit {
|
||||
|
||||
override fun onInit() = configs {
|
||||
@@ -51,10 +51,10 @@ object HookEntry : IYukiHookXposedInit {
|
||||
loadApp(PackageName.SYSTEMUI) {
|
||||
ConfigData.init(instance = this)
|
||||
when {
|
||||
isNotMIUI -> loggerW(msg = "Aborted Hook -> This System is not MIUI")
|
||||
isLowerAndroidP -> loggerW(msg = "Aborted Hook -> This System is lower than Android P")
|
||||
isNotSupportMiuiVersion -> loggerW(msg = "Aborted Hook -> This MIUI Version ${miuiVersion.ifBlank { "unknown" }} not supported")
|
||||
ConfigData.isEnableModule.not() -> loggerW(msg = "Aborted Hook -> Hook Closed")
|
||||
isNotMiSystem -> YLog.warn("Aborted Hook -> This System is not MIUI or HyperOS")
|
||||
isLowerAndroidP -> YLog.warn("Aborted Hook -> This System is lower than Android P")
|
||||
isNotSupportMiSystemVersion -> YLog.warn("Aborted Hook -> This System Version ${miSystemVersion.ifBlank { "unknown" }} not supported")
|
||||
ConfigData.isEnableModule.not() -> YLog.warn("Aborted Hook -> Hook Closed")
|
||||
else -> loadHooker(SystemUIHooker)
|
||||
}
|
||||
}
|
||||
|
@@ -18,9 +18,9 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/3/25.
|
||||
* This file is created by fankes on 2022/3/25.
|
||||
*/
|
||||
@file:Suppress("StaticFieldLeak")
|
||||
@file:Suppress("StaticFieldLeak", "ConstPropertyName")
|
||||
|
||||
package com.fankes.miui.notify.hook.entity
|
||||
|
||||
@@ -46,6 +46,7 @@ import androidx.core.graphics.drawable.toBitmap
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
import androidx.core.view.children
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.setPadding
|
||||
import com.fankes.miui.notify.R
|
||||
import com.fankes.miui.notify.bean.IconDataBean
|
||||
import com.fankes.miui.notify.const.PackageName
|
||||
@@ -53,17 +54,41 @@ import com.fankes.miui.notify.data.ConfigData
|
||||
import com.fankes.miui.notify.params.IconPackParams
|
||||
import com.fankes.miui.notify.params.factory.isAppNotifyHookAllOf
|
||||
import com.fankes.miui.notify.params.factory.isAppNotifyHookOf
|
||||
import com.fankes.miui.notify.utils.factory.*
|
||||
import com.fankes.miui.notify.utils.factory.appIconOf
|
||||
import com.fankes.miui.notify.utils.factory.appNameOf
|
||||
import com.fankes.miui.notify.utils.factory.brighterColor
|
||||
import com.fankes.miui.notify.utils.factory.delayedRun
|
||||
import com.fankes.miui.notify.utils.factory.dp
|
||||
import com.fankes.miui.notify.utils.factory.dpFloat
|
||||
import com.fankes.miui.notify.utils.factory.drawableOf
|
||||
import com.fankes.miui.notify.utils.factory.isMIOS
|
||||
import com.fankes.miui.notify.utils.factory.isNotSystemInDarkMode
|
||||
import com.fankes.miui.notify.utils.factory.isSystemInDarkMode
|
||||
import com.fankes.miui.notify.utils.factory.isUpperOfAndroidS
|
||||
import com.fankes.miui.notify.utils.factory.miuiIncrementalVersion
|
||||
import com.fankes.miui.notify.utils.factory.round
|
||||
import com.fankes.miui.notify.utils.factory.runInSafe
|
||||
import com.fankes.miui.notify.utils.factory.safeOf
|
||||
import com.fankes.miui.notify.utils.factory.safeOfFalse
|
||||
import com.fankes.miui.notify.utils.factory.systemAccentColor
|
||||
import com.fankes.miui.notify.utils.tool.ActivationPromptTool
|
||||
import com.fankes.miui.notify.utils.tool.BitmapCompatTool
|
||||
import com.fankes.miui.notify.utils.tool.IconAdaptationTool
|
||||
import com.fankes.miui.notify.utils.tool.SystemUITool
|
||||
import com.highcapable.yukihookapi.hook.bean.VariousClass
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
import com.highcapable.yukihookapi.hook.factory.*
|
||||
import com.highcapable.yukihookapi.hook.log.loggerD
|
||||
import com.highcapable.yukihookapi.hook.log.loggerW
|
||||
import com.highcapable.yukihookapi.hook.type.android.*
|
||||
import com.highcapable.yukihookapi.hook.factory.constructor
|
||||
import com.highcapable.yukihookapi.hook.factory.current
|
||||
import com.highcapable.yukihookapi.hook.factory.extends
|
||||
import com.highcapable.yukihookapi.hook.factory.field
|
||||
import com.highcapable.yukihookapi.hook.factory.hasMethod
|
||||
import com.highcapable.yukihookapi.hook.factory.injectModuleAppResources
|
||||
import com.highcapable.yukihookapi.hook.factory.method
|
||||
import com.highcapable.yukihookapi.hook.log.YLog
|
||||
import com.highcapable.yukihookapi.hook.type.android.ContextClass
|
||||
import com.highcapable.yukihookapi.hook.type.android.DrawableClass
|
||||
import com.highcapable.yukihookapi.hook.type.android.ImageViewClass
|
||||
import com.highcapable.yukihookapi.hook.type.android.StatusBarNotificationClass
|
||||
import com.highcapable.yukihookapi.hook.type.java.BooleanType
|
||||
import com.highcapable.yukihookapi.hook.type.java.IntType
|
||||
import top.defaults.drawabletoolbox.DrawableBuilder
|
||||
@@ -74,68 +99,87 @@ import top.defaults.drawabletoolbox.DrawableBuilder
|
||||
object SystemUIHooker : YukiBaseHooker() {
|
||||
|
||||
/** MIUI 新版本存在的类 */
|
||||
private const val SystemUIApplicationClass = "${PackageName.SYSTEMUI}.SystemUIApplication"
|
||||
private val SystemUIApplicationClass by lazyClassOrNull("${PackageName.SYSTEMUI}.SystemUIApplication")
|
||||
|
||||
/** MIUI 新版本存在的类 */
|
||||
private const val MiuiNotificationViewWrapperClass = "${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.MiuiNotificationViewWrapper"
|
||||
private val MiuiNotificationViewWrapperClass
|
||||
by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.MiuiNotificationViewWrapper")
|
||||
|
||||
/** MIUI 新版本存在的类 */
|
||||
private const val MiuiNotificationChildrenContainerClass =
|
||||
"${PackageName.SYSTEMUI}.statusbar.notification.stack.MiuiNotificationChildrenContainer"
|
||||
private val MiuiNotificationChildrenContainerClass
|
||||
by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.stack.MiuiNotificationChildrenContainer")
|
||||
|
||||
/** MIUI 新版本存在的类 */
|
||||
private const val NotificationHeaderViewWrapperInjectorClass =
|
||||
"${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationHeaderViewWrapperInjector"
|
||||
private val NotificationHeaderViewWrapperInjectorClass
|
||||
by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationHeaderViewWrapperInjector")
|
||||
|
||||
/** MIUI 未确定版本存在的类 */
|
||||
private val SettingsManagerClass by lazyClassOrNull("com.miui.systemui.SettingsManager")
|
||||
|
||||
/** MIUI 新版本存在的类 */
|
||||
private val NotificationStatClass by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.analytics.NotificationStat")
|
||||
|
||||
/** 原生存在的类 */
|
||||
private const val NotificationChildrenContainerClass = "${PackageName.SYSTEMUI}.statusbar.notification.stack.NotificationChildrenContainer"
|
||||
private val NotificationChildrenContainerClass by lazyClass("${PackageName.SYSTEMUI}.statusbar.notification.stack.NotificationChildrenContainer")
|
||||
|
||||
/** 原生存在的类 */
|
||||
private const val NotificationIconAreaControllerClass = "${PackageName.SYSTEMUI}.statusbar.phone.NotificationIconAreaController"
|
||||
private val NotificationIconAreaControllerClass by lazyClass("${PackageName.SYSTEMUI}.statusbar.phone.NotificationIconAreaController")
|
||||
|
||||
/** 原生存在的类 */
|
||||
private const val ContrastColorUtilClass = "com.android.internal.util.ContrastColorUtil"
|
||||
private val ContrastColorUtilClass by lazyClass("com.android.internal.util.ContrastColorUtil")
|
||||
|
||||
/** 原生存在的类 */
|
||||
private const val StatusBarIconViewClass = "${PackageName.SYSTEMUI}.statusbar.StatusBarIconView"
|
||||
private val StatusBarIconViewClass by lazyClass("${PackageName.SYSTEMUI}.statusbar.StatusBarIconView")
|
||||
|
||||
/** 原生存在的类 */
|
||||
private const val NotificationIconContainerClass = "${PackageName.SYSTEMUI}.statusbar.phone.NotificationIconContainer"
|
||||
private val NotificationIconContainerClass by lazyClass("${PackageName.SYSTEMUI}.statusbar.phone.NotificationIconContainer")
|
||||
|
||||
/** 根据多个版本存在不同的包名相同的类 */
|
||||
private val StatusBarNotificationPresenterClass = VariousClass(
|
||||
"${PackageName.SYSTEMUI}.statusbar.phone.StatusBarNotificationPresenter",
|
||||
"${PackageName.SYSTEMUI}.statusbar.phone.StatusBar"
|
||||
private val StatusBarNotificationPresenterClass by lazyClass(
|
||||
VariousClass(
|
||||
"${PackageName.SYSTEMUI}.statusbar.phone.StatusBarNotificationPresenter",
|
||||
"${PackageName.SYSTEMUI}.statusbar.phone.StatusBar"
|
||||
)
|
||||
)
|
||||
|
||||
/** 根据多个版本存在不同的包名相同的类 */
|
||||
private val ExpandableNotificationRowClass = VariousClass(
|
||||
"${PackageName.SYSTEMUI}.statusbar.notification.row.ExpandableNotificationRow",
|
||||
"${PackageName.SYSTEMUI}.statusbar.ExpandableNotificationRow"
|
||||
private val ExpandableNotificationRowClass by lazyClass(
|
||||
VariousClass(
|
||||
"${PackageName.SYSTEMUI}.statusbar.notification.row.ExpandableNotificationRow",
|
||||
"${PackageName.SYSTEMUI}.statusbar.ExpandableNotificationRow"
|
||||
)
|
||||
)
|
||||
|
||||
/** 根据多个版本存在不同的包名相同的类 */
|
||||
private val NotificationViewWrapperClass = VariousClass(
|
||||
"${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationViewWrapper",
|
||||
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationViewWrapper"
|
||||
private val NotificationViewWrapperClass by lazyClass(
|
||||
VariousClass(
|
||||
"${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationViewWrapper",
|
||||
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationViewWrapper"
|
||||
)
|
||||
)
|
||||
|
||||
/** 根据多个版本存在不同的包名相同的类 */
|
||||
private val NotificationHeaderViewWrapperClass = VariousClass(
|
||||
"${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper",
|
||||
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationHeaderViewWrapper"
|
||||
private val NotificationHeaderViewWrapperClass by lazyClass(
|
||||
VariousClass(
|
||||
"${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper",
|
||||
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationHeaderViewWrapper"
|
||||
)
|
||||
)
|
||||
|
||||
/** 根据多个版本存在不同的包名相同的类 */
|
||||
private val NotificationUtilClass = VariousClass(
|
||||
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationUtil",
|
||||
"${PackageName.SYSTEMUI}.miui.statusbar.notification.NotificationUtil"
|
||||
private val NotificationUtilClass by lazyClass(
|
||||
VariousClass(
|
||||
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationUtil",
|
||||
"${PackageName.SYSTEMUI}.miui.statusbar.notification.NotificationUtil"
|
||||
)
|
||||
)
|
||||
|
||||
/** 根据多个版本存在不同的包名相同的类 */
|
||||
private val ExpandedNotificationClass = VariousClass(
|
||||
"${PackageName.SYSTEMUI}.statusbar.notification.ExpandedNotification",
|
||||
"${PackageName.SYSTEMUI}.miui.statusbar.ExpandedNotification"
|
||||
private val ExpandedNotificationClass by lazyClass(
|
||||
VariousClass(
|
||||
"${PackageName.SYSTEMUI}.statusbar.notification.ExpandedNotification",
|
||||
"${PackageName.SYSTEMUI}.miui.statusbar.ExpandedNotification"
|
||||
)
|
||||
)
|
||||
|
||||
/** 缓存的通知图标优化数组 */
|
||||
@@ -159,6 +203,9 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
/** 通知栏通知控制器 */
|
||||
private var notificationPresenter: Any? = null
|
||||
|
||||
/** 设置管理器 */
|
||||
private var settingsManager: Any? = null
|
||||
|
||||
/** 仅监听一次主题壁纸颜色变化 */
|
||||
private var isWallpaperColorListenerSetUp = false
|
||||
|
||||
@@ -167,20 +214,19 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
* @return [Context] or null
|
||||
*/
|
||||
private val globalContext
|
||||
get() = SystemUIApplicationClass.toClassOrNull()?.method { name = "getContext" }?.ignored()?.get()?.invoke<Context?>() ?: appContext
|
||||
get() = SystemUIApplicationClass?.method { name = "getContext" }?.ignored()?.get()?.invoke<Context?>() ?: appContext
|
||||
|
||||
/**
|
||||
* 是否为 MIUI 样式通知栏 - 旧版 - 新版一律返回 false
|
||||
* @return [Boolean]
|
||||
*/
|
||||
private val isShowMiuiStyle
|
||||
get() = NotificationUtilClass.toClassOrNull()?.method { name = "showMiuiStyle" }?.ignored()?.get()?.boolean() ?: false
|
||||
private val isShowMiuiStyle get() = NotificationUtilClass.method { name = "showMiuiStyle" }.ignored().get().boolean()
|
||||
|
||||
/**
|
||||
* 是否没有单独的 MIUI 通知栏样式
|
||||
* @return [Boolean]
|
||||
*/
|
||||
private val isNotHasAbsoluteMiuiStyle get() = MiuiNotificationViewWrapperClass.hasClass().not()
|
||||
private val isNotHasAbsoluteMiuiStyle get() = MiuiNotificationViewWrapperClass == null
|
||||
|
||||
/**
|
||||
* 获取状态栏通知图标透明度
|
||||
@@ -223,6 +269,13 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
return xmsfPkg.ifBlank { targetPkg.ifBlank { packageName } }
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 MIUI 自己设置的通知图标
|
||||
* @return [Icon] or null
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
private val StatusBarNotification.miuiAppIcon get() = notification?.extras?.getParcelable<Icon?>("miui.appIcon")
|
||||
|
||||
/**
|
||||
* 打印日志
|
||||
* @param tag 标识
|
||||
@@ -232,17 +285,17 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
* @param isGrayscale 是否为灰度图标
|
||||
*/
|
||||
private fun loggerDebug(tag: String, context: Context, nf: StatusBarNotification?, isCustom: Boolean, isGrayscale: Boolean) {
|
||||
if (ConfigData.isEnableModuleLog) loggerD(
|
||||
if (ConfigData.isEnableModuleLog) YLog.debug(
|
||||
msg = "(Processing $tag) ↓\n" +
|
||||
"[Title]: ${nf?.notification?.extras?.getString(Notification.EXTRA_TITLE)}\n" +
|
||||
"[Content]: ${nf?.notification?.extras?.getString(Notification.EXTRA_TEXT)}\n" +
|
||||
"[App Name]: ${context.appNameOf(packageName = nf?.packageName ?: "")}\n" +
|
||||
"[Package Name]: ${nf?.packageName}\n" +
|
||||
"[Sender Package Name]: ${nf?.compatOpPkgName}\n" +
|
||||
"[Custom Icon]: $isCustom\n" +
|
||||
"[Grayscale Icon]: $isGrayscale\n" +
|
||||
"[From Xmsf]: ${nf?.isXmsf}\n" +
|
||||
"[String]: ${nf?.notification}"
|
||||
"[Title]: ${nf?.notification?.extras?.getString(Notification.EXTRA_TITLE)}\n" +
|
||||
"[Content]: ${nf?.notification?.extras?.getString(Notification.EXTRA_TEXT)}\n" +
|
||||
"[App Name]: ${context.appNameOf(packageName = nf?.packageName ?: "")}\n" +
|
||||
"[Package Name]: ${nf?.packageName}\n" +
|
||||
"[Sender Package Name]: ${nf?.compatOpPkgName}\n" +
|
||||
"[Custom Icon]: $isCustom\n" +
|
||||
"[Grayscale Icon]: $isGrayscale\n" +
|
||||
"[From Xmsf]: ${nf?.isXmsf}\n" +
|
||||
"[String]: ${nf?.notification}"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -256,7 +309,7 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
*/
|
||||
private fun isGrayscaleIcon(context: Context, drawable: Drawable) =
|
||||
if (ConfigData.isEnableColorIconCompat.not()) safeOfFalse {
|
||||
ContrastColorUtilClass.toClass().let {
|
||||
ContrastColorUtilClass.let {
|
||||
it.method {
|
||||
name = "isGrayscaleIcon"
|
||||
param(DrawableClass)
|
||||
@@ -304,7 +357,7 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
|
||||
/** 刷新状态栏小图标 */
|
||||
private fun refreshStatusBarIcons() = runInSafe {
|
||||
StatusBarIconViewClass.toClassOrNull()?.field { name = "mNotification" }?.also { result ->
|
||||
StatusBarIconViewClass.field { name = "mNotification" }.also { result ->
|
||||
notificationIconContainer?.children?.forEach {
|
||||
/** 得到通知实例 */
|
||||
val nf = result.get(it).cast<StatusBarNotification>() ?: return
|
||||
@@ -318,10 +371,16 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
|
||||
/** 刷新通知小图标 */
|
||||
private fun refreshNotificationIcons() = runInSafe {
|
||||
notificationPresenter?.current()?.method {
|
||||
name = "updateNotificationsOnDensityOrFontScaleChanged"
|
||||
emptyParam()
|
||||
}?.call()
|
||||
val updateNotificationMethodName = "updateNotificationsOnDensityOrFontScaleChanged"
|
||||
if (StatusBarNotificationPresenterClass.hasMethod { name = updateNotificationMethodName })
|
||||
notificationPresenter?.current(ignored = true)?.method {
|
||||
name = updateNotificationMethodName
|
||||
emptyParam()
|
||||
}?.call()
|
||||
else settingsManager?.current {
|
||||
field { name = "notifStyle" }.set(-100)
|
||||
method { name = "onNotifStyleChanged" }.call()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -389,13 +448,15 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
* @param iconView 通知图标实例
|
||||
* @param isExpanded 通知是否展开 - 可做最小化通知处理 - 默认:是
|
||||
* @param isUseMaterial3Style 是否使用 Material 3 通知图标风格 - 默认跟随系统版本决定
|
||||
* @param isMiuiPanel 是否来自 MIUI 自己的通知面板
|
||||
*/
|
||||
private fun compatNotifyIcon(
|
||||
context: Context,
|
||||
nf: StatusBarNotification?,
|
||||
iconView: ImageView,
|
||||
isExpanded: Boolean = true,
|
||||
isUseMaterial3Style: Boolean = isUpperOfAndroidS
|
||||
isUseMaterial3Style: Boolean = isUpperOfAndroidS,
|
||||
isMiuiPanel: Boolean = false
|
||||
) = runInSafe(msg = "compatNotifyIcon") {
|
||||
/**
|
||||
* 设置默认通知图标
|
||||
@@ -452,7 +513,7 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
|
||||
/** 获取通知小图标 */
|
||||
val iconDrawable = notifyInstance.notification.smallIcon.loadDrawable(context)
|
||||
?: return@let loggerW(msg = "compatNotifyIcon got null smallIcon")
|
||||
?: return@let YLog.warn("compatNotifyIcon got null smallIcon")
|
||||
|
||||
/** 判断图标风格 */
|
||||
val isGrayscaleIcon = notifyInstance.isXmsf.not() && isGrayscaleIcon(context, iconDrawable)
|
||||
@@ -474,11 +535,8 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
loggerDebug(tag = "Notification Panel Icon", context, notifyInstance, isCustom = customIcon != null, isGrayscaleIcon)
|
||||
/** 处理自定义通知图标优化 */
|
||||
when {
|
||||
ConfigData.isEnableNotifyIconForceAppIcon -> {
|
||||
@Suppress("DEPRECATION")
|
||||
val miuiAppIcon = notifyInstance.notification?.extras?.getParcelable<Icon?>("miui.appIcon")
|
||||
setDefaultNotifyIcon(drawable = miuiAppIcon?.loadDrawable(context) ?: context.appIconOf(notifyInstance.nfPkgName))
|
||||
}
|
||||
ConfigData.isEnableNotifyIconForceAppIcon ->
|
||||
setDefaultNotifyIcon(drawable = notifyInstance.miuiAppIcon?.loadDrawable(context) ?: context.appIconOf(notifyInstance.nfPkgName))
|
||||
customIcon != null -> iconView.apply {
|
||||
/** 设置不要裁切到边界 */
|
||||
clipToOutline = false
|
||||
@@ -493,8 +551,12 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
.cornerRadius(ConfigData.notifyIconCornerSize.dp(context))
|
||||
.solidColor(if (context.isSystemInDarkMode) customIconColor.brighterColor else customIconColor)
|
||||
.build()
|
||||
/** 设置原生的背景边距 */
|
||||
if (isUseMaterial3Style) setPadding(4.dp(context), 4.dp(context), 4.dp(context), 4.dp(context))
|
||||
when {
|
||||
/** 缩小 HyperOS 的通知图标 */
|
||||
isMIOS && isMiuiPanel -> setPadding(7.dp(context))
|
||||
/** 设置原生的背景边距 */
|
||||
isUseMaterial3Style -> setPadding(4.dp(context))
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
/** 重新设置图标 - 防止系统更改它 */
|
||||
@@ -514,8 +576,12 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
.solidColor(if (context.isSystemInDarkMode) it.brighterColor else it)
|
||||
.build()
|
||||
}
|
||||
/** 设置原生的背景边距 */
|
||||
if (isUseMaterial3Style) setPadding(4.dp(context), 4.dp(context), 4.dp(context), 4.dp(context))
|
||||
when {
|
||||
/** 缩小 HyperOS 的通知图标 */
|
||||
isMIOS && isMiuiPanel -> setPadding(7.dp(context))
|
||||
/** 设置原生的背景边距 */
|
||||
isUseMaterial3Style -> setPadding(4.dp(context))
|
||||
}
|
||||
} else setDefaultNotifyIcon(notifyInstance.compatPushingIcon(context, iconDrawable))
|
||||
}
|
||||
}
|
||||
@@ -528,12 +594,10 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
*/
|
||||
private fun ImageView.isGrayscaleIcon(): Boolean {
|
||||
/** 获取 [StatusBarNotification] 实例 */
|
||||
val notifyInstance = current().field { name = "mNotification" }.cast<StatusBarNotification>()
|
||||
?: return loggerW(msg = "isGrayscaleIcon got null mNotification").let { false }
|
||||
val notifyInstance = current().field { name = "mNotification" }.cast<StatusBarNotification>() ?: return false
|
||||
|
||||
/** 获取通知小图标 */
|
||||
val iconDrawable = notifyInstance.notification?.smallIcon?.loadDrawable(context)
|
||||
?: return loggerW(msg = "isGrayscaleIcon got null smallIcon").let { false }
|
||||
val iconDrawable = notifyInstance.notification?.smallIcon?.loadDrawable(context) ?: return false
|
||||
|
||||
/** 判断是否不是灰度图标 */
|
||||
val isGrayscaleIcon = notifyInstance.isXmsf.not() && isGrayscaleIcon(context, iconDrawable)
|
||||
@@ -553,20 +617,29 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
* @param isDarkIconMode 是否为深色图标模式
|
||||
* @param animColor 动画过渡颜色
|
||||
*/
|
||||
private fun updateStatusBarIconColor(container: ViewGroup, isDarkIconMode: Boolean = this.isDarkIconMode, animColor: Int? = null) {
|
||||
private fun updateStatusBarIconsColor(container: ViewGroup, isDarkIconMode: Boolean = this.isDarkIconMode, animColor: Int? = null) {
|
||||
if (container.childCount > 0) container.children.forEach { iconView ->
|
||||
if (iconView !is ImageView) return@forEach
|
||||
if (iconView.isGrayscaleIcon()) {
|
||||
/**
|
||||
* 防止图标不是纯黑的问题
|
||||
* 图标在任何场景下跟随状态栏其它图标保持半透明
|
||||
*/
|
||||
iconView.alpha = if (animColor != null) 1f else statusBarIconAlpha
|
||||
iconView.setColorFilter(animColor ?: (if (isDarkIconMode) Color.BLACK else Color.WHITE))
|
||||
} else {
|
||||
iconView.alpha = 1f
|
||||
iconView.colorFilter = null
|
||||
}
|
||||
updateStatusBarIconColor(iconView, isDarkIconMode, animColor)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新状态栏每个通知图标的颜色
|
||||
* @param isDarkIconMode 是否为深色图标模式
|
||||
* @param animColor 动画过渡颜色
|
||||
*/
|
||||
private fun updateStatusBarIconColor(iconView: ImageView, isDarkIconMode: Boolean = this.isDarkIconMode, animColor: Int? = null) {
|
||||
if (iconView.isGrayscaleIcon()) {
|
||||
/**
|
||||
* 防止图标不是纯黑的问题
|
||||
* 图标在任何场景下跟随状态栏其它图标保持半透明
|
||||
*/
|
||||
iconView.alpha = if (animColor != null) 1f else statusBarIconAlpha
|
||||
iconView.setColorFilter(animColor ?: (if (isDarkIconMode) Color.BLACK else Color.WHITE))
|
||||
} else {
|
||||
iconView.alpha = 1f
|
||||
iconView.colorFilter = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -574,16 +647,30 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
* 更新状态栏通知图标透明度
|
||||
* @param container 当前 [NotificationIconContainerClass] 的实例
|
||||
*/
|
||||
private fun updateStatusBarIconAlpha(container: ViewGroup) {
|
||||
val iconStateMethod = container.current().method { name = "getIconState"; param(StatusBarIconViewClass) }
|
||||
private fun updateStatusBarIconsAlpha(container: ViewGroup) {
|
||||
val iconStatesMap = container.current().field { name = "mIconStates" }.cast<HashMap<View, Any>>()
|
||||
if (container.childCount > 0) container.children.forEach { iconView ->
|
||||
if (iconView !is ImageView) return@forEach
|
||||
val iconAlpha = if (iconView.isGrayscaleIcon()) statusBarIconAlpha else 1f
|
||||
iconView.alpha = iconAlpha
|
||||
iconStateMethod.call(iconView)?.current()?.field { name = "alpha"; superClass() }?.set(iconAlpha)
|
||||
iconStatesMap?.get(iconView)?.current()?.field { name { it == "alpha" || it == "mAlpha" }; superClass() }?.set(iconAlpha)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook 状态栏通知图标最大数量
|
||||
* @param fieldName 最大通知图标数量 的变量名
|
||||
* @param instance 被 Hook 的 Method 的实例
|
||||
*/
|
||||
private fun hookStatusBarMaxStaticIcons(fieldName: String, instance: Any) {
|
||||
val maxStaticIconsField = NotificationIconContainerClass.field { name = fieldName }.get(instance)
|
||||
if (statusBarMaxStaticIcons == -1) statusBarMaxStaticIcons = maxStaticIconsField.int()
|
||||
/** 解除状态栏通知图标个数限制 */
|
||||
if (isShowNotificationIcons && ConfigData.isEnableLiftedStatusIconCount)
|
||||
maxStaticIconsField.set(ConfigData.liftedStatusIconCount.let { if (it in 0..100) it else 5 })
|
||||
else maxStaticIconsField.set(if (isShowNotificationIcons) statusBarMaxStaticIcons else 0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook 原生通知包装纸实例内容
|
||||
* @param wrapper 通知包装纸实例
|
||||
@@ -593,8 +680,8 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
if (isNotHasAbsoluteMiuiStyle && isShowMiuiStyle) return
|
||||
|
||||
/** 获取小图标 */
|
||||
val iconImageView = NotificationHeaderViewWrapperClass.toClassOrNull()
|
||||
?.field { name = "mIcon" }?.get(wrapper)?.cast<ImageView>() ?: return
|
||||
val iconImageView = NotificationHeaderViewWrapperClass
|
||||
.field { name = "mIcon" }.get(wrapper).cast<ImageView>() ?: return
|
||||
|
||||
/** 获取 [ExpandableNotificationRowClass] */
|
||||
val rowPair = wrapper.getRowPair()
|
||||
@@ -627,13 +714,14 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
* 从父类中得到 mRow 变量 - [ExpandableNotificationRowClass]
|
||||
* 获取其中的得到通知方法
|
||||
*/
|
||||
val row = NotificationViewWrapperClass.toClassOrNull()?.field {
|
||||
val row = NotificationViewWrapperClass.field {
|
||||
name = "mRow"
|
||||
}?.get(this)?.any()?.also {
|
||||
isExpanded = ExpandableNotificationRowClass.toClassOrNull()?.method {
|
||||
}.get(this).any()?.also {
|
||||
isExpanded = ExpandableNotificationRowClass.method {
|
||||
name = "isExpanded"
|
||||
param(BooleanType)
|
||||
returnType = BooleanType
|
||||
}?.get(it)?.boolean() ?: false
|
||||
}.get(it).boolean(false)
|
||||
}
|
||||
return Pair(isExpanded, row)
|
||||
}
|
||||
@@ -643,15 +731,15 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
* @return [StatusBarNotification] or null
|
||||
*/
|
||||
private fun Any?.getSbn() =
|
||||
ExpandableNotificationRowClass.toClassOrNull()
|
||||
?.method { name = "getEntry" }
|
||||
?.get(this)?.call()?.let {
|
||||
it.javaClass.method {
|
||||
name = "getSbn"
|
||||
}.ignored().get(it).invoke<StatusBarNotification>()
|
||||
} ?: ExpandableNotificationRowClass.toClassOrNull()
|
||||
?.method { name = "getStatusBarNotification" }
|
||||
?.get(this)?.invoke<StatusBarNotification>()
|
||||
ExpandableNotificationRowClass
|
||||
.method { name = "getEntry" }
|
||||
.get(this).call()
|
||||
?.current(ignored = true)
|
||||
?.field { name = "mSbn" }
|
||||
?.cast<StatusBarNotification>()
|
||||
?: ExpandableNotificationRowClass
|
||||
.method { name = "getStatusBarNotification" }
|
||||
.get(this).invoke<StatusBarNotification>()
|
||||
|
||||
/**
|
||||
* 根据当前 [ImageView] 的父布局克隆一个新的 [ImageView]
|
||||
@@ -735,7 +823,6 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
/** 获取可读写状态 */
|
||||
return prefs.isPreferencesAvailable.also {
|
||||
isUsingCachingMethod = true
|
||||
prefs.clearCache()
|
||||
cachingIconDatas()
|
||||
if (isRefreshCacheOnly) return@also
|
||||
refreshStatusBarIcons()
|
||||
@@ -749,226 +836,218 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
/** 缓存图标数据 */
|
||||
cachingIconDatas()
|
||||
/** 注入 MIUI 自己增加的一个工具类 */
|
||||
NotificationUtilClass.hook {
|
||||
NotificationUtilClass.apply {
|
||||
/** 强制回写系统的状态栏图标样式为原生 */
|
||||
injectMember {
|
||||
method {
|
||||
name = "shouldSubstituteSmallIcon"
|
||||
param(ExpandedNotificationClass)
|
||||
}
|
||||
replaceToFalse()
|
||||
}
|
||||
method {
|
||||
name { it == "shouldSubstituteSmallIcon" || it == "shouldSubstituteSmallIconForStatusBarNotification" }
|
||||
param { it[0] extends StatusBarNotificationClass }
|
||||
}.hookAll().replaceToFalse()
|
||||
var isUseLegacy = false
|
||||
/** 强制回写系统的状态栏图标样式为原生 */
|
||||
injectMember {
|
||||
var isUseLegacy = false
|
||||
method {
|
||||
name = "getSmallIcon"
|
||||
param { it[0] extends StatusBarNotificationClass && it[1] == IntType }
|
||||
}.remedys {
|
||||
method {
|
||||
name = "getSmallIcon"
|
||||
param(ExpandedNotificationClass, IntType)
|
||||
}.remedys {
|
||||
method {
|
||||
name = "getSmallIcon"
|
||||
param(ExpandedNotificationClass)
|
||||
}
|
||||
method {
|
||||
name = "getSmallIcon"
|
||||
param(ContextClass, ExpandedNotificationClass)
|
||||
}.onFind { isUseLegacy = true }
|
||||
param(ExpandedNotificationClass)
|
||||
}
|
||||
afterHook {
|
||||
(globalContext ?: args().first().cast())?.also { context ->
|
||||
val expandedNf = args(if (isUseLegacy) 1 else 0).cast<StatusBarNotification?>()
|
||||
/** Hook 状态栏小图标 */
|
||||
compatStatusIcon(
|
||||
context = context,
|
||||
expandedNf,
|
||||
result<Icon>()?.loadDrawable(context)
|
||||
).also { pair -> if (pair.second) result = Icon.createWithBitmap(pair.first?.toBitmap()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 注入状态栏通知图标容器管理实例 */
|
||||
NotificationIconAreaControllerClass.hook {
|
||||
/** Hook 深色图标模式改变 */
|
||||
injectMember {
|
||||
method {
|
||||
name = "onDarkChanged"
|
||||
paramCount { it > 0 }
|
||||
}
|
||||
afterHook {
|
||||
field { name = "mNotificationIcons" }.get(instance).cast<ViewGroup>()?.also {
|
||||
/** 重新设置通知图标容器实例 */
|
||||
notificationIconContainer = it
|
||||
when (args(index = 1).float()) {
|
||||
1.0f -> {
|
||||
isDarkIconMode = true
|
||||
updateStatusBarIconColor(it, isDarkIconMode = true)
|
||||
}
|
||||
0.0f -> {
|
||||
isDarkIconMode = false
|
||||
updateStatusBarIconColor(it, isDarkIconMode = false)
|
||||
}
|
||||
else -> updateStatusBarIconColor(it, isDarkIconMode = false, args(index = 2).int())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/** Hook 更新通知图标事件 */
|
||||
injectMember {
|
||||
method { name { it == "updateNotificationIcons" || it == "onChanged" } }.all()
|
||||
afterHook {
|
||||
field { name = "mNotificationIcons" }.get(instance).cast<ViewGroup>()?.also {
|
||||
/** 重新设置通知图标容器实例 */
|
||||
notificationIconContainer = it
|
||||
updateStatusBarIconColor(it)
|
||||
/** 延迟防止新添加的通知图标不刷新 */
|
||||
delayedRun { updateStatusBarIconColor(it) }
|
||||
}
|
||||
name = "getSmallIcon"
|
||||
param(ContextClass, ExpandedNotificationClass)
|
||||
}.onFind { isUseLegacy = true }
|
||||
}.hook().after {
|
||||
(globalContext ?: args().first().cast())?.also { context ->
|
||||
val expandedNf = args(if (isUseLegacy) 1 else 0).cast<StatusBarNotification?>()
|
||||
/** Hook 状态栏小图标 */
|
||||
compatStatusIcon(
|
||||
context = context,
|
||||
nf = expandedNf,
|
||||
iconDrawable = result<Icon>()?.loadDrawable(context)
|
||||
).also { pair -> if (pair.second) result = Icon.createWithBitmap(pair.first?.toBitmap()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 注入状态栏通知图标实例 */
|
||||
StatusBarIconViewClass.hook {
|
||||
/** 注册广播 */
|
||||
injectMember {
|
||||
method {
|
||||
name = "setNotification"
|
||||
param(StatusBarNotificationClass)
|
||||
}.remedys {
|
||||
method {
|
||||
name = "setNotification"
|
||||
param(ExpandedNotificationClass)
|
||||
StatusBarIconViewClass.method {
|
||||
name = "updateIconColor"
|
||||
emptyParam()
|
||||
}.ignored().hook().after {
|
||||
val iconView = instance<ImageView>()
|
||||
val expandedNf = iconView.current().field { name = "mNotification" }.cast<StatusBarNotification>()
|
||||
/** Hook 状态栏小图标 */
|
||||
compatStatusIcon(
|
||||
context = iconView.context,
|
||||
nf = expandedNf,
|
||||
iconDrawable = expandedNf?.notification?.smallIcon?.loadDrawable(iconView.context)
|
||||
).also { pair -> iconView.setImageDrawable(pair.first) }
|
||||
updateStatusBarIconColor(iconView)
|
||||
}
|
||||
/** 注入状态栏通知图标容器管理实例 */
|
||||
NotificationIconAreaControllerClass.apply {
|
||||
/** Hook 深色图标模式改变 */
|
||||
method {
|
||||
name = "onDarkChanged"
|
||||
paramCount { it > 0 }
|
||||
}.hook().after {
|
||||
field { name = "mNotificationIcons" }.get(instance).cast<ViewGroup>()?.also {
|
||||
/** 重新设置通知图标容器实例 */
|
||||
notificationIconContainer = it
|
||||
when (args(index = 1).float()) {
|
||||
1.0f -> {
|
||||
isDarkIconMode = true
|
||||
updateStatusBarIconsColor(it, isDarkIconMode = true)
|
||||
}
|
||||
0.0f -> {
|
||||
isDarkIconMode = false
|
||||
updateStatusBarIconsColor(it, isDarkIconMode = false)
|
||||
}
|
||||
else -> updateStatusBarIconsColor(it, isDarkIconMode = false, args(index = 2).int())
|
||||
}
|
||||
}
|
||||
afterHook {
|
||||
/** 注册壁纸颜色监听 */
|
||||
if (args().first().any() != null) instance<ImageView>().also { registerWallpaperColorChanged(it) }
|
||||
}
|
||||
/** Hook 更新通知图标事件 */
|
||||
method {
|
||||
name { it == "updateNotificationIcons" || it.startsWith("onChanged") }
|
||||
}.hookAll().after {
|
||||
field { name = "mNotificationIcons" }.get(instance).cast<ViewGroup>()?.also {
|
||||
/** 重新设置通知图标容器实例 */
|
||||
notificationIconContainer = it
|
||||
updateStatusBarIconsColor(it)
|
||||
/** 延迟防止新添加的通知图标不刷新 */
|
||||
delayedRun { updateStatusBarIconsColor(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 注入状态栏通知图标实例 */
|
||||
StatusBarIconViewClass.method {
|
||||
name = "setNotification"
|
||||
param(StatusBarNotificationClass)
|
||||
}.remedys {
|
||||
method {
|
||||
name = "setNotification"
|
||||
param(ExpandedNotificationClass)
|
||||
}
|
||||
}.hook().after {
|
||||
/** 注册壁纸颜色监听 */
|
||||
if (args().first().any() != null) instance<ImageView>().also { registerWallpaperColorChanged(it) }
|
||||
}
|
||||
/** 注入设置管理器实例 */
|
||||
SettingsManagerClass?.constructor()?.hookAll()?.after { settingsManager = instance }
|
||||
/** 注入通知控制器实例 */
|
||||
StatusBarNotificationPresenterClass.hook {
|
||||
injectMember {
|
||||
allMembers(MembersType.CONSTRUCTOR)
|
||||
afterHook { notificationPresenter = instance }
|
||||
}
|
||||
}
|
||||
StatusBarNotificationPresenterClass.constructor().hookAll().after { notificationPresenter = instance }
|
||||
/** 注入状态栏通知图标容器实例 */
|
||||
NotificationIconContainerClass.hook {
|
||||
injectMember {
|
||||
method { name = "applyIconStates" }
|
||||
afterHook { updateStatusBarIconAlpha(instance()) }
|
||||
}
|
||||
injectMember {
|
||||
method { name = "resetViewStates" }
|
||||
afterHook { updateStatusBarIconAlpha(instance()) }
|
||||
}
|
||||
injectMember {
|
||||
method { name = "calculateIconTranslations" }
|
||||
afterHook {
|
||||
/** 缓存实例 */
|
||||
notificationIconContainer = instance<ViewGroup>()
|
||||
/** 修复部分开发版状态栏图标只能显示一个的问题 */
|
||||
when (miuiIncrementalVersion.lowercase()) {
|
||||
"22.3.14", "22.3.15", "22.3.16", "v13.0.1.1.16.dev", "22.3.18" ->
|
||||
instance<ViewGroup>().layoutParams.width = 9999
|
||||
}
|
||||
NotificationIconContainerClass.apply {
|
||||
method {
|
||||
name = "applyIconStates"
|
||||
}.hook().after { updateStatusBarIconsAlpha(instance()) }
|
||||
method {
|
||||
name = "resetViewStates"
|
||||
}.hook().after { updateStatusBarIconsAlpha(instance()) }
|
||||
method {
|
||||
name { it == "calculateIconTranslations" || it == "calculateIconXTranslations" }
|
||||
}.hook().after {
|
||||
/** 缓存实例 */
|
||||
notificationIconContainer = instance<ViewGroup>()
|
||||
/** 修复部分开发版状态栏图标只能显示一个的问题 */
|
||||
when (miuiIncrementalVersion.lowercase()) {
|
||||
"22.3.14", "22.3.15", "22.3.16", "v13.0.1.1.16.dev", "22.3.18" ->
|
||||
instance<ViewGroup>().layoutParams.width = 9999
|
||||
}
|
||||
}
|
||||
injectMember {
|
||||
method { name = "updateState" }
|
||||
beforeHook {
|
||||
val maxStaticIconsField = field { name = "MAX_STATIC_ICONS" }.get(instance)
|
||||
if (statusBarMaxStaticIcons == -1) statusBarMaxStaticIcons = maxStaticIconsField.int()
|
||||
/** 解除状态栏通知图标个数限制 */
|
||||
if (isShowNotificationIcons && ConfigData.isEnableLiftedStatusIconCount)
|
||||
maxStaticIconsField.set(ConfigData.liftedStatusIconCount.let { if (it in 0..100) it else 5 })
|
||||
else maxStaticIconsField.set(if (isShowNotificationIcons) statusBarMaxStaticIcons else 0)
|
||||
}
|
||||
}.by { NotificationIconContainerClass.toClassOrNull()?.hasField { name = "MAX_STATIC_ICONS" } ?: false }
|
||||
/** 旧版方法 A13MIUI - 新版不存在 */
|
||||
method {
|
||||
name = "updateState"
|
||||
}.ignored().hook().before { hookStatusBarMaxStaticIcons("MAX_STATIC_ICONS", instance) }
|
||||
/** 新版方法 (A14 MIUI14 / A14 HyperOS) - 旧版不存在 */
|
||||
method {
|
||||
name = "onMeasure"
|
||||
}.ignored().hook().before { hookStatusBarMaxStaticIcons("mMaxStaticIcons", instance) }
|
||||
/** 旧版方法 - 新版不存在 */
|
||||
injectMember {
|
||||
method {
|
||||
name = "setMaxStaticIcons"
|
||||
param(IntType)
|
||||
}
|
||||
beforeHook { isShowNotificationIcons = args().first().int() > 0 }
|
||||
}.ignoredNoSuchMemberFailure()
|
||||
method {
|
||||
name = "setMaxStaticIcons"
|
||||
param(IntType)
|
||||
}.ignored().hook().before { isShowNotificationIcons = args().first().int() > 0 }
|
||||
/** 新版方法 - 旧版不存在 */
|
||||
injectMember {
|
||||
method {
|
||||
name = "miuiShowNotificationIcons"
|
||||
param(BooleanType)
|
||||
}
|
||||
beforeHook { isShowNotificationIcons = args().first().boolean() }
|
||||
}.ignoredNoSuchMemberFailure()
|
||||
method {
|
||||
name = "miuiShowNotificationIcons"
|
||||
param(BooleanType)
|
||||
}.ignored().hook().before { isShowNotificationIcons = args().first().boolean() }
|
||||
}
|
||||
/** 注入原生通知包装纸实例 */
|
||||
NotificationHeaderViewWrapperClass.hook {
|
||||
injectMember {
|
||||
method { name { it == "resolveHeaderViews" || it == "handleHeaderViews" || it == "resolveViews" } }
|
||||
afterHook { hookNotificationViewWrapper(instance) }
|
||||
}
|
||||
injectMember {
|
||||
method { name = "onContentUpdated" }
|
||||
afterHook { hookNotificationViewWrapper(instance) }
|
||||
}
|
||||
NotificationHeaderViewWrapperClass.apply {
|
||||
method {
|
||||
name { it == "resolveHeaderViews" || it == "handleHeaderViews" || it == "resolveViews" }
|
||||
}.hook().after { hookNotificationViewWrapper(instance) }
|
||||
method {
|
||||
name = "onContentUpdated"
|
||||
}.hook().after { hookNotificationViewWrapper(instance) }
|
||||
}
|
||||
/** 修改 MIUI 风格通知栏的通知图标 */
|
||||
MiuiNotificationViewWrapperClass.hook {
|
||||
/** 替换通知小图标 */
|
||||
injectMember {
|
||||
method { name = "handleAppIcon" }
|
||||
replaceUnit {
|
||||
field { name = "mAppIcon" }.get(instance).cast<ImageView>()?.clone {
|
||||
compatNotifyIcon(
|
||||
context = context,
|
||||
nf = instance.getRowPair().second.getSbn(),
|
||||
iconView = this,
|
||||
isUseMaterial3Style = true
|
||||
)
|
||||
}
|
||||
MiuiNotificationViewWrapperClass?.apply {
|
||||
constructor().hook().after {
|
||||
val nf = instance.getRowPair().second.getSbn() ?: return@after
|
||||
field { name = "mAppIcon" }.get(instance).cast<ImageView>()?.clone {
|
||||
if (ConfigData.isEnableReplaceMiuiStyleNotifyIcon || ConfigData.isEnableNotifyIconForceAppIcon)
|
||||
compatNotifyIcon(context, nf, iconView = this, isUseMaterial3Style = true, isMiuiPanel = true)
|
||||
else setImageDrawable(nf.miuiAppIcon?.loadDrawable(context) ?: context.appIconOf(nf.packageName))
|
||||
}
|
||||
}
|
||||
}.ignoredHookClassNotFoundFailure()
|
||||
}
|
||||
/** 修改 MIUI 风格通知栏的通知图标 - 折叠通知 */
|
||||
MiuiNotificationChildrenContainerClass.hook {
|
||||
MiuiNotificationChildrenContainerClass?.apply {
|
||||
/** 替换通知小图标 */
|
||||
injectMember {
|
||||
method {
|
||||
name = "updateAppIcon"
|
||||
param(BooleanType)
|
||||
}
|
||||
afterHook {
|
||||
field { name = "mAppIcon" }.get(instance).cast<ImageView>()?.apply {
|
||||
compatNotifyIcon(context, NotificationChildrenContainerClass.toClassOrNull()?.field {
|
||||
name = "mContainingNotification"
|
||||
}?.get(instance)?.any()?.getSbn(), iconView = this, isUseMaterial3Style = true)
|
||||
}
|
||||
method {
|
||||
name = "updateAppIcon"
|
||||
param(BooleanType)
|
||||
}.hook().after {
|
||||
field { name = "mAppIcon" }.get(instance).cast<ImageView>()?.apply {
|
||||
val nf = NotificationChildrenContainerClass.field {
|
||||
name = "mContainingNotification"
|
||||
}.get(instance).any()?.getSbn() ?: return@after
|
||||
if (ConfigData.isEnableReplaceMiuiStyleNotifyIcon || ConfigData.isEnableNotifyIconForceAppIcon)
|
||||
compatNotifyIcon(context, nf, iconView = this, isUseMaterial3Style = true, isMiuiPanel = true)
|
||||
else setImageDrawable(nf.miuiAppIcon?.loadDrawable(context) ?: context.appIconOf(nf.packageName))
|
||||
}
|
||||
}
|
||||
}.ignoredHookClassNotFoundFailure()
|
||||
}
|
||||
/** 干掉下拉通知图标自动设置回 APP 图标的方法 */
|
||||
NotificationHeaderViewWrapperInjectorClass.hook {
|
||||
injectMember {
|
||||
NotificationHeaderViewWrapperInjectorClass?.apply {
|
||||
method {
|
||||
name = "setAppIcon"
|
||||
param(ContextClass, ImageViewClass, ExpandedNotificationClass)
|
||||
}.remedys {
|
||||
method {
|
||||
name = "setAppIcon"
|
||||
param(ContextClass, ImageViewClass, ExpandedNotificationClass)
|
||||
}.remedys {
|
||||
method {
|
||||
name = "setAppIcon"
|
||||
param(ImageViewClass, ExpandedNotificationClass)
|
||||
}
|
||||
}
|
||||
intercept()
|
||||
}.ignoredNoSuchMemberFailure()
|
||||
injectMember {
|
||||
method {
|
||||
name = "resetIconBgAndPaddings"
|
||||
param(ImageViewClass, ExpandedNotificationClass)
|
||||
}
|
||||
intercept()
|
||||
}.ignoredNoSuchMemberFailure()
|
||||
}.ignoredHookClassNotFoundFailure()
|
||||
}.ignored().hook().intercept()
|
||||
method {
|
||||
name = "resetIconBgAndPaddings"
|
||||
param(ImageViewClass, ExpandedNotificationClass)
|
||||
}.ignored().hook().intercept()
|
||||
}
|
||||
/**
|
||||
* 尝试修复从 MIUI 14 开始出现的一个崩溃问题
|
||||
* 由于模块注入推送的通知没有对 [StatusBarNotification] 设置 TAG 会导致其空指针
|
||||
* 直接替换掉它自己的实现方法 - 使用自己的方式实现这个功能
|
||||
* ```java
|
||||
* public final boolean isUnimportantEntry(NotificationEntry notificationEntry) {
|
||||
* return notificationEntry.getSbn().getPackageName().equals("com.android.systemui") &&
|
||||
* notificationEntry.getSbn().getTag().equals("UNIMPORTANT");
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
NotificationStatClass?.method {
|
||||
name = "isUnimportantEntry"
|
||||
paramCount = 1
|
||||
}?.ignored()?.hook()?.replaceAny {
|
||||
args().first().current(ignored = true).method {
|
||||
name = "getSbn"
|
||||
superClass()
|
||||
}.invoke<StatusBarNotification>()?.let { sbn ->
|
||||
sbn.packageName == PackageName.SYSTEMUI && sbn.tag == "UNIMPORTANT"
|
||||
} ?: false
|
||||
}
|
||||
}
|
||||
}
|
@@ -18,7 +18,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/1/24.
|
||||
* This file is created by fankes on 2022/1/24.
|
||||
*/
|
||||
@file:Suppress("MemberVisibilityCanBePrivate")
|
||||
|
||||
@@ -28,7 +28,11 @@ import android.content.Context
|
||||
import android.graphics.Color
|
||||
import com.fankes.miui.notify.bean.IconDataBean
|
||||
import com.fankes.miui.notify.data.ConfigData
|
||||
import com.fankes.miui.notify.utils.factory.*
|
||||
import com.fankes.miui.notify.utils.factory.bitmap
|
||||
import com.fankes.miui.notify.utils.factory.safeOf
|
||||
import com.fankes.miui.notify.utils.factory.safeOfNan
|
||||
import com.fankes.miui.notify.utils.factory.safeOfNull
|
||||
import com.fankes.miui.notify.utils.factory.snake
|
||||
import com.highcapable.yukihookapi.hook.factory.prefs
|
||||
import com.highcapable.yukihookapi.hook.param.PackageParam
|
||||
import org.json.JSONArray
|
||||
@@ -47,7 +51,7 @@ class IconPackParams(private val context: Context? = null, private val param: Pa
|
||||
* 已存储的 JSON 数据
|
||||
* @return [String]
|
||||
*/
|
||||
internal val storageDataJson get() = (context?.prefs() ?: param?.prefs)?.direct()?.get(ConfigData.NOTIFY_ICONS_DATA)
|
||||
internal val storageDataJson get() = (context?.prefs() ?: param?.prefs)?.get(ConfigData.NOTIFY_ICONS_DATA)
|
||||
|
||||
/**
|
||||
* 获取图标数据
|
||||
@@ -135,4 +139,4 @@ class IconPackParams(private val context: Context? = null, private val param: Pa
|
||||
* @param dataJson 图标数据 JSON
|
||||
*/
|
||||
fun save(dataJson: String) = context?.prefs()?.edit { put(ConfigData.NOTIFY_ICONS_DATA, dataJson) }
|
||||
}
|
||||
}
|
@@ -18,7 +18,7 @@
|
||||
* 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.
|
||||
* This file is Modified by fankes on 2023/2/3.
|
||||
*/
|
||||
package com.fankes.miui.notify.params.factory
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/3/26.
|
||||
* This file is created by fankes on 2022/3/26.
|
||||
*/
|
||||
package com.fankes.miui.notify.service
|
||||
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* 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("SetTextI18n", "InflateParams")
|
||||
|
||||
@@ -37,7 +37,16 @@ import com.fankes.miui.notify.params.factory.isAppNotifyHookOf
|
||||
import com.fankes.miui.notify.params.factory.putAppNotifyHookAllOf
|
||||
import com.fankes.miui.notify.params.factory.putAppNotifyHookOf
|
||||
import com.fankes.miui.notify.ui.activity.base.BaseActivity
|
||||
import com.fankes.miui.notify.utils.factory.*
|
||||
import com.fankes.miui.notify.utils.factory.addOnBackPressedEvent
|
||||
import com.fankes.miui.notify.utils.factory.bindAdapter
|
||||
import com.fankes.miui.notify.utils.factory.callOnBackPressed
|
||||
import com.fankes.miui.notify.utils.factory.colorOf
|
||||
import com.fankes.miui.notify.utils.factory.copyToClipboard
|
||||
import com.fankes.miui.notify.utils.factory.navigate
|
||||
import com.fankes.miui.notify.utils.factory.openBrowser
|
||||
import com.fankes.miui.notify.utils.factory.showDialog
|
||||
import com.fankes.miui.notify.utils.factory.snake
|
||||
import com.fankes.miui.notify.utils.factory.toast
|
||||
import com.fankes.miui.notify.utils.tool.IconRuleManagerTool
|
||||
import com.fankes.miui.notify.utils.tool.SystemUITool
|
||||
import com.highcapable.yukihookapi.YukiHookAPI
|
||||
@@ -145,8 +154,8 @@ class ConfigureActivity : BaseActivity<ActivityConfigBinding>() {
|
||||
if (b) showDialog {
|
||||
title = "全部替换"
|
||||
msg = "此功能仅针对严重不遵守规范的 APP 通知图标才需要开启,例如:APP 推送通知后无法识别出现的黑白块图标。\n\n" +
|
||||
"此功能在一般情况下请保持关闭并跟随在线规则的配置,并不要随意改变此配置," +
|
||||
"开启后 APP 的通知图标可能会被规则破坏,你确定还要开启吗?"
|
||||
"此功能在一般情况下请保持关闭并跟随在线规则的配置,并不要随意改变此配置," +
|
||||
"开启后 APP 的通知图标可能会被规则破坏,你确定还要开启吗?"
|
||||
confirmButton { saveState() }
|
||||
cancelButton { btn.isChecked = btn.isChecked.not() }
|
||||
noCancelable()
|
||||
@@ -188,10 +197,10 @@ class ConfigureActivity : BaseActivity<ActivityConfigBinding>() {
|
||||
val pkgName = intent?.getStringExtra("pkgName") ?: ""
|
||||
title = "新安装应用通知图标适配"
|
||||
msg = "你已安装 $appName($pkgName)\n\n" +
|
||||
"此应用未在通知优化名单中发现适配数据,若此应用发送的通知为彩色图标," +
|
||||
"可随时点击本页面下方的“贡献通知图标优化名单”按钮提交贡献或请求适配。\n\n" +
|
||||
"若你已知晓此应用会遵守原生通知图标规范,可忽略此提示。\n\n" +
|
||||
"你可以现在立即同步适配列表,以获取最新的适配数据。"
|
||||
"此应用未在通知优化名单中发现适配数据,若此应用发送的通知为彩色图标," +
|
||||
"可随时点击本页面下方的“贡献通知图标优化名单”按钮提交贡献或请求适配。\n\n" +
|
||||
"若你已知晓此应用会遵守原生通知图标规范,可忽略此提示。\n\n" +
|
||||
"你可以现在立即同步适配列表,以获取最新的适配数据。"
|
||||
confirmButton(text = "同步列表") { onStartRefresh() }
|
||||
cancelButton(text = "复制名称+包名") { copyToClipboard(content = "$appName($pkgName)") }
|
||||
neutralButton(text = "取消")
|
||||
@@ -250,7 +259,7 @@ class ConfigureActivity : BaseActivity<ActivityConfigBinding>() {
|
||||
onChanged?.invoke()
|
||||
binding.configTitleCountText.text =
|
||||
if (filterText.isBlank()) "已适配 ${iconDatas.size} 个 APP 的通知图标"
|
||||
else "“${filterText}” 匹配到 ${iconDatas.size} 个结果"
|
||||
else "“$filterText” 匹配到 ${iconDatas.size} 个结果"
|
||||
binding.configListNoDataView.apply {
|
||||
text = if (iconAllDatas.isEmpty()) "噫,竟然什么都没有~\n请点击右上角同步按钮获取云端数据" else "噫,竟然什么都没找到~"
|
||||
isVisible = iconDatas.isEmpty()
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/1/24.
|
||||
* This file is created by fankes on 2022/1/24.
|
||||
*/
|
||||
@file:Suppress("SetTextI18n")
|
||||
|
||||
@@ -26,19 +26,36 @@ package com.fankes.miui.notify.ui.activity
|
||||
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import com.fankes.miui.notify.BuildConfig
|
||||
import com.fankes.miui.notify.R
|
||||
import com.fankes.miui.notify.const.ModuleVersion
|
||||
import com.fankes.miui.notify.data.ConfigData
|
||||
import com.fankes.miui.notify.data.factory.bind
|
||||
import com.fankes.miui.notify.databinding.ActivityMainBinding
|
||||
import com.fankes.miui.notify.databinding.DiaStatusIconCountBinding
|
||||
import com.fankes.miui.notify.params.IconPackParams
|
||||
import com.fankes.miui.notify.ui.activity.base.BaseActivity
|
||||
import com.fankes.miui.notify.utils.factory.*
|
||||
import com.fankes.miui.notify.utils.factory.androidVersionCodeName
|
||||
import com.fankes.miui.notify.utils.factory.hideOrShowLauncherIcon
|
||||
import com.fankes.miui.notify.utils.factory.isLauncherIconShowing
|
||||
import com.fankes.miui.notify.utils.factory.isLowerAndroidP
|
||||
import com.fankes.miui.notify.utils.factory.isLowerAndroidR
|
||||
import com.fankes.miui.notify.utils.factory.isMIOS
|
||||
import com.fankes.miui.notify.utils.factory.isNotMiSystem
|
||||
import com.fankes.miui.notify.utils.factory.isNotNoificationEnabled
|
||||
import com.fankes.miui.notify.utils.factory.isNotSupportMiSystemVersion
|
||||
import com.fankes.miui.notify.utils.factory.miSystemVersion
|
||||
import com.fankes.miui.notify.utils.factory.miuiVersionCode
|
||||
import com.fankes.miui.notify.utils.factory.navigate
|
||||
import com.fankes.miui.notify.utils.factory.openBrowser
|
||||
import com.fankes.miui.notify.utils.factory.openNotifySetting
|
||||
import com.fankes.miui.notify.utils.factory.showDialog
|
||||
import com.fankes.miui.notify.utils.factory.showTimePicker
|
||||
import com.fankes.miui.notify.utils.factory.snake
|
||||
import com.fankes.miui.notify.utils.factory.systemFullVersion
|
||||
import com.fankes.miui.notify.utils.tool.GithubReleaseTool
|
||||
import com.fankes.miui.notify.utils.tool.I18nWarnTool
|
||||
import com.fankes.miui.notify.utils.tool.SystemUITool
|
||||
import com.fankes.miui.notify.utils.tool.YukiPromoteTool
|
||||
import com.fankes.projectpromote.ProjectPromote
|
||||
import com.highcapable.yukihookapi.YukiHookAPI
|
||||
|
||||
class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
@@ -53,19 +70,13 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
|
||||
/** 模块是否有效 */
|
||||
internal var isModuleValied = false
|
||||
|
||||
/** 模块版本 */
|
||||
private const val moduleVersion = BuildConfig.VERSION_NAME
|
||||
|
||||
/** 预发布的版本标识 */
|
||||
private const val pendingFlag = ""
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
/** 设置可用性 */
|
||||
isActivityLive = true
|
||||
/** 检查更新 */
|
||||
GithubReleaseTool.checkingForUpdate(context = this, moduleVersion) { version, function ->
|
||||
GithubReleaseTool.checkingForUpdate(context = this, ModuleVersion.NAME) { version, function ->
|
||||
binding.mainTextReleaseVersion.apply {
|
||||
text = "点击更新 $version"
|
||||
isVisible = true
|
||||
@@ -73,11 +84,11 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
}
|
||||
}
|
||||
when {
|
||||
/** 判断是否为 MIUI 系统 */
|
||||
isNotMIUI ->
|
||||
/** 判断是否为小米系统 */
|
||||
isNotMiSystem ->
|
||||
showDialog {
|
||||
title = "不是 MIUI 系统"
|
||||
msg = "此模块专为 MIUI 系统打造,当前无法识别你的系统为 MIUI,所以模块无法工作。"
|
||||
title = "不是 MIUI 或 HyperOS 系统"
|
||||
msg = "此模块专为 MIUI、HyperOS 系统打造,当前无法识别你的系统为其中任意之一,所以模块无法工作。"
|
||||
confirmButton(text = "查看支持的模块") {
|
||||
openBrowser(url = "https://github.com/fankes/AndroidNotifyIconAdapt")
|
||||
finish()
|
||||
@@ -90,7 +101,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
showDialog {
|
||||
title = "Android 系统版本过低"
|
||||
msg = "此模块最低支持基于 Android 9 的 MIUI 系统,你的系统版本过低不再进行适配。\n\n" +
|
||||
"若有其它疑问,你可以点击下方按钮前往项目地址进行反馈。"
|
||||
"若有其它疑问,你可以点击下方按钮前往项目地址进行反馈。"
|
||||
confirmButton(text = "前往项目地址") {
|
||||
openProjectUrl()
|
||||
finish()
|
||||
@@ -98,14 +109,14 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
cancelButton(text = "退出") { finish() }
|
||||
noCancelable()
|
||||
}
|
||||
/** 判断支持的 MIUI 版本 */
|
||||
isNotSupportMiuiVersion ->
|
||||
/** 判断支持的系统版本 */
|
||||
isNotSupportMiSystemVersion ->
|
||||
showDialog {
|
||||
title = "不支持的 MIUI 版本"
|
||||
msg = (if (miuiVersion.isNotBlank())
|
||||
"此模块目前支持 MIUI 11~14 系统,你的 MIUI 版本为 ${miuiVersion},暂不支持。\n\n" +
|
||||
"如果你的 MIUI 版本识别有误,请检查是否有相关插件修改了系统版本。\n\n"
|
||||
else "无法获取 MIUI 版本,请检查你是否修改了系统参数或使用非官方系统。\n\n") + "若有其它疑问,你可以点击下方按钮前往项目地址进行反馈。"
|
||||
title = "不支持的系统版本"
|
||||
msg = (if (miSystemVersion.isNotBlank())
|
||||
"此模块目前支持 MIUI 11~14 和 HyperOS 1.0 系统,你的系统版本为 $miSystemVersion,暂不支持。\n\n" +
|
||||
"如果你的系统版本识别有误,请检查是否有相关插件修改了系统版本。\n\n"
|
||||
else "无法获取系统版本,请检查你是否修改了系统参数或使用非官方系统。\n\n") + "若有其它疑问,你可以点击下方按钮前往项目地址进行反馈。"
|
||||
confirmButton(text = "前往项目地址") {
|
||||
openProjectUrl()
|
||||
finish()
|
||||
@@ -119,7 +130,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
showDialog {
|
||||
title = "配置通知图标优化名单"
|
||||
msg = "模块需要获取在线规则以更新“通知图标优化名单”,它现在是空的,这看起来是你第一次使用模块,请首先进行配置才可以使用相关功能。\n" +
|
||||
"你可以随时在本页面下方找到“配置通知图标优化名单”手动前往。"
|
||||
"你可以随时在本页面下方找到“配置通知图标优化名单”手动前往。"
|
||||
confirmButton(text = "前往") { navigate<ConfigureActivity>() }
|
||||
cancelButton()
|
||||
noCancelable()
|
||||
@@ -136,38 +147,53 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
showDialog {
|
||||
title = "Android 版本过低"
|
||||
msg = "你当前使用的 Android 版本过低,模块的部分功能可能会发生问题," +
|
||||
"由于设备有限,无法逐一调试,若有好的建议可向我们贡献代码提交适配请求,建议在 Android 11 及以上版本中使用效果最佳。"
|
||||
"由于设备有限,无法逐一调试,若有好的建议可向我们贡献代码提交适配请求,建议在 Android 11 及以上版本中使用效果最佳。"
|
||||
confirmButton(text = "我知道了") { ConfigData.isIgnoredAndroidVersionToLow = true }
|
||||
noCancelable()
|
||||
}
|
||||
/** 推广、恰饭 */
|
||||
YukiPromoteTool.promote(context = this)
|
||||
ProjectPromote.show(activity = this, ModuleVersion.toString())
|
||||
}
|
||||
else ->
|
||||
showDialog {
|
||||
title = "模块没有激活"
|
||||
msg = "检测到模块没有激活,模块需要 Xposed 环境依赖," +
|
||||
"同时需要系统拥有 Root 权限," +
|
||||
"请自行查看本页面使用帮助与说明第二条。\n" +
|
||||
"由于需要修改系统应用达到效果,模块不支持太极阴、应用转生。"
|
||||
"同时需要系统拥有 Root 权限," +
|
||||
"请自行查看本页面使用帮助与说明第二条。\n" +
|
||||
"由于需要修改系统应用达到效果,模块不支持太极阴、应用转生。"
|
||||
confirmButton(text = "我知道了")
|
||||
noCancelable()
|
||||
}
|
||||
}
|
||||
I18nWarnTool.checkingOrShowing(context = this)
|
||||
binding.mainTextVersion.text = "模块版本:$moduleVersion $pendingFlag"
|
||||
binding.mainTextMiuiVersion.text = "系统版本:[$androidVersionCodeName] $miuiFullVersion"
|
||||
if (isMIOS) binding.mainTitle.text = binding.mainTitle.text.toString().replace("MIUI", "HyperOS")
|
||||
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}。
|
||||
|
||||
它是由代码提交后自动触发并构建、自动编译发布的,并未经任何稳定性测试,使用风险自负。
|
||||
""".trimIndent()
|
||||
confirmButton(text = "我知道了")
|
||||
noCancelable()
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.mainTextMiuiVersion.text = "系统版本:[$androidVersionCodeName] $systemFullVersion"
|
||||
binding.warnSCountDisTip.isGone = miuiVersionCode > 12.5
|
||||
binding.warnMiuiNotifyStyleTip.isGone = miuiVersionCode > 11
|
||||
binding.statusIconCountText.text = ConfigData.liftedStatusIconCount.toString()
|
||||
binding.notifyIconAutoSyncText.text = ConfigData.notifyIconFixAutoTime
|
||||
binding.moduleEnableSwitch.bind(ConfigData.ENABLE_MODULE) {
|
||||
onInitialize {
|
||||
binding.moduleEnableLogSwitch.isVisible = it
|
||||
binding.moduleEnableLogText.isVisible = it
|
||||
binding.modulePrefsCacheEnableSwitch.isVisible = it
|
||||
binding.modulePrefsCacheEnableText.isVisible = it
|
||||
binding.expAllDebugLogButton.isVisible = it && ConfigData.isEnableModuleLog
|
||||
binding.moduleEnableLogItem.isVisible = it
|
||||
binding.colorIconHookItem.isVisible = it
|
||||
binding.statusIconCountItem.isVisible = isLowerAndroidR.not() && it
|
||||
binding.notifyStyleConfigItem.isVisible = it
|
||||
@@ -179,11 +205,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
SystemUITool.showNeedRestartSnake(context = this@MainActivity)
|
||||
}
|
||||
}
|
||||
binding.modulePrefsCacheEnableSwitch.bind(ConfigData.ENABLE_PREFS_CACHE) {
|
||||
onChanged { SystemUITool.showNeedRestartSnake(context = this@MainActivity) }
|
||||
}
|
||||
binding.moduleEnableLogSwitch.bind(ConfigData.ENABLE_MODULE_LOG) {
|
||||
onInitialize { binding.expAllDebugLogButton.isVisible = it && ConfigData.isEnableModule }
|
||||
onInitialize { binding.expAllDebugLogButton.isVisible = it }
|
||||
onChanged {
|
||||
reinitialize()
|
||||
SystemUITool.refreshSystemUI(context = this@MainActivity, isRefreshCacheOnly = true)
|
||||
@@ -207,14 +230,17 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
if (it) showDialog {
|
||||
title = "启用兼容模式"
|
||||
msg = "启用兼容模式可修复部分系统版本可能出现无法判定通知图标反色的问题," +
|
||||
"但是这也可能会导致新的问题,一般情况下不建议开启,确定要继续吗?\n\n" +
|
||||
"如果系统界面刷新后通知图标颜色发生错误,请尝试重启一次系统界面。"
|
||||
"但是这也可能会导致新的问题,一般情况下不建议开启,确定要继续吗?\n\n" +
|
||||
"如果系统界面刷新后通知图标颜色发生错误,请尝试重启一次系统界面。"
|
||||
confirmButton { applyChangesAndRefresh() }
|
||||
cancelButton { cancelChanges() }
|
||||
noCancelable()
|
||||
} else applyChangesAndRefresh()
|
||||
}
|
||||
}
|
||||
binding.miuiNotifyIconReplacementSwitch.bind(ConfigData.ENABLE_REPLACE_MIUI_STYLE_NOTIFY_ICON) {
|
||||
onChanged { SystemUITool.refreshSystemUI(context = this@MainActivity) }
|
||||
}
|
||||
binding.notifyIconForceSystemColorSwitch.bind(ConfigData.ENABLE_NOTIFY_ICON_FORCE_SYSTEM_COLOR) {
|
||||
isAutoApplyChanges = false
|
||||
onChanged {
|
||||
@@ -226,7 +252,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
if (it) showDialog {
|
||||
title = "破坏性功能警告"
|
||||
msg = "开启这个功能后,任何通知栏中的通知图标都会忽略图标自身的着色属性,全部使用系统默认颜色 (系统提供的统一色调) 着色。\n\n" +
|
||||
"此功能仅面向一些追求图标美观度的用户,我们不推荐开启这个功能,且发生任何 BUG 都不会去修复,仍然继续开启吗?"
|
||||
"此功能仅面向一些追求图标美观度的用户,我们不推荐开启这个功能,且发生任何 BUG 都不会去修复,仍然继续开启吗?"
|
||||
confirmButton { applyChangesAndRefresh() }
|
||||
cancelButton { cancelChanges() }
|
||||
noCancelable()
|
||||
@@ -240,6 +266,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
binding.notifyIconCustomCornerItem,
|
||||
binding.notifyIconForceSystemColorItem
|
||||
).forEach { e -> e.isVisible = isLowerAndroidR.not() && it.not() }
|
||||
binding.miuiNotifyIconReplacementItem.isVisible = it.not()
|
||||
}
|
||||
onChanged {
|
||||
/** 应用更改并刷新系统界面 */
|
||||
@@ -250,8 +277,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
if (it) showDialog {
|
||||
title = "破坏性功能警告"
|
||||
msg = "开启这个功能后,任何通知栏中的通知图标都会被强制替换为当前推送通知的 APP 的图标," +
|
||||
"某些系统级别的 APP 通知图标可能会显示异常或发生图标丢失。\n\n" +
|
||||
"此功能仅面向一些追求图标美观度的用户,我们不推荐开启这个功能,且发生任何 BUG 都不会去修复,仍然继续开启吗?"
|
||||
"某些系统级别的 APP 通知图标可能会显示异常或发生图标丢失。\n\n" +
|
||||
"此功能仅面向一些追求图标美观度的用户,我们不推荐开启这个功能,且发生任何 BUG 都不会去修复,仍然继续开启吗?"
|
||||
confirmButton { applyChangesAndRefresh() }
|
||||
cancelButton { cancelChanges() }
|
||||
noCancelable()
|
||||
@@ -281,9 +308,9 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
if (it) showDialog {
|
||||
title = "注意"
|
||||
msg = "开启这个功能后,当发现未适配的彩色通知图标时," +
|
||||
"状态栏中显示的通知图标将会使用预置的占位符图标进行修补," +
|
||||
"通知栏中显示的通知图标保持原始图标不变。\n\n" +
|
||||
"此功能的作用仅为临时修复破坏规范的通知图标,仍然继续开启吗?"
|
||||
"状态栏中显示的通知图标将会使用预置的占位符图标进行修补," +
|
||||
"通知栏中显示的通知图标保持原始图标不变。\n\n" +
|
||||
"此功能的作用仅为临时修复破坏规范的通知图标,仍然继续开启吗?"
|
||||
confirmButton { applyChangesAndRefresh() }
|
||||
cancelButton { cancelChanges() }
|
||||
noCancelable()
|
||||
@@ -328,7 +355,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
confirmButton {
|
||||
when {
|
||||
(runCatching { binding.iconCountEdit.text.toString().toInt() }.getOrNull() ?: -1)
|
||||
!in 0..100 -> snake(msg = "请输入有效数值")
|
||||
!in 0..100 -> snake(msg = "请输入有效数值")
|
||||
binding.iconCountEdit.text.toString().isNotBlank() -> runCatching {
|
||||
ConfigData.liftedStatusIconCount = binding.iconCountEdit.text.toString().trim().toInt()
|
||||
this@MainActivity.binding.statusIconCountText.text = ConfigData.liftedStatusIconCount.toString()
|
||||
@@ -346,11 +373,11 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
showDialog {
|
||||
title = "每天 $it 自动更新"
|
||||
msg = "设置保存后将在每天 $it 自动同步名单到最新云端数据,若数据已是最新则不会显示任何提示,否则会发送一条通知。\n\n" +
|
||||
"请确保:\n\n" +
|
||||
"1.模块没有被禁止前台以及后台联网权限\n" +
|
||||
"2.模块没有被禁止被其它 APP 关联唤醒\n" +
|
||||
"3.模块的系统通知权限已开启\n\n" +
|
||||
"模块无需保持在后台运行,到达同步时间后会自动启动,如果到达时间后模块正在运行则会自动取消本次计划任务。"
|
||||
"请确保:\n\n" +
|
||||
"1.模块没有被禁止前台以及后台联网权限\n" +
|
||||
"2.模块没有被禁止被其它 APP 关联唤醒\n" +
|
||||
"3.模块的系统通知权限已开启\n\n" +
|
||||
"模块无需保持在后台运行,到达同步时间后会自动启动,如果到达时间后模块正在运行则会自动取消本次计划任务。"
|
||||
confirmButton(text = "保存设置") {
|
||||
ConfigData.notifyIconFixAutoTime = it
|
||||
this@MainActivity.binding.notifyIconAutoSyncText.text = it
|
||||
@@ -389,7 +416,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
binding.mainLinStatus.setBackgroundResource(
|
||||
when {
|
||||
YukiHookAPI.Status.isXposedModuleActive &&
|
||||
(isModuleRegular.not() || isModuleValied.not() || ConfigData.isEnableModule.not()) -> R.drawable.bg_yellow_round
|
||||
(isModuleRegular.not() || isModuleValied.not() || ConfigData.isEnableModule.not()) -> R.drawable.bg_yellow_round
|
||||
YukiHookAPI.Status.isXposedModuleActive -> R.drawable.bg_green_round
|
||||
else -> R.drawable.bg_dark_round
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/3/26.
|
||||
* This file is created by fankes on 2022/3/26.
|
||||
*/
|
||||
@file:Suppress("DEPRECATION")
|
||||
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* 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")
|
||||
|
||||
|
@@ -18,7 +18,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")
|
||||
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/10/6.
|
||||
* This file is created by fankes on 2022/10/6.
|
||||
*/
|
||||
package com.fankes.miui.notify.utils.factory
|
||||
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/6/3.
|
||||
* This file is created by fankes on 2022/6/3.
|
||||
*/
|
||||
package com.fankes.miui.notify.utils.factory
|
||||
|
||||
|
@@ -18,9 +18,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.miui.notify.utils.factory
|
||||
|
||||
@@ -38,7 +38,6 @@ import androidx.viewbinding.ViewBinding
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
import com.highcapable.yukihookapi.YukiHookAPI
|
||||
import com.highcapable.yukihookapi.annotation.CauseProblemsApi
|
||||
import com.highcapable.yukihookapi.hook.factory.method
|
||||
import com.highcapable.yukihookapi.hook.type.android.LayoutInflaterClass
|
||||
|
||||
@@ -181,7 +180,6 @@ class DialogBuilder<VB : ViewBinding>(val context: Context, private val bindingC
|
||||
fun cancel() = dialogInstance?.cancel()
|
||||
|
||||
/** 显示对话框 */
|
||||
@CauseProblemsApi
|
||||
fun show() = runInSafe {
|
||||
/** 若当前自定义 View 的对话框没有调用 [binding] 将会对其手动调用一次以确保显示布局 */
|
||||
if (bindingClass != null) binding
|
||||
|
@@ -18,13 +18,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")
|
||||
|
||||
package com.fankes.miui.notify.utils.factory
|
||||
|
||||
import com.highcapable.yukihookapi.hook.log.loggerE
|
||||
import com.highcapable.yukihookapi.hook.log.YLog
|
||||
|
||||
/**
|
||||
* 忽略异常返回值
|
||||
@@ -79,5 +79,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) }
|
||||
}
|
@@ -18,24 +18,37 @@
|
||||
* 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", "ObsoleteSdkInt")
|
||||
|
||||
package com.fankes.miui.notify.utils.factory
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.Notification
|
||||
import android.app.Service
|
||||
import android.app.WallpaperManager
|
||||
import android.content.*
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.PackageManager.PackageInfoFlags
|
||||
import android.content.res.Configuration
|
||||
import android.content.res.Resources
|
||||
import android.graphics.*
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.PorterDuffXfermode
|
||||
import android.graphics.Rect
|
||||
import android.graphics.RectF
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.Uri
|
||||
@@ -50,17 +63,20 @@ import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.core.content.pm.PackageInfoCompat
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import com.fankes.miui.notify.BuildConfig
|
||||
import com.fankes.miui.notify.wrapper.BuildConfigWrapper
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.highcapable.yukihookapi.hook.factory.hasClass
|
||||
import com.highcapable.yukihookapi.hook.factory.method
|
||||
import com.highcapable.yukihookapi.hook.factory.toClassOrNull
|
||||
import com.highcapable.yukihookapi.hook.log.YLog
|
||||
import com.highcapable.yukihookapi.hook.type.java.StringClass
|
||||
import com.highcapable.yukihookapi.hook.xposed.application.ModuleApplication.Companion.appContext
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import java.util.Calendar
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* 系统深色模式是否开启
|
||||
@@ -86,17 +102,23 @@ val Context.isSystemInDarkMode get() = (resources.configuration.uiMode and Confi
|
||||
*/
|
||||
inline val Context.isNotSystemInDarkMode get() = !isSystemInDarkMode
|
||||
|
||||
/**
|
||||
* 系统版本是否高于或等于 Android 14
|
||||
* @return [Boolean] 是否符合条件
|
||||
*/
|
||||
inline val isUpperOfAndroidU get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
|
||||
|
||||
/**
|
||||
* 系统版本是否高于或等于 Android 13
|
||||
* @return [Boolean] 是否符合条件
|
||||
*/
|
||||
inline val isUpperOfAndroidT get() = Build.VERSION.SDK_INT > Build.VERSION_CODES.S
|
||||
inline val isUpperOfAndroidT get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
|
||||
|
||||
/**
|
||||
* 系统版本是否高于或等于 Android 12
|
||||
* @return [Boolean] 是否符合条件
|
||||
*/
|
||||
inline val isUpperOfAndroidS get() = Build.VERSION.SDK_INT > Build.VERSION_CODES.R
|
||||
inline val isUpperOfAndroidS get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||
|
||||
/**
|
||||
* 系统版本是否低于 Android 9
|
||||
@@ -110,12 +132,30 @@ inline val isLowerAndroidP get() = Build.VERSION.SDK_INT < Build.VERSION_CODES.P
|
||||
*/
|
||||
inline val isLowerAndroidR get() = Build.VERSION.SDK_INT < Build.VERSION_CODES.R
|
||||
|
||||
/**
|
||||
* 当前设备是否是 MIUI、HyperOS 定制 Android 系统
|
||||
* @return [Boolean] 是否符合条件
|
||||
*/
|
||||
val isMiSystem get() = isMIUI || isMIOS
|
||||
|
||||
/**
|
||||
* 当前设备是否不是 MIUI、HyperOS 定制 Android 系统
|
||||
* @return [Boolean] 是否符合条件
|
||||
*/
|
||||
val isNotMiSystem get() = !isMiSystem
|
||||
|
||||
/**
|
||||
* 当前设备是否是 MIUI 定制 Android 系统
|
||||
* @return [Boolean] 是否符合条件
|
||||
*/
|
||||
val isMIUI by lazy { "android.miui.R".hasClass() }
|
||||
|
||||
/**
|
||||
* 当前设备是否是 HyperOS 定制 Android 系统
|
||||
* @return [Boolean] 是否符合条件
|
||||
*/
|
||||
val isMIOS get() = isMIUI && miuiVersion == "816"
|
||||
|
||||
/**
|
||||
* 当前设备是否不是 MIUI 定制 Android 系统
|
||||
* @return [Boolean] 是否符合条件
|
||||
@@ -123,20 +163,33 @@ val isMIUI by lazy { "android.miui.R".hasClass() }
|
||||
inline val isNotMIUI get() = !isMIUI
|
||||
|
||||
/**
|
||||
* 是否为支持的 MIUI 版本
|
||||
* 当前设备是否不是 HyperOS 定制 Android 系统
|
||||
* @return [Boolean] 是否符合条件
|
||||
*/
|
||||
inline val isNotMIOS get() = !isMIOS
|
||||
|
||||
/**
|
||||
* 是否为支持的 MIUI、HyperOS 版本
|
||||
* @return [Boolean]
|
||||
*/
|
||||
val isSupportMiuiVersion
|
||||
get() = when (miuiVersion) {
|
||||
"11", "12", "12.5", "13", "14" -> true
|
||||
val isSupportMiSystemVersion
|
||||
get() = when {
|
||||
isMIOS -> when (miosVersion) {
|
||||
"1.0" -> true
|
||||
else -> false
|
||||
}
|
||||
isMIUI -> when (miuiVersion) {
|
||||
"11", "12", "12.5", "13", "14" -> true
|
||||
else -> false
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否不为支持的 MIUI 版本
|
||||
* 是否不为支持的 MIUI、HyperOS 版本
|
||||
* @return [Boolean]
|
||||
*/
|
||||
inline val isNotSupportMiuiVersion get() = !isSupportMiuiVersion
|
||||
inline val isNotSupportMiSystemVersion get() = !isSupportMiSystemVersion
|
||||
|
||||
/**
|
||||
* 获取 Android 版本代号
|
||||
@@ -144,6 +197,7 @@ inline val isNotSupportMiuiVersion get() = !isSupportMiuiVersion
|
||||
*/
|
||||
val androidVersionCodeName
|
||||
get() = when (Build.VERSION.SDK_INT) {
|
||||
34 -> "U"
|
||||
33 -> "T"
|
||||
32 -> "S_V2"
|
||||
31 -> "S"
|
||||
@@ -157,9 +211,31 @@ val androidVersionCodeName
|
||||
23 -> "M"
|
||||
22 -> "L_MR1"
|
||||
21 -> "L"
|
||||
else -> "?"
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 MIUI、HyperOS 版本
|
||||
* @return [String]
|
||||
*/
|
||||
val miSystemVersion
|
||||
get() = when {
|
||||
isMIOS -> miosVersion
|
||||
isMIUI -> miuiVersion
|
||||
else -> ""
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 MIUI、HyperOS 版本号
|
||||
* @return [Float]
|
||||
*/
|
||||
val miSystemVersionCode
|
||||
get() = when {
|
||||
isMIOS -> miosVersionCode
|
||||
isMIUI -> miuiVersionCode
|
||||
else -> 0f
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 MIUI 版本
|
||||
* @return [String]
|
||||
@@ -178,11 +254,28 @@ val miuiVersion
|
||||
}.trim()
|
||||
else ""
|
||||
|
||||
/**
|
||||
* 获取 HyperOS 版本
|
||||
* @return [String]
|
||||
*/
|
||||
val miosVersion
|
||||
get() = if (isMIOS)
|
||||
findPropString("ro.mi.os.version.name").let {
|
||||
if (it.startsWith("OS")) it.replaceFirst("OS", "") else it
|
||||
}.trim()
|
||||
else ""
|
||||
|
||||
/**
|
||||
* 获取 MIUI 版本号
|
||||
* @return [Float]
|
||||
*/
|
||||
val miuiVersionCode get() = safeOf(default = 0f) { miuiVersion.toFloat() }
|
||||
val miuiVersionCode get() = miuiVersion.toFloatOrNull() ?: 0f
|
||||
|
||||
/**
|
||||
* 获取 HyperOS 版本号
|
||||
* @return [Float]
|
||||
*/
|
||||
val miosVersionCode get() = findPropString("ro.mi.os.version.code").toFloatOrNull() ?: 0f
|
||||
|
||||
/**
|
||||
* 获取 MIUI 次版本号
|
||||
@@ -191,18 +284,35 @@ val miuiVersionCode get() = safeOf(default = 0f) { miuiVersion.toFloat() }
|
||||
val miuiIncrementalVersion get() = findPropString("ro.system.build.version.incremental").trim()
|
||||
|
||||
/**
|
||||
* 获取 MIUI 完全版本
|
||||
* 获取 HyperOS 次版本号
|
||||
* @return [String]
|
||||
*/
|
||||
val miuiFullVersion
|
||||
get() = if (isMIUI) miuiIncrementalVersion.let {
|
||||
if (it.lowercase().endsWith(".dev").not() && it.lowercase().any { e -> e.code in 97..122 })
|
||||
"$it 稳定版"
|
||||
else when {
|
||||
it.lowercase().endsWith(".dev") -> "$it 开发版"
|
||||
else -> "V$miuiVersion $it 开发版"
|
||||
val miosIncrementalVersion get() = findPropString("ro.mi.os.version.incremental").trim()
|
||||
|
||||
/**
|
||||
* 获取 MIUI、HyperOS 完全版本
|
||||
* @return [String]
|
||||
*/
|
||||
val systemFullVersion
|
||||
get() = when {
|
||||
isMIOS -> "HyperOS " + miosIncrementalVersion.let {
|
||||
if (it.lowercase().endsWith(".dev").not() && it.lowercase().any { e -> e.code in 97..122 })
|
||||
"${it.replaceFirst("OS", "")} 稳定版"
|
||||
else when {
|
||||
it.lowercase().endsWith(".dev") -> "${it.replaceFirst("OS", "")} 开发版"
|
||||
else -> "$miosVersion $it 开发版"
|
||||
}
|
||||
}
|
||||
} else "不是 MIUI 系统"
|
||||
isMIUI -> miuiIncrementalVersion.let {
|
||||
if (it.lowercase().endsWith(".dev").not() && it.lowercase().any { e -> e.code in 97..122 })
|
||||
"$it 稳定版"
|
||||
else when {
|
||||
it.lowercase().endsWith(".dev") -> "$it 开发版"
|
||||
else -> "V$miuiVersion $it 开发版"
|
||||
}
|
||||
}
|
||||
else -> "不是 MIUI 或 HyperOS 系统"
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 [Drawable]
|
||||
@@ -225,7 +335,7 @@ fun Resources.colorOf(@ColorRes resId: Int) = ResourcesCompat.getColor(this, res
|
||||
* @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())
|
||||
@@ -350,6 +460,7 @@ fun Number.dpFloat(context: Context) = toFloat() * context.resources.displayMetr
|
||||
* @return [Int] Android < 12 返回 [wallpaperColor]
|
||||
*/
|
||||
val Context.systemAccentColor
|
||||
@SuppressLint("InlinedApi")
|
||||
get() = safeOf(wallpaperColor) {
|
||||
if (isUpperOfAndroidS) resources.colorOf(android.R.color.system_accent1_600) else wallpaperColor
|
||||
}
|
||||
@@ -460,7 +571,10 @@ fun findPropString(key: String, default: String = "") = safeOf(default) {
|
||||
* 是否有 Root 权限
|
||||
* @return [Boolean]
|
||||
*/
|
||||
val isRootAccess get() = safeOfFalse { Shell.rootAccess() }
|
||||
val isRootAccess get() = safeOfFalse {
|
||||
@Suppress("DEPRECATION")
|
||||
Shell.rootAccess()
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行命令
|
||||
@@ -469,6 +583,7 @@ val isRootAccess get() = safeOfFalse { Shell.rootAccess() }
|
||||
* @return [String] 执行结果
|
||||
*/
|
||||
fun execShell(cmd: String, isSu: Boolean = true) = safeOfNothing {
|
||||
@Suppress("DEPRECATION")
|
||||
(if (isSu) Shell.su(cmd) else Shell.sh(cmd)).exec().out.let {
|
||||
if (it.isNotEmpty()) it[0].trim() else ""
|
||||
}
|
||||
@@ -478,7 +593,11 @@ fun execShell(cmd: String, isSu: Boolean = true) = safeOfNothing {
|
||||
* 弹出 [Toast]
|
||||
* @param msg 提示内容
|
||||
*/
|
||||
fun toast(msg: String) = Toast.makeText(appContext, msg, Toast.LENGTH_SHORT).show()
|
||||
fun toast(msg: String) {
|
||||
runCatching {
|
||||
Toast.makeText(appContext, msg, Toast.LENGTH_SHORT).show()
|
||||
}.onFailure { YLog.warn(msg) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到指定页面
|
||||
@@ -587,7 +706,7 @@ fun Any?.delayedRun(ms: Long = 150, it: () -> Unit) = runInSafe {
|
||||
*/
|
||||
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
|
||||
)
|
||||
@@ -599,5 +718,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
|
@@ -18,7 +18,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2023/4/17.
|
||||
* This file is created by fankes on 2023/4/17.
|
||||
*/
|
||||
package com.fankes.miui.notify.utils.tool
|
||||
|
||||
@@ -32,9 +32,9 @@ import android.content.Intent
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Build
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import com.fankes.miui.notify.BuildConfig
|
||||
import com.fankes.miui.notify.R
|
||||
import com.fankes.miui.notify.utils.factory.appIconOf
|
||||
import com.fankes.miui.notify.wrapper.BuildConfigWrapper
|
||||
|
||||
/**
|
||||
* 模块更新激活提醒通知工具类
|
||||
@@ -42,7 +42,7 @@ import com.fankes.miui.notify.utils.factory.appIconOf
|
||||
object ActivationPromptTool {
|
||||
|
||||
/** 当前模块的包名 */
|
||||
private const val MODULE_PACKAGE_NAME = BuildConfig.APPLICATION_ID
|
||||
private const val MODULE_PACKAGE_NAME = BuildConfigWrapper.APPLICATION_ID
|
||||
|
||||
/** 推送通知的渠道名称 */
|
||||
private const val NOTIFY_CHANNEL = "activationPromptId"
|
||||
@@ -53,7 +53,7 @@ object ActivationPromptTool {
|
||||
* @param packageName 当前 APP 包名
|
||||
*/
|
||||
fun prompt(context: Context, packageName: String) {
|
||||
if (packageName != BuildConfig.APPLICATION_ID) return
|
||||
if (packageName != BuildConfigWrapper.APPLICATION_ID) return
|
||||
context.getSystemService(NotificationManager::class.java)?.apply {
|
||||
createNotificationChannel(
|
||||
NotificationChannel(
|
||||
@@ -73,7 +73,7 @@ object ActivationPromptTool {
|
||||
PendingIntent.getActivity(
|
||||
context, packageName.hashCode(),
|
||||
Intent().apply {
|
||||
component = ComponentName(MODULE_PACKAGE_NAME, "${MODULE_PACKAGE_NAME}.ui.activity.MainActivity")
|
||||
component = ComponentName(MODULE_PACKAGE_NAME, "$MODULE_PACKAGE_NAME.ui.activity.MainActivity")
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
}, if (Build.VERSION.SDK_INT < 31) PendingIntent.FLAG_UPDATE_CURRENT else PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
@@ -18,11 +18,15 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/2/19.
|
||||
* This file is created by fankes on 2022/2/19.
|
||||
*/
|
||||
package com.fankes.miui.notify.utils.tool
|
||||
|
||||
import android.graphics.*
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Matrix
|
||||
import android.graphics.Paint
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.drawable.AnimationDrawable
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
|
@@ -18,7 +18,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.
|
||||
*/
|
||||
package com.fankes.miui.notify.utils.tool
|
||||
|
||||
@@ -27,12 +27,20 @@ import android.content.Context
|
||||
import android.icu.text.SimpleDateFormat
|
||||
import android.icu.util.Calendar
|
||||
import android.icu.util.TimeZone
|
||||
import com.fankes.miui.notify.utils.factory.*
|
||||
import okhttp3.*
|
||||
import com.fankes.miui.notify.utils.factory.isNetWorkSuccess
|
||||
import com.fankes.miui.notify.utils.factory.openBrowser
|
||||
import com.fankes.miui.notify.utils.factory.openSelfSetting
|
||||
import com.fankes.miui.notify.utils.factory.runInSafe
|
||||
import com.fankes.miui.notify.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 最新版本工具类
|
||||
@@ -71,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()
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2023/2/3.
|
||||
* This file is created by fankes on 2023/2/3.
|
||||
*/
|
||||
package com.fankes.miui.notify.utils.tool
|
||||
|
||||
@@ -26,7 +26,7 @@ import android.content.Context
|
||||
import com.fankes.miui.notify.utils.factory.showDialog
|
||||
import com.highcapable.yukihookapi.hook.factory.prefs
|
||||
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
|
||||
import java.util.*
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* I18n 适配警告提示工具类
|
||||
@@ -46,8 +46,8 @@ object I18nWarnTool {
|
||||
context.showDialog {
|
||||
title = "Notice of I18n Support"
|
||||
msg = "This Xposed Module is only for Chinese and the Chinese region.\n\n" +
|
||||
"Currently, there will be no internationalization adaptation.\n\n" +
|
||||
"There may be plans for internationalization adaptation in the future, so stay tuned."
|
||||
"Currently, there will be no internationalization adaptation.\n\n" +
|
||||
"There may be plans for internationalization adaptation in the future, so stay tuned."
|
||||
confirmButton(text = "Got It") { saveReaded() }
|
||||
noCancelable()
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/3/21.
|
||||
* This file is created by fankes on 2022/3/21.
|
||||
*/
|
||||
package com.fankes.miui.notify.utils.tool
|
||||
|
||||
@@ -32,10 +32,15 @@ import android.content.Intent
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Build
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import com.fankes.miui.notify.BuildConfig
|
||||
import com.fankes.miui.notify.R
|
||||
import com.fankes.miui.notify.hook.HookEntry
|
||||
import com.fankes.miui.notify.utils.factory.*
|
||||
import com.fankes.miui.notify.utils.factory.appIconOf
|
||||
import com.fankes.miui.notify.utils.factory.appNameOf
|
||||
import com.fankes.miui.notify.utils.factory.isDebugApp
|
||||
import com.fankes.miui.notify.utils.factory.isSystemApp
|
||||
import com.fankes.miui.notify.utils.factory.runInSafe
|
||||
import com.fankes.miui.notify.utils.factory.stampToDate
|
||||
import com.fankes.miui.notify.wrapper.BuildConfigWrapper
|
||||
|
||||
/**
|
||||
* 通知图标适配推送通知类
|
||||
@@ -45,7 +50,7 @@ import com.fankes.miui.notify.utils.factory.*
|
||||
object IconAdaptationTool {
|
||||
|
||||
/** 当前模块的包名 */
|
||||
private const val MODULE_PACKAGE_NAME = BuildConfig.APPLICATION_ID
|
||||
private const val MODULE_PACKAGE_NAME = BuildConfigWrapper.APPLICATION_ID
|
||||
|
||||
/** 推送通知的渠道名称 */
|
||||
private const val NOTIFY_CHANNEL = "notifyRuleSupportId"
|
||||
@@ -82,7 +87,7 @@ object IconAdaptationTool {
|
||||
Intent().apply {
|
||||
component = ComponentName(
|
||||
MODULE_PACKAGE_NAME,
|
||||
"${MODULE_PACKAGE_NAME}.ui.activity.ConfigureActivity"
|
||||
"$MODULE_PACKAGE_NAME.ui.activity.ConfigureActivity"
|
||||
)
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
}.apply {
|
||||
@@ -117,7 +122,7 @@ object IconAdaptationTool {
|
||||
outTimeLimits.add(nowTime)
|
||||
context.startActivity(
|
||||
Intent().apply {
|
||||
component = ComponentName(MODULE_PACKAGE_NAME, "${MODULE_PACKAGE_NAME}.ui.activity.auto.NotifyIconRuleUpdateActivity")
|
||||
component = ComponentName(MODULE_PACKAGE_NAME, "$MODULE_PACKAGE_NAME.ui.activity.auto.NotifyIconRuleUpdateActivity")
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
}
|
||||
)
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/2/25.
|
||||
* This file is created by fankes on 2022/2/25.
|
||||
*/
|
||||
@file:Suppress("TrustAllX509TrustManager", "CustomX509TrustManager", "IMPLICIT_CAST_TO_ANY")
|
||||
|
||||
@@ -45,13 +45,25 @@ import com.fankes.miui.notify.databinding.DiaSourceFromBinding
|
||||
import com.fankes.miui.notify.databinding.DiaSourceFromStringBinding
|
||||
import com.fankes.miui.notify.params.IconPackParams
|
||||
import com.fankes.miui.notify.ui.activity.ConfigureActivity
|
||||
import com.fankes.miui.notify.utils.factory.*
|
||||
import com.highcapable.yukihookapi.hook.log.loggerD
|
||||
import okhttp3.*
|
||||
import com.fankes.miui.notify.utils.factory.delayedRun
|
||||
import com.fankes.miui.notify.utils.factory.openBrowser
|
||||
import com.fankes.miui.notify.utils.factory.safeOfNull
|
||||
import com.fankes.miui.notify.utils.factory.showDialog
|
||||
import com.fankes.miui.notify.utils.factory.snake
|
||||
import com.highcapable.yukihookapi.hook.log.YLog
|
||||
import okhttp3.Call
|
||||
import okhttp3.Callback
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import java.io.IOException
|
||||
import java.security.SecureRandom
|
||||
import java.security.cert.X509Certificate
|
||||
import javax.net.ssl.*
|
||||
import javax.net.ssl.HostnameVerifier
|
||||
import javax.net.ssl.SSLContext
|
||||
import javax.net.ssl.SSLSocketFactory
|
||||
import javax.net.ssl.TrustManager
|
||||
import javax.net.ssl.X509TrustManager
|
||||
|
||||
/**
|
||||
* 通知图标在线规则管理类
|
||||
@@ -465,11 +477,11 @@ object IconRuleManagerTool {
|
||||
get() = object : X509TrustManager {
|
||||
|
||||
override fun checkClientTrusted(chain: Array<X509Certificate?>?, authType: String?) {
|
||||
loggerD(msg = "TrustX509 --> $authType")
|
||||
YLog.debug("TrustX509 --> $authType")
|
||||
}
|
||||
|
||||
override fun checkServerTrusted(chain: Array<X509Certificate?>?, authType: String?) {
|
||||
loggerD(msg = "TrustX509 --> $authType")
|
||||
YLog.debug("TrustX509 --> $authType")
|
||||
}
|
||||
|
||||
override fun getAcceptedIssuers() = arrayOf<X509Certificate>()
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* and eula along with this software. If not, see
|
||||
* <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This file is Created by fankes on 2022/2/8.
|
||||
* This file is created by fankes on 2022/2/8.
|
||||
*/
|
||||
package com.fankes.miui.notify.utils.tool
|
||||
|
||||
@@ -32,15 +32,20 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import com.fankes.miui.notify.const.PackageName
|
||||
import com.fankes.miui.notify.data.ConfigData
|
||||
import com.fankes.miui.notify.ui.activity.MainActivity
|
||||
import com.fankes.miui.notify.utils.factory.*
|
||||
import com.fankes.miui.notify.utils.factory.delayedRun
|
||||
import com.fankes.miui.notify.utils.factory.execShell
|
||||
import com.fankes.miui.notify.utils.factory.isMIOS
|
||||
import com.fankes.miui.notify.utils.factory.showDialog
|
||||
import com.fankes.miui.notify.utils.factory.snake
|
||||
import com.fankes.miui.notify.utils.factory.systemFullVersion
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.highcapable.yukihookapi.YukiHookAPI
|
||||
import com.highcapable.yukihookapi.hook.factory.dataChannel
|
||||
import com.highcapable.yukihookapi.hook.log.YukiHookLogger
|
||||
import com.highcapable.yukihookapi.hook.log.YukiLoggerData
|
||||
import com.highcapable.yukihookapi.hook.log.YLog
|
||||
import com.highcapable.yukihookapi.hook.log.data.YLogData
|
||||
import com.highcapable.yukihookapi.hook.param.PackageParam
|
||||
import com.highcapable.yukihookapi.hook.xposed.channel.data.ChannelData
|
||||
import java.util.*
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* 系统界面工具
|
||||
@@ -51,7 +56,7 @@ object SystemUITool {
|
||||
private val CALL_MODULE_REFRESH_RESULT = ChannelData("call_module_refresh_result", false)
|
||||
|
||||
/** 当前全部调试日志 */
|
||||
private var debugLogs = ArrayList<YukiLoggerData>()
|
||||
private var debugLogs = listOf<YLogData>()
|
||||
|
||||
/** 当前启动器实例 */
|
||||
private var launcher: ActivityResultLauncher<String>? = null
|
||||
@@ -88,17 +93,17 @@ object SystemUITool {
|
||||
runCatching {
|
||||
result?.let { e ->
|
||||
val content = "" +
|
||||
"================================================================\n" +
|
||||
" Generated by MIUINativeNotifyIcon\n" +
|
||||
" Project Url: https://github.com/fankes/MIUINativeNotifyIcon\n" +
|
||||
"================================================================\n\n" +
|
||||
"[Device Brand]: ${Build.BRAND}\n" +
|
||||
"[Device Model]: ${Build.MODEL}\n" +
|
||||
"[Display]: ${Build.DISPLAY}\n" +
|
||||
"[Android Version]: ${Build.VERSION.RELEASE}\n" +
|
||||
"[Android API Level]: ${Build.VERSION.SDK_INT}\n" +
|
||||
"[MIUI Version]: $miuiFullVersion\n" +
|
||||
"[System Locale]: ${Locale.getDefault()}\n\n" + YukiHookLogger.contents(debugLogs).trim()
|
||||
"================================================================\n" +
|
||||
" Generated by MIUINativeNotifyIcon\n" +
|
||||
" Project Url: https://github.com/fankes/MIUINativeNotifyIcon\n" +
|
||||
"================================================================\n\n" +
|
||||
"[Device Brand]: ${Build.BRAND}\n" +
|
||||
"[Device Model]: ${Build.MODEL}\n" +
|
||||
"[Display]: ${Build.DISPLAY}\n" +
|
||||
"[Android Version]: ${Build.VERSION.RELEASE}\n" +
|
||||
"[Android API Level]: ${Build.VERSION.SDK_INT}\n" +
|
||||
"[${if (isMIOS) "HyperOS" else "MIUI"} Version]: $systemFullVersion\n" +
|
||||
"[System Locale]: ${Locale.getDefault()}\n\n" + YLog.contents(debugLogs).trim()
|
||||
activity.contentResolver?.openOutputStream(e)?.apply { write(content.toByteArray()) }?.close()
|
||||
activity.snake(msg = "导出完成")
|
||||
} ?: activity.snake(msg = "已取消操作")
|
||||
@@ -125,9 +130,9 @@ object SystemUITool {
|
||||
context.showDialog {
|
||||
title = "导出全部调试日志"
|
||||
msg = "调试日志中会包含当前系统推送的全部通知内容,其中可能包含你的个人隐私," +
|
||||
"你可以在导出后的日志文件中选择将这些敏感信息模糊化处理再进行共享," +
|
||||
"开发者使用并查看你导出的调试日志仅为排查与修复问题,并且在之后会及时销毁这些日志。\n\n" +
|
||||
"继续导出即代表你已阅读并知悉上述内容。"
|
||||
"你可以在导出后的日志文件中选择将这些敏感信息模糊化处理再进行共享," +
|
||||
"开发者使用并查看你导出的调试日志仅为排查与修复问题,并且在之后会及时销毁这些日志。\n\n" +
|
||||
"继续导出即代表你已阅读并知悉上述内容。"
|
||||
confirmButton(text = "继续") { doExport() }
|
||||
cancelButton()
|
||||
}
|
||||
@@ -139,8 +144,8 @@ object SystemUITool {
|
||||
showDialog {
|
||||
title = "获取 Root 权限失败"
|
||||
msg = "当前无法获取 Root 权限,请确认你的设备已经被 Root 且同意授予 Root 权限。\n" +
|
||||
"如果你正在使用 Magisk 并安装了 Shamiko 模块," +
|
||||
"请确认当前是否正处于白名单模式。 (白名单模式将导致无法申请 Root 权限)"
|
||||
"如果你正在使用 Magisk 并安装了 Shamiko 模块," +
|
||||
"请确认当前是否正处于白名单模式。 (白名单模式将导致无法申请 Root 权限)"
|
||||
confirmButton(text = "我知道了")
|
||||
}
|
||||
|
||||
@@ -160,8 +165,8 @@ object SystemUITool {
|
||||
}.onFailure {
|
||||
execShell(
|
||||
cmd = "am start -a" +
|
||||
"com.miui.notification " +
|
||||
"com.miui.notification/miui.notification.management.activity.NotificationDisplaySettingsActivity"
|
||||
"com.miui.notification " +
|
||||
"com.miui.notification/miui.notification.management.activity.NotificationDisplaySettingsActivity"
|
||||
).also {
|
||||
when {
|
||||
it.isBlank() -> context.showWhenAccessRootFail()
|
||||
@@ -181,9 +186,9 @@ object SystemUITool {
|
||||
context.showDialog {
|
||||
title = "重启系统界面"
|
||||
msg = "你确定要立即重启系统界面吗?\n\n" +
|
||||
"部分 MIUI 内测和开发版中使用了状态栏主题可能会发生主题失效的情况,这种情况请再重启一次即可。\n\n" +
|
||||
"重启过程会黑屏并等待进入锁屏重新解锁。" + (if (isDynamicAvailable)
|
||||
"\n\n你也可以选择“立即生效”来动态刷新系统界面并生效当前模块设置。" else "")
|
||||
"部分 MIUI 内测和开发版中使用了状态栏主题可能会发生主题失效的情况,这种情况请再重启一次即可。\n\n" +
|
||||
"重启过程会黑屏并等待进入锁屏重新解锁。" + (if (isDynamicAvailable)
|
||||
"\n\n你也可以选择“立即生效”来动态刷新系统界面并生效当前模块设置。" else "")
|
||||
confirmButton {
|
||||
execShell(cmd = "pgrep systemui").also { pid ->
|
||||
if (pid.isNotBlank())
|
||||
|
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
|
||||
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
* https://github.com/fankes/MIUINativeNotifyIcon
|
||||
*
|
||||
* 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.
|
||||
* <p>
|
||||
*
|
||||
* 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.miui.notify.utils.tool
|
||||
|
||||
import android.content.Context
|
||||
import com.fankes.miui.notify.BuildConfig
|
||||
import com.fankes.miui.notify.utils.factory.openBrowser
|
||||
import com.fankes.miui.notify.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,37 @@
|
||||
/*
|
||||
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
|
||||
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com)
|
||||
* https://github.com/fankes/MIUINativeNotifyIcon
|
||||
*
|
||||
* 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.
|
||||
* <p>
|
||||
*
|
||||
* 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/17.
|
||||
*/
|
||||
@file:Suppress("unused")
|
||||
|
||||
package com.fankes.miui.notify.wrapper
|
||||
|
||||
import com.fankes.miui.notify.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
|
||||
}
|
@@ -20,6 +20,7 @@
|
||||
android:paddingBottom="5dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/main_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
@@ -270,68 +271,50 @@
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<com.fankes.miui.notify.ui.widget.MaterialSwitch
|
||||
android:id="@+id/module_prefs_cache_enable_switch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="启用数据缓存"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/module_prefs_cache_enable_text"
|
||||
<LinearLayout
|
||||
android:id="@+id/module_enable_log_item"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:alpha="0.6"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:text="此选项默认开启,默认情况下模块会将数据缓存在内存中,防止每次重复读取数据造成卡顿,如果开启此选项后一段时间导致系统界面 (系统 UI) 崩溃 (内存溢出),你可以尝试关闭此选项,但是这有可能会造成在通知较多时下拉通知栏出现卡顿。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<com.fankes.miui.notify.ui.widget.MaterialSwitch
|
||||
android:id="@+id/module_enable_log_switch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:text="启用调试日志"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/exp_all_debug_log_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="13dp"
|
||||
android:layout_marginRight="13dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="@drawable/bg_button_round"
|
||||
android:gravity="center"
|
||||
android:padding="10dp"
|
||||
android:singleLine="true"
|
||||
android:text="导出全部调试日志"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/module_enable_log_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:alpha="0.6"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:text="默认情况下不建议开启此选项,仅在模块故障时开启,此时你可以发送调试日志给开发者帮助我们快速定位问题。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
<com.fankes.miui.notify.ui.widget.MaterialSwitch
|
||||
android:id="@+id/module_enable_log_switch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="启用调试日志"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/exp_all_debug_log_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="13dp"
|
||||
android:layout_marginRight="13dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="@drawable/bg_button_round"
|
||||
android:gravity="center"
|
||||
android:padding="10dp"
|
||||
android:singleLine="true"
|
||||
android:text="导出全部调试日志"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:alpha="0.6"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:text="默认情况下不建议开启此选项,仅在模块故障时开启,此时你可以发送调试日志给开发者帮助我们快速定位问题。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@@ -395,7 +378,7 @@
|
||||
android:layout_marginBottom="10dp"
|
||||
android:alpha="0.6"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:text="此选项默认开启,MIUI 默认最多只能显示 3 个图标,其余图标将变成省略号,你可以在下方自定义最多显示的图标个数,修改为 0 则只会显示省略号代表图标个数,为防止发生异常,最大限制 100 个,超出的图标可能会被信号或网速指示器遮挡。"
|
||||
android:text="此选项默认开启,MIUI 默认最多只能显示 3 个图标 (HyperOS 是 1 个),其余图标将变成省略号,你可以在下方自定义最多显示的图标个数,修改为 0 则只会显示省略号代表图标个数,为防止发生异常,最大限制 100 个,超出的图标可能会被信号或网速指示器遮挡。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
|
||||
@@ -405,7 +388,7 @@
|
||||
android:layout_marginBottom="10dp"
|
||||
android:alpha="0.6"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:text="此功能针对不同类型的异形屏设备所搭载的 MIUI 会有不同的效果,如果你正在使用的是中置挖孔屏设备,那么通知图标的个数无论多少都不会超过挖孔区域,如果是居左或居右挖孔屏设备则通知图标的个数不会超过右侧信号图标区域。"
|
||||
android:text="此功能针对不同类型的异形屏设备所搭载的 MIUI、HyperOS 会有不同的效果,如果你正在使用的是中置挖孔屏设备,那么通知图标的个数无论多少都不会超过挖孔区域,如果是居左或居右挖孔屏设备则通知图标的个数不会超过右侧信号图标区域。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold" />
|
||||
@@ -781,7 +764,7 @@
|
||||
android:gravity="center"
|
||||
android:padding="10dp"
|
||||
android:singleLine="true"
|
||||
android:text="打开 MIUI 通知显示设置"
|
||||
android:text="打开系统通知显示设置"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
|
||||
@@ -792,7 +775,7 @@
|
||||
android:layout_marginRight="15dp"
|
||||
android:alpha="0.6"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:text="点击上方按钮可以直接打开 MIUI 的通知显示设置界面,可以调整当前通知栏显示的通知样式为 MIUI 经典样式或原生样式,如果无法打开则是当前系统不支持此功能。"
|
||||
android:text="点击上方按钮可以直接打开系统的通知显示设置界面,可以调整当前通知栏显示的通知样式为 MIUI 经典样式或原生样式,如果无法打开则是当前系统不支持此功能。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
|
||||
@@ -894,12 +877,40 @@
|
||||
android:layout_marginRight="15dp"
|
||||
android:alpha="0.6"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:text="此功能仅支持 Android 12 及以上系统的 Material 3 通知图标风格以及 MIUI 后期的经典样式通知图标风格。"
|
||||
android:text="此功能仅支持 Android 12 及以上系统的 Material 3 通知图标风格以及 MIUI、HyperOS 后期的经典样式通知图标风格。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/miui_notify_icon_replacement_item"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.fankes.miui.notify.ui.widget.MaterialSwitch
|
||||
android:id="@+id/miui_notify_icon_replacement_switch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="15dp"
|
||||
android:paddingRight="15dp"
|
||||
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:paddingLeft="15dp"
|
||||
android:paddingRight="15dp"
|
||||
android:text="此选项默认开启,开启后经典 (MIUI) 样式的下拉通知栏中的通知图标将同样应用替换后的通知图标,否则将保持系统自己设置的图标。(此功能无法对所有系统版本兼容)"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/notify_icon_force_system_color_item"
|
||||
android:layout_width="match_parent"
|
||||
@@ -1403,7 +1414,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
|
||||
@@ -1441,7 +1453,7 @@
|
||||
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>
|
||||
|
BIN
app/src/main/res/mipmap-xxhdpi/bg_payment_code.jpg
Normal file
After Width: | Height: | Size: 122 KiB |
Before Width: | Height: | Size: 201 KiB |
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 : 28,
|
||||
targetSdk : 33
|
||||
]
|
||||
app = [
|
||||
versionName : '2.98',
|
||||
versionCode : 38,
|
||||
signingConfigs: [
|
||||
secretConfigsDirPath : "${projectDir.getAbsolutePath()}/.secret",
|
||||
secretConfigsFileName: "key_store_secret.json"
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
5
build.gradle.kts
Normal file
@@ -0,0 +1,5 @@
|
||||
plugins {
|
||||
autowire(libs.plugins.android.application) apply false
|
||||
autowire(libs.plugins.kotlin.android) apply false
|
||||
autowire(libs.plugins.kotlin.ksp) apply false
|
||||
}
|
@@ -1,23 +1,18 @@
|
||||
# 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
|
||||
kotlin.incremental.useClasspathSnapshot=true
|
||||
# Project Configuration
|
||||
project.name=MIUINativeNotifyIcon
|
||||
project.android.compileSdk=34
|
||||
project.android.minSdk=28
|
||||
project.android.targetSdk=34
|
||||
project.app.packageName=com.fankes.miui.notify
|
||||
project.app.versionName="2.110"
|
||||
project.app.versionCode=42
|
||||
project.app.signing.keyAlias=public
|
||||
project.app.signing.keyPassword="123456"
|
||||
project.app.signing.storePassword="123456"
|
||||
project.app.signing.storeFilePath=.secret/universal.p12
|
78
gradle/sweet-dependency/sweet-dependency-config.yaml
Normal file
@@ -0,0 +1,78 @@
|
||||
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.1.2
|
||||
org.jetbrains.kotlin.android:
|
||||
alias: kotlin-android
|
||||
version: 1.9.10
|
||||
com.google.devtools.ksp:
|
||||
alias: kotlin-ksp
|
||||
version: 1.9.10-1.0.13
|
||||
|
||||
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.2.0
|
||||
ksp-xposed:
|
||||
version-ref: <this>::api
|
||||
com.github.topjohnwu.libsu:
|
||||
core:
|
||||
version: 5.2.1
|
||||
com.github.duanhong169:
|
||||
drawabletoolbox:
|
||||
version: 1.0.7
|
||||
com.squareup.okhttp3:
|
||||
okhttp:
|
||||
version: 5.0.0-alpha.11
|
||||
androidx.core:
|
||||
core-ktx:
|
||||
version: 1.12.0
|
||||
androidx.appcompat:
|
||||
appcompat:
|
||||
version: 1.6.1
|
||||
com.google.android.material:
|
||||
material:
|
||||
version: 1.10.0
|
||||
androidx.constraintlayout:
|
||||
constraintlayout:
|
||||
version: 2.1.4
|
||||
androidx.test.ext:
|
||||
junit:
|
||||
version: 1.1.5
|
||||
androidx.test.espresso:
|
||||
espresso-core:
|
||||
version: 3.5.1
|
||||
junit:
|
||||
junit:
|
||||
version: 4.13.2
|
5
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,5 @@
|
||||
#Wed May 25 04:36:53 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.3-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStoreBase=GRADLE_USER_HOME
|
BIN
img-src/icon.png
Normal file
After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 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 = "MIUINativeNotifyIcon"
|
||||
include ':app'
|
23
settings.gradle.kts
Normal file
@@ -0,0 +1,23 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
plugins {
|
||||
id("com.highcapable.sweetdependency") version "1.0.2"
|
||||
id("com.highcapable.sweetproperty") version "1.0.3"
|
||||
}
|
||||
sweetProperty {
|
||||
global {
|
||||
all {
|
||||
permanentKeyValues("GITHUB_CI_COMMIT_ID" to "")
|
||||
generateFrom(ROOT_PROJECT, SYSTEM_ENV)
|
||||
}
|
||||
sourcesCode { includeKeys("GITHUB_CI_COMMIT_ID") }
|
||||
}
|
||||
rootProject { all { isEnable = false } }
|
||||
}
|
||||
rootProject.name = "MIUINativeNotifyIcon"
|
||||
include(":app")
|