26 Commits
2.2 ... 2.5

Author SHA1 Message Date
25399cd88b Update version to 2.5 2022-04-14 03:11:17 +08:00
18691d8b8d 更换通知刷新方案,彻底解决系统界面卡死问题 2022-04-14 02:55:43 +08:00
7c61b09054 Update YukiHookAPI 2022-04-13 04:59:35 +08:00
7a7e179a2b Merge code 2022-04-11 23:07:37 +08:00
dbd7dbf172 Update YukiHookAPI 2022-04-10 03:13:04 +08:00
502e5dc04b Update YukiHookAPI 2022-04-09 02:32:13 +08:00
ff0c57319a Update README.md 2022-04-09 01:50:24 +08:00
647a39c327 Update README.md 2022-04-05 22:45:32 +08:00
04e8d43356 加入新安装应用的通知图标优化适配通知忽略 DEBUG 版本的 APP 2022-04-05 21:56:37 +08:00
f85d2db36e Update YukiHookAPI 2022-04-04 22:55:09 +08:00
2e5284ebe9 Update version to 2.35 2022-04-04 13:55:10 +08:00
abffc4d853 Update version to 2.35 2022-04-04 13:54:42 +08:00
5d81b8ff87 尝试修复 MIUI 12 的问题 2022-04-04 13:48:54 +08:00
d91d2736e6 修复图标缓存过大造成系统界面停止运行的问题 2022-04-04 13:38:38 +08:00
72169989f2 Merge code 2022-04-04 12:04:12 +08:00
c85da002f5 Update YukiHookAPI 2022-04-04 03:13:19 +08:00
c09a1b5760 Update README.md 2022-03-30 20:56:52 +08:00
c30e56c5aa Update YukiHookAPI 2022-03-30 14:13:48 +08:00
822e988c16 Update version to 2.3 2022-03-29 23:50:37 +08:00
fc728a75a4 Update version to 2.3 2022-03-29 23:50:09 +08:00
256e2ebfce 优化 Android 12 风格通知图标深色模式的颜色 2022-03-29 23:47:21 +08:00
be4b952f62 修复折叠情况下的经典通知图标无变化问题,添加安卓 12 以下系统经典通知情况下图标颜色实时跟随壁纸功能 2022-03-29 23:14:57 +08:00
c7263c6d94 Fix a receiver bug 2022-03-29 21:46:20 +08:00
4733578912 Update YukiHookAPI 2022-03-29 21:05:49 +08:00
87879301f0 Update YukiHookAPI 2022-03-29 21:04:03 +08:00
c9be72e5f7 Update version to 2.2 2022-03-28 14:16:58 +08:00
12 changed files with 288 additions and 165 deletions

View File

