mirror of
https://github.com/fankes/MIUINativeNotifyIcon.git
synced 2025-09-05 18:25:23 +08:00
适配系统深色模式的图标颜色,修复之前的 MIUI 版本通知图标 Hook 失败的问题
This commit is contained in:
@@ -28,7 +28,6 @@ import android.graphics.Outline
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Build
|
||||
import android.service.notification.StatusBarNotification
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
@@ -39,10 +38,7 @@ import androidx.core.graphics.drawable.toBitmap
|
||||
import com.fankes.miui.notify.hook.HookMedium.QQ_PACKAGE_NAME
|
||||
import com.fankes.miui.notify.hook.HookMedium.SELF_PACKAGE_NAME
|
||||
import com.fankes.miui.notify.hook.HookMedium.SYSTEMUI_PACKAGE_NAME
|
||||
import com.fankes.miui.notify.utils.XPrefUtils
|
||||
import com.fankes.miui.notify.utils.dp
|
||||
import com.fankes.miui.notify.utils.isNotMIUI
|
||||
import com.fankes.miui.notify.utils.round
|
||||
import com.fankes.miui.notify.utils.*
|
||||
import de.robv.android.xposed.*
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||
|
||||
@@ -156,7 +152,7 @@ class HookMain : IXposedHookLoadPackage {
|
||||
.invoke(null) as Context
|
||||
|
||||
/**
|
||||
* Hook 通知栏小图标
|
||||
* Hook 状态栏小图标
|
||||
* 区分系统版本 - 由于每个系统版本的方法不一样这里单独拿出来进行 Hook
|
||||
* @param param Hook Param
|
||||
*/
|
||||
@@ -184,6 +180,73 @@ class HookMain : IXposedHookLoadPackage {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook 通知栏小图标
|
||||
* 区分系统版本 - 由于每个系统版本的方法不一样这里单独拿出来进行 Hook
|
||||
* @param param Hook Param
|
||||
* @param isNew 是否为新版方式
|
||||
*/
|
||||
private fun XC_LoadPackage.LoadPackageParam.hookNotifyIconOnSet(param: XC_MethodHook.MethodHookParam, isNew: Boolean) =
|
||||
runWithoutError(error = "AutoSetAppIconOnSet") {
|
||||
/** 获取通知对象 - 由于 MIUI 的版本迭代不规范性可能是空的 */
|
||||
(param.args?.get(if (isNew) 2 else 1) as? StatusBarNotification?)?.let { notifyInstance ->
|
||||
/** 获取 [Context] */
|
||||
val context = if (isNew) param.args[0] as Context else globalContext
|
||||
|
||||
/** 新版风格反色 */
|
||||
val newStyle = if (context.isSystemInDarkMode) 0xFF2D2D2D.toInt() else Color.WHITE
|
||||
|
||||
/** 旧版风格反色 */
|
||||
val oldStyle = if (context.isNotSystemInDarkMode) 0xFF515151.toInt() else Color.WHITE
|
||||
|
||||
/** 获取图标框 */
|
||||
val iconImageView = param.args[if (isNew) 1 else 0] as ImageView
|
||||
|
||||
/** 获取通知小图标 */
|
||||
val iconDrawable = notifyInstance.notification.smallIcon.loadDrawable(context)
|
||||
|
||||
/** 获取发送通知的 APP */
|
||||
val packageName = notifyInstance.opPkg
|
||||
/** 如果开启了修复聊天 APP 的图标 */
|
||||
if (packageName == QQ_PACKAGE_NAME &&
|
||||
XPrefUtils.getBoolean(HookMedium.ENABLE_CHAT_ICON_HOOK, default = true)
|
||||
)
|
||||
iconImageView.apply {
|
||||
/** 设置自定义小图标 */
|
||||
setImageDrawable(BitmapDrawable(IconPackParams.qqSmallIcon))
|
||||
/** 上色 */
|
||||
setColorFilter(if (isUpperOfAndroidS) newStyle else oldStyle)
|
||||
}
|
||||
else {
|
||||
/** 重新设置图标 - 防止系统更改它 */
|
||||
iconImageView.setImageDrawable(iconDrawable)
|
||||
/** 判断如果是灰度图标就给他设置一个白色颜色遮罩 */
|
||||
if (isGrayscaleIcon(context, iconDrawable))
|
||||
iconImageView.setColorFilter(if (isUpperOfAndroidS) newStyle else oldStyle)
|
||||
else
|
||||
iconImageView.apply {
|
||||
clipToOutline = true
|
||||
/** 设置一个圆角轮廓裁切 */
|
||||
outlineProvider = object : ViewOutlineProvider() {
|
||||
override fun getOutline(view: View, out: Outline) {
|
||||
out.setRoundRect(
|
||||
0,
|
||||
0,
|
||||
view.width,
|
||||
view.height,
|
||||
5.dp(context)
|
||||
)
|
||||
}
|
||||
}
|
||||
/** 清除原生的背景边距设置 */
|
||||
if (isUpperOfAndroidS) setPadding(0, 0, 0, 0)
|
||||
/** 清除原生的主题色背景圆圈颜色 */
|
||||
if (isUpperOfAndroidS) setBackgroundDrawable(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {
|
||||
if (lpparam == null) return
|
||||
when (lpparam.packageName) {
|
||||
@@ -276,8 +339,41 @@ class HookMain : IXposedHookLoadPackage {
|
||||
}
|
||||
)
|
||||
}
|
||||
/** 修复下拉通知图标自动设置回 APP 图标的方法 - 新版本 */
|
||||
runWithoutError(ignored = true) {
|
||||
XposedHelpers.findAndHookMethod(
|
||||
NotificationHeaderViewWrapperInjectorClass,
|
||||
lpparam.classLoader,
|
||||
"setAppIcon",
|
||||
Context::class.java,
|
||||
ImageView::class.java,
|
||||
lpparam.findClass(ExpandedNotificationClass),
|
||||
object : XC_MethodReplacement() {
|
||||
override fun replaceHookedMethod(param: MethodHookParam): Any? {
|
||||
lpparam.hookNotifyIconOnSet(param, isNew = true)
|
||||
return null
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
/** 修复下拉通知图标自动设置回 APP 图标的方法 - 旧版本 */
|
||||
runWithoutError(ignored = true) {
|
||||
XposedHelpers.findAndHookMethod(
|
||||
NotificationHeaderViewWrapperInjectorClass,
|
||||
lpparam.classLoader,
|
||||
"setAppIcon",
|
||||
ImageView::class.java,
|
||||
lpparam.findClass(ExpandedNotificationClass),
|
||||
object : XC_MethodReplacement() {
|
||||
override fun replaceHookedMethod(param: MethodHookParam): Any? {
|
||||
lpparam.hookNotifyIconOnSet(param, isNew = false)
|
||||
return null
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
/** 干掉下拉通知图标自动设置回 APP 图标的方法 - Android 12 */
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R)
|
||||
if (isUpperOfAndroidS)
|
||||
runWithoutError(error = "ResetIconBgAndPaddings") {
|
||||
XposedHelpers.findAndHookMethod(
|
||||
NotificationHeaderViewWrapperInjectorClass,
|
||||
@@ -288,68 +384,6 @@ class HookMain : IXposedHookLoadPackage {
|
||||
replaceToNull
|
||||
)
|
||||
}
|
||||
/** 修复下拉通知图标自动设置回 APP 图标的方法 - Android 12 */
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R)
|
||||
runWithoutError(error = "AutoSetAppIcon") {
|
||||
XposedHelpers.findAndHookMethod(
|
||||
NotificationHeaderViewWrapperInjectorClass,
|
||||
lpparam.classLoader,
|
||||
"setAppIcon",
|
||||
Context::class.java,
|
||||
ImageView::class.java,
|
||||
lpparam.findClass(ExpandedNotificationClass),
|
||||
object : XC_MethodReplacement() {
|
||||
override fun replaceHookedMethod(param: MethodHookParam): Any? {
|
||||
runWithoutError(error = "AutoSetAppIconOnSet") {
|
||||
/** 获取 [Context] */
|
||||
val context = param.args[0] as Context
|
||||
|
||||
/** 获取图标框 */
|
||||
val iconImageView = param.args[1] as ImageView
|
||||
|
||||
/** 获取通知小图标 */
|
||||
val iconDrawable = (param.args[2] as StatusBarNotification)
|
||||
.notification.smallIcon.loadDrawable(context)
|
||||
|
||||
/** 获取发送通知的 APP */
|
||||
val packageName = (param.args[2] as StatusBarNotification).opPkg
|
||||
/** 如果开启了修复聊天 APP 的图标 */
|
||||
if (packageName == QQ_PACKAGE_NAME &&
|
||||
XPrefUtils.getBoolean(HookMedium.ENABLE_CHAT_ICON_HOOK, default = true)
|
||||
)
|
||||
iconImageView.apply {
|
||||
/** 设置自定义小图标 */
|
||||
setImageDrawable(BitmapDrawable(IconPackParams.qqSmallIcon))
|
||||
/** 上色 */
|
||||
setColorFilter(Color.WHITE)
|
||||
}
|
||||
else {
|
||||
/** 重新设置图标 - 防止系统更改它 */
|
||||
iconImageView.setImageDrawable(iconDrawable)
|
||||
/** 判断如果是灰度图标就给他设置一个白色颜色遮罩 */
|
||||
if (lpparam.isGrayscaleIcon(context, iconDrawable))
|
||||
iconImageView.setColorFilter(Color.WHITE)
|
||||
else
|
||||
iconImageView.apply {
|
||||
clipToOutline = true
|
||||
/** 设置一个圆角轮廓裁切 */
|
||||
outlineProvider = object : ViewOutlineProvider() {
|
||||
override fun getOutline(view: View, out: Outline) {
|
||||
out.setRoundRect(0, 0, view.width, view.height, 5.dp(context))
|
||||
}
|
||||
}
|
||||
/** 清除原生的背景边距设置 */
|
||||
setPadding(0, 0, 0, 0)
|
||||
/** 清除原生的主题色背景圆圈颜色 */
|
||||
setBackgroundDrawable(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
logD("hook Completed!")
|
||||
}
|
||||
}
|
||||
|
@@ -28,6 +28,7 @@ import android.content.pm.PackageManager
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.*
|
||||
import android.graphics.Bitmap.createBitmap
|
||||
import android.os.Build
|
||||
import android.util.Base64
|
||||
import com.fankes.miui.notify.application.MNvApplication.Companion.appContext
|
||||
import java.io.DataInputStream
|
||||
@@ -46,6 +47,24 @@ val isSystemInDarkMode
|
||||
*/
|
||||
inline val isNotSystemInDarkMode get() = !isSystemInDarkMode
|
||||
|
||||
/**
|
||||
* 系统深色模式是否开启
|
||||
* @return [Boolean] 是否开启
|
||||
*/
|
||||
val Context.isSystemInDarkMode get() = (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
|
||||
|
||||
/**
|
||||
* 系统深色模式是否没开启
|
||||
* @return [Boolean] 是否开启
|
||||
*/
|
||||
inline val Context.isNotSystemInDarkMode get() = !isSystemInDarkMode
|
||||
|
||||
/**
|
||||
* 系统版本是否高于或等于 Android 12
|
||||
* @return [Boolean] 是否符合条件
|
||||
*/
|
||||
inline val isUpperOfAndroidS get() = Build.VERSION.SDK_INT > Build.VERSION_CODES.R
|
||||
|
||||
/**
|
||||
* 当前设备是否是 MIUI 定制 Android 系统
|
||||
* @return [Boolean] 是否符合条件
|
||||
|
Reference in New Issue
Block a user