diff --git a/app/src/main/java/com/fankes/miui/notify/hook/entity/SystemUIHooker.kt b/app/src/main/java/com/fankes/miui/notify/hook/entity/SystemUIHooker.kt index c759527..db942c1 100644 --- a/app/src/main/java/com/fankes/miui/notify/hook/entity/SystemUIHooker.kt +++ b/app/src/main/java/com/fankes/miui/notify/hook/entity/SystemUIHooker.kt @@ -30,6 +30,7 @@ import android.app.WallpaperManager import android.content.Context import android.content.Intent import android.content.IntentFilter +import android.graphics.Bitmap import android.graphics.Color import android.graphics.Outline import android.graphics.drawable.Drawable @@ -65,8 +66,8 @@ import com.fankes.miui.notify.utils.factory.isMIOS import com.fankes.miui.notify.utils.factory.isNotSystemInDarkMode import com.fankes.miui.notify.utils.factory.isSystemInDarkMode import com.fankes.miui.notify.utils.factory.isUpperOfAndroidS +import com.fankes.miui.notify.utils.factory.miosVersion import com.fankes.miui.notify.utils.factory.miuiIncrementalVersion -import com.fankes.miui.notify.utils.factory.replaceColor import com.fankes.miui.notify.utils.factory.round import com.fankes.miui.notify.utils.factory.runInSafe import com.fankes.miui.notify.utils.factory.safeOf @@ -92,9 +93,11 @@ import com.highcapable.yukihookapi.hook.type.android.ImageViewClass import com.highcapable.yukihookapi.hook.type.android.NotificationClass import com.highcapable.yukihookapi.hook.type.android.RemoteViewsClass import com.highcapable.yukihookapi.hook.type.android.StatusBarNotificationClass +import com.highcapable.yukihookapi.hook.type.java.ArrayListClass 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 de.robv.android.xposed.XposedHelpers import top.defaults.drawabletoolbox.DrawableBuilder /** @@ -195,7 +198,10 @@ object SystemUIHooker : YukiBaseHooker() { ) /** HyperOS 焦点通知的用到的库 */ - private val FocusUtils by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.utils.FocusUtils") + private val FocusUtilsClass by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.notification.utils.FocusUtils") + + /** HyperOS 焦点通知的用到的库 */ + private val FocusedNotifPromptViewClass by lazyClassOrNull("${PackageName.SYSTEMUI}.statusbar.phone.FocusedNotifPromptView") /** 缓存的通知图标优化数组 */ private var iconDatas = ArrayList() @@ -303,7 +309,31 @@ object SystemUIHooker : YukiBaseHooker() { * @param isGrayscale 是否为灰度图标 */ private fun loggerDebug(tag: String, context: Context, nf: StatusBarNotification?, isCustom: Boolean, isGrayscale: Boolean) { - if (ConfigData.isEnableModuleLog) YLog.debug( + if (ConfigData.isEnableModuleLog){ + val focusticker = nf?.notification?.extras?.getString("miui.focus.ticker","") + val focusiconId = nf?.notification?.extras?.getInt(" miui.focus.iconId",0) + val focusrv = nf?.notification?.extras?.getParcelable("miui.focus.rv") + val focus = nf?.notification?.extras?.getString("miui.focus.param","") + if (focusticker != "" ){ + YLog.debug( + msg = "(Focus open,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" + + "[Focus IconId]: $focusiconId\n" + + "[Focus String] : ${focus}\n" + + "[Focus rv String] : ${focusrv}\n" + + "[Focus ticker String] : ${focusticker}\n" + + "[Dark 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" + @@ -313,8 +343,11 @@ object SystemUIHooker : YukiBaseHooker() { "[Custom Icon]: $isCustom\n" + "[Grayscale Icon]: $isGrayscale\n" + "[From Xmsf]: ${nf?.isXmsf}\n" + - "[String]: ${nf?.notification}" + "[String]: ${nf?.notification}\n"+ + "[Dark mode] $isDarkIconMode " ) + } + } } /** @@ -929,21 +962,34 @@ object SystemUIHooker : YukiBaseHooker() { context = context, nf = expandedNf, iconDrawable = result()?.loadDrawable(context) - ).also { pair -> - /** 针对澎湃老版本适配*/ - if (pair.second){ - if (!isDarkIconMode) { - result = Icon.createWithBitmap(pair.first?.toBitmap()?.replaceColor(Color.BLACK, Color.WHITE, tolerance = 90)) - } else { - result = Icon.createWithBitmap(pair.first?.toBitmap()?.replaceColor(Color.WHITE, Color.BLACK, tolerance = 90)) - } - } + ).also { pair -> if (pair.second) result = Icon.createWithBitmap(pair.first?.toBitmap()) } } } + } + /** 焦点通知深色模式切换点 */ + FocusedNotifPromptViewClass?.apply { + method { + name = "onDarkChanged" + param(ArrayListClass, Float::class.java, IntType, IntType, IntType, BooleanType) + }.hook().after { + val isdark = args(index = 1).float() + val mIcon = field { name = "mIcon" }.get(instance).any() + if (ConfigData.isEnableModuleLog){ + YLog.debug("FocusedNotifPromptView debug $isdark ${mIcon}") + } + if (miosVersion == "1.0" || miosVersion == "1.1"){ + if (isdark <= 0.5f ) { + XposedHelpers.callMethod(mIcon, "setColorFilter", Color.WHITE) + } else { + XposedHelpers.callMethod(mIcon, "setColorFilter", Color.BLACK) + } + } + } } + /** 去他妈的焦点通知彩色图标 */ - FocusUtils?.apply { + FocusUtilsClass?.apply { method { name = "getStatusBarTickerDarkIcon" param(StatusBarNotificationClass) @@ -955,16 +1001,19 @@ object SystemUIHooker : YukiBaseHooker() { }.hook().after { (globalContext ?: args().first().cast())?.also { context -> val expandedNf = args().first().cast() - val small = expandedNf?.notification?.smallIcon?.loadDrawable(context) - val icon = small?.toBitmap() + val small = expandedNf?.notification?.smallIcon /** Hook 状态栏小图标 */ compatStatusIcon( context = context, nf = expandedNf, - iconDrawable = icon?.toDrawable(context.resources) - ).also { pair -> if (!pair.second) return@after - val bitmap = pair.first?.toBitmap()?.replaceColor(Color.WHITE, Color.BLACK, tolerance = 90) - result = Icon.createWithBitmap(bitmap)} + iconDrawable = small?.loadDrawable(context) + ).also { pair -> + val originalBitmap = pair.first?.toBitmap() + val bitmap = originalBitmap?.let { Bitmap.createScaledBitmap(it, 50, 50, true) } + val icon = Icon.createWithBitmap(bitmap) + icon.setTint(Color.BLACK) + result = icon + } } } method { @@ -978,16 +1027,19 @@ object SystemUIHooker : YukiBaseHooker() { }.hook().after { (globalContext ?: args().first().cast())?.also { context -> val expandedNf = args(0).cast() - val small = expandedNf?.notification?.smallIcon?.loadDrawable(context) - val icon = small?.toBitmap() + val small = expandedNf?.notification?.smallIcon /** Hook 状态栏小图标 */ compatStatusIcon( context = context, nf = expandedNf, - iconDrawable = icon?.toDrawable(context.resources) - ).also { pair -> if (!pair.second) return@after - val bitmap = pair.first?.toBitmap()?.replaceColor(Color.BLACK, Color.WHITE, tolerance = 90) - result = Icon.createWithBitmap(bitmap)} + iconDrawable = small?.loadDrawable(context) + ).also { pair -> + val originalBitmap = pair.first?.toBitmap() + val bitmap = originalBitmap?.let { Bitmap.createScaledBitmap(it, 50, 50, true) } + val icon = Icon.createWithBitmap(bitmap) + icon.setTint(Color.WHITE) + result = icon + } } } } @@ -1005,12 +1057,7 @@ object SystemUIHooker : YukiBaseHooker() { iconDrawable = expandedNf?.notification?.smallIcon?.loadDrawable(iconView.context) ).also { pair -> if (pair.second){ - /** 针对澎湃老版本适配*/ - if (!isDarkIconMode) { - result = iconView.setImageDrawable(pair.first?.toBitmap()?.replaceColor(Color.BLACK, Color.WHITE, tolerance = 90)?.toDrawable(iconView.resources)) - } else { - result = iconView.setImageDrawable(pair.first?.toBitmap()?.replaceColor(Color.WHITE, Color.BLACK, tolerance = 90)?.toDrawable(iconView.resources)) - } + result = iconView.setImageDrawable(pair.first?.toBitmap()?.toDrawable(iconView.resources)) } } updateStatusBarIconColor(iconView) diff --git a/app/src/main/java/com/fankes/miui/notify/utils/factory/FunctionFactory.kt b/app/src/main/java/com/fankes/miui/notify/utils/factory/FunctionFactory.kt index c40b77c..f422fce 100644 --- a/app/src/main/java/com/fankes/miui/notify/utils/factory/FunctionFactory.kt +++ b/app/src/main/java/com/fankes/miui/notify/utils/factory/FunctionFactory.kt @@ -556,48 +556,6 @@ fun Bitmap.round(radius: Float): Bitmap = safeOf(default = this) { } } -/** 替换位图颜色 - * @param oldColor 要替换的颜色 (忽略透明度部分,仅匹配 RGB) - * @param newColor 新颜色 (将替换原颜色的 RGB 部分,保留原透明度) - * @param tolerance 容差范围 (0-255),默认 0 (完全匹配) - * @return [Bitmap] 替换颜色后的位图 - */ -fun Bitmap.replaceColor(oldColor: Int, newColor: Int, tolerance: Int = 0): Bitmap { - // 创建一个可变的副本 - val nBitmap = copy(Bitmap.Config.ARGB_8888, true) - val nBitmapWidth = nBitmap.width - val nBitmapHeight = nBitmap.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 nBitmapHeight) { - for (j in 0 until nBitmapWidth) { - val color = nBitmap.getPixel(j, i) - // 当前像素的 RGB 值 - val r = Color.red(color) - val g = Color.green(color) - val b = Color.blue(color) - // 判断颜色是否接近目标颜色 (模糊匹配) - if (abs(r - oldR) <= tolerance && - abs(g - oldG) <= tolerance && - abs(b - oldB) <= tolerance - ) { - // 保留原始透明度 - val alpha = Color.alpha(color) - // 替换 RGB 并保留透明度 - val replacedColor = Color.argb(alpha, newR, newG, newB) - nBitmap.setPixel(j, i, replacedColor) - } - } - }; return nBitmap -} - /** * 获取系统 Prop 值 * @param key Key