@@ -2,52 +2,61 @@
[![Blank](https://img.shields.io/badge/build-passing-brightgreen)](https://github.com/fankes/MIUINativeNotifyIcon) [![Blank](https://img.shields.io/badge/build-passing-brightgreen)](https://github.com/fankes/MIUINativeNotifyIcon)
[![Blank](https://img.shields.io/badge/license-AGPL3.0-blue)](https://github.com/fankes/MIUINativeNotifyIcon/blob/master/LICENSE) [![Blank](https://img.shields.io/badge/license-AGPL3.0-blue)](https://github.com/fankes/MIUINativeNotifyIcon/blob/master/LICENSE)
[![Blank](https://img.shields.io/badge/version-v2.2-green)](https://github.com/fankes/MIUINativeNotifyIcon/releases) [![Blank](https://img.shields.io/badge/version-v2.5-green)](https://github.com/fankes/MIUINativeNotifyIcon/releases)
[![Blank](https://img.shields.io/github/downloads/fankes/MIUINativeNotifyIcon/total?label=Release)](https://github.com/fankes/MIUINativeNotifyIcon/releases) [![Blank](https://img.shields.io/github/downloads/fankes/MIUINativeNotifyIcon/total?label=Release)](https://github.com/fankes/MIUINativeNotifyIcon/releases)
[![Blank](https://img.shields.io/github/downloads/Xposed-Modules-Repo/com.fankes.miui.notify/total?label=LSPosed%20Repo&logo=Android&style=flat&labelColor=F48FB1&logoColor=ffffff)](https://github.com/Xposed-Modules-Repo/com.fankes.miui.notify/releases) [![Blank](https://img.shields.io/github/downloads/Xposed-Modules-Repo/com.fankes.miui.notify/total?label=LSPosed%20Repo&logo=Android&style=flat&labelColor=F48FB1&logoColor=ffffff)](https://github.com/Xposed-Modules-Repo/com.fankes.miui.notify/releases)
[![Telegram](https://img.shields.io/static/v1?label=Telegram&message=交流讨论&color=0088cc)](https://t.me/XiaofangInternet) [![Telegram](https://img.shields.io/badge/Follow-Telegram-blue.svg?logo=telegram)](https://t.me/XiaofangInternet)
<br/><br/> <br/><br/>
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/app/src/main/ic_launcher-playstore.png" width = "100" height = "100"/> <img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/app/src/main/ic_launcher-playstore.png" width = "100" height = "100"/>
<br/> <br/>
Fix the native notification bar icon function abandoned by the MIUI development team.<br/> Fix the native notification bar icon function abandoned by the MIUI development team.<br/>
修复被 MIUI 开发组丢弃的原生通知图标,支持 MIUI 12、12.5、13 以及最新版本。 修复被 MIUI 开发组丢弃的原生通知图标,支持 MIUI 12、12.5、13 以及最新版本。
# Developer ## Developer
[酷安 @星夜不荟](http://www.coolapk.com/u/876977) [酷安 @星夜不荟](http://www.coolapk.com/u/876977)
# 适配说明 ## 适配说明
- 此模块仅支持 <b>LSPosed</b>(作用域“系统界面”)、<b>~~EdXposed(随时停止支持)~~</b>、不支持<b>太极、无极</b> - 此模块仅支持 <b>LSPosed</b>(作用域“系统界面”)、<b>~~EdXposed(随时停止支持)~~</b>、不支持<b>太极、无极</b>
- 请确保你使用的是 MIUI 官方版本,任何第三方官改包发生的问题,开发者没有义务去解决和修复,请自求多福 - 请确保你使用的是 MIUI 官方版本,任何第三方官改包发生的问题,开发者没有义务去解决和修复,请自求多福
- 目前最低支持基于 Android 9 版本的 MIUI 12 或 MIUI 12.5(最低建议) - 目前最低支持基于 Android 9 版本的 MIUI 12 或 MIUI 12.5(最低建议)
- 建议最低从 MIUI 12.5 `2021-5-18` 开发版以后开始使用模块,之前的版本可能或多或少存在 MIUI 自身 BUG 不生效、黑白块的问题 - 建议最低从 MIUI 12.5 `2021-5-18` 开发版以后开始使用模块,之前的版本可能或多或少存在 MIUI 自身 BUG 不生效、黑白块的问题
- 请始终保持最新版本的 LSPosed旧版本可能会出现 Hook 不生效的问题,若最新版本依然不生效请在作用域中长按“系统界面”(“系统 UI”)选择重新优化 - 请始终保持最新版本的 LSPosed旧版本可能会出现 Hook 不生效的问题,若最新版本依然不生效请在作用域中长按“系统界面”(“系统 UI”)选择重新优化
# 请勿用于非法用途 ## 请勿用于非法用途
- 本模块完全开源免费,如果好用你可以打赏支持开发,但是请不要用于非法用途。 - 本模块完全开源免费,如果好用你可以打赏支持开发,但是请不要用于非法用途。
- 本模块发布地址仅有 [Xposed-Modules-Repo](https://github.com/Xposed-Modules-Repo/com.fankes.miui.notify/releases)、 - 本模块发布地址仅有 [Xposed-Modules-Repo](https://github.com/Xposed-Modules-Repo/com.fankes.miui.notify/releases)、
[Release](https://github.com/fankes/MIUINativeNotifyIcon/releases) [Release](https://github.com/fankes/MIUINativeNotifyIcon/releases)
及 [蓝奏云](https://fankes.lanzouy.com/b030o2e8h),从其他非正规渠道下载到的版本或对您造成任何影响均与我们无关。 及 [蓝奏云](https://fankes.lanzouy.com/b030o2e8h),从其他非正规渠道下载到的版本或对您造成任何影响均与我们无关。
# 贡献通知图标优化名单 ## 贡献通知图标优化名单
此项目是 `AndroidNotifyIconAdapt` 项目的一部分,详情请参考下方。<br/> 此项目是 `AndroidNotifyIconAdapt` 项目的一部分,详情请参考下方。
- [Android 通知图标规范适配计划](https://github.com/fankes/AndroidNotifyIconAdapt) - [Android 通知图标规范适配计划](https://github.com/fankes/AndroidNotifyIconAdapt)
# 历史背景 ## 历史背景
这个模块诞生来源于 MIUI 的乱改和不规范,本来 MIUI 9 之后,官方给出了原生通知图标样式,后面由于用户反应通知栏经常出现黑白块。
这当然不是系统的错,而是国内 APP 和 `MIPUSH` 的通知极其不规范的通知图标设计。
但是呢,接到反馈后 MIUI 开发组选择直接忽略这个问题,在 `2021-5-18` 的开发版开始,把全部通知图标都改成了 APP 的彩色图标,使得之前拥有自有样式的原生图标也被破坏。
对于 Android 开发者来说,官方文档中的 `setSmallIcon` 不再适用于魔改后的 MIUI这将会严重破坏非常多的状态图标。
当然,国内的手机生态除了 `MIPUSH` 的营销通知就是社交软件的通知,可能大部分人都不会在意这件事情。
这个模块诞生来源于 MIUI 的乱改和不规范,本来 MIUI 9 之后,官方给出了原生通知图标样式,后面由于用户反应通知栏经常出现黑白块。<br/><br/>
这当然不是系统的错,而是国内 APP 和 `MIPUSH` 的通知极其不规范的通知图标设计。<br/><br/>
但是呢,接到反馈后 MIUI 开发组选择直接忽略这个问题,在 `2021-5-18` 的开发版开始,把全部通知图标都改成了 APP 的彩色图标,使得之前拥有自有样式的原生图标也被破坏。<br/><br/>
对于 Android 开发者来说,官方文档中的 `setSmallIcon` 不再适用于魔改后的 MIUI这将会严重破坏非常多的状态图标。<br/><br/>
当然,国内的手机生态除了 `MIPUSH` 的营销通知就是社交软件的通知,可能大部分人都不会在意这件事情。<br/><br/>
但是,这个模块就是为了修复被 MIUI 开发组忽略的图标问题才诞生的,并完美地给 MIUI 修复了黑白块图标的问题。 但是,这个模块就是为了修复被 MIUI 开发组忽略的图标问题才诞生的,并完美地给 MIUI 修复了黑白块图标的问题。
<br/>
# 探索历程 ## 探索历程
原生 Android 的小图标和通知图标具有状态性。<br/><br/> 原生 Android 的小图标和通知图标具有状态性。<br/><br/>
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/native.jpg" height = "35"/><br/><br/> <img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/native.jpg" height = "35"/><br/><br/>
@@ -59,9 +68,11 @@ Fix the native notification bar icon function abandoned by the MIUI development
而 MIUI 做了什么呢?<br/><br/> 而 MIUI 做了什么呢?<br/><br/>
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/miui_n_1.jpg" height = "100"/><br/> <img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/miui_n_1.jpg" height = "100"/><br/>
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/miui_n_2.jpg" height = "100"/><br/><br/> <img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/miui_n_2.jpg" height = "100"/><br/><br/>
不曾记得是什么版本开始MIUI 把通知图标改成了这个鬼样子,寻找开发组提案也是无人问津,最后转念一想,自己干吧。<br/><br/> 不曾记得是什么版本开始MIUI 把通知图标改成了这个鬼样子,寻找开发组提案也是无人问津,最后转念一想,自己干吧。
由于目前大量通知图标都来自 `MIPUSH` 发出的营销通知,而 `MIPUSH` 的图标都是统一的彩色应用图标,很多应用也没有适配这一特性, 在通知栏广告满天飞的情况下MIUI 由于目前大量通知图标都来自 `MIPUSH` 发出的营销通知,而 `MIPUSH` 的图标都是统一的彩色应用图标,很多应用也没有适配这一特性, 在通知栏广告满天飞的情况下MIUI
选择放弃原生通知功能,而做出这种违反原生通知规则的做法,而这些彩色图标被设置为单色调图标,也确实会发生黑白块的问题,但是同时又会破坏遵守规范的图标。<br/><br/> 选择放弃原生通知功能,而做出这种违反原生通知规则的做法,而这些彩色图标被设置为单色调图标,也确实会发生黑白块的问题,但是同时又会破坏遵守规范的图标。
真的没有办法了吗?在不断探索下,我找到了原生支持色彩判断的类。 真的没有办法了吗?在不断探索下,我找到了原生支持色彩判断的类。
```kotlin ```kotlin
@@ -74,18 +85,28 @@ com.android.internal.util.ContrastColorUtil
ContrastColorUtil.getInstance().isGrayscaleIcon(drawable) ContrastColorUtil.getInstance().isGrayscaleIcon(drawable)
``` ```
问题就被解决了,顺便修了一下被 MIUI 破坏的通知图标以及优化了一下应用本身方块图标的圆角......<br/><br/> 问题就被解决了,顺便修了一下被 MIUI 破坏的通知图标以及优化了一下应用本身方块图标的圆角......
最后,我想大声问一句 MIUI 开发组:“就这?” 就这么简单的问题为什么拖了这么长时间也没有结论,还要交给用户去修复,这真的是一种负责任的表现吗?<br/><br/>
后来一想,也是啊,被国内生态毒害的用户,怎么可能会去想到这些问题呢,最后只能是我自作多情,还对 MIUI 留有一点情怀吧。<br/><br/> 最后,我想大声问一句 MIUI 开发组:“就这?” 就这么简单的问题为什么拖了这么长时间也没有结论,还要交给用户去修复,这真的是一种负责任的表现吗?
后来一想,也是啊,被国内生态毒害的用户,怎么可能会去想到这些问题呢,最后只能是我自作多情,还对 MIUI 留有一点情怀吧。
——来自一个无可奈何的 MIUI 老用户 ——来自一个无可奈何的 MIUI 老用户
# 后记 ## 后记
近期重新适配了 MIUI 12、12.5、13 版本,每个版本的图标设置方法都不一样,而且改的乱七八糟的,我都要无语了,只能用了很多折中方案,毕竟我也没有那么大精力每个版本去修复,实在是累了。
特地的把自己能有的小米手机刷成各种 MIUI 版本去为酷友做专项适配,我也是很累了,也希望你们能够多多支持,也能让 MIUI 做得更好。
近期重新适配了 MIUI 12、12.5、13 版本,每个版本的图标设置方法都不一样,而且改的乱七八糟的,我都要无语了,只能用了很多折中方案,毕竟我也没有那么大精力每个版本去修复,实在是累了。<br/><br/>
特地的把自己能有的小米手机刷成各种 MIUI 版本去为酷友做专项适配,我也是很累了,也希望你们能够多多支持,也能让 MIUI 做得更好。<br/><br/>
MIUI 再不重写,怕是永远会变成安卓之光。雷军,金凡!! MIUI 再不重写,怕是永远会变成安卓之光。雷军,金凡!!
# 许可证 ## 捐赠支持
- 工作不易,无意外情况此项目将继续维护下去,提供更多可能,欢迎打赏。<br/><br/>
<img src="https://github.com/fankes/YuKiHookAPI/blob/master/img-src/wechat_code.jpg" width = "200" height = "200"/>
## 许可证
- [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.html) - [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.html)
@@ -106,5 +127,6 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
``` ```
Powered by [YukiHookAPI](https://github.com/fankes/YukiHookAPI)<br/><br/> Powered by [YukiHookAPI](https://github.com/fankes/YukiHookAPI)
版权所有 © 2019-2022 Fankes Studio(qzmmcn@163.com) 版权所有 © 2019-2022 Fankes Studio(qzmmcn@163.com)

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id 'com.android.application' id 'com.android.application'
id 'kotlin-android' id 'kotlin-android'
id 'com.google.devtools.ksp' version '1.6.10-1.0.2' id 'com.google.devtools.ksp' version '1.6.10-1.0.4'
} }
android { android {
@@ -38,17 +38,17 @@ android {
buildTypes { buildTypes {
release { release {
minifyEnabled true minifyEnabled rootProject.ext.enableR8
signingConfig signingConfigs.debug signingConfig signingConfigs.debug
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
} }
} }
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_11
} }
kotlinOptions { kotlinOptions {
jvmTarget = '1.8' jvmTarget = '11'
} }
buildFeatures { buildFeatures {
viewBinding true viewBinding true
@@ -72,8 +72,8 @@ tasks.whenTaskAdded {
dependencies { dependencies {
compileOnly 'de.robv.android.xposed:api:82' compileOnly 'de.robv.android.xposed:api:82'
implementation 'com.highcapable.yukihookapi:api:1.0.67' implementation 'com.highcapable.yukihookapi:api:1.0.75'
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.0.67' ksp 'com.highcapable.yukihookapi:ksp-xposed:1.0.75'
implementation "com.github.topjohnwu.libsu:core:3.1.2" implementation "com.github.topjohnwu.libsu:core:3.1.2"
implementation 'androidx.annotation:annotation:1.3.0' implementation 'androidx.annotation:annotation:1.3.0'
implementation 'com.geyifeng.immersionbar:immersionbar:3.2.0' implementation 'com.geyifeng.immersionbar:immersionbar:3.2.0'

View File

@@ -41,7 +41,7 @@ object Const {
const val MODULE_VERSION_CODE = BuildConfig.VERSION_CODE const val MODULE_VERSION_CODE = BuildConfig.VERSION_CODE
/** 当前模块的版本校验 */ /** 当前模块的版本校验 */
const val MODULE_VERSION_VERIFY = "${MODULE_VERSION_NAME}_${MODULE_VERSION_CODE}_202203281323" const val MODULE_VERSION_VERIFY = "${MODULE_VERSION_NAME}_${MODULE_VERSION_CODE}_202204140309"
/** 当前模块的版本校验标签 */ /** 当前模块的版本校验标签 */
const val MODULE_VERSION_VERIFY_TAG = "module_version_verify" const val MODULE_VERSION_VERIFY_TAG = "module_version_verify"

View File

@@ -23,6 +23,7 @@
package com.fankes.miui.notify.hook.entity package com.fankes.miui.notify.hook.entity
import android.app.NotificationManager import android.app.NotificationManager
import android.app.WallpaperManager
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@@ -40,6 +41,7 @@ import android.view.ViewGroup
import android.view.ViewOutlineProvider import android.view.ViewOutlineProvider
import android.widget.ImageView import android.widget.ImageView
import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toBitmap
import androidx.core.view.children
import com.fankes.miui.notify.bean.IconDataBean import com.fankes.miui.notify.bean.IconDataBean
import com.fankes.miui.notify.const.Const import com.fankes.miui.notify.const.Const
import com.fankes.miui.notify.data.DataConst import com.fankes.miui.notify.data.DataConst
@@ -53,10 +55,7 @@ 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.highcapable.yukihookapi.hook.bean.VariousClass import com.highcapable.yukihookapi.hook.bean.VariousClass
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
import com.highcapable.yukihookapi.hook.factory.field import com.highcapable.yukihookapi.hook.factory.*
import com.highcapable.yukihookapi.hook.factory.hasField
import com.highcapable.yukihookapi.hook.factory.hasMethod
import com.highcapable.yukihookapi.hook.factory.method
import com.highcapable.yukihookapi.hook.log.loggerD import com.highcapable.yukihookapi.hook.log.loggerD
import com.highcapable.yukihookapi.hook.log.loggerW import com.highcapable.yukihookapi.hook.log.loggerW
import com.highcapable.yukihookapi.hook.type.android.* import com.highcapable.yukihookapi.hook.type.android.*
@@ -71,62 +70,76 @@ class SystemUIHooker : YukiBaseHooker() {
companion object { companion object {
/** MIUI 新版本存在的类 */ /** MIUI 新版本存在的类 */
private const val SystemUIApplicationClass = "${SYSTEMUI_PACKAGE_NAME}.SystemUIApplication" private const val SystemUIApplicationClass = "$SYSTEMUI_PACKAGE_NAME.SystemUIApplication"
/** MIUI 新版本存在的类 */ /** MIUI 新版本存在的类 */
private const val NotificationHeaderViewWrapperInjectorClass = private const val NotificationHeaderViewWrapperInjectorClass =
"${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.row.wrapper.NotificationHeaderViewWrapperInjector" "$SYSTEMUI_PACKAGE_NAME.statusbar.notification.row.wrapper.NotificationHeaderViewWrapperInjector"
/** MIUI 新版本存在的类 */
private const val MiuiNotificationViewWrapperClass =
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.row.wrapper.MiuiNotificationViewWrapper"
/** MIUI 新版本存在的类 */
private const val MiuiNotificationChildrenContainerClass =
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.stack.MiuiNotificationChildrenContainer"
/** 原生存在的类 */
private const val NotificationChildrenContainerClass =
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.stack.NotificationChildrenContainer"
/** 原生存在的类 */ /** 原生存在的类 */
private const val ContrastColorUtilClass = "com.android.internal.util.ContrastColorUtil" private const val ContrastColorUtilClass = "com.android.internal.util.ContrastColorUtil"
/** 原生存在的类 */ /** 原生存在的类 */
private const val StatusBarIconViewClass = "${SYSTEMUI_PACKAGE_NAME}.statusbar.StatusBarIconView" private const val StatusBarIconViewClass = "$SYSTEMUI_PACKAGE_NAME.statusbar.StatusBarIconView"
/** 原生存在的类 */ /** 原生存在的类 */
private const val NotificationIconContainerClass = "${SYSTEMUI_PACKAGE_NAME}.statusbar.phone.NotificationIconContainer" private const val NotificationIconContainerClass = "$SYSTEMUI_PACKAGE_NAME.statusbar.phone.NotificationIconContainer"
/** 原生存在的类 */ /** 原生存在的类 */
private const val PluginManagerImplClass = "${SYSTEMUI_PACKAGE_NAME}.shared.plugins.PluginManagerImpl" private const val PluginManagerImplClass = "$SYSTEMUI_PACKAGE_NAME.shared.plugins.PluginManagerImpl"
/** MIUI 存在的类 - 旧版本没有 */
private const val MiuiNotificationViewWrapperClass =
"${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.row.wrapper.MiuiNotificationViewWrapper"
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val MiuiClockClass = VariousClass( private val MiuiClockClass = VariousClass(
"${SYSTEMUI_PACKAGE_NAME}.statusbar.views.MiuiClock", "$SYSTEMUI_PACKAGE_NAME.statusbar.views.MiuiClock",
"${SYSTEMUI_PACKAGE_NAME}.statusbar.policy.MiuiClock" "$SYSTEMUI_PACKAGE_NAME.statusbar.policy.MiuiClock"
)
/** 根据多个版本存在不同的包名相同的类 */
private val StatusBarNotificationPresenterClass = VariousClass(
"$SYSTEMUI_PACKAGE_NAME.statusbar.phone.StatusBarNotificationPresenter",
"$SYSTEMUI_PACKAGE_NAME.statusbar.phone.StatusBar"
) )
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val ExpandableNotificationRowClass = VariousClass( private val ExpandableNotificationRowClass = VariousClass(
"${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.row.ExpandableNotificationRow", "$SYSTEMUI_PACKAGE_NAME.statusbar.notification.row.ExpandableNotificationRow",
"${SYSTEMUI_PACKAGE_NAME}.statusbar.ExpandableNotificationRow" "$SYSTEMUI_PACKAGE_NAME.statusbar.ExpandableNotificationRow"
) )
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val NotificationViewWrapperClass = VariousClass( private val NotificationViewWrapperClass = VariousClass(
"${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.row.wrapper.NotificationViewWrapper", "$SYSTEMUI_PACKAGE_NAME.statusbar.notification.row.wrapper.NotificationViewWrapper",
"${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.NotificationViewWrapper" "$SYSTEMUI_PACKAGE_NAME.statusbar.notification.NotificationViewWrapper"
) )
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val NotificationHeaderViewWrapperClass = VariousClass( private val NotificationHeaderViewWrapperClass = VariousClass(
"${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper", "$SYSTEMUI_PACKAGE_NAME.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper",
"${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.NotificationHeaderViewWrapper" "$SYSTEMUI_PACKAGE_NAME.statusbar.notification.NotificationHeaderViewWrapper"
) )
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val NotificationUtilClass = VariousClass( private val NotificationUtilClass = VariousClass(
"${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.NotificationUtil", "$SYSTEMUI_PACKAGE_NAME.statusbar.notification.NotificationUtil",
"${SYSTEMUI_PACKAGE_NAME}.miui.statusbar.notification.NotificationUtil" "$SYSTEMUI_PACKAGE_NAME.miui.statusbar.notification.NotificationUtil"
) )
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val ExpandedNotificationClass = VariousClass( private val ExpandedNotificationClass = VariousClass(
"${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.ExpandedNotification", "$SYSTEMUI_PACKAGE_NAME.statusbar.notification.ExpandedNotification",
"${SYSTEMUI_PACKAGE_NAME}.miui.statusbar.ExpandedNotification" "$SYSTEMUI_PACKAGE_NAME.miui.statusbar.ExpandedNotification"
) )
} }
@@ -139,14 +152,14 @@ class SystemUIHooker : YukiBaseHooker() {
/** 是否已经使用过缓存刷新功能 */ /** 是否已经使用过缓存刷新功能 */
private var isUsingCachingMethod = false private var isUsingCachingMethod = false
/** 缓存的状态栏小图标实例 */ /** 状态栏通知图标容器 */
private var statusBarIconViews = HashSet<ImageView>() private var notificationIconContainer: ViewGroup? = null
/** 缓存的通知小图标包装纸实例 */ /** 通知栏通知控制器 */
private var notificationViewWrappers = HashSet<Any>() private var notificationPresenter: Any? = null
/** MIUI 样式下的缓存的通知小图标包装纸实例 */ /** 仅监听一次主题壁纸颜色变化 */
private var miuiNotificationViewWrappers = HashSet<Any>() private var isWallpaperColorListenerSetUp = false
/** 是否已经注册广播 */ /** 是否已经注册广播 */
private var isRegisterReceiver = false private var isRegisterReceiver = false
@@ -232,7 +245,7 @@ class SystemUIHooker : YukiBaseHooker() {
}.get(it.method { }.get(it.method {
name = "getInstance" name = "getInstance"
param(ContextClass) param(ContextClass)
}.get().invoke(context)).callBoolean(drawable) }.get().invoke(context)).boolean(drawable)
} }
} else BitmapCompatTool.isGrayscaleDrawable(drawable) } else BitmapCompatTool.isGrayscaleDrawable(drawable)
@@ -253,19 +266,10 @@ class SystemUIHooker : YukiBaseHooker() {
get() = safeOfFalse { get() = safeOfFalse {
NotificationUtilClass.clazz.hasMethod { NotificationUtilClass.clazz.hasMethod {
name = "ignoreStatusBarIconColor" name = "ignoreStatusBarIconColor"
param(ExpandedNotificationClass.clazz) param(ExpandedNotificationClass)
} }
} }
/**
* 获取当前通知栏的样式
*
* - ❗新版本可能不存在这个方法
* @return [Boolean]
*/
private val isShowMiuiStyle
get() = safeOfFalse { NotificationUtilClass.clazz.method { name = "showMiuiStyle" }.get().invoke() ?: false }
/** /**
* 处理为圆角图标 * 处理为圆角图标
* @return [Drawable] * @return [Drawable]
@@ -351,18 +355,31 @@ class SystemUIHooker : YukiBaseHooker() {
*/ */
private val globalContext private val globalContext
get() = safeOfNull { get() = safeOfNull {
SystemUIApplicationClass.clazz.method { name = "getContext" }.ignoredError().get().invoke<Context>() SystemUIApplicationClass.clazz.method { name = "getContext" }.ignoredError().get().invoke<Context?>() ?: appContext
}
/**
* 注册主题壁纸改变颜色监听
*
* - 仅限在 Android 12 以下注册
* @param view 实例
*/
private fun registerWallpaperColorChanged(view: View) = runInSafe {
if (isWallpaperColorListenerSetUp.not() && isUpperOfAndroidS.not()) view.apply {
WallpaperManager.getInstance(context).addOnColorsChangedListener({ _, _ -> refreshNotificationIcons() }, handler)
}
isWallpaperColorListenerSetUp = true
} }
/** 刷新状态栏小图标 */ /** 刷新状态栏小图标 */
private fun refreshStatusBarIcons() = runInSafe { private fun refreshStatusBarIcons() = runInSafe {
StatusBarIconViewClass.clazz.field { name = "mNotification" }.also { result -> StatusBarIconViewClass.clazz.field { name = "mNotification" }.also { result ->
statusBarIconViews.takeIf { it.isNotEmpty() }?.forEach { notificationIconContainer?.children?.forEach {
/** 得到通知实例 */ /** 得到通知实例 */
val nf = result.of<StatusBarNotification>(it) ?: return val nf = result.get(it).cast<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.setImageDrawable(e) } pair.first.let { e -> (it as? ImageView?)?.setImageDrawable(e) }
} }
} }
} }
@@ -370,13 +387,11 @@ class SystemUIHooker : YukiBaseHooker() {
/** 刷新通知小图标 */ /** 刷新通知小图标 */
private fun refreshNotificationIcons() = runInSafe { private fun refreshNotificationIcons() = runInSafe {
(if (hasHandleHeaderViews) notificationPresenter?.current {
NotificationHeaderViewWrapperClass.clazz.method { name = "handleHeaderViews" } method {
else NotificationHeaderViewWrapperClass.clazz.method { name = "resolveHeaderViews" }).also { result -> name = "updateNotificationsOnDensityOrFontScaleChanged"
notificationViewWrappers.takeIf { it.isNotEmpty() }?.forEach { result.get(it).call() } emptyParam()
} }.call()
MiuiNotificationViewWrapperClass.clazz.method { name = "handleViews" }.ignoredError().also { result ->
miuiNotificationViewWrappers.takeIf { it.isNotEmpty() }?.forEach { result.get(it).call() }
} }
} }
@@ -498,7 +513,10 @@ class SystemUIHooker : YukiBaseHooker() {
setColorFilter(if (isUseAndroid12Style || customIconColor == 0) supportColor else customIconColor) setColorFilter(if (isUseAndroid12Style || customIconColor == 0) supportColor else customIconColor)
/** Android 12 设置图标外圈颜色 */ /** Android 12 设置图标外圈颜色 */
if (isUseAndroid12Style && customIconColor != 0) if (isUseAndroid12Style && customIconColor != 0)
background = DrawableBuilder().rounded().solidColor(customIconColor).build() background = DrawableBuilder()
.rounded()
.solidColor(if (context.isSystemInDarkMode) customIconColor.brighter else customIconColor)
.build()
/** 设置原生的背景边距 */ /** 设置原生的背景边距 */
if (isUseAndroid12Style) setPadding(4.dp(context), 4.dp(context), 4.dp(context), 4.dp(context)) if (isUseAndroid12Style) setPadding(4.dp(context), 4.dp(context), 4.dp(context), 4.dp(context))
} else { } else {
@@ -511,8 +529,13 @@ class SystemUIHooker : YukiBaseHooker() {
/** 设置图标着色 */ /** 设置图标着色 */
setColorFilter(supportColor) setColorFilter(supportColor)
/** Android 12 设置图标外圈颜色 */ /** Android 12 设置图标外圈颜色 */
if (isUseAndroid12Style) background = (if (hasIconColor) iconColor else context.systemAccentColor).also {
DrawableBuilder().rounded().solidColor(if (hasIconColor) iconColor else context.systemAccentColor).build() if (isUseAndroid12Style)
background = DrawableBuilder()
.rounded()
.solidColor(if (context.isSystemInDarkMode) it.brighter else it)
.build()
}
/** 设置原生的背景边距 */ /** 设置原生的背景边距 */
if (isUseAndroid12Style) setPadding(4.dp(context), 4.dp(context), 4.dp(context), 4.dp(context)) if (isUseAndroid12Style) setPadding(4.dp(context), 4.dp(context), 4.dp(context), 4.dp(context))
} else iconImageView.apply { } else iconImageView.apply {
@@ -572,10 +595,10 @@ class SystemUIHooker : YukiBaseHooker() {
} }
/** /**
* 从 [NotificationViewWrapperClass] 中获取 [StatusBarNotification] * 从 [NotificationViewWrapperClass] 中获取 [ExpandableNotificationRowClass]
* @return [Pair] - ([Boolean] 通知是否展开,[StatusBarNotification] 通知实例) * @return [Pair] - ([Boolean] 通知是否展开,[Any] 通知 Row 实例)
*/ */
private fun Any.getSbnPair(): Pair<Boolean, StatusBarNotification?> { private fun Any.getRowPair(): Pair<Boolean, Any?> {
/** 通知是否展开 */ /** 通知是否展开 */
var isExpanded = false var isExpanded = false
@@ -583,16 +606,25 @@ class SystemUIHooker : YukiBaseHooker() {
* 从父类中得到 mRow 变量 - [ExpandableNotificationRowClass] * 从父类中得到 mRow 变量 - [ExpandableNotificationRowClass]
* 获取其中的得到通知方法 * 获取其中的得到通知方法
*/ */
val expandedNf = ExpandableNotificationRowClass.clazz val row = NotificationViewWrapperClass.clazz.field {
.method { name = "getEntry" }
.get(NotificationViewWrapperClass.clazz.field {
name = "mRow" name = "mRow"
}.get(this).self?.also { }.get(this).self?.also {
isExpanded = ExpandableNotificationRowClass.clazz.method { isExpanded = ExpandableNotificationRowClass.clazz.method {
name = "isExpanded" name = "isExpanded"
returnType = BooleanType returnType = BooleanType
}.get(it).callBoolean() }.get(it).boolean()
}).call()?.let { }
return Pair(isExpanded, row)
}
/**
* 从 [ExpandableNotificationRowClass] 中获取 [StatusBarNotification]
* @return [StatusBarNotification] or null
*/
private fun Any?.getSbn() =
ExpandableNotificationRowClass.clazz
.method { name = "getEntry" }
.get(this).call()?.let {
it.javaClass.method { it.javaClass.method {
name = "getSbn" name = "getSbn"
}.get(it).invoke<StatusBarNotification>() }.get(it).invoke<StatusBarNotification>()
@@ -600,8 +632,6 @@ class SystemUIHooker : YukiBaseHooker() {
.method { name = "getStatusBarNotification" } .method { name = "getStatusBarNotification" }
.get(NotificationViewWrapperClass.clazz.field { name = "mRow" }.get(this).self) .get(NotificationViewWrapperClass.clazz.field { name = "mRow" }.get(this).self)
.invoke<StatusBarNotification>() .invoke<StatusBarNotification>()
return Pair(isExpanded, expandedNf)
}
/** 缓存图标数据 */ /** 缓存图标数据 */
private fun cachingIconDatas() { private fun cachingIconDatas() {
@@ -636,38 +666,34 @@ class SystemUIHooker : YukiBaseHooker() {
injectMember { injectMember {
method { method {
name = "shouldSubstituteSmallIcon" name = "shouldSubstituteSmallIcon"
param(ExpandedNotificationClass.clazz) param(ExpandedNotificationClass)
} }
/** replaceToFalse()
* MIUI 12 在非原生样式下 MIPUSH 的图标着色异常
* 所以判断是 MIUI 样式就停止 Hook 状态栏图标
*/
replaceAny { hasIgnoreStatusBarIconColor.not() && isShowMiuiStyle }
} }
/** 强制回写系统的状态栏图标样式为原生 */ /** 强制回写系统的状态栏图标样式为原生 */
injectMember { injectMember {
var isUseLegacy = false var isUseLegacy = false
method { method {
name = "getSmallIcon" name = "getSmallIcon"
param(ExpandedNotificationClass.clazz, IntType) param(ExpandedNotificationClass, IntType)
}.remedys { }.remedys {
method { method {
name = "getSmallIcon" name = "getSmallIcon"
param(ExpandedNotificationClass.clazz) param(ExpandedNotificationClass)
} }
method { method {
name = "getSmallIcon" name = "getSmallIcon"
param(ContextClass, ExpandedNotificationClass.clazz) param(ContextClass, ExpandedNotificationClass)
}.onFind { isUseLegacy = true } }.onFind { isUseLegacy = true }
} }
afterHook { afterHook {
(globalContext ?: firstArgs())?.also { context -> (globalContext ?: args().first().cast())?.also { context ->
val expandedNf = args(if (isUseLegacy) 1 else 0).of<StatusBarNotification?>() val expandedNf = args(if (isUseLegacy) 1 else 0).cast<StatusBarNotification?>()
/** Hook 状态栏小图标 */ /** Hook 状态栏小图标 */
compatStatusIcon( compatStatusIcon(
context = context, context = context,
expandedNf, expandedNf,
(result as Icon).loadDrawable(context) result<Icon>()?.loadDrawable(context)
).also { pair -> if (pair.second) result = Icon.createWithBitmap(pair.first?.toBitmap()) } ).also { pair -> if (pair.second) result = Icon.createWithBitmap(pair.first?.toBitmap()) }
} }
} }
@@ -681,7 +707,7 @@ class SystemUIHooker : YukiBaseHooker() {
afterHook { afterHook {
instance<ImageView>().also { instance<ImageView>().also {
if (hasIgnoreStatusBarIconColor(it.context, field { name = "mNotification" } if (hasIgnoreStatusBarIconColor(it.context, field { name = "mNotification" }
.of<StatusBarNotification>(instance))) it.apply { .get(instance).cast<StatusBarNotification>())) it.apply {
alpha = 1f alpha = 1f
colorFilter = null colorFilter = null
} else it.apply { } else it.apply {
@@ -690,7 +716,7 @@ class SystemUIHooker : YukiBaseHooker() {
* 图标在任何场景下跟随状态栏其它图标保持半透明 * 图标在任何场景下跟随状态栏其它图标保持半透明
* MIUI 12 进行单独判断 * MIUI 12 进行单独判断
*/ */
field { name = "mCurrentSetColor" }.ofInt(instance).also { color -> field { name = "mCurrentSetColor" }.get(instance).int().also { color ->
if (hasIgnoreStatusBarIconColor) { if (hasIgnoreStatusBarIconColor) {
alpha = if (color.isWhite) 0.95f else 0.8f alpha = if (color.isWhite) 0.95f else 0.8f
setColorFilter(if (color.isWhite) color else Color.BLACK) setColorFilter(if (color.isWhite) color else Color.BLACK)
@@ -700,7 +726,7 @@ class SystemUIHooker : YukiBaseHooker() {
} }
} }
} }
/** 记录实例 */ /** 注册广播 */
injectMember { injectMember {
method { method {
name = "setNotification" name = "setNotification"
@@ -708,22 +734,33 @@ class SystemUIHooker : YukiBaseHooker() {
}.remedys { }.remedys {
method { method {
name = "setNotification" name = "setNotification"
param(ExpandedNotificationClass.clazz) param(ExpandedNotificationClass)
} }
} }
afterHook { afterHook {
if (firstArgs != null) instance<ImageView>().also { if (args[0] != null) instance<ImageView>().also {
/** 注册壁纸颜色监听 */
registerWallpaperColorChanged(it)
/** 注册广播 */
registerReceiver(it.context) registerReceiver(it.context)
statusBarIconViews.add(it)
} }
} }
} }
} }
/** 注入通知控制器实例 */
StatusBarNotificationPresenterClass.hook {
injectMember {
allConstructors()
afterHook { notificationPresenter = instance }
}
}
/** 注入状态栏通知图标容器实例 */ /** 注入状态栏通知图标容器实例 */
NotificationIconContainerClass.hook { NotificationIconContainerClass.hook {
injectMember { injectMember {
method { name = "calculateIconTranslations" } method { name = "calculateIconTranslations" }
afterHook { afterHook {
/** 缓存实例 */
notificationIconContainer = instance<ViewGroup>()
/** 修复部分开发版状态栏图标只能显示一个的问题 */ /** 修复部分开发版状态栏图标只能显示一个的问题 */
when (miuiIncrementalVersion.lowercase()) { when (miuiIncrementalVersion.lowercase()) {
"22.3.14", "22.3.15", "22.3.16", "v13.0.1.1.16.dev", "22.3.18" -> "22.3.14", "22.3.15", "22.3.16", "v13.0.1.1.16.dev", "22.3.18" ->
@@ -740,14 +777,14 @@ class SystemUIHooker : YukiBaseHooker() {
.get(instance).set(prefs.get(DataConst.HOOK_STATUS_ICON_COUNT) .get(instance).set(prefs.get(DataConst.HOOK_STATUS_ICON_COUNT)
.let { if (it in 0..100) it else 5 }) .let { if (it in 0..100) it else 5 })
} }
} }.by { NotificationIconContainerClass.clazz.hasField { name = "MAX_STATIC_ICONS" } }
/** 旧版方法 - 新版不存在 */ /** 旧版方法 - 新版不存在 */
injectMember { injectMember {
method { method {
name = "setMaxStaticIcons" name = "setMaxStaticIcons"
param(IntType) param(IntType)
} }
beforeHook { isShowNotificationIcons = (firstArgs<Int>() ?: 0) > 0 } beforeHook { isShowNotificationIcons = args().first().int() > 0 }
}.ignoredNoSuchMemberFailure() }.ignoredNoSuchMemberFailure()
/** 新版方法 - 旧版不存在 */ /** 新版方法 - 旧版不存在 */
injectMember { injectMember {
@@ -755,9 +792,9 @@ class SystemUIHooker : YukiBaseHooker() {
name = "miuiShowNotificationIcons" name = "miuiShowNotificationIcons"
param(BooleanType) param(BooleanType)
} }
beforeHook { isShowNotificationIcons = firstArgs<Boolean>() ?: false } beforeHook { isShowNotificationIcons = args().first().boolean() }
}.ignoredNoSuchMemberFailure() }.ignoredNoSuchMemberFailure()
}.by { NotificationIconContainerClass.clazz.hasField { name = "MAX_STATIC_ICONS" } } }
/** 注入原生通知包装纸实例 */ /** 注入原生通知包装纸实例 */
NotificationHeaderViewWrapperClass.hook { NotificationHeaderViewWrapperClass.hook {
/** 修复下拉通知图标自动设置回 APP 图标的方法 */ /** 修复下拉通知图标自动设置回 APP 图标的方法 */
@@ -769,29 +806,27 @@ class SystemUIHooker : YukiBaseHooker() {
/** 获取小图标 */ /** 获取小图标 */
val iconImageView = val iconImageView =
NotificationHeaderViewWrapperClass.clazz NotificationHeaderViewWrapperClass.clazz
.field { name = "mIcon" }.of<ImageView>(instance) ?: return@afterHook .field { name = "mIcon" }.get(instance).cast<ImageView>() ?: return@afterHook
/** 获取 [ExpandableNotificationRowClass] */
val rowPair = instance.getRowPair()
/** 获取 [StatusBarNotification] */ /** 获取 [StatusBarNotification] */
val sbnPair = instance.getSbnPair() val expandedNf = rowPair.second.getSbn()
/** 通知是否展开 */ /** 通知是否展开 */
var isExpanded = sbnPair.first var isExpanded = rowPair.first
/** 获取优先级 */ /** 获取优先级 */
val importance = val importance =
(iconImageView.context.getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager?) (iconImageView.context.getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager?)
?.getNotificationChannel(sbnPair.second?.notification?.channelId)?.importance ?: 0 ?.getNotificationChannel(expandedNf?.notification?.channelId)?.importance ?: 0
/** 非最小化优先级的通知全部设置为展开状态 */ /** 非最小化优先级的通知全部设置为展开状态 */
if (importance != 1) isExpanded = true if (importance != 1) isExpanded = true
/** 执行 Hook */ /** 执行 Hook */
compatNotifyIcon(iconImageView.context, sbnPair.second, iconImageView, isExpanded) compatNotifyIcon(iconImageView.context, expandedNf, iconImageView, isExpanded)
} }
} }
/** 记录实例 */
injectMember {
constructor { param(ContextClass, ViewClass, ExpandableNotificationRowClass.clazz) }
afterHook { notificationViewWrappers.add(instance) }
}
} }
/** 修改 MIUI 风格通知栏的通知图标 */ /** 修改 MIUI 风格通知栏的通知图标 */
MiuiNotificationViewWrapperClass.hook { MiuiNotificationViewWrapperClass.hook {
@@ -799,15 +834,33 @@ class SystemUIHooker : YukiBaseHooker() {
injectMember { injectMember {
method { name = "handleAppIcon" } method { name = "handleAppIcon" }
replaceUnit { replaceUnit {
field { name = "mAppIcon" }.of<ImageView>(instance)?.apply { field { name = "mAppIcon" }.get(instance).cast<ImageView>()?.apply {
compatNotifyIcon(context, instance.getSbnPair().second, iconImageView = this, isUseAndroid12Style = true) compatNotifyIcon(
context = context,
expandedNf = instance.getRowPair().second.getSbn(),
iconImageView = this,
isUseAndroid12Style = true
)
} }
} }
} }
/** 记录实例 */ }.ignoredHookClassNotFoundFailure()
/** 修改 MIUI 风格通知栏的通知图标 - 折叠通知 */
MiuiNotificationChildrenContainerClass.hook {
/** 替换通知小图标 */
injectMember { injectMember {
constructor { param(ContextClass, ViewClass, ExpandableNotificationRowClass.clazz) } method {
afterHook { miuiNotificationViewWrappers.add(instance) } name = "updateAppIcon"
param(BooleanType)
}
afterHook {
val expandedNf = NotificationChildrenContainerClass.clazz.field {
name = "mContainingNotification"
}.get(instance).self.getSbn()
field { name = "mAppIcon" }.get(instance).cast<ImageView>()?.apply {
compatNotifyIcon(context, expandedNf, iconImageView = this, isUseAndroid12Style = true)
}
}
} }
}.ignoredHookClassNotFoundFailure() }.ignoredHookClassNotFoundFailure()
/** 干掉下拉通知图标自动设置回 APP 图标的方法 */ /** 干掉下拉通知图标自动设置回 APP 图标的方法 */
@@ -815,11 +868,11 @@ class SystemUIHooker : YukiBaseHooker() {
injectMember { injectMember {
method { method {
name = "setAppIcon" name = "setAppIcon"
param(ContextClass, ImageViewClass, ExpandedNotificationClass.clazz) param(ContextClass, ImageViewClass, ExpandedNotificationClass)
}.remedys { }.remedys {
method { method {
name = "setAppIcon" name = "setAppIcon"
param(ImageViewClass, ExpandedNotificationClass.clazz) param(ImageViewClass, ExpandedNotificationClass)
} }
} }
intercept() intercept()
@@ -827,7 +880,7 @@ class SystemUIHooker : YukiBaseHooker() {
injectMember { injectMember {
method { method {
name = "resetIconBgAndPaddings" name = "resetIconBgAndPaddings"
param(ImageViewClass, ExpandedNotificationClass.clazz) param(ImageViewClass, ExpandedNotificationClass)
} }
intercept() intercept()
}.ignoredNoSuchMemberFailure() }.ignoredNoSuchMemberFailure()
@@ -840,7 +893,7 @@ class SystemUIHooker : YukiBaseHooker() {
param(ContextClass, IntentClass) param(ContextClass, IntentClass)
} }
afterHook { afterHook {
if (isEnableHookColorNotifyIcon()) (lastArgs as? Intent)?.also { if (isEnableHookColorNotifyIcon()) args().last().cast<Intent>()?.also {
if (it.action.equals(Intent.ACTION_PACKAGE_REPLACED).not() && if (it.action.equals(Intent.ACTION_PACKAGE_REPLACED).not() &&
it.getBooleanExtra(Intent.EXTRA_REPLACING, false) it.getBooleanExtra(Intent.EXTRA_REPLACING, false)
) return@also ) return@also
@@ -850,11 +903,11 @@ class SystemUIHooker : YukiBaseHooker() {
if (iconDatas.takeIf { e -> e.isNotEmpty() } if (iconDatas.takeIf { e -> e.isNotEmpty() }
?.filter { e -> e.packageName == newPkgName } ?.filter { e -> e.packageName == newPkgName }
.isNullOrEmpty() .isNullOrEmpty()
) IconAdaptationTool.pushNewAppSupportNotify(firstArgs()!!, newPkgName) ) IconAdaptationTool.pushNewAppSupportNotify(args().first().cast()!!, newPkgName)
} }
Intent.ACTION_PACKAGE_REMOVED -> Intent.ACTION_PACKAGE_REMOVED ->
IconAdaptationTool.removeNewAppSupportNotify( IconAdaptationTool.removeNewAppSupportNotify(
context = firstArgs()!!, context = args().first().cast()!!,
packageName = it.data?.schemeSpecificPart ?: "" packageName = it.data?.schemeSpecificPart ?: ""
) )
} }
@@ -867,13 +920,18 @@ class SystemUIHooker : YukiBaseHooker() {
injectMember { injectMember {
method { name = "updateTime" } method { name = "updateTime" }
afterHook { afterHook {
instance<View>().context.also {
/** 注册广播 */
registerReceiver(it)
/** 注册定时监听 */
if (isEnableHookColorNotifyIcon() && prefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX_AUTO)) if (isEnableHookColorNotifyIcon() && prefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX_AUTO))
IconAdaptationTool.prepareAutoUpdateIconRule( IconAdaptationTool.prepareAutoUpdateIconRule(
context = instance<View>().context, context = it,
timeSet = prefs.get(DataConst.NOTIFY_ICON_FIX_AUTO_TIME) timeSet = prefs.get(DataConst.NOTIFY_ICON_FIX_AUTO_TIME)
) )
} }
} }
}
}.ignoredHookClassNotFoundFailure() }.ignoredHookClassNotFoundFailure()
} }
} }

View File

@@ -45,7 +45,7 @@ class MaterialSwitch(context: Context, attrs: AttributeSet?) : SwitchCompat(cont
return ColorStateList(states, colors) return ColorStateList(states, colors)
} }
private val thumbColor get() = if (isSystemInDarkMode) 0xFF7C7C7C else 0xFFCCCCCC private val thumbColor get() = if (context.isSystemInDarkMode) 0xFF7C7C7C else 0xFFCCCCCC
init { init {
trackDrawable = DrawableBuilder() trackDrawable = DrawableBuilder()

View File

@@ -39,7 +39,7 @@ import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.highcapable.yukihookapi.annotation.DoNotUseField import com.highcapable.yukihookapi.annotation.CauseProblemsApi
import com.highcapable.yukihookapi.hook.factory.method import com.highcapable.yukihookapi.hook.factory.method
import com.highcapable.yukihookapi.hook.type.android.LayoutInflaterClass import com.highcapable.yukihookapi.hook.type.android.LayoutInflaterClass
@@ -71,7 +71,7 @@ class DialogBuilder(val context: Context, private val isUseBlackTheme: Boolean)
private var dialogInstance: Dialog? = null // 对话框实例 private var dialogInstance: Dialog? = null // 对话框实例
@DoNotUseField @CauseProblemsApi
var customLayoutView: View? = null // 自定义布局 var customLayoutView: View? = null // 自定义布局
/** /**

View File

@@ -32,6 +32,7 @@ import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo import android.content.pm.PackageInfo
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.res.Configuration import android.content.res.Configuration
@@ -57,6 +58,7 @@ import java.io.ByteArrayOutputStream
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
/** /**
* 系统深色模式是否开启 * 系统深色模式是否开启
* @return [Boolean] 是否开启 * @return [Boolean] 是否开启
@@ -237,6 +239,14 @@ fun Context.findAppName(name: String) =
fun Context.findAppIcon(name: String) = fun Context.findAppIcon(name: String) =
safeOfNull { packageManager?.getPackageInfo(name, 0)?.applicationInfo?.loadIcon(packageManager) } safeOfNull { packageManager?.getPackageInfo(name, 0)?.applicationInfo?.loadIcon(packageManager) }
/**
* 获取 APP 是否为 DEBUG 版本
* @param name APP 包名
* @return [Boolean]
*/
fun Context.isAppDebuggable(name: String) =
safeOfFalse { (packageManager?.getPackageInfo(name, 0)?.applicationInfo?.flags?.and(ApplicationInfo.FLAG_DEBUGGABLE) ?: 0) != 0 }
/** /**
* 对数值自动补零 * 对数值自动补零
* @return [String] * @return [String]
@@ -305,7 +315,20 @@ val Context.systemAccentColor
*/ */
val Context.wallpaperColor val Context.wallpaperColor
get() = safeOfNan { get() = safeOfNan {
WallpaperManager.getInstance(this).getWallpaperColors(WallpaperManager.FLAG_SYSTEM)?.secondaryColor?.toArgb() ?: 0 WallpaperManager.getInstance(this).getWallpaperColors(WallpaperManager.FLAG_SYSTEM)?.primaryColor?.toArgb() ?: 0
}
/**
* 获取较浅的颜色
* @return [Int]
*/
val Int.brighter: Int
get() {
val hsv = FloatArray(3)
Color.colorToHSV(this, hsv)
hsv[1] = hsv[1] - 0.3f
hsv[2] = hsv[2] + 0.3f
return Color.HSVToColor(hsv)
} }
/** /**
@@ -389,12 +412,19 @@ fun findPropString(key: String, default: String = "") = safeOf(default) {
} }
/** /**
* 执行命令 - su * 是否有 Root 权限
* @return [Boolean]
*/
val isRootAccess get() = safeOfFalse { Shell.rootAccess() }
/**
* 执行命令
* @param cmd 命令 * @param cmd 命令
* @param isSu 是否使用 Root 权限执行 - 默认:是
* @return [String] 执行结果 * @return [String] 执行结果
*/ */
fun execShellSu(cmd: String) = safeOfNothing { fun execShell(cmd: String, isSu: Boolean = true) = safeOfNothing {
Shell.su(cmd).exec().out.let { (if (isSu) Shell.su(cmd) else Shell.sh(cmd)).exec().out.let {
if (it.isNotEmpty()) it[0].trim() else "" if (it.isNotEmpty()) it[0].trim() else ""
} }
} }

View File

@@ -116,6 +116,7 @@ object IconAdaptationTool {
* @param packageName 安装的 APP 包名 * @param packageName 安装的 APP 包名
*/ */
fun pushNewAppSupportNotify(context: Context, packageName: String) { fun pushNewAppSupportNotify(context: Context, packageName: String) {
if (context.isAppDebuggable(packageName)) return
context.getSystemService(NotificationManager::class.java)?.apply { context.getSystemService(NotificationManager::class.java)?.apply {
createNotificationChannel( createNotificationChannel(
NotificationChannel( NotificationChannel(

View File

@@ -121,7 +121,7 @@ object IconRuleManagerTool {
cancelButton() cancelButton()
neutralButton(text = "自定义规则") { neutralButton(text = "自定义规则") {
context.showDialog { context.showDialog {
title = "自定义规则" title = "自定义规则(调试)"
val editText = bind<DiaSourceFromStringBinding>().diaSfsInputEdit.apply { val editText = bind<DiaSourceFromStringBinding>().diaSfsInputEdit.apply {
requestFocus() requestFocus()
invalidate() invalidate()

View File

@@ -87,9 +87,9 @@ object SystemUITool {
"部分 MIUI 内测和开发版中使用了状态栏主题可能会发生主题失效的情况,这种情况请再重启一次即可。\n\n" + "部分 MIUI 内测和开发版中使用了状态栏主题可能会发生主题失效的情况,这种情况请再重启一次即可。\n\n" +
"重启过程会黑屏并等待进入锁屏重新解锁。" "重启过程会黑屏并等待进入锁屏重新解锁。"
confirmButton { confirmButton {
execShellSu(cmd = "pgrep systemui").also { pid -> execShell(cmd = "pgrep systemui").also { pid ->
if (pid.isNotBlank()) if (pid.isNotBlank())
execShellSu(cmd = "kill -9 $pid") execShell(cmd = "kill -9 $pid")
else toast(msg = "ROOT 权限获取失败") else toast(msg = "ROOT 权限获取失败")
} }
} }

View File

@@ -9,6 +9,17 @@
android:paddingRight="15dp" android:paddingRight="15dp"
tools:ignore="HardcodedText"> tools:ignore="HardcodedText">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="17.5dp"
android:lineSpacingExtra="6dp"
android:text="此功能仅用于调试单条规则或多条规则,同步最新在线规则后这里的内容将会被覆盖清空。"
android:textColor="@color/colorTextDark"
android:textSize="13sp" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">

View File

@@ -1,12 +1,13 @@
plugins { plugins {
id 'com.android.application' version '7.1.2' apply false id 'com.android.application' version '7.1.3' apply false
id 'com.android.library' version '7.1.2' apply false id 'com.android.library' version '7.1.3' apply false
id 'org.jetbrains.kotlin.android' version '1.6.10' apply false id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
} }
ext { ext {
appVersionName = "2.2" appVersionName = "2.5"
appVersionCode = 27 appVersionCode = 30
enableR8 = true
} }
task clean(type: Delete) { task clean(type: Delete) {