81 Commits

Author SHA1 Message Date
3e29a70969 chore: update target sdk to 36 2025-08-19 16:52:33 +08:00
3015eade97 chore: update jdk to 21 2025-08-19 16:52:18 +08:00
c172e1e229 chore: bump gradle to 8.14.3 2025-08-19 16:52:11 +08:00
25b7853313 chore: bump dependencies 2025-08-19 16:52:00 +08:00
08e38c6770 chore(ci): trigger build #241 2025-08-17 00:50:06 +08:00
李太白
058c4534f7 fix:处理通知图标的 “app_package ” 并修复焦点通知图标的颜色 (#241)
* fix:处理通知图标的 “app_package ”并修复焦点通知图标的颜色

此提交解决了两个问题:

1.  **通知图标软件包名称:** 现在,如果通知中的 "app_package" 字符串可用,它将正确使用该字符串,并返回到通知的软件包名称。这可确保在一个应用程序代表另一个应用程序(如系统服务)发送通知时加载正确的图标。
2.  **焦点通知图标颜色:** 焦点通知图标的着色现在可根据通知图标优化配置正确应用,从而防止出现不正确的图标颜色。

Signed-off-by: ghhccghk <2137610394@qq.com>

* fix: 修复焦点通知图标逻辑异常,修复setTint导致无法正确着色

Signed-off-by: ghhccghk <2137610394@qq.com>

* fix: 修复焦点通知反色功能异常

Signed-off-by: ghhccghk <2137610394@qq.com>

* feat: 新增开关强制对焦点通知进行反色

- 新增开关 `ENABLE_FOCUS_NOTIFICATION_FIX`,默认关闭
- 当该开关开启时,强制对焦点通知图标进行反色处理
- 调整了 SystemUIHooker 中对焦点通知图标的反色逻辑,使其在 `ENABLE_FOCUS_NOTIFICATION_FIX` 开启时生效
- 修复了当图标不是灰度图标时,也标记为需要反色的问题

Signed-off-by: ghhccghk <2137610394@qq.com>

* style: some tweaks in SystemUIHooker

---------

Signed-off-by: ghhccghk <2137610394@qq.com>
Co-authored-by: fankesyooni <qzmmcn@163.com>
2025-08-16 20:57:57 +08:00
1551013414 refactor: update KavaRef usage to 1.0.1 2025-07-06 21:32:43 +08:00
8a775b3fdd refactor: migrate and update to YukiHookAPI 1.3.0 2025-06-25 23:25:58 +08:00
c5ed4f720f misc: invalidate 2025-06-25 23:25:57 +08:00
914e44942a refactor: migrate and update to YukiHookAPI 1.3.0 2025-06-25 23:22:23 +08:00
1b44e232ea docs: update README 2025-06-24 14:11:42 +08:00
7eb69e45f0 docs: update README 2025-06-20 12:50:08 +08:00
487e249f33 chore: disable type auto conversion for sweet-property 2025-05-09 23:20:18 +08:00
bbc14beb2e chore: bump dependencies 2025-03-16 23:22:17 +08:00
8a24cf3a4a chore: bump gradle to 8.13 2025-03-16 23:22:11 +08:00
139fafc758 chore: update project files 2025-03-16 23:22:01 +08:00
19e93cb15d Recommit #234 2025-02-22 00:55:40 +08:00
739816c31a chore: bump ci to v4 2025-02-22 00:55:35 +08:00
a7d457eb67 chore: update .gitignore 2025-02-21 23:19:09 +08:00
李太白
76f113de78 fix: 修复新版本焦点通知反色异常,取消对getStatusBarTickerDarkIcon进行着色 (#231)
* fix: 未适配图标的app在焦点通知会以白块显示

* fix: 修复调用方式解决Hyper 1.0 焦点反色失败

* fix: 修复调用方式解决Hyper 1.0 焦点反色失败

* fix: 修复新版本焦点通知反色异常,取消对getStatusBarTickerDarkIcon进行着色
2025-01-21 15:49:56 +08:00
aec000e252 docs: update license 2025-01-13 11:15:31 +08:00
d308111476 chore: update project files 2025-01-12 04:45:30 +08:00
c8f1099326 chore: update project files 2025-01-06 22:20:55 +08:00
李太白
350e54fac7 fix: 修复调用方式解决Hyper 1.0 焦点反色失败 (#228)
* fix: 未适配图标的app在焦点通知会以白块显示

* fix: 修复调用方式解决Hyper 1.0 焦点反色失败

* fix: 修复调用方式解决Hyper 1.0 焦点反色失败
2025-01-06 21:57:41 +08:00
李太白
4f1d74d5ff fix: 未适配图标的app在焦点通知会以白块显示 (#225) 2025-01-02 23:56:49 +09:00
f00f6efcf3 fix: getStatusBarTickerIcon/getStatusBarTickerDarkIcon lost state color in SystemUIHooker 2024-12-13 17:39:03 +08:00
8b6d35fa01 refactor: completion code optimizing 2024-12-13 10:35:06 +08:00
李太白
0c43bc5b97 fix: Log添加澎湃焦点通知相关,彻底修复焦点通知反色问题 (#222) 2024-12-12 21:52:25 +08:00
李太白
a134385d26 fix: 修复澎湃焦点通知1.0反色异常 (#219) 2024-12-09 19:26:24 +08:00
李太白
6d62c02b42 尝试修复反色异常,并以small图标为基准。 (#218) 2024-12-08 19:43:06 +08:00
4dcb05797c refactor: change use "miui.appIcon" to push system ui notification 2024-12-07 01:16:22 +08:00
7598da4d65 fix: small icon color transition @Nep-Timeline 2024-12-07 01:05:46 +08:00
992db5c4cf style: format code in SystemUIHooker 2024-12-07 00:48:06 +08:00
李太白
3cc2787a88 强制修改 getCustomAppIcon 获取的图标为 smallIcon,同时清理错误提交的代码 (#216)
* 强制修改 getCustomAppIcon 获取的图标为 smallIcon,同时清理错误提交的代码

* Resources.getSystem 换成 ct.resources
2024-12-05 22:42:15 +08:00
b476c19035 refactor: hook HyperOS focus icon and other fixing (cb4bf479) 2024-12-05 15:56:47 +08:00
李太白
cb4bf479ba add hook HyperOS 焦点通知彩色图标 (#215)
* add hook HyperOS 焦点通知彩色图标

* clean code

* fix: hyper os 2.0.25.0 bug
2024-12-05 15:37:03 +08:00
cd38dbf579 refactor: support Android 15 edge-to-edge system bars 2024-11-25 18:50:30 +08:00
259eb1dbd4 chore: update target sdk to 35 2024-11-10 20:42:28 +08:00
4d2160ce8a chore: some tweaks in build.gradle.kts 2024-11-10 20:42:10 +08:00
bcf3a17e21 chore: update project files 2024-11-10 20:42:01 +08:00
e7763baa22 chore: bump dependencies 2024-11-10 20:36:10 +08:00
e47754b870 chore: bump gradle to 8.10.2 2024-11-10 20:36:03 +08:00
YuSaki丶Kanade
e9e27b1d5a fix: HyperOS 2.0 handleAppIcon param (#212) 2024-11-06 20:39:45 +08:00
b10ff658ab refactor: test HyperOS 2.0 2024-11-02 00:25:00 +08:00
94f3fd12cd docs: add Android 15 option 2024-10-10 09:09:03 +08:00
7678ea7612 fix: HyperOS 1.1.3.0 (Android 15) status bar icons dark mode in SystemUIHooker 2024-10-03 19:02:51 +08:00
hamjin
d1a7d140a3 feat: Replace ghproxy.com with ghp.ci (#209) 2024-10-03 15:48:47 +08:00
01f5c902e9 Revert "feat: custom GitHub Proxy (#208)"
This reverts commit a601739679.
2024-10-03 01:27:14 +08:00
hamjin
a601739679 feat: custom GitHub Proxy (#208)
* feat: Custom GitHub Proxy

Signed-off-by: hamjin <jinham@qq.com>

* refactor: organize text layout

---------

Signed-off-by: hamjin <jinham@qq.com>
Co-authored-by: Fankesyooni <37344460+fankes@users.noreply.github.com>
2024-10-03 00:29:51 +08:00
YuSaki丶Kanade
a2bf9d24eb [修复] Android 15 解除状态栏图标无效 / 类及方法错误 (#206)
* Update FunctionFactory.kt

* Update SystemUIHooker.kt

* Update SystemUIHooker.kt

* Update SystemUIHooker.kt

* Update SystemUIHooker.kt

* Update FunctionFactory.kt
2024-09-24 19:09:12 +08:00
5a1672c0a4 fix: support HyperOS of commit(a5066814) in SystemUIHooker 2024-09-12 12:39:00 +08:00
a506681431 fix: notification icon reset in NotificationContentInflaterInjector in SystemUIHooker 2024-09-10 10:15:56 +08:00
abd1189e75 chore: update .editorconfig 2024-06-21 10:10:26 +08:00
ad0a538f13 refactor: support Kotlin 2.0.0 2024-06-20 11:20:30 +08:00
46abe6a6c1 chore: bump dependencies 2024-06-20 11:20:19 +08:00
b855113e4d chore: bump dependencies 2024-06-20 11:17:50 +08:00
c9411e5aa0 chore: bump gradle to 8.7 2024-06-20 11:17:46 +08:00
8729979c33 chore: update .editorconfig 2024-06-20 11:17:35 +08:00
28d3d7fd86 fix: wrong field name for MIUI14 in SystemUIHooker 2024-06-16 01:28:43 +08:00
hamjin
d2f8ef69c6 StatusBarMaxStaticIcons: Fully managed by us if enabled else do nothing (#199)
* StatusBarMaxStaticIcons: Fully managed by us if enabled else do nothing

Signed-off-by: hamjin <jinham@qq.com>

* Fix restore original count and enhance manage on HyperOS

* Remove unused code

---------

Signed-off-by: hamjin <jinham@qq.com>
2024-03-05 14:49:13 +08:00
c5b5fcfe35 chore: bump dependencies 2024-02-20 11:33:30 +08:00
219dd8b9e3 chore: bump gradle to 8.6 2024-02-20 11:33:25 +08:00
ad8fb50183 chore: update .editorconfig 2024-01-13 21:23:03 +08:00
ba74c7c9d4 docs: update copyright date to 2024 for all existing files 2024-01-01 01:27:09 +08:00
f398f2bcc3 style: merge to new ktlint version & rules 2023-12-29 21:37:12 +08:00
0377bb7062 chore: update project files 2023-12-29 21:36:08 +08:00
099133c6d6 chore: bump dependencies 2023-12-28 23:51:17 +08:00
7925629ef7 chore: bump gradle to 8.5 2023-12-28 23:49:06 +08:00
c42fad05c6 chore: update .gitignore 2023-12-28 23:48:56 +08:00
44483f1bd2 docs: use relative link 2023-12-11 02:41:29 +08:00
1e4bf54b80 chore: update project files 2023-12-11 02:41:27 +08:00
3fe8dca9e9 chore: bump dependency versions 2023-12-11 00:21:18 +08:00
b101210ed1 docs: update piracy statement 2023-12-11 00:21:12 +08:00
2a3398990b docs: update promotion 2023-11-18 18:16:09 +08:00
86d325ac31 chore: bump "com.highcapable.sweetdependency" version to 1.0.4 2023-11-14 01:03:18 +08:00
c74718572d chore: bump "com.highcapable.sweetproperty" version to 1.0.5 2023-11-08 15:16:46 +08:00
d1dc64108a fix: some problem in MIUI 14 (14.0.4) Android 14 2023-11-06 11:20:53 +08:00
386d3c254b chore: update project files 2023-11-06 11:20:13 +08:00
f2118bdc79 chore: bump dependencies 2023-11-04 03:56:18 +08:00
5651618506 chore: bump plugin versions
- bump "com.highcapable.sweetdependency" version to 1.0.3
- bump "com.highcapable.sweetproperty" version to 1.0.4
2023-11-04 03:52:36 +08:00
91f3a3418b Bump version to 2.110 2023-11-03 13:46:37 +08:00
54 changed files with 801 additions and 391 deletions

View File

@@ -10,6 +10,22 @@ ktlint_standard_argument-list-wrapping = disabled
ktlint_standard_parameter-list-wrapping = disabled ktlint_standard_parameter-list-wrapping = disabled
ktlint_standard_trailing-comma-on-declaration-site = disabled ktlint_standard_trailing-comma-on-declaration-site = disabled
ktlint_function_signature_body_expression_wrapping = multiline ktlint_function_signature_body_expression_wrapping = multiline
ktlint_standard_string-template-indent = disabled
ktlint_standard_function-signature = disabled
ktlint_standard_trailing-comma-on-call-site = disabled
ktlint_standard_multiline-expression-wrapping = disabled
ktlint_standard_no-empty-first-line-in-class-body = disabled
ktlint_standard_if-else-wrapping = disabled
ktlint_standard_if-else-bracing = disabled
ktlint_standard_statement-wrapping = disabled
ktlint_standard_blank-line-before-declaration = disabled
ktlint_standard_no-empty-file = disabled
ktlint_standard_property-naming = disabled
ktlint_standard_function-naming = disabled
ktlint_standard_chain-method-continuation = disabled
ktlint_standard_class-signature = disabled
ktlint_standard_condition-wrapping = disabled
ktlint_standard_class-signature = disabled
ij_continuation_indent_size = 2 ij_continuation_indent_size = 2
indent_size = 4 indent_size = 4
indent_style = space indent_style = space

View File

@@ -41,6 +41,7 @@ body:
attributes: attributes:
label: Android 版本 label: Android 版本
options: options:
- 15
- 14 - 14
- 13 - 13
- 12L/12.1 - 12L/12.1

View File

@@ -27,7 +27,7 @@ jobs:
See commit detail [here](${{ github.event.head_commit.url }}) See commit detail [here](${{ github.event.head_commit.url }})
COMMIT_URL: ${{ github.event.head_commit.url }} COMMIT_URL: ${{ github.event.head_commit.url }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Prepare GitHub Env - name: Prepare GitHub Env
run: | run: |
GITHUB_SHA=${{ github.sha }} GITHUB_SHA=${{ github.sha }}
@@ -37,10 +37,10 @@ jobs:
uses: jwlawson/actions-setup-cmake@v1 uses: jwlawson/actions-setup-cmake@v1
with: with:
cmake-version: '3.22.1' cmake-version: '3.22.1'
- name: Prepare Java 17 - name: Prepare Java 21
uses: actions/setup-java@v3 uses: actions/setup-java@v4
with: with:
java-version: 17 java-version: 21
java-package: jdk java-package: jdk
distribution: 'temurin' distribution: 'temurin'
cache: 'gradle' cache: 'gradle'
@@ -69,12 +69,12 @@ jobs:
echo "DEBUG_APK_PATH=$(find ${{ env.APK_OUTPUT_PATH }}/debug -name '*.apk')" >> $GITHUB_ENV 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 echo "RELEASE_APK_PATH=$(find ${{ env.APK_OUTPUT_PATH }}/release -name '*.apk')" >> $GITHUB_ENV
- name: Upload Artifacts (Debug) - name: Upload Artifacts (Debug)
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
path: ${{ env.DEBUG_APK_PATH }} path: ${{ env.DEBUG_APK_PATH }}
name: MIUINativeNotifyIcon-debug-${{ github.event.head_commit.id }} name: MIUINativeNotifyIcon-debug-${{ github.event.head_commit.id }}
- name: Upload Artifacts (Release) - name: Upload Artifacts (Release)
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
path: ${{ env.RELEASE_APK_PATH }} path: ${{ env.RELEASE_APK_PATH }}
name: MIUINativeNotifyIcon-release-${{ github.event.head_commit.id }} name: MIUINativeNotifyIcon-release-${{ github.event.head_commit.id }}

View File

@@ -17,7 +17,7 @@ jobs:
env: env:
APK_OUTPUT_PATH: 'app/build/outputs/apk' APK_OUTPUT_PATH: 'app/build/outputs/apk'
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Prepare GitHub Env - name: Prepare GitHub Env
run: | run: |
GITHUB_SHA=${{ github.sha }} GITHUB_SHA=${{ github.sha }}
@@ -27,10 +27,10 @@ jobs:
uses: jwlawson/actions-setup-cmake@v1 uses: jwlawson/actions-setup-cmake@v1
with: with:
cmake-version: '3.22.1' cmake-version: '3.22.1'
- name: Prepare Java 17 - name: Prepare Java 21
uses: actions/setup-java@v3 uses: actions/setup-java@v4
with: with:
java-version: 17 java-version: 21
java-package: jdk java-package: jdk
distribution: 'temurin' distribution: 'temurin'
cache: 'gradle' cache: 'gradle'
@@ -59,12 +59,12 @@ jobs:
echo "DEBUG_APK_PATH=$(find ${{ env.APK_OUTPUT_PATH }}/debug -name '*.apk')" >> $GITHUB_ENV 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 echo "RELEASE_APK_PATH=$(find ${{ env.APK_OUTPUT_PATH }}/release -name '*.apk')" >> $GITHUB_ENV
- name: Upload Artifacts (Debug) - name: Upload Artifacts (Debug)
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
path: ${{ env.DEBUG_APK_PATH }} path: ${{ env.DEBUG_APK_PATH }}
name: MIUINativeNotifyIcon-debug-${{ github.event.head_commit.id }} name: MIUINativeNotifyIcon-debug-${{ github.event.head_commit.id }}
- name: Upload Artifacts (Release) - name: Upload Artifacts (Release)
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
path: ${{ env.RELEASE_APK_PATH }} path: ${{ env.RELEASE_APK_PATH }}
name: MIUINativeNotifyIcon-release-${{ github.event.head_commit.id }} name: MIUINativeNotifyIcon-release-${{ github.event.head_commit.id }}

117
.gitignore vendored
View File

@@ -1,15 +1,110 @@
## Fully .gtignore for IntelliJ, Android Studio and Gradle based Java projects
## References:
## - https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
## - https://github.com/android/platform-samples/blob/main/.gitignore
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
.idea/.name
.idea/artifacts
.idea/compiler.xml
.idea/jarRepositories.xml
.idea/modules.xml
.idea/*.iml
.idea/modules
.idea/caches
.idea/material_theme**
.idea/other.xml
*.iml *.iml
.gradle *.ipr
/local.properties
/.idea/caches # Kotlin
/.idea/libraries .kotlin
/.idea/modules.xml
/.idea/workspace.xml # Misc
/.idea/navEditor.xml .idea/misc.xml
/.idea/assetWizardSettings.xml
.DS_Store # CMake
/build cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
# Android studio 3.1+ additional
.idea/deployment*.xml
.idea/assetWizardSettings.xml
.idea/androidTestResultsUserPreferences.xml
# Android projects
**/local.properties
/captures /captures
.externalNativeBuild .externalNativeBuild
.cxx .cxx
local.properties
# Gradle projects
.gradle
build/
# Mkdocs temporary serving folder
docs-gen
site
*.bak
.idea/appInsightsSettings.xml
# Mac OS
.DS_Store

5
.idea/.gitignore generated vendored
View File

@@ -1,5 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
/gradle.xml
/misc.xml

6
.idea/AndroidProjectSystem.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AndroidProjectSystem">
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
</component>
</project>

View File

@@ -1,26 +0,0 @@
<?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>

6
.idea/compiler.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
</component>
</project>

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<value>
<entry key="app">
<State />
</entry>
</value>
</component>
</project>

View File

@@ -1,6 +1,7 @@
<component name="InspectionProjectProfileManager"> <component name="InspectionProjectProfileManager">
<profile version="1.0"> <profile version="1.0">
<option name="myName" value="Project Default" /> <option name="myName" value="Project Default" />
<inspection_tool class="CheckImageSize" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false"> <inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" /> <option name="processCode" value="true" />
<option name="processLiterals" value="true" /> <option name="processLiterals" value="true" />

View File

@@ -1,40 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenRepo" />
<option name="name" value="MavenRepo" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven3" />
<option name="name" value="maven3" />
<option name="url" value="https://www.jitpack.io" />
</remote-repository>
<remote-repository>
<option name="id" value="maven" />
<option name="name" value="maven" />
<option name="url" value="https://maven.aliyun.com/nexus/content/groups/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven2" />
<option name="name" value="maven2" />
<option name="url" value="https://maven.aliyun.com/nexus/content/repositories/jcenter" />
</remote-repository>
<remote-repository>
<option name="id" value="Google" />
<option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository>
</component>
</project>

2
.idea/kotlinc.xml generated
View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="KotlinJpsPluginSettings"> <component name="KotlinJpsPluginSettings">
<option name="version" value="1.9.10" /> <option name="version" value="2.1.10" />
</component> </component>
</project> </project>

10
.idea/ktlint-plugin.xml generated Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KtLint plugin">
<ktlintMode>MANUAL</ktlintMode>
<formatOnSave>false</formatOnSave>
</component>
<component name="com.nbadal.ktlint.KtlintProjectSettings">
<ktlintMode>MANUAL</ktlintMode>
</component>
</project>

17
.idea/runConfigurations.xml generated Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
</set>
</option>
</component>
</project>

View File

@@ -1,17 +1,17 @@
# MIUI 原生通知图标 # MIUI 原生通知图标
[![GitHub license](https://img.shields.io/github/license/fankes/MIUINativeNotifyIcon?color=blue)](https://github.com/fankes/MIUINativeNotifyIcon/blob/master/LICENSE) [![GitHub license](https://img.shields.io/github/license/fankes/MIUINativeNotifyIcon?color=blue&style=flat-square)](https://github.com/fankes/MIUINativeNotifyIcon/blob/master/LICENSE)
[![GitHub CI](https://img.shields.io/github/actions/workflow/status/fankes/MIUINativeNotifyIcon/commit_ci.yml?label=CI%20builds)](https://github.com/fankes/MIUINativeNotifyIcon/actions/workflows/commit_ci.yml) [![GitHub CI](https://img.shields.io/github/actions/workflow/status/fankes/MIUINativeNotifyIcon/commit_ci.yml?label=CI%20builds&style=flat-square)](https://github.com/fankes/MIUINativeNotifyIcon/actions/workflows/commit_ci.yml)
[![GitHub release](https://img.shields.io/github/v/release/fankes/MIUINativeNotifyIcon?display_name=release&logo=github&color=green)](https://github.com/fankes/MIUINativeNotifyIcon/releases) [![GitHub release](https://img.shields.io/github/v/release/fankes/MIUINativeNotifyIcon?display_name=release&logo=github&color=green&style=flat-square)](https://github.com/fankes/MIUINativeNotifyIcon/releases)
![GitHub all releases](https://img.shields.io/github/downloads/fankes/MIUINativeNotifyIcon/total?label=downloads) ![GitHub all releases](https://img.shields.io/github/downloads/fankes/MIUINativeNotifyIcon/total?label=downloads&style=flat-square)
![GitHub all releases](https://img.shields.io/github/downloads/Xposed-Modules-Repo/com.fankes.miui.notify/total?label=LSPosed%20downloads&labelColor=F48FB1) ![GitHub all releases](https://img.shields.io/github/downloads/Xposed-Modules-Repo/com.fankes.miui.notify/total?label=LSPosed%20downloads&labelColor=F48FB1&style=flat-square)
[![Telegram CI](https://img.shields.io/badge/CI%20builds-Telegram-blue.svg?logo=telegram)](https://t.me/MIUINativeNotifyIcon_CI) [![Telegram CI](https://img.shields.io/badge/CI%20builds-Telegram-blue.svg?logo=telegram&style=flat-square)](https://t.me/MIUINativeNotifyIcon_CI)
[![Telegram](https://img.shields.io/badge/discussion-Telegram-blue.svg?logo=telegram)](https://t.me/XiaofangInternet) [![Telegram](https://img.shields.io/badge/discussion-Telegram-blue.svg?logo=telegram&style=flat-square)](https://t.me/XiaofangInternet)
[![QQ](https://img.shields.io/badge/discussion-QQ-blue.svg?logo=tencent-qq&logoColor=red)](https://qm.qq.com/cgi-bin/qm/qr?k=dp2h5YhWiga9WWb_Oh7kSHmx01X8I8ii&jump_from=webapi&authKey=Za5CaFP0lk7+Zgsk2KpoBD7sSaYbeXbsDgFjiWelOeH4VSionpxFJ7V0qQBSqvFM) [![QQ](https://img.shields.io/badge/discussion-QQ-blue.svg?logo=tencent-qq&logoColor=red&style=flat-square)](https://qm.qq.com/cgi-bin/qm/qr?k=dp2h5YhWiga9WWb_Oh7kSHmx01X8I8ii&jump_from=webapi&authKey=Za5CaFP0lk7+Zgsk2KpoBD7sSaYbeXbsDgFjiWelOeH4VSionpxFJ7V0qQBSqvFM)
[![QQ 频道](https://img.shields.io/badge/discussion-QQ%20频道-blue.svg?logo=tencent-qq&logoColor=red)](https://pd.qq.com/s/44gcy28h) [![QQ 频道](https://img.shields.io/badge/discussion-QQ%20频道-blue.svg?logo=tencent-qq&logoColor=red&style=flat-square)](https://pd.qq.com/s/44gcy28h)
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/img-src/icon.png?raw=true" width = "100" height = "100" alt="LOGO"/> <img src="img-src/icon.png" width = "100" height = "100" alt="LOGO"/>
Fix the native notification bar icon function abandoned by the MIUI development team. Fix the native notification bar icon function abandoned by the MIUI development team.
@@ -43,7 +43,7 @@ This project will not be adapted i18n, please stay tuned for my new projects in
点击下方的链接查看此模块的历史背景与探索历程。 点击下方的链接查看此模块的历史背景与探索历程。
- [EXPLORE_HISTORY](https://github.com/fankes/MIUINativeNotifyIcon/blob/master/EXPLORE_HISTORY.md) - [EXPLORE_HISTORY](EXPLORE_HISTORY.md)
## 贡献通知图标优化名单 ## 贡献通知图标优化名单
@@ -68,28 +68,31 @@ This project will not be adapted i18n, please stay tuned for my new projects in
| <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/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) | 正式版 (稳定版) |
|------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------|-----------|
本模块发布地址仅限于上述所列出的地址,从其他非正规渠道下载到的版本或对您造成任何影响均与我们无关。 本模块发布地址仅限于上述所列出的地址,从其他非正规渠道下载到的版本或对您造成任何影响均与我们无关。
## 请勿用于非法用途 ## 注意事项
- 本模块完全开源免费,如果好用你可以打赏支持开发,但是请不要用于非法用途。 <h3>1.&nbsp;本软件免费、由兴趣驱动开发,仅供学习交流使用。如果你是从其他非官方渠道付费获得本软件,可能已遭遇欺诈,欢迎向我们举报可疑行为。</h3>
<h3>2.&nbsp;本软件采用 <strong>GNU Affero General Public License (AGPL 3.0)</strong> 许可证。根据该许可证的要求:</h3>
- 任何衍生作品必须采用相同的 AGPL 许可证
- 分发本软件或其修改版本时,必须提供完整的源代码
- 必须保留原始的版权声明及许可证信息
- 不得额外施加限制来限制他人对本软件的自由使用
<h3>3.&nbsp;我们鼓励在遵守 AGPL 3.0 条款的前提下进行自由传播和改进,但请尊重作者署名权,勿冒用原作者名义。</h3>
## 项目推广 ## 项目推广
如果你正在寻找一个可以自动管理 Gradle 项目依赖的 Gradle 插件,你可以了解一下 [SweetDependency](https://github.com/HighCapable/SweetDependency) 项目。 <!--suppress HtmlDeprecatedAttribute -->
<div align="center">
如果你正在寻找一个可以自动生成属性键值的 Gradle 插件,你可以了解一下 [SweetProperty](https://github.com/HighCapable/SweetProperty) 项目。 <h2>嘿,还请君留步!👋</h2>
<h3>这里有 Android 开发工具、UI 设计、Gradle 插件、Xposed 模块和实用软件等相关项目。</h3>
本项目同样使用了 **SweetDependency****SweetProperty** <h3>如果下方的项目能为你提供帮助,不妨为我点个 star 吧!</h3>
<h3>所有项目免费、开源,遵循对应开源许可协议。</h3>
## 捐赠支持 <h1><a href="https://github.com/fankes/fankes/blob/main/project-promote/README-zh-CN.md">→ 查看更多关于我的项目,请点击这里 ←</a></h1>
</div>
工作不易,无意外情况此项目将继续维护下去,提供更多可能,欢迎打赏。
<img src="https://github.com/fankes/fankes/blob/main/img-src/payment_code.jpg?raw=true" width = "500" alt="Payment Code"/>
## Star History ## Star History
@@ -97,14 +100,14 @@ This project will not be adapted i18n, please stay tuned for my new projects in
## 隐私政策 ## 隐私政策
- [PRIVACY](https://github.com/fankes/MIUINativeNotifyIcon/blob/master/PRIVACY.md) - [PRIVACY](PRIVACY.md)
## 许可证 ## 许可证
- [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.html) - [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.html)
``` ```
Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as it under the terms of the GNU Affero General Public License as
@@ -122,4 +125,4 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
Powered by [YukiHookAPI](https://github.com/HighCapable/YukiHookAPI) Powered by [YukiHookAPI](https://github.com/HighCapable/YukiHookAPI)
版权所有 © 2017-2023 Fankes Studio(qzmmcn@163.com) 版权所有 © 2017 Fankes Studio(qzmmcn@163.com)

1
app/.gitignore vendored
View File

@@ -1,3 +1,2 @@
/build
/src/main/assets/xposed_init /src/main/assets/xposed_init
/src/main/resources/META-INF/yukihookapi_init /src/main/resources/META-INF/yukihookapi_init

View File

@@ -38,14 +38,6 @@ android {
sourceCompatibility = JavaVersion.VERSION_17 sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17
} }
kotlinOptions {
jvmTarget = "17"
freeCompilerArgs = listOf(
"-Xno-param-assertions",
"-Xno-call-assertions",
"-Xno-receiver-assertions"
)
}
buildFeatures { buildFeatures {
buildConfig = true buildConfig = true
viewBinding = true viewBinding = true
@@ -58,7 +50,18 @@ androidComponents {
onVariants(selector().all()) { onVariants(selector().all()) {
it.outputs.forEach { output -> it.outputs.forEach { output ->
val currentType = it.buildType val currentType = it.buildType
val currentSuffix = property.github.ci.commit.id.let { suffix -> if (suffix.isNotBlank()) "-$suffix" else "" }
// Workaround for GitHub Actions.
// Why? I don't know, but it works.
// Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
// public inline fun CharSequence.isNotBlank(): Boolean defined in kotlin.text.
@Suppress("UNNECESSARY_SAFE_CALL", "RemoveRedundantCallsOfConversionMethods")
val currentSuffix = property.github.ci.commit.id?.let { suffix ->
// Workaround for GitHub Actions.
// Strongly transfer type to [String].
val sSuffix = suffix.toString()
if (sSuffix.isNotBlank()) "-$sSuffix" else ""
}
val currentVersion = "${output.versionName.get()}$currentSuffix(${output.versionCode.get()})" val currentVersion = "${output.versionName.get()}$currentSuffix(${output.versionCode.get()})"
if (output is com.android.build.api.variant.impl.VariantOutputImpl) if (output is com.android.build.api.variant.impl.VariantOutputImpl)
output.outputFileName.set("${property.project.name}-v$currentVersion-$currentType.apk") output.outputFileName.set("${property.project.name}-v$currentVersion-$currentType.apk")
@@ -70,6 +73,8 @@ dependencies {
compileOnly(de.robv.android.xposed.api) compileOnly(de.robv.android.xposed.api)
implementation(com.highcapable.yukihookapi.api) implementation(com.highcapable.yukihookapi.api)
ksp(com.highcapable.yukihookapi.ksp.xposed) ksp(com.highcapable.yukihookapi.ksp.xposed)
implementation(com.highcapable.kavaref.kavaref.core)
implementation(com.highcapable.kavaref.kavaref.extension)
implementation(com.fankes.projectpromote.project.promote) implementation(com.fankes.projectpromote.project.promote)
implementation(com.github.topjohnwu.libsu.core) implementation(com.github.topjohnwu.libsu.core)
implementation(com.github.duanhong169.drawabletoolbox) implementation(com.github.duanhong169.drawabletoolbox)

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it
@@ -72,6 +72,9 @@ object ConfigData {
/** 启用通知图标优化 */ /** 启用通知图标优化 */
val ENABLE_NOTIFY_ICON_FIX = PrefsData("_notify_icon_fix", true) val ENABLE_NOTIFY_ICON_FIX = PrefsData("_notify_icon_fix", true)
/** 强制启用焦点通知反色 */
val ENABLE_FOCUS_NOTIFICATION_FIX = PrefsData("_enable_focus_notification_fix", false)
/** 使用占位符修补未适配的通知图标 */ /** 使用占位符修补未适配的通知图标 */
val ENABLE_NOTIFY_ICON_FIX_PLACEHOLDER = PrefsData("_notify_icon_fix_placeholder", false) val ENABLE_NOTIFY_ICON_FIX_PLACEHOLDER = PrefsData("_notify_icon_fix_placeholder", false)
@@ -303,6 +306,16 @@ object ConfigData {
putBoolean(ENABLE_NOTIFY_ICON_FIX, value) putBoolean(ENABLE_NOTIFY_ICON_FIX, value)
} }
/**
* 是否强制启用焦点通知反色
* @return [Boolean]*/
var isEnableFocusNotificationFix
get() = getBoolean(ENABLE_FOCUS_NOTIFICATION_FIX)
set(value) {
putBoolean(ENABLE_FOCUS_NOTIFICATION_FIX, value)
}
/** /**
* 是否使用占位符修补未适配的通知图标 * 是否使用占位符修补未适配的通知图标
* @return [Boolean] * @return [Boolean]

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it
@@ -32,7 +32,6 @@ import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.graphics.Color import android.graphics.Color
import android.graphics.Outline import android.graphics.Outline
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.graphics.drawable.Icon import android.graphics.drawable.Icon
import android.os.Build import android.os.Build
@@ -42,9 +41,12 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewOutlineProvider import android.view.ViewOutlineProvider
import android.widget.ImageView import android.widget.ImageView
import android.widget.RemoteViews
import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toBitmap
import androidx.core.graphics.drawable.toDrawable import androidx.core.graphics.drawable.toDrawable
import androidx.core.graphics.scale
import androidx.core.view.children import androidx.core.view.children
import androidx.core.view.isNotEmpty
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.setPadding import androidx.core.view.setPadding
import com.fankes.miui.notify.R import com.fankes.miui.notify.R
@@ -75,22 +77,20 @@ import com.fankes.miui.notify.utils.tool.ActivationPromptTool
import com.fankes.miui.notify.utils.tool.BitmapCompatTool import com.fankes.miui.notify.utils.tool.BitmapCompatTool
import com.fankes.miui.notify.utils.tool.IconAdaptationTool import com.fankes.miui.notify.utils.tool.IconAdaptationTool
import com.fankes.miui.notify.utils.tool.SystemUITool import com.fankes.miui.notify.utils.tool.SystemUITool
import com.highcapable.yukihookapi.hook.bean.VariousClass import com.highcapable.kavaref.KavaRef.Companion.asResolver
import com.highcapable.kavaref.KavaRef.Companion.resolve
import com.highcapable.kavaref.condition.MethodCondition
import com.highcapable.kavaref.extension.VariousClass
import com.highcapable.kavaref.extension.classOf
import com.highcapable.kavaref.extension.isSubclassOf
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
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.injectModuleAppResources
import com.highcapable.yukihookapi.hook.factory.method
import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.log.YLog
import com.highcapable.yukihookapi.hook.param.HookParam
import com.highcapable.yukihookapi.hook.type.android.ContextClass import com.highcapable.yukihookapi.hook.type.android.ContextClass
import com.highcapable.yukihookapi.hook.type.android.DrawableClass import com.highcapable.yukihookapi.hook.type.android.NotificationClass
import com.highcapable.yukihookapi.hook.type.android.ImageViewClass import com.highcapable.yukihookapi.hook.type.android.RemoteViewsClass
import com.highcapable.yukihookapi.hook.type.android.StatusBarNotificationClass import com.highcapable.yukihookapi.hook.type.java.BooleanClass
import com.highcapable.yukihookapi.hook.type.java.BooleanType
import com.highcapable.yukihookapi.hook.type.java.IntType
import top.defaults.drawabletoolbox.DrawableBuilder import top.defaults.drawabletoolbox.DrawableBuilder
/** /**
@@ -113,17 +113,24 @@ object SystemUIHooker : YukiBaseHooker() {
private val NotificationHeaderViewWrapperInjectorClass private val NotificationHeaderViewWrapperInjectorClass
by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationHeaderViewWrapperInjector") by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationHeaderViewWrapperInjector")
/** MIUI 未确定版本存在的类 */
private val NotificationContentInflaterInjectorClass
by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.row.NotificationContentInflaterInjector")
/** MIUI 未确定版本存在的类 */ /** MIUI 未确定版本存在的类 */
private val SettingsManagerClass by lazyClassOrNull("com.miui.systemui.SettingsManager") private val SettingsManagerClass by lazyClassOrNull("com.miui.systemui.SettingsManager")
/** MIUI 未确定版本存在的类 */
private val MiuiClockClass by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.views.MiuiClock")
/** MIUI 新版本存在的类 */ /** MIUI 新版本存在的类 */
private val NotificationStatClass by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.analytics.NotificationStat") private val NotificationStatClass by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.analytics.NotificationStat")
/** 原生存在的类 */ /** 原生存在的类 */
private val NotificationChildrenContainerClass by lazyClass("${PackageName.SYSTEMUI}.statusbar.notification.stack.NotificationChildrenContainer") private val NotificationChildrenContainerClass by lazyClass("${PackageName.SYSTEMUI}.statusbar.notification.stack.NotificationChildrenContainer")
/** 原生存在的类 */ /** 原生存在的类 (A15 HyperOS 已变成 `interface`) */
private val NotificationIconAreaControllerClass by lazyClass("${PackageName.SYSTEMUI}.statusbar.phone.NotificationIconAreaController") private val NotificationIconAreaControllerClass by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.phone.NotificationIconAreaController")
/** 原生存在的类 */ /** 原生存在的类 */
private val ContrastColorUtilClass by lazyClass("com.android.internal.util.ContrastColorUtil") private val ContrastColorUtilClass by lazyClass("com.android.internal.util.ContrastColorUtil")
@@ -170,7 +177,8 @@ object SystemUIHooker : YukiBaseHooker() {
private val NotificationUtilClass by lazyClass( private val NotificationUtilClass by lazyClass(
VariousClass( VariousClass(
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationUtil", "${PackageName.SYSTEMUI}.statusbar.notification.NotificationUtil",
"${PackageName.SYSTEMUI}.miui.statusbar.notification.NotificationUtil" "${PackageName.SYSTEMUI}.miui.statusbar.notification.NotificationUtil",
"${PackageName.SYSTEMUI}.statusbar.notification.utils.NotifImageUtil"
) )
) )
@@ -182,6 +190,12 @@ object SystemUIHooker : YukiBaseHooker() {
) )
) )
/** HyperOS 焦点通知的用到的 API */
private val FocusUtilsClass by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.utils.FocusUtils")
/** HyperOS 焦点通知的用到的 API */
private val FocusedNotifPromptViewClass by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.phone.FocusedNotifPromptView")
/** 缓存的通知图标优化数组 */ /** 缓存的通知图标优化数组 */
private var iconDatas = ArrayList<IconDataBean>() private var iconDatas = ArrayList<IconDataBean>()
@@ -194,6 +208,9 @@ object SystemUIHooker : YukiBaseHooker() {
/** 状态栏原始通知图标最大个数限制 */ /** 状态栏原始通知图标最大个数限制 */
private var statusBarMaxStaticIcons = -1 private var statusBarMaxStaticIcons = -1
/** 模块上次设置的通知图标最大个数限制 */
private var moduleLastSetStatusBarMaxStaticIcons = -1
/** 是否已经使用过缓存刷新功能 */ /** 是否已经使用过缓存刷新功能 */
private var isUsingCachingMethod = false private var isUsingCachingMethod = false
@@ -209,18 +226,26 @@ object SystemUIHooker : YukiBaseHooker() {
/** 仅监听一次主题壁纸颜色变化 */ /** 仅监听一次主题壁纸颜色变化 */
private var isWallpaperColorListenerSetUp = false private var isWallpaperColorListenerSetUp = false
/** 用来同步是否需要焦点图标染色 */
private var focusedIcon = false
/** /**
* 获取全局上下文 * 获取全局上下文
* @return [Context] or null * @return [Context] or null
*/ */
private val globalContext private val globalContext
get() = SystemUIApplicationClass?.method { name = "getContext" }?.ignored()?.get()?.invoke<Context?>() ?: appContext get() = SystemUIApplicationClass?.resolve()?.optional(silent = true)
?.firstMethodOrNull { name = "getContext" }
?.invoke<Context?>() ?: appContext
/** /**
* 是否为 MIUI 样式通知栏 - 旧版 - 新版一律返回 false * 是否为 MIUI 样式通知栏 - 旧版 - 新版一律返回 false
* @return [Boolean] * @return [Boolean]
*/ */
private val isShowMiuiStyle get() = NotificationUtilClass.method { name = "showMiuiStyle" }.ignored().get().boolean() private val isShowMiuiStyle
get() = NotificationUtilClass.resolve().optional(silent = true)
.firstMethodOrNull { name = "showMiuiStyle" }
?.invoke<Boolean>() == true
/** /**
* 是否没有单独的 MIUI 通知栏样式 * 是否没有单独的 MIUI 通知栏样式
@@ -284,19 +309,46 @@ object SystemUIHooker : YukiBaseHooker() {
* @param isCustom 是否为通知优化生效图标 * @param isCustom 是否为通知优化生效图标
* @param isGrayscale 是否为灰度图标 * @param isGrayscale 是否为灰度图标
*/ */
@Suppress("DEPRECATION")
private fun loggerDebug(tag: String, context: Context, nf: StatusBarNotification?, isCustom: Boolean, isGrayscale: Boolean) { private fun loggerDebug(tag: String, context: Context, nf: StatusBarNotification?, isCustom: Boolean, isGrayscale: Boolean) {
if (ConfigData.isEnableModuleLog) YLog.debug( if (ConfigData.isEnableModuleLog) {
msg = "(Processing $tag) ↓\n" + val focusTicker = nf?.notification?.extras?.getString("miui.focus.ticker")
"[Title]: ${nf?.notification?.extras?.getString(Notification.EXTRA_TITLE)}\n" + val focusIconId = nf?.notification?.extras?.getInt("miui.focus.iconId", -1)
"[Content]: ${nf?.notification?.extras?.getString(Notification.EXTRA_TEXT)}\n" + val focusRv = nf?.notification?.extras?.getParcelable<RemoteViews?>("miui.focus.rv")
"[App Name]: ${context.appNameOf(packageName = nf?.packageName ?: "")}\n" + val focusParam = nf?.notification?.extras?.getString("miui.focus.param")
"[Package Name]: ${nf?.packageName}\n" + if (focusRv != null)
"[Sender Package Name]: ${nf?.compatOpPkgName}\n" + YLog.debug(
"[Custom Icon]: $isCustom\n" + msg = "(Processing $tag with Focus Notification) ↓\n" +
"[Grayscale Icon]: $isGrayscale\n" + "[Title]: ${nf.notification?.extras?.getString(Notification.EXTRA_TITLE)}\n" +
"[From Xmsf]: ${nf?.isXmsf}\n" + "[Content]: ${nf.notification?.extras?.getString(Notification.EXTRA_TEXT)}\n" +
"[String]: ${nf?.notification}" "[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}\n" +
"[Focus IconId]: $focusIconId\n" +
"[Focus String]: ${focusParam}\n" +
"[Focus rv String]: ${focusRv}\n" +
"[Focus Ticker String]: ${focusTicker}\n" +
"[Dark Icon Mode]: $isDarkIconMode"
)
else
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}\n" +
"[Dark Icon Mode]: $isDarkIconMode"
)
}
} }
/** /**
@@ -309,15 +361,19 @@ object SystemUIHooker : YukiBaseHooker() {
*/ */
private fun isGrayscaleIcon(context: Context, drawable: Drawable) = private fun isGrayscaleIcon(context: Context, drawable: Drawable) =
if (ConfigData.isEnableColorIconCompat.not()) safeOfFalse { if (ConfigData.isEnableColorIconCompat.not()) safeOfFalse {
ContrastColorUtilClass.let { ContrastColorUtilClass.resolve()
it.method { .optional(silent = true)
name = "isGrayscaleIcon" .let {
param(DrawableClass) it.firstMethodOrNull {
}.get(it.method { name = "isGrayscaleIcon"
name = "getInstance" parameters(Drawable::class)
param(ContextClass) }?.of(
}.get().invoke(context)).boolean(drawable) it.firstMethodOrNull {
} name = "getInstance"
parameters(Context::class)
}?.invoke(context)
)?.invokeQuietly<Boolean>(drawable) == true
}
} else BitmapCompatTool.isGrayscaleDrawable(drawable) } else BitmapCompatTool.isGrayscaleDrawable(drawable)
/** /**
@@ -325,7 +381,7 @@ object SystemUIHooker : YukiBaseHooker() {
* @return [Drawable] * @return [Drawable]
*/ */
private fun Drawable.rounded(context: Context) = private fun Drawable.rounded(context: Context) =
safeOf(default = this) { BitmapDrawable(context.resources, toBitmap().round(10.dpFloat(context))) } safeOf(default = this) { toBitmap().round(10.dpFloat(context)).toDrawable(context.resources) }
/** /**
* 适配通知栏、状态栏来自系统推送的彩色 APP 图标 * 适配通知栏、状态栏来自系统推送的彩色 APP 图标
@@ -357,10 +413,10 @@ object SystemUIHooker : YukiBaseHooker() {
/** 刷新状态栏小图标 */ /** 刷新状态栏小图标 */
private fun refreshStatusBarIcons() = runInSafe { private fun refreshStatusBarIcons() = runInSafe {
StatusBarIconViewClass.field { name = "mNotification" }.also { result -> StatusBarIconViewClass.resolve().optional(silent = true).firstFieldOrNull { name = "mNotification" }?.also { result ->
notificationIconContainer?.children?.forEach { notificationIconContainer?.children?.forEach {
/** 得到通知实例 */ /** 得到通知实例 */
val nf = result.get(it).cast<StatusBarNotification>() ?: return val nf = result.of(it).get<StatusBarNotification>() ?: return
/** 刷新状态栏图标 */ /** 刷新状态栏图标 */
compatStatusIcon(it.context, nf, nf.notification.smallIcon.loadDrawable(it.context)).also { pair -> compatStatusIcon(it.context, nf, nf.notification.smallIcon.loadDrawable(it.context)).also { pair ->
pair.first.let { e -> (it as? ImageView?)?.setImageDrawable(e) } pair.first.let { e -> (it as? ImageView?)?.setImageDrawable(e) }
@@ -372,14 +428,13 @@ object SystemUIHooker : YukiBaseHooker() {
/** 刷新通知小图标 */ /** 刷新通知小图标 */
private fun refreshNotificationIcons() = runInSafe { private fun refreshNotificationIcons() = runInSafe {
val updateNotificationMethodName = "updateNotificationsOnDensityOrFontScaleChanged" val updateNotificationMethodName = "updateNotificationsOnDensityOrFontScaleChanged"
if (StatusBarNotificationPresenterClass.hasMethod { name = updateNotificationMethodName }) val result = notificationPresenter?.asResolver()?.optional(silent = true)?.firstMethodOrNull {
notificationPresenter?.current(ignored = true)?.method { name = updateNotificationMethodName
name = updateNotificationMethodName emptyParameters()
emptyParam() }?.invoke()
}?.call() if (result == null) settingsManager?.asResolver()?.optional(silent = true)?.apply {
else settingsManager?.current { firstFieldOrNull { name = "notifStyle" }?.set(-100)
field { name = "notifStyle" }.set(-100) firstMethodOrNull { name = "onNotifStyleChanged" }?.invoke()
method { name = "onNotifStyleChanged" }.call()
} }
} }
@@ -422,8 +477,12 @@ object SystemUIHooker : YukiBaseHooker() {
/** 判断是否不是灰度图标 */ /** 判断是否不是灰度图标 */
val isGrayscaleIcon = notifyInstance.isXmsf.not() && isGrayscaleIcon(context, iconDrawable) val isGrayscaleIcon = notifyInstance.isXmsf.not() && isGrayscaleIcon(context, iconDrawable)
/** 读取通知是否附加包名,如果没有则使用通知包名 */
val extras = notifyInstance.notification.extras
val pkgname = extras.getString("app_package")?.takeIf { it.isNotBlank() } ?: notifyInstance.nfPkgName
/** 目标彩色通知 APP 图标 */ /** 目标彩色通知 APP 图标 */
val customTriple = compatCustomIcon(context, isGrayscaleIcon, notifyInstance.nfPkgName) val customTriple = compatCustomIcon(context, isGrayscaleIcon, pkgname)
/** 是否为通知优化生效图标 */ /** 是否为通知优化生效图标 */
val isCustom = customTriple.first != null && customTriple.third.not() val isCustom = customTriple.first != null && customTriple.third.not()
@@ -521,9 +580,13 @@ object SystemUIHooker : YukiBaseHooker() {
/** 自定义默认小图标 */ /** 自定义默认小图标 */
var customIcon: Drawable? = null var customIcon: Drawable? = null
/** 读取通知是否附加包名,如果没有则使用通知包名 */
val extras = notifyInstance.notification.extras
val pkgname = extras.getString("app_package")?.takeIf { it.isNotBlank() } ?: notifyInstance.nfPkgName
/** 自定义默认小图标颜色 */ /** 自定义默认小图标颜色 */
var customIconColor = 0 var customIconColor = 0
compatCustomIcon(context, isGrayscaleIcon, notifyInstance.nfPkgName).also { compatCustomIcon(context, isGrayscaleIcon, pkgname).also {
/** 不处理占位符图标 */ /** 不处理占位符图标 */
if (it.third) return@also if (it.third) return@also
customIcon = it.first customIcon = it.first
@@ -594,7 +657,7 @@ object SystemUIHooker : YukiBaseHooker() {
*/ */
private fun ImageView.isGrayscaleIcon(): Boolean { private fun ImageView.isGrayscaleIcon(): Boolean {
/** 获取 [StatusBarNotification] 实例 */ /** 获取 [StatusBarNotification] 实例 */
val notifyInstance = current().field { name = "mNotification" }.cast<StatusBarNotification>() ?: return false val notifyInstance = asResolver().optional().firstFieldOrNull { name = "mNotification" }?.get<StatusBarNotification>() ?: return false
/** 获取通知小图标 */ /** 获取通知小图标 */
val iconDrawable = notifyInstance.notification?.smallIcon?.loadDrawable(context) ?: return false val iconDrawable = notifyInstance.notification?.smallIcon?.loadDrawable(context) ?: return false
@@ -618,7 +681,7 @@ object SystemUIHooker : YukiBaseHooker() {
* @param animColor 动画过渡颜色 * @param animColor 动画过渡颜色
*/ */
private fun updateStatusBarIconsColor(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 (container.isNotEmpty()) container.children.forEach { iconView ->
if (iconView !is ImageView) return@forEach if (iconView !is ImageView) return@forEach
updateStatusBarIconColor(iconView, isDarkIconMode, animColor) updateStatusBarIconColor(iconView, isDarkIconMode, animColor)
} }
@@ -648,27 +711,53 @@ object SystemUIHooker : YukiBaseHooker() {
* @param container 当前 [NotificationIconContainerClass] 的实例 * @param container 当前 [NotificationIconContainerClass] 的实例
*/ */
private fun updateStatusBarIconsAlpha(container: ViewGroup) { private fun updateStatusBarIconsAlpha(container: ViewGroup) {
val iconStatesMap = container.current().field { name = "mIconStates" }.cast<HashMap<View, Any>>() val iconStatesMap = container.asResolver().optional().firstFieldOrNull { name = "mIconStates" }?.get<HashMap<View, Any>>()
if (container.childCount > 0) container.children.forEach { iconView -> if (container.isNotEmpty()) container.children.forEach { iconView ->
if (iconView !is ImageView) return@forEach if (iconView !is ImageView) return@forEach
val iconAlpha = if (iconView.isGrayscaleIcon()) statusBarIconAlpha else 1f val iconAlpha = if (iconView.isGrayscaleIcon()) statusBarIconAlpha else 1f
iconView.alpha = iconAlpha iconView.alpha = iconAlpha
iconStatesMap?.get(iconView)?.current()?.field { name { it == "alpha" || it == "mAlpha" }; superClass() }?.set(iconAlpha) iconStatesMap?.get(iconView)?.asResolver()?.optional()?.firstFieldOrNull {
name { it == "alpha" || it == "mAlpha" }
superclass()
}?.set(iconAlpha)
} }
} }
/** /**
* Hook 状态栏通知图标最大数量 * Hook 状态栏通知图标最大数量
* @param fieldName 最大通知图标数量 的变量名
* @param instance 被 Hook 的 Method 的实例 * @param instance 被 Hook 的 Method 的实例
*/ */
private fun hookStatusBarMaxStaticIcons(fieldName: String, instance: Any) { private fun hookStatusBarMaxStaticIcons(instance: Any) {
val maxStaticIconsField = NotificationIconContainerClass.field { name = fieldName }.get(instance) val maxStaticIconsResolver = NotificationIconContainerClass.resolve().optional().firstFieldOrNull {
if (statusBarMaxStaticIcons == -1) statusBarMaxStaticIcons = maxStaticIconsField.int() name {
/** 旧版名称 */
val oldVersion = it == "mMaxStaticIcons"
/** 旧版名称 */
val oldVersion2 = it == "MAX_STATIC_ICONS"
/** 新版本名称 */
val newVersion = it == "mMaxIcons"
oldVersion || oldVersion2 || newVersion
}
}?.of(instance) ?: return
if (statusBarMaxStaticIcons == -1 ||
/** 系统设置内修改,模块同步更新 */
moduleLastSetStatusBarMaxStaticIcons != maxStaticIconsResolver.get<Int>()) {
statusBarMaxStaticIcons = maxStaticIconsResolver.get<Int>() ?: return
}
if (!ConfigData.isEnableLiftedStatusIconCount) {
maxStaticIconsResolver.set(statusBarMaxStaticIcons)
return
}
/** 解除状态栏通知图标个数限制 */ /** 解除状态栏通知图标个数限制 */
if (isShowNotificationIcons && ConfigData.isEnableLiftedStatusIconCount) if (isShowNotificationIcons) {
maxStaticIconsField.set(ConfigData.liftedStatusIconCount.let { if (it in 0..100) it else 5 }) moduleLastSetStatusBarMaxStaticIcons = ConfigData.liftedStatusIconCount.let { if (it in 0..100) it else 5 }
else maxStaticIconsField.set(if (isShowNotificationIcons) statusBarMaxStaticIcons else 0) maxStaticIconsResolver.set(moduleLastSetStatusBarMaxStaticIcons)
} else {
maxStaticIconsResolver.set(0)
moduleLastSetStatusBarMaxStaticIcons = 0
}
} }
/** /**
@@ -680,8 +769,8 @@ object SystemUIHooker : YukiBaseHooker() {
if (isNotHasAbsoluteMiuiStyle && isShowMiuiStyle) return if (isNotHasAbsoluteMiuiStyle && isShowMiuiStyle) return
/** 获取小图标 */ /** 获取小图标 */
val iconImageView = NotificationHeaderViewWrapperClass val iconImageView = NotificationHeaderViewWrapperClass.resolve().optional()
.field { name = "mIcon" }.get(wrapper).cast<ImageView>() ?: return .firstFieldOrNull { name = "mIcon" }?.of(wrapper)?.get<ImageView>() ?: return
/** 获取 [ExpandableNotificationRowClass] */ /** 获取 [ExpandableNotificationRowClass] */
val rowPair = wrapper.getRowPair() val rowPair = wrapper.getRowPair()
@@ -714,16 +803,15 @@ object SystemUIHooker : YukiBaseHooker() {
* 从父类中得到 mRow 变量 - [ExpandableNotificationRowClass] * 从父类中得到 mRow 变量 - [ExpandableNotificationRowClass]
* 获取其中的得到通知方法 * 获取其中的得到通知方法
*/ */
val row = NotificationViewWrapperClass.field { val row = NotificationViewWrapperClass.resolve().optional().firstFieldOrNull {
name = "mRow" name = "mRow"
}.get(this).any()?.also { }?.of(this)?.get()?.also {
isExpanded = ExpandableNotificationRowClass.method { isExpanded = ExpandableNotificationRowClass.resolve().optional().firstMethodOrNull {
name = "isExpanded" name = "isExpanded"
param(BooleanType) parameters(Boolean::class)
returnType = BooleanType returnType = Boolean::class
}.get(it).boolean(false) }?.of(it)?.invoke<Boolean>(false) == true
} }; return isExpanded to row
return Pair(isExpanded, row)
} }
/** /**
@@ -731,15 +819,18 @@ object SystemUIHooker : YukiBaseHooker() {
* @return [StatusBarNotification] or null * @return [StatusBarNotification] or null
*/ */
private fun Any?.getSbn() = private fun Any?.getSbn() =
ExpandableNotificationRowClass ExpandableNotificationRowClass.resolve()
.method { name = "getEntry" } .optional(silent = true)
.get(this).call() .firstFieldOrNull {
?.current(ignored = true) name = "mEntry"
?.field { name = "mSbn" } }?.of(this)?.get()?.asResolver()
?.cast<StatusBarNotification>() ?.optional(silent = true)
?: ExpandableNotificationRowClass ?.firstFieldOrNull { name = "mSbn" }
.method { name = "getStatusBarNotification" } ?.get<StatusBarNotification>()
.get(this).invoke<StatusBarNotification>() ?: ExpandableNotificationRowClass.resolve()
.optional(silent = true)
.firstMethodOrNull { name = "getStatusBarNotification" }
?.of(this)?.invoke<StatusBarNotification>()
/** /**
* 根据当前 [ImageView] 的父布局克隆一个新的 [ImageView] * 根据当前 [ImageView] 的父布局克隆一个新的 [ImageView]
@@ -769,7 +860,11 @@ object SystemUIHooker : YukiBaseHooker() {
private fun registerLifecycle() { private fun registerLifecycle() {
onAppLifecycle { onAppLifecycle {
/** 解锁后重新刷新状态栏图标防止系统重新设置它 */ /** 解锁后重新刷新状态栏图标防止系统重新设置它 */
registerReceiver(Intent.ACTION_USER_PRESENT) { _, _ -> if (isUsingCachingMethod) refreshStatusBarIcons() } registerReceiver(Intent.ACTION_USER_PRESENT) { _, _ ->
if (isUsingCachingMethod) refreshStatusBarIcons()
/** 每次解锁时都对通知栏的图标进行刷新以响应 [RemoteViews] 阶段的图标改变 */
refreshNotificationIcons()
}
/** 注册定时监听 */ /** 注册定时监听 */
registerReceiver(Intent.ACTION_TIME_TICK) { context, _ -> registerReceiver(Intent.ACTION_TIME_TICK) { context, _ ->
if (ConfigData.isEnableNotifyIconFix && ConfigData.isEnableNotifyIconFixNotify && ConfigData.isEnableNotifyIconFixAuto) if (ConfigData.isEnableNotifyIconFix && ConfigData.isEnableNotifyIconFixNotify && ConfigData.isEnableNotifyIconFixAuto)
@@ -838,25 +933,48 @@ object SystemUIHooker : YukiBaseHooker() {
/** 注入 MIUI 自己增加的一个工具类 */ /** 注入 MIUI 自己增加的一个工具类 */
NotificationUtilClass.apply { NotificationUtilClass.apply {
/** 强制回写系统的状态栏图标样式为原生 */ /** 强制回写系统的状态栏图标样式为原生 */
method { resolve().optional().method {
name { it == "shouldSubstituteSmallIcon" || it == "shouldSubstituteSmallIconForStatusBarNotification" } name { it == "shouldSubstituteSmallIcon" || it == "shouldSubstituteSmallIconForStatusBarNotification" }
param { it[0] extends StatusBarNotificationClass } parameters { it.first() isSubclassOf StatusBarNotification::class }
}.hookAll().replaceToFalse() }.hookAll().replaceToFalse()
var isUseLegacy = false var isUseLegacy = false
/** 强制回写系统的状态栏图标样式为原生 */ /**
method { * 强制修改 getCustomAppIcon 获取的图标为 smallIcon
* 部分系统没有 "getCustomAppIcon" 这个方法 - 所以直接忽略
*/
resolve().optional(silent = true).firstMethodOrNull {
name = "getCustomAppIcon"
parameters(Notification::class, Context::class)
}?.hook()?.after {
val nf = args().first().cast<Notification>()
val context = args(index = 1).cast<Context>()
val iconBitmap = nf?.smallIcon?.loadDrawable(context)?.toBitmap()
result = if (context != null && iconBitmap != null && !iconBitmap.isRecycled)
iconBitmap.toDrawable(context.resources)
else null
}
/**
* 强制回写系统的状态栏图标样式为原生
* 部分系统没有 "getSmallIcon" 这个方法 - 所以直接忽略
*/
val getSmallIconCondition1 = MethodCondition<Any>().apply {
name = "getSmallIcon" name = "getSmallIcon"
param { it[0] extends StatusBarNotificationClass && it[1] == IntType } parameters { it[0] isSubclassOf StatusBarNotification::class && it[1] == classOf<Int>() }
}.remedys { }
method { val getSmallIconCondition2 = MethodCondition<Any>().apply {
name = "getSmallIcon" name = "getSmallIcon"
param(ExpandedNotificationClass) parameters(ExpandedNotificationClass)
} }
method { val getSmallIconCondition3 = MethodCondition<Any>().apply {
name = "getSmallIcon" name = "getSmallIcon"
param(ContextClass, ExpandedNotificationClass) parameters { it[0] == classOf<Context>() && it[1] isSubclassOf StatusBarNotification::class }
}.onFind { isUseLegacy = true } }
}.hook().after { val getSmallIconResolver = resolve().optional(silent = true)
val getSmallIcon = getSmallIconResolver.firstMethodOrNull(getSmallIconCondition1)
?: getSmallIconResolver.firstMethodOrNull(getSmallIconCondition2)
?: getSmallIconResolver.firstMethodOrNull(getSmallIconCondition3)
?.also { isUseLegacy = true }
getSmallIcon?.hook()?.after {
(globalContext ?: args().first().cast())?.also { context -> (globalContext ?: args().first().cast())?.also { context ->
val expandedNf = args(if (isUseLegacy) 1 else 0).cast<StatusBarNotification?>() val expandedNf = args(if (isUseLegacy) 1 else 0).cast<StatusBarNotification?>()
/** Hook 状态栏小图标 */ /** Hook 状态栏小图标 */
@@ -868,29 +986,90 @@ object SystemUIHooker : YukiBaseHooker() {
} }
} }
} }
/** 焦点通知深色模式切换点 */
FocusedNotifPromptViewClass?.resolve()?.optional()?.apply {
firstMethodOrNull {
name = "onDarkChanged"
parameters(ArrayList::class, Float::class, Int::class, Int::class, Int::class, Boolean::class)
}?.hook()?.after {
val isDark = args(index = 1).float()
val mIcon = firstFieldOrNull { name = "mIcon" }?.of(instance)?.get()
if (ConfigData.isEnableModuleLog)
YLog.debug("FocusedNotifPromptView DEBUG $isDark $mIcon")
if (focusedIcon || ConfigData.isEnableFocusNotificationFix)
mIcon?.asResolver()?.optional()?.firstMethodOrNull {
name = "setColorFilter"
superclass()
}?.invoke(if (isDark <= 0.5f) Color.WHITE else Color.BLACK)
}
}
/** 去他妈的焦点通知彩色图标 */
FocusUtilsClass?.resolve()?.optional()?.apply {
fun HookParam.hookTickerDarkIcon(isDark: Boolean) {
(globalContext ?: args().first().cast())?.also { context ->
val expandedNf = args().first().cast<StatusBarNotification?>()
val small = expandedNf?.notification?.smallIcon
/** Hook 状态栏小图标 */
compatStatusIcon(
context = context,
nf = expandedNf,
iconDrawable = small?.loadDrawable(context)
).also { pair ->
focusedIcon = pair.second
val originalBitmap = pair.first?.toBitmap()
val bitmap = originalBitmap?.scale(50, 50)
result = Icon.createWithBitmap(bitmap).apply {
if (pair.second || ConfigData.isEnableFocusNotificationFix)
setTint(if (isDark) Color.BLACK else Color.WHITE)
}
}
}
}
firstMethodOrNull {
name = "getStatusBarTickerDarkIcon"
parameters {
(it.first() == classOf<StatusBarNotification>() ||
it.first() == ExpandedNotificationClass) && it.size == 1
}
}?.hook()?.after { hookTickerDarkIcon(isDark = true) }
firstMethodOrNull {
name = "getStatusBarTickerIcon"
parameters {
(it.first() == classOf<StatusBarNotification>() ||
it.first() == ExpandedNotificationClass) && it.size == 1
}
}?.hook()?.after { hookTickerDarkIcon(isDark = false) }
}
/** 注入状态栏通知图标实例 */ /** 注入状态栏通知图标实例 */
StatusBarIconViewClass.method { StatusBarIconViewClass.resolve().optional().firstMethodOrNull {
name = "updateIconColor" name = "updateIconColor"
emptyParam() emptyParameters()
}.ignored().hook().after { }?.hook()?.after {
val iconView = instance<ImageView>() val iconView = instance<ImageView>()
val expandedNf = iconView.current().field { name = "mNotification" }.cast<StatusBarNotification>() val expandedNf = iconView.asResolver().optional().firstFieldOrNull { name = "mNotification" }?.get<StatusBarNotification>()
/** Hook 状态栏小图标 */ /** Hook 状态栏小图标 */
compatStatusIcon( compatStatusIcon(
context = iconView.context, context = iconView.context,
nf = expandedNf, nf = expandedNf,
iconDrawable = expandedNf?.notification?.smallIcon?.loadDrawable(iconView.context) iconDrawable = expandedNf?.notification?.smallIcon?.loadDrawable(iconView.context)
).also { pair -> iconView.setImageDrawable(pair.first) } ).also { pair ->
if (pair.second)
result = iconView.setImageDrawable(pair.first?.toBitmap()?.toDrawable(iconView.resources))
}
updateStatusBarIconColor(iconView) updateStatusBarIconColor(iconView)
} }
/** 注入状态栏通知图标容器管理实例 */ /**
NotificationIconAreaControllerClass.apply { * 注入状态栏通知图标容器管理实例
* 在 Android 15 中,这个类被移除变成了 `interface`,所以判断并跳过 Hook 行为
*/
val isPlaceholder = NotificationIconAreaControllerClass?.isInterface == true
if (!isPlaceholder) NotificationIconAreaControllerClass?.resolve()?.optional()?.apply {
/** Hook 深色图标模式改变 */ /** Hook 深色图标模式改变 */
method { firstMethodOrNull {
name = "onDarkChanged" name = "onDarkChanged"
paramCount { it > 0 } parameterCount { it > 0 }
}.hook().after { }?.hook()?.after {
field { name = "mNotificationIcons" }.get(instance).cast<ViewGroup>()?.also { firstFieldOrNull { name = "mNotificationIcons" }?.of(instance)?.get<ViewGroup>()?.also {
/** 重新设置通知图标容器实例 */ /** 重新设置通知图标容器实例 */
notificationIconContainer = it notificationIconContainer = it
when (args(index = 1).float()) { when (args(index = 1).float()) {
@@ -910,7 +1089,7 @@ object SystemUIHooker : YukiBaseHooker() {
method { method {
name { it == "updateNotificationIcons" || it.startsWith("onChanged") } name { it == "updateNotificationIcons" || it.startsWith("onChanged") }
}.hookAll().after { }.hookAll().after {
field { name = "mNotificationIcons" }.get(instance).cast<ViewGroup>()?.also { firstFieldOrNull { name = "mNotificationIcons" }?.of(instance)?.get<ViewGroup>()?.also {
/** 重新设置通知图标容器实例 */ /** 重新设置通知图标容器实例 */
notificationIconContainer = it notificationIconContainer = it
updateStatusBarIconsColor(it) updateStatusBarIconsColor(it)
@@ -918,35 +1097,76 @@ object SystemUIHooker : YukiBaseHooker() {
delayedRun { updateStatusBarIconsColor(it) } delayedRun { updateStatusBarIconsColor(it) }
} }
} }
} else MiuiClockClass?.resolve()?.optional()?.apply {
firstMethodOrNull {
name = "onDarkChanged"
parameterCount { it > 4 }
}?.hook()?.after {
notificationIconContainer?.let {
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())
}
}
}
} }
/** 注入状态栏通知图标实例 */ /** 注入状态栏通知图标实例 */
StatusBarIconViewClass.method { StatusBarIconViewClass.resolve().optional().apply {
name = "setNotification" firstMethodOrNull {
param(StatusBarNotificationClass)
}.remedys {
method {
name = "setNotification" name = "setNotification"
param(ExpandedNotificationClass) parameters {
(it.first() == classOf<StatusBarNotification>() ||
it.first() == ExpandedNotificationClass) && it.size == 1
}
}?.hook()?.after {
/** 注册壁纸颜色监听 */
if (args().first().any() != null) instance<ImageView>().also { registerWallpaperColorChanged(it) }
}
/** Hook 深色图标模式改变 */
if (isPlaceholder) firstMethodOrNull {
name = "onDarkChanged"
parameterCount { it > 4 }
}?.hook()?.after {
val self = instance<ImageView>()
when (args(index = 1).float()) {
1.0f -> {
isDarkIconMode = true
updateStatusBarIconColor(self, isDarkIconMode = true)
}
0.0f -> {
isDarkIconMode = false
updateStatusBarIconColor(self, isDarkIconMode = false)
}
else -> updateStatusBarIconColor(self, isDarkIconMode = false, args(index = 2).int())
}
} }
}.hook().after {
/** 注册壁纸颜色监听 */
if (args().first().any() != null) instance<ImageView>().also { registerWallpaperColorChanged(it) }
} }
/** 注入设置管理器实例 */ /** 注入设置管理器实例 */
SettingsManagerClass?.constructor()?.hookAll()?.after { settingsManager = instance } SettingsManagerClass?.resolve()?.optional()?.constructor {}?.hookAll()?.after { settingsManager = instance }
/** 注入通知控制器实例 */ /** 注入通知控制器实例 */
StatusBarNotificationPresenterClass.constructor().hookAll().after { notificationPresenter = instance } StatusBarNotificationPresenterClass.resolve().optional().constructor {}.hookAll().after { notificationPresenter = instance }
/** 注入状态栏通知图标容器实例 */ /** 注入状态栏通知图标容器实例 */
NotificationIconContainerClass.apply { NotificationIconContainerClass.apply {
method { resolve().optional().firstMethodOrNull {
name = "applyIconStates" name = "applyIconStates"
}.hook().after { updateStatusBarIconsAlpha(instance()) } }?.hook()?.after { updateStatusBarIconsAlpha(instance()) }
method { resolve().optional().firstMethodOrNull {
name = "resetViewStates" name = "resetViewStates"
}.hook().after { updateStatusBarIconsAlpha(instance()) } }?.hook()?.after {
method { updateStatusBarIconsAlpha(instance())
/** HyperOS 系统设置修改通知图标个数触发此方法 */
hookStatusBarMaxStaticIcons(instance)
}
resolve().optional().firstMethodOrNull {
name { it == "calculateIconTranslations" || it == "calculateIconXTranslations" } name { it == "calculateIconTranslations" || it == "calculateIconXTranslations" }
}.hook().after { }?.hook()?.after {
/** 缓存实例 */ /** 缓存实例 */
notificationIconContainer = instance<ViewGroup>() notificationIconContainer = instance<ViewGroup>()
/** 修复部分开发版状态栏图标只能显示一个的问题 */ /** 修复部分开发版状态栏图标只能显示一个的问题 */
@@ -955,39 +1175,39 @@ object SystemUIHooker : YukiBaseHooker() {
instance<ViewGroup>().layoutParams.width = 9999 instance<ViewGroup>().layoutParams.width = 9999
} }
} }
/** 旧版方法 A13MIUI - 新版不存在 */ /** 旧版方法 (A13 MIUI) - 新版不存在 */
method { resolve().optional(silent = true).firstMethodOrNull {
name = "updateState" name = "updateState"
}.ignored().hook().before { hookStatusBarMaxStaticIcons("MAX_STATIC_ICONS", instance) } }?.hook()?.before { hookStatusBarMaxStaticIcons(instance) }
/** 新版方法 (A14 MIUI14 / A14 HyperOS) - 旧版不存在 */ /** 新版方法 (A14 MIUI14 / A14 HyperOS) - 旧版不存在 */
method { resolve().optional(silent = true).firstMethodOrNull {
name = "onMeasure" name = "onMeasure"
}.ignored().hook().before { hookStatusBarMaxStaticIcons("mMaxStaticIcons", instance) } }?.hook()?.before { hookStatusBarMaxStaticIcons(instance) }
/** 旧版方法 - 新版不存在 */ /** 旧版方法 - 新版不存在 */
method { resolve().optional(silent = true).firstMethodOrNull {
name = "setMaxStaticIcons" name = "setMaxStaticIcons"
param(IntType) parameters(Int::class)
}.ignored().hook().before { isShowNotificationIcons = args().first().int() > 0 } }?.hook()?.before { isShowNotificationIcons = args().first().int() > 0 }
/** 版方法 - 旧版不存在 */ /** 版方法 - 新版 (A15 HyperOS) 不存在 */
method { resolve().optional(silent = true).firstMethodOrNull {
name = "miuiShowNotificationIcons" name = "miuiShowNotificationIcons"
param(BooleanType) parameters(Boolean::class)
}.ignored().hook().before { isShowNotificationIcons = args().first().boolean() } }?.hook()?.before { isShowNotificationIcons = args().first().boolean() }
} }
/** 注入原生通知包装纸实例 */ /** 注入原生通知包装纸实例 */
NotificationHeaderViewWrapperClass.apply { NotificationHeaderViewWrapperClass.resolve().optional().apply {
method { firstMethodOrNull {
name { it == "resolveHeaderViews" || it == "handleHeaderViews" || it == "resolveViews" } name { it == "resolveHeaderViews" || it == "handleHeaderViews" || it == "resolveViews" }
}.hook().after { hookNotificationViewWrapper(instance) } }?.hook()?.after { hookNotificationViewWrapper(instance) }
method { firstMethodOrNull {
name = "onContentUpdated" name = "onContentUpdated"
}.hook().after { hookNotificationViewWrapper(instance) } }?.hook()?.after { hookNotificationViewWrapper(instance) }
} }
/** 修改 MIUI 风格通知栏的通知图标 */ /** 修改 MIUI 风格通知栏的通知图标 */
MiuiNotificationViewWrapperClass?.apply { MiuiNotificationViewWrapperClass?.resolve()?.optional()?.apply {
constructor().hook().after { constructor {}.hookAll().after {
val nf = instance.getRowPair().second.getSbn() ?: return@after val nf = instance.getRowPair().second.getSbn() ?: return@after
field { name = "mAppIcon" }.get(instance).cast<ImageView>()?.clone { firstFieldOrNull { name = "mAppIcon" }?.of(instance)?.get<ImageView>()?.clone {
if (ConfigData.isEnableReplaceMiuiStyleNotifyIcon || ConfigData.isEnableNotifyIconForceAppIcon) if (ConfigData.isEnableReplaceMiuiStyleNotifyIcon || ConfigData.isEnableNotifyIconForceAppIcon)
compatNotifyIcon(context, nf, iconView = this, isUseMaterial3Style = true, isMiuiPanel = true) compatNotifyIcon(context, nf, iconView = this, isUseMaterial3Style = true, isMiuiPanel = true)
else setImageDrawable(nf.miuiAppIcon?.loadDrawable(context) ?: context.appIconOf(nf.packageName)) else setImageDrawable(nf.miuiAppIcon?.loadDrawable(context) ?: context.appIconOf(nf.packageName))
@@ -995,16 +1215,16 @@ object SystemUIHooker : YukiBaseHooker() {
} }
} }
/** 修改 MIUI 风格通知栏的通知图标 - 折叠通知 */ /** 修改 MIUI 风格通知栏的通知图标 - 折叠通知 */
MiuiNotificationChildrenContainerClass?.apply { MiuiNotificationChildrenContainerClass?.resolve()?.optional()?.apply {
/** 替换通知小图标 */ /** 替换通知小图标 */
method { firstMethodOrNull {
name = "updateAppIcon" name = "updateAppIcon"
param(BooleanType) parameters(Boolean::class)
}.hook().after { }?.hook()?.after {
field { name = "mAppIcon" }.get(instance).cast<ImageView>()?.apply { firstFieldOrNull { name = "mAppIcon" }?.of(instance)?.get<ImageView>()?.apply {
val nf = NotificationChildrenContainerClass.field { val nf = NotificationChildrenContainerClass.resolve().optional().firstFieldOrNull {
name = "mContainingNotification" name = "mContainingNotification"
}.get(instance).any()?.getSbn() ?: return@after }?.of(instance)?.get()?.getSbn() ?: return@after
if (ConfigData.isEnableReplaceMiuiStyleNotifyIcon || ConfigData.isEnableNotifyIconForceAppIcon) if (ConfigData.isEnableReplaceMiuiStyleNotifyIcon || ConfigData.isEnableNotifyIconForceAppIcon)
compatNotifyIcon(context, nf, iconView = this, isUseMaterial3Style = true, isMiuiPanel = true) compatNotifyIcon(context, nf, iconView = this, isUseMaterial3Style = true, isMiuiPanel = true)
else setImageDrawable(nf.miuiAppIcon?.loadDrawable(context) ?: context.appIconOf(nf.packageName)) else setImageDrawable(nf.miuiAppIcon?.loadDrawable(context) ?: context.appIconOf(nf.packageName))
@@ -1012,21 +1232,29 @@ object SystemUIHooker : YukiBaseHooker() {
} }
} }
/** 干掉下拉通知图标自动设置回 APP 图标的方法 */ /** 干掉下拉通知图标自动设置回 APP 图标的方法 */
NotificationHeaderViewWrapperInjectorClass?.apply { NotificationHeaderViewWrapperInjectorClass?.resolve()?.optional(silent = true)?.apply {
method { firstMethodOrNull {
name = "setAppIcon" name = "setAppIcon"
param(ContextClass, ImageViewClass, ExpandedNotificationClass) parameters(Context::class, ImageView::class, ExpandedNotificationClass)
}.remedys { }?.hook()?.intercept()
method { firstMethodOrNull {
name = "setAppIcon" name = "setAppIcon"
param(ImageViewClass, ExpandedNotificationClass) parameters(ImageView::class, ExpandedNotificationClass)
} }?.hook()?.intercept()
}.ignored().hook().intercept() firstMethodOrNull {
method {
name = "resetIconBgAndPaddings" name = "resetIconBgAndPaddings"
param(ImageViewClass, ExpandedNotificationClass) parameters(ImageView::class, ExpandedNotificationClass)
}.ignored().hook().intercept() }?.hook()?.intercept()
} }
NotificationContentInflaterInjectorClass?.resolve()?.optional()?.firstMethodOrNull {
name = "handleAppIcon"
/**
* MIUI 14 ([RemoteViewsClass], [NotificationClass])
* HyperOS ([RemoteViewsClass], [NotificationClass], [ContextClass])
* HyperOS 2.0 ([RemoteViewsClass], [NotificationClass], [ContextClass], [BooleanClass])
*/
parameterCount { it in 2..4 }
}?.hook()?.intercept()
/** /**
* 尝试修复从 MIUI 14 开始出现的一个崩溃问题 * 尝试修复从 MIUI 14 开始出现的一个崩溃问题
* 由于模块注入推送的通知没有对 [StatusBarNotification] 设置 TAG 会导致其空指针 * 由于模块注入推送的通知没有对 [StatusBarNotification] 设置 TAG 会导致其空指针
@@ -1038,14 +1266,14 @@ object SystemUIHooker : YukiBaseHooker() {
* } * }
* ``` * ```
*/ */
NotificationStatClass?.method { NotificationStatClass?.resolve()?.optional(silent = true)?.firstMethodOrNull {
name = "isUnimportantEntry" name = "isUnimportantEntry"
paramCount = 1 parameterCount = 1
}?.ignored()?.hook()?.replaceAny { }?.hook()?.replaceAny {
args().first().current(ignored = true).method { args().first().any()?.asResolver()?.optional()?.firstMethodOrNull {
name = "getSbn" name = "getSbn"
superClass() superclass()
}.invoke<StatusBarNotification>()?.let { sbn -> }?.invoke<StatusBarNotification>()?.let { sbn ->
sbn.packageName == PackageName.SYSTEMUI && sbn.tag == "UNIMPORTANT" sbn.packageName == PackageName.SYSTEMUI && sbn.tag == "UNIMPORTANT"
} ?: false } ?: false
} }

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it
@@ -114,7 +114,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
showDialog { showDialog {
title = "不支持的系统版本" title = "不支持的系统版本"
msg = (if (miSystemVersion.isNotBlank()) msg = (if (miSystemVersion.isNotBlank())
"此模块目前支持 MIUI 11~14 和 HyperOS 1.0 系统,你的系统版本为 $miSystemVersion,暂不支持。\n\n" + "此模块目前支持 MIUI 11~14 和 HyperOS 1.0~2.0 系统,你的系统版本为 $miSystemVersion,暂不支持。\n\n" +
"如果你的系统版本识别有误,请检查是否有相关插件修改了系统版本。\n\n" "如果你的系统版本识别有误,请检查是否有相关插件修改了系统版本。\n\n"
else "无法获取系统版本,请检查你是否修改了系统参数或使用非官方系统。\n\n") + "若有其它疑问,你可以点击下方按钮前往项目地址进行反馈。" else "无法获取系统版本,请检查你是否修改了系统参数或使用非官方系统。\n\n") + "若有其它疑问,你可以点击下方按钮前往项目地址进行反馈。"
confirmButton(text = "前往项目地址") { confirmButton(text = "前往项目地址") {
@@ -241,6 +241,9 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
binding.miuiNotifyIconReplacementSwitch.bind(ConfigData.ENABLE_REPLACE_MIUI_STYLE_NOTIFY_ICON) { binding.miuiNotifyIconReplacementSwitch.bind(ConfigData.ENABLE_REPLACE_MIUI_STYLE_NOTIFY_ICON) {
onChanged { SystemUITool.refreshSystemUI(context = this@MainActivity) } onChanged { SystemUITool.refreshSystemUI(context = this@MainActivity) }
} }
binding.miuiFocusNotifyIconFixSwitch.bind(ConfigData.ENABLE_FOCUS_NOTIFICATION_FIX) {
onChanged { SystemUITool.refreshSystemUI(context = this@MainActivity) }
}
binding.notifyIconForceSystemColorSwitch.bind(ConfigData.ENABLE_NOTIFY_ICON_FORCE_SYSTEM_COLOR) { binding.notifyIconForceSystemColorSwitch.bind(ConfigData.ENABLE_NOTIFY_ICON_FORCE_SYSTEM_COLOR) {
isAutoApplyChanges = false isAutoApplyChanges = false
onChanged { onChanged {

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it
@@ -20,20 +20,20 @@
* *
* This file is created by fankes on 2022/1/30. * This file is created by fankes on 2022/1/30.
*/ */
@file:Suppress("UNCHECKED_CAST")
package com.fankes.miui.notify.ui.activity.base package com.fankes.miui.notify.ui.activity.base
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import com.fankes.miui.notify.R import com.fankes.miui.notify.R
import com.fankes.miui.notify.utils.factory.isNotSystemInDarkMode import com.fankes.miui.notify.utils.factory.isNotSystemInDarkMode
import com.highcapable.yukihookapi.hook.factory.current import com.highcapable.kavaref.KavaRef.Companion.resolve
import com.highcapable.yukihookapi.hook.factory.method import com.highcapable.kavaref.extension.genericSuperclassTypeArguments
import com.highcapable.yukihookapi.hook.type.android.LayoutInflaterClass import com.highcapable.kavaref.extension.toClassOrNull
abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() { abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
@@ -49,10 +49,12 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
isMainThreadRunning = true isMainThreadRunning = true
binding = current().generic()?.argument()?.method { val bindingClass = javaClass.genericSuperclassTypeArguments().firstOrNull()?.toClassOrNull()
binding = bindingClass?.resolve()?.optional()?.firstMethodOrNull {
name = "inflate" name = "inflate"
param(LayoutInflaterClass) parameters(LayoutInflater::class)
}?.get()?.invoke<VB>(layoutInflater) ?: error("binding failed") }?.invoke<VB>(layoutInflater) ?: error("binding failed")
if (Build.VERSION.SDK_INT >= 35) binding.root.fitsSystemWindows = true
setContentView(binding.root) setContentView(binding.root)
/** 隐藏系统的标题栏 */ /** 隐藏系统的标题栏 */
supportActionBar?.hide() supportActionBar?.hide()
@@ -61,6 +63,7 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
isAppearanceLightStatusBars = isNotSystemInDarkMode isAppearanceLightStatusBars = isNotSystemInDarkMode
isAppearanceLightNavigationBars = isNotSystemInDarkMode isAppearanceLightNavigationBars = isNotSystemInDarkMode
} }
@Suppress("DEPRECATION")
ResourcesCompat.getColor(resources, R.color.colorThemeBackground, null).also { ResourcesCompat.getColor(resources, R.color.colorThemeBackground, null).also {
window?.statusBarColor = it window?.statusBarColor = it
window?.navigationBarColor = it window?.navigationBarColor = it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it
@@ -64,6 +64,7 @@ class BaseAdapterCreater(val context: Context) {
* 绑定 [BaseAdapter] 到 [ListView] * 绑定 [BaseAdapter] 到 [ListView]
* @param bindViews 回调 - ([VB] 每项,[Int] 下标) * @param bindViews 回调 - ([VB] 每项,[Int] 下标)
*/ */
@Suppress("DEPRECATION")
inline fun <reified VB : ViewBinding> onBindViews(crossinline bindViews: (binding: VB, position: Int) -> Unit) { inline fun <reified VB : ViewBinding> onBindViews(crossinline bindViews: (binding: VB, position: Int) -> Unit) {
baseAdapter = object : BaseAdapter() { baseAdapter = object : BaseAdapter() {
override fun getCount() = listDataCallback?.let { it() }?.size ?: 0 override fun getCount() = listDataCallback?.let { it() }?.size ?: 0

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it
@@ -68,6 +68,7 @@ inline fun Context.showDialog(initiate: DialogBuilder<*>.() -> Unit) = DialogBui
* @param context 实例 * @param context 实例
* @param bindingClass [ViewBinding] 的 [Class] 实例 or null * @param bindingClass [ViewBinding] 的 [Class] 实例 or null
*/ */
@Suppress("DEPRECATION")
class DialogBuilder<VB : ViewBinding>(val context: Context, private val bindingClass: Class<*>? = null) { class DialogBuilder<VB : ViewBinding>(val context: Context, private val bindingClass: Class<*>? = null) {
/** 实例对象 */ /** 实例对象 */

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it
@@ -63,6 +63,8 @@ import androidx.core.app.NotificationManagerCompat
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import androidx.core.content.pm.PackageInfoCompat import androidx.core.content.pm.PackageInfoCompat
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.createBitmap
import androidx.core.net.toUri
import com.fankes.miui.notify.wrapper.BuildConfigWrapper import com.fankes.miui.notify.wrapper.BuildConfigWrapper
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.highcapable.yukihookapi.hook.factory.hasClass import com.highcapable.yukihookapi.hook.factory.hasClass
@@ -148,6 +150,7 @@ val isNotMiSystem get() = !isMiSystem
* 当前设备是否是 MIUI 定制 Android 系统 * 当前设备是否是 MIUI 定制 Android 系统
* @return [Boolean] 是否符合条件 * @return [Boolean] 是否符合条件
*/ */
@Suppress("DEPRECATION")
val isMIUI by lazy { "android.miui.R".hasClass() } val isMIUI by lazy { "android.miui.R".hasClass() }
/** /**
@@ -175,7 +178,7 @@ inline val isNotMIOS get() = !isMIOS
val isSupportMiSystemVersion val isSupportMiSystemVersion
get() = when { get() = when {
isMIOS -> when (miosVersion) { isMIOS -> when (miosVersion) {
"1.0" -> true "1.0", "1.1", "2.0" -> true
else -> false else -> false
} }
isMIUI -> when (miuiVersion) { isMIUI -> when (miuiVersion) {
@@ -197,6 +200,7 @@ inline val isNotSupportMiSystemVersion get() = !isSupportMiSystemVersion
*/ */
val androidVersionCodeName val androidVersionCodeName
get() = when (Build.VERSION.SDK_INT) { get() = when (Build.VERSION.SDK_INT) {
35 -> "V"
34 -> "U" 34 -> "U"
33 -> "T" 33 -> "T"
32 -> "S_V2" 32 -> "S_V2"
@@ -540,7 +544,7 @@ val String.bitmap: Bitmap get() = unbase64.bitmap
* @return [Bitmap] 圆角后的位图 - 失败会返回处理之前的位图 * @return [Bitmap] 圆角后的位图 - 失败会返回处理之前的位图
*/ */
fun Bitmap.round(radius: Float): Bitmap = safeOf(default = this) { fun Bitmap.round(radius: Float): Bitmap = safeOf(default = this) {
Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).also { out -> createBitmap(width, height).also { out ->
Canvas(out).also { canvas -> Canvas(out).also { canvas ->
Paint().also { paint -> Paint().also { paint ->
paint.isAntiAlias = true paint.isAntiAlias = true
@@ -560,6 +564,7 @@ fun Bitmap.round(radius: Float): Bitmap = safeOf(default = this) {
* @param default 默认值 * @param default 默认值
* @return [String] * @return [String]
*/ */
@Suppress("DEPRECATION")
fun findPropString(key: String, default: String = "") = safeOf(default) { fun findPropString(key: String, default: String = "") = safeOf(default) {
"android.os.SystemProperties".toClassOrNull()?.method { "android.os.SystemProperties".toClassOrNull()?.method {
name = "get" name = "get"
@@ -633,7 +638,7 @@ fun Context.openBrowser(url: String, packageName: String = "") = runCatching {
startActivity(Intent().apply { startActivity(Intent().apply {
if (packageName.isNotBlank()) setPackage(packageName) if (packageName.isNotBlank()) setPackage(packageName)
action = Intent.ACTION_VIEW action = Intent.ACTION_VIEW
data = Uri.parse(url) data = url.toUri()
/** 防止顶栈一样重叠在自己的 APP 中 */ /** 防止顶栈一样重叠在自己的 APP 中 */
flags = Intent.FLAG_ACTIVITY_NEW_TASK flags = Intent.FLAG_ACTIVITY_NEW_TASK
}) })

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it
@@ -31,6 +31,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.drawable.Icon import android.graphics.drawable.Icon
import android.os.Build import android.os.Build
import android.os.Bundle
import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toBitmap
import com.fankes.miui.notify.R import com.fankes.miui.notify.R
import com.fankes.miui.notify.utils.factory.appIconOf import com.fankes.miui.notify.utils.factory.appIconOf
@@ -68,7 +69,9 @@ object ActivationPromptTool {
setColor(0xFFE06818.toInt()) setColor(0xFFE06818.toInt())
setAutoCancel(true) setAutoCancel(true)
setSmallIcon(Icon.createWithResource(MODULE_PACKAGE_NAME, R.drawable.ic_notify_update)) setSmallIcon(Icon.createWithResource(MODULE_PACKAGE_NAME, R.drawable.ic_notify_update))
setLargeIcon(context.appIconOf(packageName)?.toBitmap()) setExtras(Bundle().apply {
putParcelable("miui.appIcon", Icon.createWithBitmap(context.appIconOf(MODULE_PACKAGE_NAME)?.toBitmap()))
})
setContentIntent( setContentIntent(
PendingIntent.getActivity( PendingIntent.getActivity(
context, packageName.hashCode(), context, packageName.hashCode(),

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it
@@ -32,6 +32,7 @@ import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.graphics.drawable.VectorDrawable import android.graphics.drawable.VectorDrawable
import android.util.ArrayMap import android.util.ArrayMap
import androidx.core.graphics.createBitmap
import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toBitmap
import com.fankes.miui.notify.utils.factory.safeOfFalse import com.fankes.miui.notify.utils.factory.safeOfFalse
import kotlin.math.abs import kotlin.math.abs
@@ -77,7 +78,7 @@ object BitmapCompatTool {
var width = bitmap.width var width = bitmap.width
if (height > 64 || width > 64) { if (height > 64 || width > 64) {
if (tempCompactBitmap == null) { if (tempCompactBitmap == null) {
tempCompactBitmap = Bitmap.createBitmap(64, 64, Bitmap.Config.ARGB_8888) tempCompactBitmap = createBitmap(64, 64)
.also { tempCompactBitmapCanvas = Canvas(it) } .also { tempCompactBitmapCanvas = Canvas(it) }
tempCompactBitmapPaint = Paint(Paint.FILTER_BITMAP_FLAG).apply { isFilterBitmap = true } tempCompactBitmapPaint = Paint(Paint.FILTER_BITMAP_FLAG).apply { isFilterBitmap = true }
} }
@@ -91,11 +92,12 @@ object BitmapCompatTool {
val size = height * width val size = height * width
ensureBufferSize(size) ensureBufferSize(size)
tempCompactBitmap?.getPixels(tempBuffer, 0, width, 0, 0, width, height) tempCompactBitmap?.getPixels(tempBuffer, 0, width, 0, 0, width, height)
for (i in 0 until size) for (i in 0 until size) {
if (isGrayscaleColor(tempBuffer[i]).not()) { if (isGrayscaleColor(tempBuffer[i]).not()) {
cachedBitmapGrayscales[bitmap.generationId] = false cachedBitmapGrayscales[bitmap.generationId] = false
return@let false return@let false
} }
}
cachedBitmapGrayscales[bitmap.generationId] = true cachedBitmapGrayscales[bitmap.generationId] = true
true true
} }

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it
@@ -31,6 +31,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.drawable.Icon import android.graphics.drawable.Icon
import android.os.Build import android.os.Build
import android.os.Bundle
import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toBitmap
import com.fankes.miui.notify.R import com.fankes.miui.notify.R
import com.fankes.miui.notify.hook.HookEntry import com.fankes.miui.notify.hook.HookEntry
@@ -80,7 +81,9 @@ object IconAdaptationTool {
setColor(0xFF2993F0.toInt()) setColor(0xFF2993F0.toInt())
setAutoCancel(true) setAutoCancel(true)
setSmallIcon(Icon.createWithResource(MODULE_PACKAGE_NAME, R.drawable.ic_unsupported)) setSmallIcon(Icon.createWithResource(MODULE_PACKAGE_NAME, R.drawable.ic_unsupported))
setLargeIcon(context.appIconOf(packageName)?.toBitmap()) setExtras(Bundle().apply {
putParcelable("miui.appIcon", Icon.createWithBitmap(context.appIconOf(MODULE_PACKAGE_NAME)?.toBitmap()))
})
setContentIntent( setContentIntent(
PendingIntent.getActivity( PendingIntent.getActivity(
context, packageName.hashCode(), context, packageName.hashCode(),

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it
@@ -83,7 +83,7 @@ object IconRuleManagerTool {
private const val SYNC_DIRECT_URL = "https://raw.githubusercontent.com/fankes/AndroidNotifyIconAdapt/main" private const val SYNC_DIRECT_URL = "https://raw.githubusercontent.com/fankes/AndroidNotifyIconAdapt/main"
/** 同步地址 - GitHub Raw (代理 - GitHub Proxy) */ /** 同步地址 - GitHub Raw (代理 - GitHub Proxy) */
private const val SYNC_PROXY_1_URL = "https://ghproxy.com/$SYNC_DIRECT_URL" private const val SYNC_PROXY_1_URL = "https://ghp.ci/$SYNC_DIRECT_URL"
/** 同步地址 - GitHub Raw (代理 - 7ED Services) */ /** 同步地址 - GitHub Raw (代理 - 7ED Services) */
private const val SYNC_PROXY_2_URL = "https://raw.githubusercontentS.com/fankes/AndroidNotifyIconAdapt/main" private const val SYNC_PROXY_2_URL = "https://raw.githubusercontentS.com/fankes/AndroidNotifyIconAdapt/main"
@@ -248,7 +248,7 @@ object IconRuleManagerTool {
notifyRefresh(context) notifyRefresh(context)
callback() callback()
} }
else -> (if (context is AppCompatActivity) context.snake(msg = "列表数据已是最新")) else -> (if (context is AppCompatActivity) context.snake(msg = "列表数据已是最新") else Unit)
} }
} }
context is AppCompatActivity -> context is AppCompatActivity ->
@@ -298,7 +298,7 @@ object IconRuleManagerTool {
notifyRefresh(context) notifyRefresh(context)
callback() callback()
} }
else -> (if (context is AppCompatActivity) context.snake(msg = "列表数据已是最新")) else -> (if (context is AppCompatActivity) context.snake(msg = "列表数据已是最新") else Unit)
} }
context is AppCompatActivity -> context is AppCompatActivity ->
context.showDialog { context.showDialog {

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1,6 +1,6 @@
/* /*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team. * MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2017-2023 Fankes Studio(qzmmcn@163.com) * Copyright (C) 2017 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon * https://github.com/fankes/MIUINativeNotifyIcon
* *
* This software is non-free but opensource software: you can redistribute it * This software is non-free but opensource software: you can redistribute it

View File

@@ -1105,6 +1105,34 @@
android:textSize="12sp" /> android:textSize="12sp" />
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/miui_focus_notify_icon_fix_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_focus_notify_icon_fix_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="是否强制启用焦点通知反色,由于无法准确判断反色,所以给了个强制开关。(默认关闭)"
android:textColor="@color/colorTextDark"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/notify_icon_fix_notify_item" android:id="@+id/notify_icon_fix_notify_item"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -1457,6 +1485,35 @@
android:textColor="@color/colorTextGray" android:textColor="@color/colorTextGray"
android:textSize="11sp" /> android:textSize="11sp" />
</LinearLayout> </LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="10dp"
android:background="@drawable/bg_permotion_round"
android:gravity="center|start"
android:orientation="horizontal"
android:padding="10dp">
<ImageView
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginEnd="10dp"
android:src="@mipmap/ic_kavaref" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autoLink="web"
android:ellipsize="end"
android:lineSpacingExtra="6dp"
android:maxLines="2"
android:text="此模块使用 KavaRef 强力驱动。\n了解更多 https://github.com/HighCapable/KavaRef"
android:textColor="@color/colorTextGray"
android:textSize="11sp" />
</LinearLayout>
</LinearLayout> </LinearLayout>
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
</LinearLayout> </LinearLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -1,5 +1,21 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
plugins { plugins {
autowire(libs.plugins.android.application) apply false autowire(libs.plugins.android.application) apply false
autowire(libs.plugins.kotlin.android) apply false autowire(libs.plugins.kotlin.android) apply false
autowire(libs.plugins.kotlin.ksp) apply false autowire(libs.plugins.kotlin.ksp) apply false
}
allprojects {
tasks.withType<KotlinJvmCompile>().configureEach {
compilerOptions {
jvmTarget = JvmTarget.JVM_17
freeCompilerArgs.addAll(
"-Xno-param-assertions",
"-Xno-call-assertions",
"-Xno-receiver-assertions"
)
}
}
} }

View File

@@ -3,12 +3,11 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
android.useAndroidX=true android.useAndroidX=true
android.nonTransitiveRClass=true android.nonTransitiveRClass=true
kotlin.code.style=official kotlin.code.style=official
kotlin.incremental.useClasspathSnapshot=true
# Project Configuration # Project Configuration
project.name=MIUINativeNotifyIcon project.name=MIUINativeNotifyIcon
project.android.compileSdk=34 project.android.compileSdk=36
project.android.minSdk=28 project.android.minSdk=28
project.android.targetSdk=34 project.android.targetSdk=36
project.app.packageName=com.fankes.miui.notify project.app.packageName=com.fankes.miui.notify
project.app.versionName="2.110" project.app.versionName="2.110"
project.app.versionCode=42 project.app.versionCode=42

View File

@@ -22,13 +22,13 @@ repositories:
plugins: plugins:
com.android.application: com.android.application:
alias: android-application alias: android-application
version: 8.1.2 version: 8.12.1
org.jetbrains.kotlin.android: org.jetbrains.kotlin.android:
alias: kotlin-android alias: kotlin-android
version: 1.9.10 version: 2.2.10
com.google.devtools.ksp: com.google.devtools.ksp:
alias: kotlin-ksp alias: kotlin-ksp
version: 1.9.10-1.0.13 version: 2.2.10-2.0.2
libraries: libraries:
com.fankes.projectpromote: com.fankes.projectpromote:
@@ -43,36 +43,42 @@ libraries:
rovo89-xposed-api rovo89-xposed-api
com.highcapable.yukihookapi: com.highcapable.yukihookapi:
api: api:
version: 1.2.0 version: 1.3.0
ksp-xposed: ksp-xposed:
version-ref: <this>::api version-ref: <this>::api
com.highcapable.kavaref:
kavaref-core:
version: 1.0.1
kavaref-extension:
version: 1.0.1
com.github.topjohnwu.libsu: com.github.topjohnwu.libsu:
core: core:
version: 5.2.1 version: 5.2.2
auto-update: false
com.github.duanhong169: com.github.duanhong169:
drawabletoolbox: drawabletoolbox:
version: 1.0.7 version: 1.0.7
com.squareup.okhttp3: com.squareup.okhttp3:
okhttp: okhttp:
version: 5.0.0-alpha.11 version: 5.1.0
androidx.core: androidx.core:
core-ktx: core-ktx:
version: 1.12.0 version: 1.17.0
androidx.appcompat: androidx.appcompat:
appcompat: appcompat:
version: 1.6.1 version: 1.7.1
com.google.android.material: com.google.android.material:
material: material:
version: 1.10.0 version: 1.12.0
androidx.constraintlayout: androidx.constraintlayout:
constraintlayout: constraintlayout:
version: 2.1.4 version: 2.2.1
androidx.test.ext: androidx.test.ext:
junit: junit:
version: 1.1.5 version: 1.3.0
androidx.test.espresso: androidx.test.espresso:
espresso-core: espresso-core:
version: 3.5.1 version: 3.7.0
junit: junit:
junit: junit:
version: 4.13.2 version: 4.13.2

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

View File

@@ -6,8 +6,8 @@ pluginManagement {
} }
} }
plugins { plugins {
id("com.highcapable.sweetdependency") version "1.0.2" id("com.highcapable.sweetdependency") version "1.0.4"
id("com.highcapable.sweetproperty") version "1.0.3" id("com.highcapable.sweetproperty") version "1.0.8"
} }
sweetProperty { sweetProperty {
global { global {
@@ -15,7 +15,11 @@ sweetProperty {
permanentKeyValues("GITHUB_CI_COMMIT_ID" to "") permanentKeyValues("GITHUB_CI_COMMIT_ID" to "")
generateFrom(ROOT_PROJECT, SYSTEM_ENV) generateFrom(ROOT_PROJECT, SYSTEM_ENV)
} }
sourcesCode { includeKeys("GITHUB_CI_COMMIT_ID") } sourcesCode {
includeKeys("GITHUB_CI_COMMIT_ID")
// 关闭类型自动转换功能,防止一些特殊 "COMMIT ID" 被生成为数值
isEnableTypeAutoConversion = false
}
} }
rootProject { all { isEnable = false } } rootProject { all { isEnable = false } }
} }