适配系统壁纸主题色着色通知图标,加入通知图标动态刷新

This commit is contained in:
2022-03-23 14:58:57 +08:00
parent 3ae5ce1058
commit e7ff1b2b2d
3 changed files with 82 additions and 7 deletions

View File

@@ -22,15 +22,19 @@
*/
package com.fankes.coloros.notify.hook
import android.app.WallpaperManager
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.Outline
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.Icon
import android.graphics.drawable.VectorDrawable
import android.service.notification.StatusBarNotification
import android.view.View
import android.view.ViewOutlineProvider
import android.widget.ImageView
import androidx.core.graphics.drawable.toBitmap
import com.fankes.coloros.notify.application.CNNApplication.Companion.MODULE_PACKAGE_NAME
@@ -150,6 +154,9 @@ class HookEntry : YukiHookXposedInitProxy {
/** 缓存的通知小图标包装纸实例 */
private var notificationViewWrappers = HashSet<Any>()
/** 仅监听一次主题壁纸颜色变化 */
private var isWallpaperColorListenerSetUp = false
/**
* 是否启用通知图标优化功能
* @param isHooking 是否判断启用通知功能 - 默认:是
@@ -181,6 +188,18 @@ class HookEntry : YukiHookXposedInitProxy {
)
}
/**
* 注册主题壁纸改变颜色监听
*
* - 仅限在 Android 12 上注册
* @param view 实例
*/
private fun PackageParam.registerWallpaperColorChanged(view: View) = runInSafe {
if (isUpperOfAndroidS && !isWallpaperColorListenerSetUp)
WallpaperManager.getInstance(view.context).addOnColorsChangedListener({ _, _ -> refreshNotificationIcons() }, view.handler)
isWallpaperColorListenerSetUp = true
}
/** 刷新状态栏小图标 */
private fun PackageParam.refreshStatusBarIcons() = runInSafe {
val unknown = StatusBarIconViewClass.clazz.field { name = "mIcon" }
@@ -210,7 +229,9 @@ class HookEntry : YukiHookXposedInitProxy {
/** 刷新通知小图标 */
private fun PackageParam.refreshNotificationIcons() = runInSafe {
// TODO
NotificationHeaderViewWrapperClass.clazz.method { name = "resolveHeaderViews" }.also { result ->
notificationViewWrappers.takeIf { it.isNotEmpty() }?.forEach { result.get(it).call() }
}
}
/**
@@ -291,7 +312,10 @@ class HookEntry : YukiHookXposedInitProxy {
compatCustomIcon(isGrayscaleIcon, packageName).also { customPair ->
when {
customPair.first != null || isGrayscaleIcon -> iconView.apply {
/** 重新设置图标 */
setImageBitmap(customPair.first ?: drawable.toBitmap())
/** 设置不要裁切到边界 */
clipToOutline = false
/** 是否开启 Android 12 风格 */
val isA12Style = prefs.getBoolean(ENABLE_ANDROID12_STYLE, isUpperOfAndroidS)
@@ -301,14 +325,15 @@ class HookEntry : YukiHookXposedInitProxy {
/** 新版风格 */
val newStyle = (if (context.isSystemInDarkMode) 0xffdcdcdc else Color.WHITE).toInt()
/** 优化风格 */
val fixStyle = (if (context.isSystemInDarkMode) 0xff707173 else oldStyle).toInt()
/** 原生着色 */
val a12Style = if (isUpperOfAndroidS) context.wallpaperColor else
(if (context.isSystemInDarkMode) 0xff707173 else oldStyle).toInt()
/** 旧版图标着色 */
val oldApplyColor = customPair.second.takeIf { it != 0 } ?: iconColor.takeIf { it != 0 } ?: oldStyle
/** 新版图标着色 */
val newApplyColor = customPair.second.takeIf { it != 0 } ?: iconColor.takeIf { it != 0 } ?: fixStyle
val newApplyColor = customPair.second.takeIf { it != 0 } ?: iconColor.takeIf { it != 0 } ?: a12Style
/** 判断风格并开始 Hook */
if (isA12Style) {
background = DrawableBuilder().rounded().solidColor(newApplyColor).build()
@@ -321,8 +346,24 @@ class HookEntry : YukiHookXposedInitProxy {
}
}
else -> iconView.apply {
/** 重新设置图标 */
setImageDrawable(drawable)
/** 设置裁切到边界 */
clipToOutline = true
/** 设置一个圆角轮廓裁切 */
outlineProvider = object : ViewOutlineProvider() {
override fun getOutline(view: View, out: Outline) {
out.setRoundRect(
0, 0,
view.width, view.height, 3.dpFloat(context)
)
}
}
/** 清除图标间距 */
setPadding(0, 0, 0, 0)
/** 清除背景 */
background = null
/** 清除着色 */
colorFilter = null
}
}
@@ -454,7 +495,23 @@ class HookEntry : YukiHookXposedInitProxy {
name = "setNotification"
param(StatusBarNotificationClass)
}
afterHook { if (firstArgs != null) statusBarIconViews.add(instance()) }
afterHook {
if (firstArgs != null) instance<ImageView>().also {
registerWallpaperColorChanged(it)
statusBarIconViews.add(it)
}
}
}
injectMember {
method {
name = "onConfigurationChanged"
param(ConfigurationClass)
}
intercept()
}
injectMember {
method { name = "updateIconScaleForSystemIcons" }
intercept()
}
}
/** 替换通知图标和样式 */
@@ -486,6 +543,11 @@ class HookEntry : YukiHookXposedInitProxy {
}
}
}
/** 记录实例 */
injectMember {
constructor { param(ContextClass, ViewClass, ExpandableNotificationRowClass.clazz) }
afterHook { notificationViewWrappers.add(instance) }
}
}
/** 发送适配新的 APP 图标通知 */
PluginManagerImplClass.hook {

View File

@@ -25,6 +25,8 @@
package com.fankes.coloros.notify.utils.factory
import android.app.Activity
import android.app.WallpaperManager
import android.app.WallpaperManager.FLAG_SYSTEM
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
@@ -214,6 +216,17 @@ fun Number.dp(context: Context) = dpFloat(context).toInt()
*/
fun Number.dpFloat(context: Context) = toFloat() * context.resources.displayMetrics.density
/**
* 获取系统壁纸颜色
*
* 由于 ColorOS 阉割了 [android.R.color.system_accent1_600] 这里取系统壁纸颜色做补偿
* @return [Int] 无法获取时返回透明色
*/
val Context.wallpaperColor
get() = safeOfNan {
WallpaperManager.getInstance(this).getWallpaperColors(FLAG_SYSTEM)?.secondaryColor?.toArgb() ?: 0
}
/**
* 是否为白色
* @return [Boolean]

View File

@@ -484,7 +484,7 @@
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:layout_marginBottom="10dp"
android:alpha="0.6"
android:lineSpacingExtra="6dp"
android:text="此选项默认开启,开启后将对优化名单内的 APP 通知小图标使用单色调进行修复,特别是通过系统级别推送的通知,它们始终是 APP 默认图标(彩色的 APP 图标),修复后使得它们的图标看起来更加符合 Android 原生的统一规范。"
@@ -502,7 +502,7 @@
<com.fankes.coloros.notify.ui.view.MaterialSwitch
android:id="@+id/notify_icon_fix_notify_switch"
android:layout_width="match_parent"
android:layout_height="35dp"
android:layout_height="30dp"
android:layout_marginBottom="5dp"
android:text="提醒未适配通知图标的新安装应用"
android:textColor="@color/colorTextGray"