mirror of
https://github.com/fankes/ColorOSNotifyIcon.git
synced 2025-12-11 00:03:44 +08:00
fix: The onContentUpdated hook does not work on ColorOS 16 (#85)
* fix: block coloros 15 fixSmallIcon method * fix: hook error * feat: complete ColorOS 15 support * docs: update README * misc: Add API 35 and API 36 to androidVersions CodeName * fix: The onContentUpdated hook does not work on ColorOS 16 * refactor: update code style --------- Co-authored-by: fankesyooni <qzmmcn@163.com>
This commit is contained in:
@@ -44,6 +44,7 @@ import android.widget.ImageView
|
|||||||
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.view.children
|
import androidx.core.view.children
|
||||||
|
import androidx.core.view.setPadding
|
||||||
import com.fankes.coloros.notify.R
|
import com.fankes.coloros.notify.R
|
||||||
import com.fankes.coloros.notify.bean.IconDataBean
|
import com.fankes.coloros.notify.bean.IconDataBean
|
||||||
import com.fankes.coloros.notify.const.PackageName
|
import com.fankes.coloros.notify.const.PackageName
|
||||||
@@ -136,6 +137,12 @@ object SystemUIHooker : YukiBaseHooker() {
|
|||||||
/** ColorOS 存在的类 - 旧版本不存在 */
|
/** ColorOS 存在的类 - 旧版本不存在 */
|
||||||
private val OplusNotificationSmallIconUtilClass by lazyClassOrNull("com.oplus.systemui.statusbar.notification.util.OplusNotificationSmallIconUtil")
|
private val OplusNotificationSmallIconUtilClass by lazyClassOrNull("com.oplus.systemui.statusbar.notification.util.OplusNotificationSmallIconUtil")
|
||||||
|
|
||||||
|
/** ColorOS 存在的类 - 旧版本不存在 */
|
||||||
|
private val OplusNotificationHeaderViewWrapperExImpClass by lazyClassOrNull("com.oplus.systemui.statusbar.notification.row.wrapper.OplusNotificationHeaderViewWrapperExImp")
|
||||||
|
|
||||||
|
/** ColorOS 存在的类 - 旧版本不存在 */
|
||||||
|
private val OplusNotificationGroupTemplateWrapperClass by lazyClassOrNull("com.oplus.systemui.notification.row.oplusgroup.OplusNotificationGroupTemplateWrapper")
|
||||||
|
|
||||||
/** 根据多个版本存在不同的包名相同的类 */
|
/** 根据多个版本存在不同的包名相同的类 */
|
||||||
private val OplusNotificationIconAreaControllerClass by lazyClass(
|
private val OplusNotificationIconAreaControllerClass by lazyClass(
|
||||||
VariousClass(
|
VariousClass(
|
||||||
@@ -276,6 +283,17 @@ object SystemUIHooker : YukiBaseHooker() {
|
|||||||
parameterCount = 2
|
parameterCount = 2
|
||||||
} != null
|
} != null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断通知是否为新版本
|
||||||
|
* @return [Boolean]
|
||||||
|
*/
|
||||||
|
private val isNewNotification
|
||||||
|
get() = OplusNotificationHeaderViewWrapperExImpClass?.resolve()?.optional(silent = true)
|
||||||
|
?.firstMethodOrNull {
|
||||||
|
name = "proxyOnContentUpdated"
|
||||||
|
parameterCount = 1
|
||||||
|
} != null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打印日志
|
* 打印日志
|
||||||
* @param tag 标识
|
* @param tag 标识
|
||||||
@@ -314,6 +332,7 @@ object SystemUIHooker : YukiBaseHooker() {
|
|||||||
|
|
||||||
/** 刷新状态栏小图标 */
|
/** 刷新状态栏小图标 */
|
||||||
private fun refreshStatusBarIcons() = runInSafe {
|
private fun refreshStatusBarIcons() = runInSafe {
|
||||||
|
if (isNewNotification) return@runInSafe
|
||||||
val nfField = StatusBarIconViewClass.resolve().optional().firstFieldOrNull { name = "mNotification" }
|
val nfField = StatusBarIconViewClass.resolve().optional().firstFieldOrNull { name = "mNotification" }
|
||||||
val sRadiusField = StatusBarIconViewClass.resolve().optional(silent = true).firstFieldOrNull {
|
val sRadiusField = StatusBarIconViewClass.resolve().optional(silent = true).firstFieldOrNull {
|
||||||
name = "sIconRadiusFraction"
|
name = "sIconRadiusFraction"
|
||||||
@@ -533,11 +552,11 @@ object SystemUIHooker : YukiBaseHooker() {
|
|||||||
.solidColor(newApplyColor)
|
.solidColor(newApplyColor)
|
||||||
.build()
|
.build()
|
||||||
setColorFilter(newStyle)
|
setColorFilter(newStyle)
|
||||||
setPadding(2.dp(context), 2.dp(context), 2.dp(context), 2.dp(context))
|
setPadding(2.dp(context))
|
||||||
} else {
|
} else {
|
||||||
background = null
|
background = null
|
||||||
setColorFilter(oldApplyColor)
|
setColorFilter(oldApplyColor)
|
||||||
setPadding(0, 0, 0, 0)
|
setPadding(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> iconView.apply {
|
else -> iconView.apply {
|
||||||
@@ -599,7 +618,7 @@ object SystemUIHooker : YukiBaseHooker() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** 清除图标间距 */
|
/** 清除图标间距 */
|
||||||
setPadding(0, 0, 0, 0)
|
setPadding(0)
|
||||||
/** 清除背景 */
|
/** 清除背景 */
|
||||||
background = null
|
background = null
|
||||||
/** 清除着色 */
|
/** 清除着色 */
|
||||||
@@ -767,46 +786,6 @@ object SystemUIHooker : YukiBaseHooker() {
|
|||||||
}
|
}
|
||||||
/** 注入通知控制器实例 */
|
/** 注入通知控制器实例 */
|
||||||
StatusBarNotificationPresenterClass.resolve().optional().constructor {}.hookAll().after { notificationPresenter = instance }
|
StatusBarNotificationPresenterClass.resolve().optional().constructor {}.hookAll().after { notificationPresenter = instance }
|
||||||
/** 注入状态栏通知图标容器实例 */
|
|
||||||
OplusNotificationIconAreaControllerClass.resolve().optional().apply {
|
|
||||||
var way = 0
|
|
||||||
(firstMethodOrNull {
|
|
||||||
name = "updateIconsForLayout"
|
|
||||||
parameterCount = 10
|
|
||||||
} ?: firstMethodOrNull {
|
|
||||||
/** ColorOS 14 */
|
|
||||||
name = "updateIconsForLayout"
|
|
||||||
parameterCount = 5
|
|
||||||
} ?: firstMethodOrNull {
|
|
||||||
name = "updateIconsForLayout"
|
|
||||||
parameterCount = 1
|
|
||||||
}?.apply { way = 1 }
|
|
||||||
?: firstMethodOrNull {
|
|
||||||
name = "updateIconsForLayout"
|
|
||||||
}?.apply { way = 2 })?.hook()?.after {
|
|
||||||
when (way) {
|
|
||||||
2 -> notificationIconContainer = OplusNotificationIconAreaControllerClass.resolve().optional()
|
|
||||||
.firstMethodOrNull { name = "getNotificationIcons" }
|
|
||||||
?.of(instance)?.invoke<ViewGroup>()
|
|
||||||
1 -> {
|
|
||||||
notificationIconInstances.clear()
|
|
||||||
firstFieldOrNull { name = "mLastToShow" }?.of(instance)?.get<List<View>>()
|
|
||||||
?.takeIf { it.isNotEmpty() }?.forEach { notificationIconInstances.add(it) }
|
|
||||||
}
|
|
||||||
else -> notificationIconContainer = args(index = 1).cast()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/** 注入状态栏通知图标容器实例 */
|
|
||||||
(LegacyNotificationIconAreaControllerImpl ?: NotificationIconAreaControllerClass)
|
|
||||||
.resolve().optional().apply {
|
|
||||||
firstMethodOrNull {
|
|
||||||
name = "updateIconsForLayout"
|
|
||||||
parameterCount = 8
|
|
||||||
}?.hook()?.after {
|
|
||||||
notificationIconContainer = args(index = 1).cast()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/** 替换通知面板背景 - 新版本 */
|
/** 替换通知面板背景 - 新版本 */
|
||||||
if (!isOldNotificationBackground)
|
if (!isOldNotificationBackground)
|
||||||
OplusNotificationBackgroundViewClass?.resolve()?.optional()?.apply {
|
OplusNotificationBackgroundViewClass?.resolve()?.optional()?.apply {
|
||||||
@@ -876,25 +855,32 @@ object SystemUIHooker : YukiBaseHooker() {
|
|||||||
}?.of(holder)?.invokeQuietly<View>()?.performClick()
|
}?.of(holder)?.invokeQuietly<View>()?.performClick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** 替换通知图标和样式 */
|
|
||||||
NotificationHeaderViewWrapperClass.resolve().optional().apply {
|
if (isNewNotification) {
|
||||||
method {
|
/** 替换通知图标和样式 */
|
||||||
name { it == "resolveHeaderViews" || it == "onContentUpdated" }
|
OplusNotificationHeaderViewWrapperExImpClass?.resolve()?.optional()?.apply {
|
||||||
}.hookAll().after {
|
firstMethodOrNull {
|
||||||
firstFieldOrNull { name = "mIcon" }?.of(instance)?.get<ImageView>()?.apply {
|
name = "proxyOnContentUpdated"
|
||||||
ExpandableNotificationRowClass.resolve().optional()
|
parameterCount = 1
|
||||||
.firstMethodOrNull { name = "getEntry" }
|
}?.hook()?.after {
|
||||||
?.of(NotificationViewWrapperClass.resolve().optional().firstFieldOrNull {
|
val mBase = instance.asResolver().optional().firstMethodOrNull {
|
||||||
name = "mRow"
|
name = "getBase"
|
||||||
}?.of(instance)?.get())?.invokeQuietly()?.let {
|
emptyParameters()
|
||||||
it.asResolver().optional().firstMethodOrNull {
|
}?.invokeQuietly()
|
||||||
name = "getSbn"
|
val imageView = mBase?.asResolver()?.optional()?.firstFieldOrNull {
|
||||||
}?.invoke<StatusBarNotification>()
|
name = "mIcon"
|
||||||
}.also { nf ->
|
type = ImageView::class
|
||||||
nf?.notification?.also {
|
}?.getQuietly<ImageView>()
|
||||||
it.smallIcon.loadDrawable(context)?.also { iconDrawable ->
|
imageView?.apply {
|
||||||
/** 执行替换 */
|
ExpandableNotificationRowClass.resolve().optional()
|
||||||
fun doParse() {
|
.firstMethodOrNull { name = "getEntry" }
|
||||||
|
?.of(args[0])?.invokeQuietly()?.let {
|
||||||
|
it.asResolver().optional().firstMethodOrNull {
|
||||||
|
name = "getSbn"
|
||||||
|
}?.invoke<StatusBarNotification>()
|
||||||
|
}.also { nf ->
|
||||||
|
nf?.notification?.also {
|
||||||
|
it.smallIcon.loadDrawable(context)?.also { iconDrawable ->
|
||||||
compatNotifyIcon(
|
compatNotifyIcon(
|
||||||
context = context,
|
context = context,
|
||||||
nf = nf,
|
nf = nf,
|
||||||
@@ -905,12 +891,132 @@ object SystemUIHooker : YukiBaseHooker() {
|
|||||||
iconView = this
|
iconView = this
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
doParse()
|
|
||||||
/** 延迟重新设置防止部分机型的系统重新设置图标出现图标着色后黑白块问题 */
|
|
||||||
delayedRun(ms = 1500) { doParse() }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OplusNotificationGroupTemplateWrapperClass?.resolve()?.optional()?.apply {
|
||||||
|
firstMethodOrNull {
|
||||||
|
name = "initIcon"
|
||||||
|
}?.hook()?.before {
|
||||||
|
val instanceContext = firstFieldOrNull {
|
||||||
|
name = "context"
|
||||||
|
}?.of(instance)?.get() as Context?
|
||||||
|
if (instanceContext == null)
|
||||||
|
return@before
|
||||||
|
resultNull()
|
||||||
|
NotificationHeaderViewWrapperClass.resolve().optional().firstFieldOrNull { name = "mIcon" }?.of(instance)?.get<ImageView>()?.apply {
|
||||||
|
ExpandableNotificationRowClass.resolve().optional()
|
||||||
|
.firstMethodOrNull { name = "getEntry" }
|
||||||
|
?.of(NotificationViewWrapperClass.resolve().optional().firstFieldOrNull {
|
||||||
|
name = "mRow"
|
||||||
|
}?.of(instance)?.get())?.invokeQuietly()?.let {
|
||||||
|
it.asResolver().optional().firstMethodOrNull {
|
||||||
|
name = "getSbn"
|
||||||
|
}?.invoke<StatusBarNotification>()
|
||||||
|
}.also { nf ->
|
||||||
|
val context = StatusBarNotification::class.resolve().firstMethod {
|
||||||
|
name = "getPackageContext"
|
||||||
|
}.of(nf).invoke<Context>(instanceContext)
|
||||||
|
if (context == null) return@also
|
||||||
|
|
||||||
|
nf?.notification?.also {
|
||||||
|
it.smallIcon.loadDrawable(context)?.also { iconDrawable ->
|
||||||
|
compatNotifyIcon(
|
||||||
|
context = context,
|
||||||
|
nf = nf,
|
||||||
|
isGrayscaleIcon = isGrayscaleIcon(context, iconDrawable),
|
||||||
|
packageName = context.packageName,
|
||||||
|
drawable = iconDrawable,
|
||||||
|
iconColor = it.color,
|
||||||
|
iconView = this
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/** 注入状态栏通知图标容器实例 */
|
||||||
|
OplusNotificationIconAreaControllerClass.resolve().optional().apply {
|
||||||
|
var way = 0
|
||||||
|
(firstMethodOrNull {
|
||||||
|
name = "updateIconsForLayout"
|
||||||
|
parameterCount = 10
|
||||||
|
} ?: firstMethodOrNull {
|
||||||
|
/** ColorOS 14 */
|
||||||
|
name = "updateIconsForLayout"
|
||||||
|
parameterCount = 5
|
||||||
|
} ?: firstMethodOrNull {
|
||||||
|
name = "updateIconsForLayout"
|
||||||
|
parameterCount = 1
|
||||||
|
}?.apply { way = 1 }
|
||||||
|
?: firstMethodOrNull {
|
||||||
|
name = "updateIconsForLayout"
|
||||||
|
}?.apply { way = 2 })?.hook()?.after {
|
||||||
|
when (way) {
|
||||||
|
2 -> notificationIconContainer = OplusNotificationIconAreaControllerClass.resolve().optional()
|
||||||
|
.firstMethodOrNull { name = "getNotificationIcons" }
|
||||||
|
?.of(instance)?.invoke<ViewGroup>()
|
||||||
|
1 -> {
|
||||||
|
notificationIconInstances.clear()
|
||||||
|
firstFieldOrNull { name = "mLastToShow" }?.of(instance)?.get<List<View>>()
|
||||||
|
?.takeIf { it.isNotEmpty() }?.forEach { notificationIconInstances.add(it) }
|
||||||
}
|
}
|
||||||
|
else -> notificationIconContainer = args(index = 1).cast()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** 注入状态栏通知图标容器实例 */
|
||||||
|
(LegacyNotificationIconAreaControllerImpl ?: NotificationIconAreaControllerClass)
|
||||||
|
.resolve().optional().apply {
|
||||||
|
firstMethodOrNull {
|
||||||
|
name = "updateIconsForLayout"
|
||||||
|
parameterCount = 8
|
||||||
|
}?.hook()?.after {
|
||||||
|
notificationIconContainer = args(index = 1).cast()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 替换通知图标和样式 */
|
||||||
|
NotificationHeaderViewWrapperClass.resolve().optional().apply {
|
||||||
|
method {
|
||||||
|
name { it == "resolveHeaderViews" || it == "onContentUpdated" }
|
||||||
|
}.hookAll().after {
|
||||||
|
firstFieldOrNull { name = "mIcon" }?.of(instance)?.get<ImageView>()?.apply {
|
||||||
|
ExpandableNotificationRowClass.resolve().optional()
|
||||||
|
.firstMethodOrNull { name = "getEntry" }
|
||||||
|
?.of(NotificationViewWrapperClass.resolve().optional().firstFieldOrNull {
|
||||||
|
name = "mRow"
|
||||||
|
}?.of(instance)?.get())?.invokeQuietly()?.let {
|
||||||
|
it.asResolver().optional().firstMethodOrNull {
|
||||||
|
name = "getSbn"
|
||||||
|
}?.invoke<StatusBarNotification>()
|
||||||
|
}.also { nf ->
|
||||||
|
nf?.notification?.also {
|
||||||
|
it.smallIcon.loadDrawable(context)?.also { iconDrawable ->
|
||||||
|
/** 执行替换 */
|
||||||
|
fun doParse() {
|
||||||
|
compatNotifyIcon(
|
||||||
|
context = context,
|
||||||
|
nf = nf,
|
||||||
|
isGrayscaleIcon = isGrayscaleIcon(context, iconDrawable),
|
||||||
|
packageName = context.packageName,
|
||||||
|
drawable = iconDrawable,
|
||||||
|
iconColor = it.color,
|
||||||
|
iconView = this
|
||||||
|
)
|
||||||
|
}
|
||||||
|
doParse()
|
||||||
|
/** 延迟重新设置防止部分机型的系统重新设置图标出现图标着色后黑白块问题 */
|
||||||
|
delayedRun(ms = 1500) { doParse() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,6 +150,8 @@ val isRealmeUI
|
|||||||
*/
|
*/
|
||||||
val androidVersionCodeName
|
val androidVersionCodeName
|
||||||
get() = when (Build.VERSION.SDK_INT) {
|
get() = when (Build.VERSION.SDK_INT) {
|
||||||
|
36 -> "B"
|
||||||
|
35 -> "V"
|
||||||
34 -> "U"
|
34 -> "U"
|
||||||
33 -> "T"
|
33 -> "T"
|
||||||
32 -> "S_V2"
|
32 -> "S_V2"
|
||||||
|
|||||||
Reference in New Issue
Block a user