mirror of
https://github.com/fankes/ColorOSNotifyIcon.git
synced 2025-09-08 03:24:11 +08:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
1f2b1d5046 | |||
7896e4836c | |||
d2ff1fe3ec | |||
f5722e3e5c | |||
44e99cb3da | |||
1386833c91 | |||
69af0172eb | |||
81e66d2da2 | |||
73a9142e71 | |||
5af6ffb614 | |||
230b3b4e38 |
@@ -2,7 +2,7 @@
|
||||
|
||||
[](https://github.com/fankes/ColorOSNotifyIcon)
|
||||
[](https://github.com/fankes/ColorOSNotifyIcon/blob/master/LICENSE)
|
||||
[](https://github.com/fankes/ColorOSNotifyIcon/releases)
|
||||
[](https://github.com/fankes/ColorOSNotifyIcon/releases)
|
||||
[](https://github.com/fankes/ColorOSNotifyIcon/releases)
|
||||
[](https://github.com/Xposed-Modules-Repo/com.fankes.coloros.notify/releases)
|
||||
[](https://t.me/XiaofangInternet)
|
||||
@@ -40,6 +40,11 @@ Optimize notification icons for ColorOS and adapt to native notification icon sp
|
||||
继 MIUI 之后的第二大系统 ColorOS 虽然支持原生通知图标,但是第三方推送五颜六色的图标系统并没有做适配,甚至系统自己的图标都是彩色的,极其不友好。<br/>
|
||||
而且从 ColorOS 12 开始,原生图标丢失了着色属性,这也是一种对原生 Android 生态的破坏。
|
||||
|
||||
# 捐赠支持
|
||||
|
||||
- 工作不易,无意外情况此项目将继续维护下去,提供更多可能,欢迎打赏。<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)
|
||||
|
@@ -72,8 +72,8 @@ tasks.whenTaskAdded {
|
||||
|
||||
dependencies {
|
||||
compileOnly 'de.robv.android.xposed:api:82'
|
||||
implementation 'com.highcapable.yukihookapi:api:1.0.68'
|
||||
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.0.68'
|
||||
implementation 'com.highcapable.yukihookapi:api:1.0.71'
|
||||
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.0.71'
|
||||
implementation 'com.github.tiann:FreeReflection:3.1.0'
|
||||
implementation "com.github.topjohnwu.libsu:core:3.1.2"
|
||||
implementation 'androidx.annotation:annotation:1.3.0'
|
||||
|
@@ -41,7 +41,7 @@ object Const {
|
||||
const val MODULE_VERSION_CODE = BuildConfig.VERSION_CODE
|
||||
|
||||
/** 当前模块的版本校验 */
|
||||
const val MODULE_VERSION_VERIFY = "${MODULE_VERSION_NAME}_${MODULE_VERSION_CODE}_202203292119"
|
||||
const val MODULE_VERSION_VERIFY = "${MODULE_VERSION_NAME}_${MODULE_VERSION_CODE}_202204042319"
|
||||
|
||||
/** 当前模块的版本校验标签 */
|
||||
const val MODULE_VERSION_VERIFY_TAG = "module_version_verify"
|
||||
|
@@ -35,10 +35,14 @@ import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.Icon
|
||||
import android.graphics.drawable.VectorDrawable
|
||||
import android.service.notification.StatusBarNotification
|
||||
import android.util.ArrayMap
|
||||
import android.util.ArraySet
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewOutlineProvider
|
||||
import android.widget.ImageView
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import androidx.core.view.children
|
||||
import com.fankes.coloros.notify.bean.IconDataBean
|
||||
import com.fankes.coloros.notify.const.Const
|
||||
import com.fankes.coloros.notify.data.DataConst
|
||||
@@ -74,33 +78,40 @@ class SystemUIHooker : YukiBaseHooker() {
|
||||
private const val ContrastColorUtilClass = "com.android.internal.util.ContrastColorUtil"
|
||||
|
||||
/** 原生存在的类 */
|
||||
private const val NotificationUtilsClass = "${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.NotificationUtils"
|
||||
private const val NotificationUtilsClass = "$SYSTEMUI_PACKAGE_NAME.statusbar.notification.NotificationUtils"
|
||||
|
||||
/** 原生存在的类 */
|
||||
private const val NotificationEntryClass = "${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.collection.NotificationEntry"
|
||||
private const val NotificationEntryClass = "$SYSTEMUI_PACKAGE_NAME.statusbar.notification.collection.NotificationEntry"
|
||||
|
||||
/** 原生存在的类 */
|
||||
private const val StatusBarIconClass = "com.android.internal.statusbar.StatusBarIcon"
|
||||
|
||||
/** 原生存在的类 */
|
||||
private const val StatusBarIconViewClass = "${SYSTEMUI_PACKAGE_NAME}.statusbar.StatusBarIconView"
|
||||
private const val StatusBarIconViewClass = "$SYSTEMUI_PACKAGE_NAME.statusbar.StatusBarIconView"
|
||||
|
||||
/** 原生存在的类 */
|
||||
private const val IconBuilderClass = "${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.icon.IconBuilder"
|
||||
private const val IconBuilderClass = "$SYSTEMUI_PACKAGE_NAME.statusbar.notification.icon.IconBuilder"
|
||||
|
||||
/** 原生存在的类 */
|
||||
private const val IconManagerClass = "${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.icon.IconManager"
|
||||
private const val IconManagerClass = "$SYSTEMUI_PACKAGE_NAME.statusbar.notification.icon.IconManager"
|
||||
|
||||
/** ColorOS 存在的类 - 旧版本不存在 */
|
||||
private const val OplusContrastColorUtilClass = "com.oplusos.util.OplusContrastColorUtil"
|
||||
|
||||
/** 原生存在的类 */
|
||||
private const val PluginManagerImplClass = "${SYSTEMUI_PACKAGE_NAME}.shared.plugins.PluginManagerImpl"
|
||||
private const val PluginManagerImplClass = "$SYSTEMUI_PACKAGE_NAME.shared.plugins.PluginManagerImpl"
|
||||
|
||||
/** 根据多个版本存在不同的包名相同的类 */
|
||||
private val OplusNotificationIconAreaControllerClass = VariousClass(
|
||||
"com.oplusos.systemui.statusbar.phone.OplusNotificationIconAreaController",
|
||||
"com.oplusos.systemui.statusbar.policy.OplusNotificationIconAreaController",
|
||||
"com.coloros.systemui.statusbar.policy.ColorNotificationIconAreaController"
|
||||
)
|
||||
|
||||
/** 根据多个版本存在不同的包名相同的类 */
|
||||
private val SystemPromptControllerClass = VariousClass(
|
||||
"com.oplusos.systemui.statusbar.policy.SystemPromptController",
|
||||
"com.coloros.systemui.statusbar.policy.SystemPromptController"
|
||||
"com.coloros.systemui.statusbar.policy.ColorSystemPromptController"
|
||||
)
|
||||
|
||||
/** 根据多个版本存在不同的包名相同的类 */
|
||||
@@ -135,34 +146,37 @@ class SystemUIHooker : YukiBaseHooker() {
|
||||
|
||||
/** 根据多个版本存在不同的包名相同的类 */
|
||||
private val ExpandableNotificationRowClass = VariousClass(
|
||||
"${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.row.ExpandableNotificationRow",
|
||||
"${SYSTEMUI_PACKAGE_NAME}.statusbar.ExpandableNotificationRow"
|
||||
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.row.ExpandableNotificationRow",
|
||||
"$SYSTEMUI_PACKAGE_NAME.statusbar.ExpandableNotificationRow"
|
||||
)
|
||||
|
||||
/** 根据多个版本存在不同的包名相同的类 */
|
||||
private val NotificationViewWrapperClass = VariousClass(
|
||||
"${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.row.wrapper.NotificationViewWrapper",
|
||||
"${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.NotificationViewWrapper"
|
||||
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.row.wrapper.NotificationViewWrapper",
|
||||
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.NotificationViewWrapper"
|
||||
)
|
||||
|
||||
/** 根据多个版本存在不同的包名相同的类 */
|
||||
private val NotificationHeaderViewWrapperClass = VariousClass(
|
||||
"${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper",
|
||||
"${SYSTEMUI_PACKAGE_NAME}.statusbar.notification.NotificationHeaderViewWrapper"
|
||||
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper",
|
||||
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.NotificationHeaderViewWrapper"
|
||||
)
|
||||
}
|
||||
|
||||
/** 缓存的彩色 APP 图标 */
|
||||
private var appIcons = HashMap<String, Drawable>()
|
||||
private var appIcons = ArrayMap<String, Drawable>()
|
||||
|
||||
/** 缓存的通知优化图标数组 */
|
||||
private var iconDatas = ArrayList<IconDataBean>()
|
||||
|
||||
/** 缓存的状态栏小图标实例 */
|
||||
private var statusBarIconViews = HashSet<ImageView>()
|
||||
/** 状态栏通知图标容器 */
|
||||
private var notificationIconContainer: ViewGroup? = null
|
||||
|
||||
/** 状态栏通知图标数组 */
|
||||
private var notificationIconInstances = ArrayList<View>()
|
||||
|
||||
/** 缓存的通知小图标包装纸实例 */
|
||||
private var notificationViewWrappers = HashSet<Any>()
|
||||
private var notificationViewWrappers = ArraySet<Any>()
|
||||
|
||||
/** 仅监听一次主题壁纸颜色变化 */
|
||||
private var isWallpaperColorListenerSetUp = false
|
||||
@@ -290,7 +304,7 @@ class SystemUIHooker : YukiBaseHooker() {
|
||||
.get(RoundRectDrawableUtilClass.clazz.field { name = "Companion" }.get().self)
|
||||
/** 启动一个线程防止卡顿 */
|
||||
Thread {
|
||||
statusBarIconViews.takeIf { it.isNotEmpty() }?.forEach {
|
||||
(notificationIconContainer?.children?.toList() ?: notificationIconInstances.takeIf { it.isNotEmpty() })?.forEach {
|
||||
runInSafe {
|
||||
/** 得到通知实例 */
|
||||
val nf = nfField.get(it).cast<StatusBarNotification>() ?: return@Thread
|
||||
@@ -311,7 +325,7 @@ class SystemUIHooker : YukiBaseHooker() {
|
||||
/** 得到缩放大小 */
|
||||
val sNfSize = sNfSizeField.get(it).int()
|
||||
/** 在主线程设置图标 */
|
||||
it.post { it.setImageDrawable(roundUtil.invoke(pair.first, sRadius, sNfSize, sNfSize, it.context)) }
|
||||
it.post { (it as? ImageView?)?.setImageDrawable(roundUtil.invoke(pair.first, sRadius, sNfSize, sNfSize, it.context)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -552,12 +566,12 @@ class SystemUIHooker : YukiBaseHooker() {
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 修复并替换新版本 ColorOS 原生灰度图标色彩判断*/
|
||||
/** 修复并替换新版本 ColorOS 原生灰度图标色彩判断 */
|
||||
NotificationUtilsClass.hook {
|
||||
injectMember {
|
||||
method {
|
||||
name = "isGrayscaleOplus"
|
||||
param(ImageViewClass, OplusContrastColorUtilClass.clazz)
|
||||
param(ImageViewClass, OplusContrastColorUtilClass)
|
||||
}
|
||||
replaceAny { firstArgs<ImageView>()?.let { isGrayscaleIcon(it.context, it.drawable) } }
|
||||
}.ignoredHookingFailure()
|
||||
@@ -567,7 +581,7 @@ class SystemUIHooker : YukiBaseHooker() {
|
||||
injectMember {
|
||||
method {
|
||||
name = "getIconDescriptor"
|
||||
param(NotificationEntryClass.clazz, BooleanType)
|
||||
param(NotificationEntryClass, BooleanType)
|
||||
}
|
||||
afterHook {
|
||||
IconBuilderClass.clazz.field { name = "context" }
|
||||
@@ -607,13 +621,36 @@ class SystemUIHooker : YukiBaseHooker() {
|
||||
}
|
||||
afterHook {
|
||||
if (firstArgs != null) instance<ImageView>().also {
|
||||
/** 注册壁纸颜色监听 */
|
||||
registerWallpaperColorChanged(it)
|
||||
/** 注册广播 */
|
||||
registerReceiver(it.context)
|
||||
statusBarIconViews.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 注入状态栏通知图标容器实例 */
|
||||
OplusNotificationIconAreaControllerClass.hook {
|
||||
injectMember {
|
||||
var isOldWay = false
|
||||
method {
|
||||
name = "updateIconsForLayout"
|
||||
paramCount = 10
|
||||
}.remedys {
|
||||
method {
|
||||
name = "updateIconsForLayout"
|
||||
paramCount = 1
|
||||
}.onFind { isOldWay = true }
|
||||
}
|
||||
afterHook {
|
||||
if (isOldWay) {
|
||||
notificationIconInstances.clear()
|
||||
field { name = "mLastToShow" }.get(instance).list<View>()
|
||||
.takeIf { it.isNotEmpty() }?.forEach { notificationIconInstances.add(it) }
|
||||
} else notificationIconContainer = args(index = 1).cast()
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 替换通知图标和样式 */
|
||||
NotificationHeaderViewWrapperClass.hook {
|
||||
injectMember {
|
||||
@@ -649,7 +686,7 @@ class SystemUIHooker : YukiBaseHooker() {
|
||||
}
|
||||
/** 记录实例 */
|
||||
injectMember {
|
||||
constructor { param(ContextClass, ViewClass, ExpandableNotificationRowClass.clazz) }
|
||||
constructor { param(ContextClass, ViewClass, ExpandableNotificationRowClass) }
|
||||
afterHook { notificationViewWrappers.add(instance) }
|
||||
}
|
||||
}
|
||||
@@ -691,11 +728,16 @@ class SystemUIHooker : YukiBaseHooker() {
|
||||
param(ContextClass, IntentClass)
|
||||
}
|
||||
afterHook {
|
||||
if (isEnableHookColorNotifyIcon() && prefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX_AUTO))
|
||||
IconAdaptationTool.prepareAutoUpdateIconRule(
|
||||
context = firstArgs()!!,
|
||||
timeSet = prefs.get(DataConst.NOTIFY_ICON_FIX_AUTO_TIME)
|
||||
)
|
||||
firstArgs<Context>()?.also {
|
||||
/** 注册广播 */
|
||||
registerReceiver(it)
|
||||
/** 注册定时监听 */
|
||||
if (isEnableHookColorNotifyIcon() && prefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX_AUTO))
|
||||
IconAdaptationTool.prepareAutoUpdateIconRule(
|
||||
context = it,
|
||||
timeSet = prefs.get(DataConst.NOTIFY_ICON_FIX_AUTO_TIME)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -39,7 +39,7 @@ import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.viewbinding.ViewBinding
|
||||
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.type.android.LayoutInflaterClass
|
||||
|
||||
@@ -71,7 +71,7 @@ class DialogBuilder(val context: Context, private val isUseBlackTheme: Boolean)
|
||||
|
||||
private var dialogInstance: Dialog? = null // 对话框实例
|
||||
|
||||
@DoNotUseField
|
||||
@CauseProblemsApi
|
||||
var customLayoutView: View? = null // 自定义布局
|
||||
|
||||
/**
|
||||
|
@@ -121,7 +121,7 @@ object IconRuleManagerTool {
|
||||
cancelButton()
|
||||
neutralButton(text = "自定义规则") {
|
||||
context.showDialog {
|
||||
title = "自定义规则"
|
||||
title = "自定义规则(调试)"
|
||||
val editText = bind<DiaSourceFromStringBinding>().diaSfsInputEdit.apply {
|
||||
requestFocus()
|
||||
invalidate()
|
||||
|
@@ -9,6 +9,17 @@
|
||||
android:paddingRight="15dp"
|
||||
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
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
@@ -5,8 +5,8 @@ plugins {
|
||||
}
|
||||
|
||||
ext {
|
||||
appVersionName = "1.51"
|
||||
appVersionCode = 8
|
||||
appVersionName = "1.53"
|
||||
appVersionCode = 10
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
|
Reference in New Issue
Block a user