add hook HyperOS 焦点通知彩色图标 (#215)

* add hook HyperOS 焦点通知彩色图标

* clean code

* fix: hyper os 2.0.25.0 bug
This commit is contained in:
李太白
2024-12-05 15:37:03 +08:00
committed by GitHub
parent cd38dbf579
commit cb4bf479ba

View File

@@ -31,7 +31,10 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.graphics.Color import android.graphics.Color
import android.graphics.Bitmap
import android.graphics.Outline import android.graphics.Outline
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.graphics.drawable.BitmapDrawable 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
@@ -182,6 +185,9 @@ object SystemUIHooker : YukiBaseHooker() {
) )
) )
/** 澎湃系统焦点通知的用到的库 */
private val FocusUtils by lazyClass("com.android.systemui.statusbar.notification.utils.FocusUtils")
/** 根据多个版本存在不同的包名相同的类 */ /** 根据多个版本存在不同的包名相同的类 */
private val ExpandedNotificationClass by lazyClass( private val ExpandedNotificationClass by lazyClass(
VariousClass( VariousClass(
@@ -189,7 +195,6 @@ object SystemUIHooker : YukiBaseHooker() {
"${PackageName.SYSTEMUI}.miui.statusbar.ExpandedNotification" "${PackageName.SYSTEMUI}.miui.statusbar.ExpandedNotification"
) )
) )
/** 缓存的通知图标优化数组 */ /** 缓存的通知图标优化数组 */
private var iconDatas = ArrayList<IconDataBean>() private var iconDatas = ArrayList<IconDataBean>()
@@ -868,6 +873,55 @@ object SystemUIHooker : YukiBaseHooker() {
} }
} }
/** 图标颜色替换工具
* @param oldBitmap 原始 Bitmap
* @param oldColor 要替换的颜色(忽略透明度部分,仅匹配 RGB
* @param newColor 新颜色(将替换原颜色的 RGB 部分,保留原透明度)
* @param tolerance 容差范围0-255默认0完全匹配
* @return 替换颜色后的 Bitmap
*/
private fun replaceBitmapColor(oldBitmap: Bitmap, oldColor: Int, newColor: Int, tolerance: Int = 0): Bitmap {
// 创建一个可变的副本
val mBitmap = oldBitmap.copy(Bitmap.Config.ARGB_8888, true)
val mBitmapWidth = mBitmap.width
val mBitmapHeight = mBitmap.height
// 获取目标颜色的 RGB 值
val oldR = Color.red(oldColor)
val oldG = Color.green(oldColor)
val oldB = Color.blue(oldColor)
// 获取替换颜色的 RGB 值
val newR = Color.red(newColor)
val newG = Color.green(newColor)
val newB = Color.blue(newColor)
// 遍历每个像素点
for (i in 0 until mBitmapHeight) {
for (j in 0 until mBitmapWidth) {
val color = mBitmap.getPixel(j, i)
// 当前像素的 RGB 值
val r = Color.red(color)
val g = Color.green(color)
val b = Color.blue(color)
// 判断颜色是否接近目标颜色(模糊匹配)
if (Math.abs(r - oldR) <= tolerance &&
Math.abs(g - oldG) <= tolerance &&
Math.abs(b - oldB) <= tolerance
) {
// 保留原始透明度
val alpha = Color.alpha(color)
// 替换 RGB 并保留透明度
val replacedColor = Color.argb(alpha, newR, newG, newB)
mBitmap.setPixel(j, i, replacedColor)
}
}
}
return mBitmap
}
override fun onHook() { override fun onHook() {
/** 注册生命周期 */ /** 注册生命周期 */
registerLifecycle() registerLifecycle()
@@ -894,6 +948,10 @@ object SystemUIHooker : YukiBaseHooker() {
name = "getSmallIcon" name = "getSmallIcon"
param(ExpandedNotificationClass) param(ExpandedNotificationClass)
} }
method {
name = "getSmallIcon"
param { it[0] == ContextClass && it[1] extends SystemUIApplicationClass && it[2] == IntType && it[3] == BooleanType }
}
method { method {
name = "getSmallIcon" name = "getSmallIcon"
param { it[0] == ContextClass && it[1] extends StatusBarNotificationClass } param { it[0] == ContextClass && it[1] extends StatusBarNotificationClass }
@@ -910,6 +968,53 @@ object SystemUIHooker : YukiBaseHooker() {
} }
} }
} }
/** 去他妈的焦点通知彩色图标 */
FocusUtils.apply {
method{
name = "getStatusBarTickerDarkIcon"
param(StatusBarNotificationClass)
}.remedys {
method {
name = "getStatusBarTickerDarkIcon"
param(ExpandedNotificationClass)
}
}.hook().after {
(globalContext ?: args().first().cast())?.also { context ->
val expandedNf = args(0).cast<StatusBarNotification?>()
/** Hook 状态栏小图标 */
compatStatusIcon(
context = context,
nf = expandedNf,
iconDrawable = result<Icon>()?.loadDrawable(context)
).also { pair ->
if (pair.second) result = Icon.createWithBitmap(pair.first?.let { replaceBitmapColor(it.toBitmap(),Color.WHITE,Color.BLACK,210) })
}
}
}
method{
name = "getStatusBarTickerIcon"
param(StatusBarNotificationClass)
}.remedys {
method {
name = "getStatusBarTickerIcon"
param(ExpandedNotificationClass)
}
}.hook().after {
(globalContext ?: args().first().cast())?.also { context ->
val expandedNf = args(0).cast<StatusBarNotification?>()
/** Hook 状态栏小图标 */
compatStatusIcon(
context = context,
nf = expandedNf,
iconDrawable = result<Icon>()?.loadDrawable(context)
).also { pair ->
if (pair.second) result = Icon.createWithBitmap(pair.first?.toBitmap())
}
}
}
}
/** 注入状态栏通知图标实例 */ /** 注入状态栏通知图标实例 */
StatusBarIconViewClass.method { StatusBarIconViewClass.method {
name = "updateIconColor" name = "updateIconColor"