Modify merge all store methods to ConfigData and fix module activation status problem

This commit is contained in:
2023-02-03 04:19:05 +08:00
parent d8e549b360
commit fc9d2a0d21
13 changed files with 636 additions and 289 deletions

View File

@@ -25,6 +25,7 @@
package com.fankes.miui.notify.application
import androidx.appcompat.app.AppCompatDelegate
import com.fankes.miui.notify.data.ConfigData
import com.highcapable.yukihookapi.hook.xposed.application.ModuleApplication
class MNNApplication : ModuleApplication() {
@@ -33,5 +34,7 @@ class MNNApplication : ModuleApplication() {
super.onCreate()
/** 跟随系统夜间模式 */
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
/** 装载存储控制类 */
ConfigData.init(instance = this)
}
}

View File

@@ -18,17 +18,30 @@
* and eula along with this software. If not, see
* <https://www.gnu.org/licenses/>
*
* This file is Created by fankes on 2022/1/24.
* This file is Created by fankes on 2023/2/2.
*/
@file:Suppress("SetWorldReadable")
package com.fankes.miui.notify.const
package com.fankes.miui.notify.hook
/**
* 包名常量定义类
*/
object PackageName {
object HookConst {
/** 系统界面 (系统 UI) */
const val SYSTEMUI = "com.android.systemui"
}
const val TYPE_SOURCE_SYNC_WAY_1 = 1000
const val TYPE_SOURCE_SYNC_WAY_2 = 2000
const val TYPE_SOURCE_SYNC_WAY_3 = 3000
/**
* 通知图标优化名单同步方式定义类
*/
object IconRuleSourceSyncType {
const val SYSTEMUI_PACKAGE_NAME = "com.android.systemui"
/** Github Raw (代理) */
const val GITHUB_RAW_PROXY = 1000
/** Github Raw (直连) */
const val GITHUB_RAW_DIRECT = 2000
/** 自定义地址 */
const val CUSTOM_URL = 3000
}

View File

@@ -0,0 +1,310 @@
/*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon
*
* This software is non-free but opensource software: you can redistribute it
* and/or modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
* <p>
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* and eula along with this software. If not, see
* <https://www.gnu.org/licenses/>
*
* This file is Created by fankes on 2023/2/2.
*/
@file:Suppress("MemberVisibilityCanBePrivate")
package com.fankes.miui.notify.data
import android.content.Context
import com.fankes.miui.notify.const.IconRuleSourceSyncType
import com.highcapable.yukihookapi.hook.factory.modulePrefs
import com.highcapable.yukihookapi.hook.log.loggerW
import com.highcapable.yukihookapi.hook.param.PackageParam
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
/**
* 全局配置存储控制类
*/
object ConfigData {
/** 启用模块 */
val ENABLE_MODULE = PrefsData("_enable_module", true)
/** 启用模块日志 */
val ENABLE_MODULE_LOG = PrefsData("_enable_module_log", false)
/** 解除状态栏通知图标个数限制 */
val ENABLE_LIFTED_STATUS_ICON_COUNT = PrefsData("_enable_hook_status_icon_count", true)
/** 解除后的状态栏通知图标最大个数 */
val LIFTED_STATUS_ICON_COUNT = PrefsData("_hook_status_icon_count", 5)
/** 启用通知图标兼容模式 */
val ENABLE_COLOR_ICON_COMPAT = PrefsData("_color_icon_compat", false)
/** 通知栏中的通知图标圆角程度 */
val NOTIFY_ICON_CORNER_SIZE = PrefsData("_notify_icon_corner", 15)
/** 强制通知栏中的通知图标为 APP 图标 */
val ENABLE_NOTIFY_ICON_FORCE_APP_ICON = PrefsData("_notify_icon_force_app_icon", false)
/** 启用通知图标优化 */
val ENABLE_NOTIFY_ICON_FIX = PrefsData("_notify_icon_fix", true)
/** 提醒未适配通知图标的新安装应用 */
val ENABLE_NOTIFY_ICON_FIX_NOTIFY = PrefsData("_notify_icon_fix_notify", true)
/** 启用通知图标优化名单自动更新 */
val ENABLE_NOTIFY_ICON_FIX_AUTO = PrefsData("_enable_notify_icon_fix_auto", true)
/** 通知图标优化名单自动更新时间 */
val NOTIFY_ICON_FIX_AUTO_TIME = PrefsData("_notify_icon_fix_auto_time", "07:00")
/** 通知图标优化适配数据 */
val NOTIFY_ICONS_DATA = PrefsData("_notify_icon_datas", "")
/** 通知图标优化名单同步方式 */
val ICON_RULE_SOURCE_SYNC_TYPE = PrefsData("_rule_source_sync_way", IconRuleSourceSyncType.GITHUB_RAW_PROXY)
/** 通知图标优化名单同步地址 */
val ICON_RULE_SOURCE_SYNC_CUSTOM_URL = PrefsData("_rule_source_sync_way_custom_url", "")
/** 忽略 Android 版本过低提示 */
val IGNORED_ANDROID_VERSION_TO_LOW = PrefsData("_ignored_android_version_to_low", false)
/** 当前实例 - [Context] or [PackageParam] */
private var instance: Any? = null
/**
* 初始化存储控制类
* @param instance 实例 - 只能是 [Context] or [PackageParam]
* @throws IllegalStateException 如果类型错误
*/
fun init(instance: Any) {
when (instance) {
is Context, is PackageParam -> this.instance = instance
else -> error("Unknown type for init ConfigData")
}
}
/**
* 读取 [Int] 数据
* @param data 键值数据模板
* @return [Int]
*/
private fun getInt(data: PrefsData<Int>) = when (instance) {
is Context -> (instance as Context).modulePrefs.get(data)
is PackageParam -> (instance as PackageParam).prefs.get(data)
else -> error("Unknown type for get prefs data")
}
/**
* 存入 [Int] 数据
* @param data 键值数据模板
* @param value 键值内容
*/
private fun putInt(data: PrefsData<Int>, value: Int) {
when (instance) {
is Context -> (instance as Context).modulePrefs.put(data, value)
is PackageParam -> loggerW(msg = "Not support for this method")
else -> error("Unknown type for put prefs data")
}
}
/**
* 读取 [String] 数据
* @param data 键值数据模板
* @return [String]
*/
private fun getString(data: PrefsData<String>) = when (instance) {
is Context -> (instance as Context).modulePrefs.get(data)
is PackageParam -> (instance as PackageParam).prefs.get(data)
else -> error("Unknown type for get prefs data")
}
/**
* 存入 [String] 数据
* @param data 键值数据模板
* @param value 键值内容
*/
private fun putString(data: PrefsData<String>, value: String) {
when (instance) {
is Context -> (instance as Context).modulePrefs.put(data, value)
is PackageParam -> loggerW(msg = "Not support for this method")
else -> error("Unknown type for put prefs data")
}
}
/**
* 读取 [Boolean] 数据
* @param data 键值数据模板
* @return [Boolean]
*/
internal fun getBoolean(data: PrefsData<Boolean>) = when (instance) {
is Context -> (instance as Context).modulePrefs.get(data)
is PackageParam -> (instance as PackageParam).prefs.get(data)
else -> error("Unknown type for get prefs data")
}
/**
* 存入 [Boolean] 数据
* @param data 键值数据模板
* @param value 键值内容
*/
internal fun putBoolean(data: PrefsData<Boolean>, value: Boolean) {
when (instance) {
is Context -> (instance as Context).modulePrefs.put(data, value)
is PackageParam -> loggerW(msg = "Not support for this method")
else -> error("Unknown type for put prefs data")
}
}
/**
* 是否启用模块
* @return [Boolean]
*/
var isEnableModule
get() = getBoolean(ENABLE_MODULE)
set(value) {
putBoolean(ENABLE_MODULE, value)
}
/**
* 是否启用模块日志
* @return [Boolean]
*/
var isEnableModuleLog
get() = getBoolean(ENABLE_MODULE_LOG)
set(value) {
putBoolean(ENABLE_MODULE_LOG, value)
}
/**
* 是否解除状态栏通知图标个数限制
* @return [Boolean]
*/
var isEnableLiftedStatusIconCount
get() = getBoolean(ENABLE_LIFTED_STATUS_ICON_COUNT)
set(value) {
putBoolean(ENABLE_LIFTED_STATUS_ICON_COUNT, value)
}
/**
* 解除后的状态栏通知图标最大个数
* @return [Int]
*/
var liftedStatusIconCount
get() = getInt(LIFTED_STATUS_ICON_COUNT)
set(value) {
putInt(LIFTED_STATUS_ICON_COUNT, value)
}
/**
* 是否启用通知图标兼容模式
* @return [Boolean]
*/
var isEnableColorIconCompat
get() = getBoolean(ENABLE_COLOR_ICON_COMPAT)
set(value) {
putBoolean(ENABLE_COLOR_ICON_COMPAT, value)
}
/**
* 通知栏中的通知图标圆角程度
* @return [Int]
*/
var notifyIconCornerSize
get() = getInt(NOTIFY_ICON_CORNER_SIZE)
set(value) {
putInt(NOTIFY_ICON_CORNER_SIZE, value)
}
/**
* 是否强制通知栏中的通知图标为 APP 图标
* @return [Boolean]
*/
var isEnableNotifyIconForceAppIcon
get() = getBoolean(ENABLE_NOTIFY_ICON_FORCE_APP_ICON)
set(value) {
putBoolean(ENABLE_NOTIFY_ICON_FORCE_APP_ICON, value)
}
/**
* 是否启用通知图标优化
* @return [Boolean]
*/
var isEnableNotifyIconFix
get() = getBoolean(ENABLE_NOTIFY_ICON_FIX)
set(value) {
putBoolean(ENABLE_NOTIFY_ICON_FIX, value)
}
/**
* 是否提醒未适配通知图标的新安装应用
* @return [Boolean]
*/
var isEnableNotifyIconFixNotify
get() = getBoolean(ENABLE_NOTIFY_ICON_FIX_NOTIFY)
set(value) {
putBoolean(ENABLE_NOTIFY_ICON_FIX_NOTIFY, value)
}
/**
* 是否启用通知图标优化名单自动更新
* @return [Boolean]
*/
var isEnableNotifyIconFixAuto
get() = getBoolean(ENABLE_NOTIFY_ICON_FIX_AUTO)
set(value) {
putBoolean(ENABLE_NOTIFY_ICON_FIX_AUTO, value)
}
/**
* 通知图标优化名单自动更新时间
* @return [String]
*/
var notifyIconFixAutoTime
get() = getString(NOTIFY_ICON_FIX_AUTO_TIME)
set(value) {
putString(NOTIFY_ICON_FIX_AUTO_TIME, value)
}
/**
* 通知图标优化名单同步方式
* @return [Int]
*/
var iconRuleSourceSyncType
get() = getInt(ICON_RULE_SOURCE_SYNC_TYPE)
set(value) {
putInt(ICON_RULE_SOURCE_SYNC_TYPE, value)
}
/**
* 通知图标优化名单同步地址
* @return [String]
*/
var iconRuleSourceSyncCustomUrl
get() = getString(ICON_RULE_SOURCE_SYNC_CUSTOM_URL)
set(value) {
putString(ICON_RULE_SOURCE_SYNC_CUSTOM_URL, value)
}
/**
* 是否忽略 Android 版本过低提示
* @return [Boolean]
*/
var isIgnoredAndroidVersionToLow
get() = getBoolean(IGNORED_ANDROID_VERSION_TO_LOW)
set(value) {
putBoolean(IGNORED_ANDROID_VERSION_TO_LOW, value)
}
}

View File

@@ -1,47 +0,0 @@
/*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon
*
* This software is non-free but opensource software: you can redistribute it
* and/or modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
* <p>
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* and eula along with this software. If not, see
* <https://www.gnu.org/licenses/>
*
* This file is Created by fankes on 2022/3/26.
*/
package com.fankes.miui.notify.data
import com.fankes.miui.notify.hook.HookConst
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
object DataConst {
val ENABLE_MODULE = PrefsData("_enable_module", true)
val ENABLE_MODULE_LOG = PrefsData("_enable_module_log", false)
val ENABLE_COLOR_ICON_COMPAT = PrefsData("_color_icon_compat", false)
val ENABLE_NOTIFY_ICON_FIX = PrefsData("_notify_icon_fix", true)
val ENABLE_NOTIFY_ICON_FORCE_APP_ICON = PrefsData("_notify_icon_force_app_icon", false)
val ENABLE_NOTIFY_ICON_FIX_NOTIFY = PrefsData("_notify_icon_fix_notify", true)
val ENABLE_HOOK_STATUS_ICON_COUNT = PrefsData("_enable_hook_status_icon_count", true)
val ENABLE_NOTIFY_ICON_FIX_AUTO = PrefsData("_enable_notify_icon_fix_auto", true)
val NOTIFY_ICON_CORNER = PrefsData("_notify_icon_corner", 15)
val NOTIFY_ICON_DATAS = PrefsData("_notify_icon_datas", "")
val NOTIFY_ICON_FIX_AUTO_TIME = PrefsData("_notify_icon_fix_auto_time", "07:00")
val HOOK_STATUS_ICON_COUNT = PrefsData("_hook_status_icon_count", 5)
val IGNORED_ANDROID_VERSION_TO_LOW = PrefsData("_ignored_android_version_to_low", false)
val SOURCE_SYNC_WAY = PrefsData("_rule_source_sync_way", HookConst.TYPE_SOURCE_SYNC_WAY_1)
val SOURCE_SYNC_WAY_CUSTOM_URL = PrefsData("_rule_source_sync_way_custom_url", "")
}

View File

@@ -0,0 +1,102 @@
/*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon
*
* This software is non-free but opensource software: you can redistribute it
* and/or modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
* <p>
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* and eula along with this software. If not, see
* <https://www.gnu.org/licenses/>
*
* This file is Created by fankes on 2023/2/3.
*/
@file:Suppress("unused", "MemberVisibilityCanBePrivate")
package com.fankes.miui.notify.data.factory
import android.widget.CompoundButton
import com.fankes.miui.notify.data.ConfigData
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
/**
* 绑定到 [CompoundButton] 自动设置选中状态
* @param data 键值数据模板
* @param initiate 方法体
*/
fun CompoundButton.bind(data: PrefsData<Boolean>, initiate: CompoundButtonDataBinder.(CompoundButton) -> Unit = {}) {
val binder = CompoundButtonDataBinder(button = this).also { initiate(it, this) }
isChecked = ConfigData.getBoolean(data).also { binder.initializeCallback?.invoke(it) }
binder.applyChangesCallback = { ConfigData.putBoolean(data, it) }
setOnCheckedChangeListener { button, isChecked ->
if (button.isPressed) {
if (binder.isAutoApplyChanges) binder.applyChangesCallback?.invoke(isChecked)
binder.changedCallback?.invoke(isChecked)
}
}
}
/**
* [CompoundButton] 数据绑定管理器实例
* @param button 当前实例
*/
class CompoundButtonDataBinder(private val button: CompoundButton) {
/** 状态初始化回调事件 */
internal var initializeCallback: ((Boolean) -> Unit)? = null
/** 状态改变回调事件 */
internal var changedCallback: ((Boolean) -> Unit)? = null
/** 应用更改回调事件 */
internal var applyChangesCallback: ((Boolean) -> Unit)? = null
/** 是否启用自动应用更改 */
var isAutoApplyChanges = true
/**
* 监听状态初始化
* @param result 回调结果
*/
fun onInitialize(result: (Boolean) -> Unit) {
initializeCallback = result
}
/**
* 监听状态改变
* @param result 回调结果
*/
fun onChanged(result: (Boolean) -> Unit) {
changedCallback = result
}
/** 重新初始化 */
fun reinitialize() {
initializeCallback?.invoke(button.isChecked)
}
/** 应用更改并重新初始化 */
fun applyChangesAndReinitialize() {
applyChanges()
reinitialize()
}
/** 应用更改 */
fun applyChanges() {
applyChangesCallback?.invoke(button.isChecked)
}
/** 取消更改 */
fun cancelChanges() {
button.isChecked = button.isChecked.not()
}
}

View File

@@ -22,8 +22,8 @@
*/
package com.fankes.miui.notify.hook
import com.fankes.miui.notify.data.DataConst
import com.fankes.miui.notify.hook.HookConst.SYSTEMUI_PACKAGE_NAME
import com.fankes.miui.notify.const.PackageName
import com.fankes.miui.notify.data.ConfigData
import com.fankes.miui.notify.hook.entity.SystemUIHooker
import com.fankes.miui.notify.utils.factory.isLowerAndroidP
import com.fankes.miui.notify.utils.factory.isNotMIUI
@@ -44,17 +44,13 @@ object HookEntry : IYukiHookXposedInit {
}
override fun onHook() = encase {
loadApp(SYSTEMUI_PACKAGE_NAME) {
loadApp(PackageName.SYSTEMUI) {
ConfigData.init(instance = this)
when {
/** 不是 MIUI 系统停止 Hook */
isNotMIUI -> loggerW(msg = "Aborted Hook -> This System is not MIUI")
/** 系统版本低于 Android P 停止 Hook */
isLowerAndroidP -> loggerW(msg = "Aborted Hook -> This System is lower than Android P")
/** 不是支持的 MIUI 系统停止 Hook */
isNotSupportMiuiVersion -> loggerW(msg = "Aborted Hook -> This MIUI Version ${miuiVersion.ifBlank { "unknown" }} not supported")
/** Hook 被手动关闭停止 Hook */
prefs.get(DataConst.ENABLE_MODULE).not() -> loggerW(msg = "Aborted Hook -> Hook Closed")
/** 开始 Hook */
ConfigData.isEnableModule.not() -> loggerW(msg = "Aborted Hook -> Hook Closed")
else -> loadHooker(SystemUIHooker)
}
}

View File

@@ -46,11 +46,11 @@ import androidx.core.graphics.drawable.toBitmap
import androidx.core.view.children
import androidx.core.view.isVisible
import com.fankes.miui.notify.bean.IconDataBean
import com.fankes.miui.notify.data.DataConst
import com.fankes.miui.notify.hook.HookConst.SYSTEMUI_PACKAGE_NAME
import com.fankes.miui.notify.hook.factory.isAppNotifyHookAllOf
import com.fankes.miui.notify.hook.factory.isAppNotifyHookOf
import com.fankes.miui.notify.const.PackageName
import com.fankes.miui.notify.data.ConfigData
import com.fankes.miui.notify.params.IconPackParams
import com.fankes.miui.notify.params.factory.isAppNotifyHookAllOf
import com.fankes.miui.notify.params.factory.isAppNotifyHookOf
import com.fankes.miui.notify.utils.factory.*
import com.fankes.miui.notify.utils.tool.BitmapCompatTool
import com.fankes.miui.notify.utils.tool.IconAdaptationTool
@@ -73,70 +73,68 @@ import top.defaults.drawabletoolbox.DrawableBuilder
object SystemUIHooker : YukiBaseHooker() {
/** MIUI 新版本存在的类 */
private const val SystemUIApplicationClass = "$SYSTEMUI_PACKAGE_NAME.SystemUIApplication"
private const val SystemUIApplicationClass = "${PackageName.SYSTEMUI}.SystemUIApplication"
/** MIUI 新版本存在的类 */
private const val NotificationHeaderViewWrapperInjectorClass =
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.row.wrapper.NotificationHeaderViewWrapperInjector"
/** MIUI 新版本存在的类 */
private const val MiuiNotificationViewWrapperClass =
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.row.wrapper.MiuiNotificationViewWrapper"
private const val MiuiNotificationViewWrapperClass = "${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.MiuiNotificationViewWrapper"
/** MIUI 新版本存在的类 */
private const val MiuiNotificationChildrenContainerClass =
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.stack.MiuiNotificationChildrenContainer"
"${PackageName.SYSTEMUI}.statusbar.notification.stack.MiuiNotificationChildrenContainer"
/** MIUI 新版本存在的类 */
private const val NotificationHeaderViewWrapperInjectorClass =
"${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationHeaderViewWrapperInjector"
/** 原生存在的类 */
private const val NotificationChildrenContainerClass =
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.stack.NotificationChildrenContainer"
private const val NotificationChildrenContainerClass = "${PackageName.SYSTEMUI}.statusbar.notification.stack.NotificationChildrenContainer"
/** 原生存在的类 */
private const val NotificationIconAreaControllerClass = "$SYSTEMUI_PACKAGE_NAME.statusbar.phone.NotificationIconAreaController"
private const val NotificationIconAreaControllerClass = "${PackageName.SYSTEMUI}.statusbar.phone.NotificationIconAreaController"
/** 原生存在的类 */
private const val ContrastColorUtilClass = "com.android.internal.util.ContrastColorUtil"
/** 原生存在的类 */
private const val StatusBarIconViewClass = "$SYSTEMUI_PACKAGE_NAME.statusbar.StatusBarIconView"
private const val StatusBarIconViewClass = "${PackageName.SYSTEMUI}.statusbar.StatusBarIconView"
/** 原生存在的类 */
private const val NotificationIconContainerClass = "$SYSTEMUI_PACKAGE_NAME.statusbar.phone.NotificationIconContainer"
private const val NotificationIconContainerClass = "${PackageName.SYSTEMUI}.statusbar.phone.NotificationIconContainer"
/** 根据多个版本存在不同的包名相同的类 */
private val StatusBarNotificationPresenterClass = VariousClass(
"$SYSTEMUI_PACKAGE_NAME.statusbar.phone.StatusBarNotificationPresenter",
"$SYSTEMUI_PACKAGE_NAME.statusbar.phone.StatusBar"
"${PackageName.SYSTEMUI}.statusbar.phone.StatusBarNotificationPresenter",
"${PackageName.SYSTEMUI}.statusbar.phone.StatusBar"
)
/** 根据多个版本存在不同的包名相同的类 */
private val ExpandableNotificationRowClass = VariousClass(
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.row.ExpandableNotificationRow",
"$SYSTEMUI_PACKAGE_NAME.statusbar.ExpandableNotificationRow"
"${PackageName.SYSTEMUI}.statusbar.notification.row.ExpandableNotificationRow",
"${PackageName.SYSTEMUI}.statusbar.ExpandableNotificationRow"
)
/** 根据多个版本存在不同的包名相同的类 */
private val NotificationViewWrapperClass = VariousClass(
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.row.wrapper.NotificationViewWrapper",
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.NotificationViewWrapper"
"${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationViewWrapper",
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationViewWrapper"
)
/** 根据多个版本存在不同的包名相同的类 */
private val NotificationHeaderViewWrapperClass = VariousClass(
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper",
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.NotificationHeaderViewWrapper"
"${PackageName.SYSTEMUI}.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper",
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationHeaderViewWrapper"
)
/** 根据多个版本存在不同的包名相同的类 */
private val NotificationUtilClass = VariousClass(
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.NotificationUtil",
"$SYSTEMUI_PACKAGE_NAME.miui.statusbar.notification.NotificationUtil"
"${PackageName.SYSTEMUI}.statusbar.notification.NotificationUtil",
"${PackageName.SYSTEMUI}.miui.statusbar.notification.NotificationUtil"
)
/** 根据多个版本存在不同的包名相同的类 */
private val ExpandedNotificationClass = VariousClass(
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.ExpandedNotification",
"$SYSTEMUI_PACKAGE_NAME.miui.statusbar.ExpandedNotification"
"${PackageName.SYSTEMUI}.statusbar.notification.ExpandedNotification",
"${PackageName.SYSTEMUI}.miui.statusbar.ExpandedNotification"
)
/** 缓存的通知图标优化数组 */
@@ -169,14 +167,6 @@ object SystemUIHooker : YukiBaseHooker() {
*/
private val statusBarIconAlpha get() = if (isDarkIconMode) 0.75f else 0.95f
/**
* 是否启用通知图标优化功能
* @param isHooking 是否判断启用通知功能 - 默认:是
* @return [Boolean]
*/
private fun isEnableHookColorNotifyIcon(isHooking: Boolean = true) =
prefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX) && (if (isHooking) prefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX_NOTIFY) else true)
/**
* - 这个是修复彩色图标的关键核心代码判断
*
@@ -186,7 +176,7 @@ object SystemUIHooker : YukiBaseHooker() {
* @return [Boolean]
*/
private fun isGrayscaleIcon(context: Context, drawable: Drawable) =
if (prefs.get(DataConst.ENABLE_COLOR_ICON_COMPAT).not()) safeOfFalse {
if (ConfigData.isEnableColorIconCompat.not()) safeOfFalse {
ContrastColorUtilClass.toClass().let {
it.method {
name = "isGrayscaleIcon"
@@ -235,7 +225,7 @@ object SystemUIHooker : YukiBaseHooker() {
isCustom: Boolean,
isGrayscale: Boolean
) {
if (prefs.get(DataConst.ENABLE_MODULE_LOG)) loggerD(
if (ConfigData.isEnableModuleLog) loggerD(
msg = "$tag --> [${context.appNameOf(packageName = expandedNf?.nfPkgName ?: "")}][${expandedNf?.nfPkgName}] " +
"custom [$isCustom] " +
"grayscale [$isGrayscale] " +
@@ -340,7 +330,7 @@ object SystemUIHooker : YukiBaseHooker() {
*/
private fun compatCustomIcon(isGrayscaleIcon: Boolean, packageName: String): Pair<Bitmap?, Int> {
var customPair: Pair<Bitmap?, Int>? = null
if (prefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX)) run {
if (ConfigData.isEnableNotifyIconFix) run {
iconDatas.takeIf { it.isNotEmpty() }?.forEach {
if (packageName == it.packageName && isAppNotifyHookOf(it)) {
if (isGrayscaleIcon.not() || isAppNotifyHookAllOf(it))
@@ -436,9 +426,6 @@ object SystemUIHooker : YukiBaseHooker() {
/** 旧版风格反色 */
val oldStyle = if (context.isNotSystemInDarkMode) 0xFF707070.toInt() else Color.WHITE
/** 通知图标边框圆角大小 */
val iconCorner = prefs.get(DataConst.NOTIFY_ICON_CORNER)
/** 通知图标原始颜色 */
val iconColor = notifyInstance.notification.color
@@ -475,7 +462,7 @@ object SystemUIHooker : YukiBaseHooker() {
printLogcat(tag = "NotifyIcon", context, notifyInstance, isCustom = customIcon != null, isGrayscaleIcon)
/** 处理自定义通知图标优化 */
when {
prefs.get(DataConst.ENABLE_NOTIFY_ICON_FORCE_APP_ICON) -> {
ConfigData.isEnableNotifyIconForceAppIcon -> {
@Suppress("DEPRECATION")
val miuiAppIcon = notifyInstance.notification?.extras?.getParcelable<Icon?>("miui.appIcon")
setDefaultNotifyIcon(drawable = miuiAppIcon?.loadDrawable(context) ?: context.appIconOf(notifyInstance.nfPkgName))
@@ -491,7 +478,7 @@ object SystemUIHooker : YukiBaseHooker() {
if (isUseMaterial3Style && customIconColor != 0)
background = DrawableBuilder()
.rectangle()
.cornerRadius(iconCorner.dp(context))
.cornerRadius(ConfigData.notifyIconCornerSize.dp(context))
.solidColor(if (context.isSystemInDarkMode) customIconColor.brighterColor else customIconColor)
.build()
/** 设置原生的背景边距 */
@@ -511,7 +498,7 @@ object SystemUIHooker : YukiBaseHooker() {
if (isUseMaterial3Style)
background = DrawableBuilder()
.rectangle()
.cornerRadius(iconCorner.dp(context))
.cornerRadius(ConfigData.notifyIconCornerSize.dp(context))
.solidColor(if (context.isSystemInDarkMode) it.brighterColor else it)
.build()
}
@@ -659,8 +646,8 @@ object SystemUIHooker : YukiBaseHooker() {
registerReceiver(Intent.ACTION_USER_PRESENT) { _, _ -> if (isUsingCachingMethod) refreshStatusBarIcons() }
/** 注册定时监听 */
registerReceiver(Intent.ACTION_TIME_TICK) { context, _ ->
if (isEnableHookColorNotifyIcon() && prefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX_AUTO))
IconAdaptationTool.prepareAutoUpdateIconRule(context, prefs.get(DataConst.NOTIFY_ICON_FIX_AUTO_TIME))
if (ConfigData.isEnableNotifyIconFix && ConfigData.isEnableNotifyIconFixNotify && ConfigData.isEnableNotifyIconFixAuto)
IconAdaptationTool.prepareAutoUpdateIconRule(context, ConfigData.notifyIconFixAutoTime)
}
/** 注册发送适配新的 APP 图标通知监听 */
registerReceiver(IntentFilter().apply {
@@ -669,21 +656,21 @@ object SystemUIHooker : YukiBaseHooker() {
addAction(Intent.ACTION_PACKAGE_REPLACED)
addAction(Intent.ACTION_PACKAGE_REMOVED)
}) { context, intent ->
if (isEnableHookColorNotifyIcon().not()) return@registerReceiver
if (intent.action.equals(Intent.ACTION_PACKAGE_REPLACED).not() &&
intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)
) return@registerReceiver
intent.data?.schemeSpecificPart?.also { packageName ->
when (intent.action) {
Intent.ACTION_PACKAGE_ADDED -> {
if (iconDatas.takeIf { e -> e.isNotEmpty() }
?.filter { e -> e.packageName == packageName }
.isNullOrEmpty()
) IconAdaptationTool.pushNewAppSupportNotify(context, packageName)
if (ConfigData.isEnableNotifyIconFix && ConfigData.isEnableNotifyIconFixNotify)
intent.data?.schemeSpecificPart?.also { packageName ->
when (intent.action) {
Intent.ACTION_PACKAGE_ADDED -> {
if (iconDatas.takeIf { e -> e.isNotEmpty() }
?.filter { e -> e.packageName == packageName }
.isNullOrEmpty()
) IconAdaptationTool.pushNewAppSupportNotify(context, packageName)
}
Intent.ACTION_PACKAGE_REMOVED -> IconAdaptationTool.removeNewAppSupportNotify(context, packageName)
}
Intent.ACTION_PACKAGE_REMOVED -> IconAdaptationTool.removeNewAppSupportNotify(context, packageName)
}
}
}
/** 注入模块资源 */
onCreate { injectModuleAppResources() }
@@ -695,12 +682,7 @@ object SystemUIHooker : YukiBaseHooker() {
/** 缓存图标数据 */
private fun cachingIconDatas() {
iconDatas.clear()
IconPackParams(param = this).iconDatas.apply {
when {
isNotEmpty() -> forEach { iconDatas.add(it) }
isEmpty() && isEnableHookColorNotifyIcon(isHooking = false) -> loggerW(msg = "NotifyIconSupportData is empty!")
}
}
IconPackParams(param = this).iconDatas.apply { if (isNotEmpty()) forEach { iconDatas.add(it) } }
}
/**
@@ -863,8 +845,8 @@ object SystemUIHooker : YukiBaseHooker() {
val maxStaticIconsField = field { name = "MAX_STATIC_ICONS" }.get(instance)
if (statusBarMaxStaticIcons == -1) statusBarMaxStaticIcons = maxStaticIconsField.int()
/** 解除状态栏通知图标个数限制 */
if (isShowNotificationIcons && prefs.get(DataConst.ENABLE_HOOK_STATUS_ICON_COUNT))
maxStaticIconsField.set(prefs.get(DataConst.HOOK_STATUS_ICON_COUNT).let { if (it in 0..100) it else 5 })
if (isShowNotificationIcons && ConfigData.isEnableLiftedStatusIconCount)
maxStaticIconsField.set(ConfigData.liftedStatusIconCount.let { if (it in 0..100) it else 5 })
else maxStaticIconsField.set(statusBarMaxStaticIcons)
}
}.by { NotificationIconContainerClass.toClassOrNull()?.hasField { name = "MAX_STATIC_ICONS" } ?: false }

View File

@@ -27,7 +27,7 @@ package com.fankes.miui.notify.params
import android.content.Context
import android.graphics.Color
import com.fankes.miui.notify.bean.IconDataBean
import com.fankes.miui.notify.data.DataConst
import com.fankes.miui.notify.data.ConfigData
import com.fankes.miui.notify.utils.factory.*
import com.highcapable.yukihookapi.hook.factory.modulePrefs
import com.highcapable.yukihookapi.hook.param.PackageParam
@@ -47,7 +47,7 @@ class IconPackParams(private val context: Context? = null, private val param: Pa
* 已存储的 JSON 数据
* @return [String]
*/
internal val storageDataJson get() = (context?.modulePrefs ?: param?.prefs)?.direct()?.get(DataConst.NOTIFY_ICON_DATAS)
internal val storageDataJson get() = (context?.modulePrefs ?: param?.prefs)?.direct()?.get(ConfigData.NOTIFY_ICONS_DATA)
/**
* 获取图标数据
@@ -134,5 +134,5 @@ class IconPackParams(private val context: Context? = null, private val param: Pa
* 保存图标数据
* @param dataJson 图标数据 JSON
*/
fun save(dataJson: String) = context?.modulePrefs?.put(DataConst.NOTIFY_ICON_DATAS, dataJson)
fun save(dataJson: String) = context?.modulePrefs?.put(ConfigData.NOTIFY_ICONS_DATA, dataJson)
}

View File

@@ -19,8 +19,9 @@
* <https://www.gnu.org/licenses/>
*
* This file is Created by fankes on 2022/2/15.
* This file is Modified by fankes on 2023/2/3.
*/
package com.fankes.miui.notify.hook.factory
package com.fankes.miui.notify.params.factory
import android.content.Context
import com.fankes.miui.notify.bean.IconDataBean

View File

@@ -30,11 +30,11 @@ import com.fankes.miui.notify.bean.IconDataBean
import com.fankes.miui.notify.databinding.ActivityConfigBinding
import com.fankes.miui.notify.databinding.AdapterConfigBinding
import com.fankes.miui.notify.databinding.DiaIconFilterBinding
import com.fankes.miui.notify.hook.factory.isAppNotifyHookAllOf
import com.fankes.miui.notify.hook.factory.isAppNotifyHookOf
import com.fankes.miui.notify.hook.factory.putAppNotifyHookAllOf
import com.fankes.miui.notify.hook.factory.putAppNotifyHookOf
import com.fankes.miui.notify.params.IconPackParams
import com.fankes.miui.notify.params.factory.isAppNotifyHookAllOf
import com.fankes.miui.notify.params.factory.isAppNotifyHookOf
import com.fankes.miui.notify.params.factory.putAppNotifyHookAllOf
import com.fankes.miui.notify.params.factory.putAppNotifyHookOf
import com.fankes.miui.notify.ui.activity.base.BaseActivity
import com.fankes.miui.notify.utils.factory.*
import com.fankes.miui.notify.utils.tool.IconRuleManagerTool

View File

@@ -29,7 +29,8 @@ import androidx.core.view.isGone
import androidx.core.view.isVisible
import com.fankes.miui.notify.BuildConfig
import com.fankes.miui.notify.R
import com.fankes.miui.notify.data.DataConst
import com.fankes.miui.notify.data.ConfigData
import com.fankes.miui.notify.data.factory.bind
import com.fankes.miui.notify.databinding.ActivityMainBinding
import com.fankes.miui.notify.databinding.DiaStatusIconCountBinding
import com.fankes.miui.notify.params.IconPackParams
@@ -39,7 +40,6 @@ import com.fankes.miui.notify.utils.tool.GithubReleaseTool
import com.fankes.miui.notify.utils.tool.SystemUITool
import com.fankes.miui.notify.utils.tool.YukiPromoteTool
import com.highcapable.yukihookapi.YukiHookAPI
import com.highcapable.yukihookapi.hook.factory.modulePrefs
class MainActivity : BaseActivity<ActivityMainBinding>() {
@@ -64,9 +64,6 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun onCreate() {
/** 设置可用性 */
isActivityLive = true
/** 设置文本 */
binding.mainTextVersion.text = "模块版本:$moduleVersion $pendingFlag"
binding.mainTextMiuiVersion.text = "系统版本:$miuiFullVersion"
/** 检查更新 */
GithubReleaseTool.checkingForUpdate(context = this, moduleVersion) { version, function ->
binding.mainTextReleaseVersion.apply {
@@ -118,7 +115,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
}
/** 判断是否 Hook */
YukiHookAPI.Status.isXposedModuleActive -> {
if (IconPackParams(context = this).iconDatas.isEmpty() && modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX))
if (IconPackParams(context = this).iconDatas.isEmpty() && ConfigData.isEnableNotifyIconFix)
showDialog {
title = "配置通知图标优化名单"
msg = "模块需要获取在线规则以更新“通知图标优化名单”,它现在是空的,这看起来是你第一次使用模块,请首先进行配置才可以使用相关功能。\n" +
@@ -127,7 +124,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
cancelButton()
noCancelable()
}
if (isNotNoificationEnabled && modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX))
if (isNotNoificationEnabled && ConfigData.isEnableNotifyIconFix)
showDialog {
title = "模块的通知权限已关闭"
msg = "请开启通知权限,以确保你能收到通知图标优化在线规则的更新。"
@@ -135,12 +132,12 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
cancelButton()
noCancelable()
}
if (isLowerAndroidR && modulePrefs.get(DataConst.IGNORED_ANDROID_VERSION_TO_LOW).not())
if (isLowerAndroidR && ConfigData.isIgnoredAndroidVersionToLow.not())
showDialog {
title = "Android 版本过低"
msg = "你当前使用的 Android 版本过低,模块的部分功能可能会发生问题," +
"由于设备有限,无法逐一调试,若有好的建议可向我们贡献代码提交适配请求,建议在 Android 11 及以上版本中使用效果最佳。"
confirmButton(text = "我知道了") { modulePrefs.put(DataConst.IGNORED_ANDROID_VERSION_TO_LOW, value = true) }
confirmButton(text = "我知道了") { ConfigData.isIgnoredAndroidVersionToLow = true }
noCancelable()
}
/** 推广、恰饭 */
@@ -157,104 +154,96 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
noCancelable()
}
}
var statusBarIconCount = modulePrefs.get(DataConst.HOOK_STATUS_ICON_COUNT)
var notifyIconAutoSyncTime = modulePrefs.get(DataConst.NOTIFY_ICON_FIX_AUTO_TIME)
binding.colorIconHookItem.isVisible = modulePrefs.get(DataConst.ENABLE_MODULE)
binding.statusIconCountItem.isVisible = modulePrefs.get(DataConst.ENABLE_MODULE) && isLowerAndroidR.not()
binding.notifyStyleConfigItem.isVisible = modulePrefs.get(DataConst.ENABLE_MODULE)
binding.notifyIconConfigItem.isVisible = modulePrefs.get(DataConst.ENABLE_MODULE)
binding.notifyIconFixButton.isVisible = modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX)
binding.notifyIconCustomCornerItem.isVisible = isLowerAndroidR.not() &&
modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FORCE_APP_ICON).not()
binding.notifyIconFixNotifyItem.isVisible = modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX)
binding.notifyIconAutoSyncItem.isVisible = modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX)
binding.statusIconCountSwitch.isChecked = modulePrefs.get(DataConst.ENABLE_HOOK_STATUS_ICON_COUNT)
binding.statusIconCountChildItem.isVisible = modulePrefs.get(DataConst.ENABLE_HOOK_STATUS_ICON_COUNT)
binding.notifyIconAutoSyncChildItem.isVisible = modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX_AUTO)
binding.moduleEnableSwitch.isChecked = modulePrefs.get(DataConst.ENABLE_MODULE)
binding.moduleEnableLogSwitch.isChecked = modulePrefs.get(DataConst.ENABLE_MODULE_LOG)
binding.colorIconCompatSwitch.isChecked = modulePrefs.get(DataConst.ENABLE_COLOR_ICON_COMPAT)
binding.notifyIconFixSwitch.isChecked = modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX)
binding.notifyIconForceAppIconSwitch.isChecked = modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FORCE_APP_ICON)
binding.notifyIconFixNotifySwitch.isChecked = modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX_NOTIFY)
binding.notifyIconAutoSyncSwitch.isChecked = modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX_AUTO)
binding.notifyIconCustomCornerSeekbar.progress = modulePrefs.get(DataConst.NOTIFY_ICON_CORNER)
binding.notifyIconCustomCornerText.text = "${modulePrefs.get(DataConst.NOTIFY_ICON_CORNER)} dp"
binding.statusIconCountText.text = statusBarIconCount.toString()
binding.notifyIconAutoSyncText.text = notifyIconAutoSyncTime
binding.moduleEnableSwitch.setOnCheckedChangeListener { btn, b ->
if (btn.isPressed.not()) return@setOnCheckedChangeListener
modulePrefs.put(DataConst.ENABLE_MODULE, b)
binding.moduleEnableLogSwitch.isVisible = b
binding.colorIconHookItem.isVisible = b
binding.statusIconCountItem.isVisible = b && isLowerAndroidR.not()
binding.notifyStyleConfigItem.isVisible = b
binding.notifyIconConfigItem.isVisible = b
SystemUITool.showNeedRestartSnake(context = this)
}
binding.moduleEnableLogSwitch.setOnCheckedChangeListener { btn, b ->
if (btn.isPressed.not()) return@setOnCheckedChangeListener
modulePrefs.put(DataConst.ENABLE_MODULE_LOG, b)
SystemUITool.showNeedRestartSnake(context = this)
}
binding.statusIconCountSwitch.setOnCheckedChangeListener { btn, b ->
if (btn.isPressed.not()) return@setOnCheckedChangeListener
modulePrefs.put(DataConst.ENABLE_HOOK_STATUS_ICON_COUNT, b)
binding.statusIconCountChildItem.isVisible = b
SystemUITool.refreshSystemUI(context = this) { snake(msg = "设置将在新通知推送或状态栏刷新后自动生效") }
}
binding.colorIconCompatSwitch.setOnCheckedChangeListener { btn, b ->
if (btn.isPressed.not()) return@setOnCheckedChangeListener
/** 保存当前配置并生效 */
fun saveConfigs() {
modulePrefs.put(DataConst.ENABLE_COLOR_ICON_COMPAT, b)
SystemUITool.refreshSystemUI(context = this)
binding.mainTextVersion.text = "模块版本:$moduleVersion $pendingFlag"
binding.mainTextMiuiVersion.text = "系统版本:$miuiFullVersion"
binding.warnSCountDisTip.isGone = miuiVersionCode > 12.5
binding.notifyIconCustomCornerSeekbar.progress = ConfigData.notifyIconCornerSize
binding.notifyIconCustomCornerText.text = "${ConfigData.notifyIconCornerSize} dp"
binding.statusIconCountText.text = ConfigData.liftedStatusIconCount.toString()
binding.notifyIconAutoSyncText.text = ConfigData.notifyIconFixAutoTime
binding.moduleEnableSwitch.bind(ConfigData.ENABLE_MODULE) {
onInitialize {
binding.moduleEnableLogSwitch.isVisible = it
binding.colorIconHookItem.isVisible = it
binding.statusIconCountItem.isVisible = isLowerAndroidR.not() && it
binding.notifyStyleConfigItem.isVisible = it
binding.notifyIconConfigItem.isVisible = it
}
if (b) showDialog {
title = "启用兼容模式"
msg = "启用兼容模式可修复部分系统版本可能出现无法判定通知图标反色的问题," +
"但是这也可能会导致新的问题,一般情况下不建议开启,确定要继续吗?\n\n" +
"如果系统界面刷新后通知图标颜色发生错误,请尝试重启一次系统界面。"
confirmButton { saveConfigs() }
cancelButton { btn.isChecked = false }
noCancelable()
} else saveConfigs()
}
binding.notifyIconFixSwitch.setOnCheckedChangeListener { btn, b ->
if (btn.isPressed.not()) return@setOnCheckedChangeListener
modulePrefs.put(DataConst.ENABLE_NOTIFY_ICON_FIX, b)
binding.notifyIconFixButton.isVisible = b
binding.notifyIconFixNotifyItem.isVisible = b
binding.notifyIconAutoSyncItem.isVisible = b
SystemUITool.refreshSystemUI(context = this)
}
binding.notifyIconForceAppIconSwitch.setOnCheckedChangeListener { btn, b ->
if (btn.isPressed.not()) return@setOnCheckedChangeListener
fun saveState() {
binding.notifyIconCustomCornerItem.isVisible = b.not() && isLowerAndroidR.not()
modulePrefs.put(DataConst.ENABLE_NOTIFY_ICON_FORCE_APP_ICON, b)
SystemUITool.refreshSystemUI(context = this)
onChanged {
reinitialize()
refreshModuleStatus()
SystemUITool.showNeedRestartSnake(context = this@MainActivity)
}
if (b) showDialog {
title = "破坏性功能警告"
msg = "开启这个功能后,任何通知栏中的通知图标都会被强制替换为当前推送通知的 APP 的图标," +
"某些系统级别的 APP 通知图标可能会显示异常或发生图标丢失。\n\n" +
"此功能仅面向一些追求图标美观度的用户,我们不推荐开启这个功能,且发生任何 BUG 都不会去修复,仍然继续开启吗?"
confirmButton { saveState() }
cancelButton { btn.isChecked = btn.isChecked.not() }
noCancelable()
} else saveState()
}
binding.notifyIconFixNotifySwitch.setOnCheckedChangeListener { btn, b ->
if (btn.isPressed.not()) return@setOnCheckedChangeListener
modulePrefs.put(DataConst.ENABLE_NOTIFY_ICON_FIX_NOTIFY, b)
SystemUITool.refreshSystemUI(context = this, isRefreshCacheOnly = true)
binding.moduleEnableLogSwitch.bind(ConfigData.ENABLE_MODULE_LOG) {
onChanged { SystemUITool.showNeedRestartSnake(context = this@MainActivity) }
}
binding.notifyIconAutoSyncSwitch.setOnCheckedChangeListener { btn, b ->
if (btn.isPressed.not()) return@setOnCheckedChangeListener
modulePrefs.put(DataConst.ENABLE_NOTIFY_ICON_FIX_AUTO, b)
binding.notifyIconAutoSyncChildItem.isVisible = b
SystemUITool.refreshSystemUI(context = this, isRefreshCacheOnly = true)
binding.statusIconCountSwitch.bind(ConfigData.ENABLE_LIFTED_STATUS_ICON_COUNT) {
onInitialize { binding.statusIconCountChildItem.isVisible = it }
onChanged {
reinitialize()
SystemUITool.refreshSystemUI(context = this@MainActivity) { snake(msg = "设置将在新通知推送或状态栏刷新后自动生效") }
}
}
binding.colorIconCompatSwitch.bind(ConfigData.ENABLE_COLOR_ICON_COMPAT) {
isAutoApplyChanges = false
onChanged {
/** 应用更改并刷新系统界面 */
fun applyChangesAndRefresh() {
applyChanges()
SystemUITool.refreshSystemUI(context = this@MainActivity)
}
if (it) showDialog {
title = "启用兼容模式"
msg = "启用兼容模式可修复部分系统版本可能出现无法判定通知图标反色的问题," +
"但是这也可能会导致新的问题,一般情况下不建议开启,确定要继续吗?\n\n" +
"如果系统界面刷新后通知图标颜色发生错误,请尝试重启一次系统界面。"
confirmButton { applyChangesAndRefresh() }
cancelButton { cancelChanges() }
noCancelable()
} else applyChangesAndRefresh()
}
}
binding.notifyIconForceAppIconSwitch.bind(ConfigData.ENABLE_NOTIFY_ICON_FORCE_APP_ICON) {
isAutoApplyChanges = false
onInitialize { binding.notifyIconCustomCornerItem.isVisible = isLowerAndroidR.not() && it.not() }
onChanged {
/** 应用更改并刷新系统界面 */
fun applyChangesAndRefresh() {
applyChangesAndReinitialize()
SystemUITool.refreshSystemUI(context = this@MainActivity)
}
if (it) showDialog {
title = "破坏性功能警告"
msg = "开启这个功能后,任何通知栏中的通知图标都会被强制替换为当前推送通知的 APP 的图标," +
"某些系统级别的 APP 通知图标可能会显示异常或发生图标丢失。\n\n" +
"此功能仅面向一些追求图标美观度的用户,我们不推荐开启这个功能,且发生任何 BUG 都不会去修复,仍然继续开启吗?"
confirmButton { applyChangesAndRefresh() }
cancelButton { cancelChanges() }
noCancelable()
} else applyChangesAndRefresh()
}
}
binding.notifyIconFixSwitch.bind(ConfigData.ENABLE_NOTIFY_ICON_FIX) {
onInitialize {
binding.notifyIconFixButton.isVisible = it
binding.notifyIconFixNotifyItem.isVisible = it
binding.notifyIconAutoSyncItem.isVisible = it
}
onChanged {
reinitialize()
SystemUITool.refreshSystemUI(context = this@MainActivity)
}
}
binding.notifyIconFixNotifySwitch.bind(ConfigData.ENABLE_NOTIFY_ICON_FIX_NOTIFY) {
onChanged { SystemUITool.refreshSystemUI(context = this@MainActivity, isRefreshCacheOnly = true) }
}
binding.notifyIconAutoSyncSwitch.bind(ConfigData.ENABLE_NOTIFY_ICON_FIX_AUTO) {
onInitialize { binding.notifyIconAutoSyncChildItem.isVisible = it }
onChanged {
reinitialize()
SystemUITool.refreshSystemUI(context = this@MainActivity, isRefreshCacheOnly = true)
}
}
binding.notifyIconCustomCornerSeekbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
@@ -262,22 +251,14 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
}
override fun onStopTrackingTouch(seekBar: SeekBar) {
modulePrefs.put(DataConst.NOTIFY_ICON_CORNER, seekBar.progress)
ConfigData.notifyIconCornerSize = seekBar.progress
SystemUITool.refreshSystemUI(context = this@MainActivity)
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {}
})
/** 设置桌面图标显示隐藏 */
binding.hideIconInLauncherSwitch.isChecked = isLauncherIconShowing.not()
binding.hideIconInLauncherSwitch.setOnCheckedChangeListener { btn, b ->
if (btn.isPressed.not()) return@setOnCheckedChangeListener
hideOrShowLauncherIcon(b)
}
/** 通知图标优化名单按钮点击事件 */
binding.notifyIconFixButton.setOnClickListener { navigate<ConfigureActivity>() }
/** 设置警告 */
binding.warnSCountDisTip.isGone = miuiVersionCode > 12.5
/** 修改状态栏通知图标个数按钮点击事件 */
binding.statusIconCountButton.setOnClickListener {
showDialog<DiaStatusIconCountBinding> {
@@ -285,17 +266,16 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
binding.iconCountEdit.apply {
requestFocus()
invalidate()
setText(statusBarIconCount.toString())
setSelection(statusBarIconCount.toString().length)
setText(ConfigData.liftedStatusIconCount.toString())
setSelection(ConfigData.liftedStatusIconCount.toString().length)
}
confirmButton {
when {
(runCatching { binding.iconCountEdit.text.toString().toInt() }.getOrNull() ?: -1)
!in 0..100 -> snake(msg = "请输入有效数值")
binding.iconCountEdit.text.toString().isNotBlank() -> runCatching {
statusBarIconCount = binding.iconCountEdit.text.toString().trim().toInt()
modulePrefs.put(DataConst.HOOK_STATUS_ICON_COUNT, statusBarIconCount)
this@MainActivity.binding.statusIconCountText.text = statusBarIconCount.toString()
ConfigData.liftedStatusIconCount = binding.iconCountEdit.text.toString().trim().toInt()
this@MainActivity.binding.statusIconCountText.text = ConfigData.liftedStatusIconCount.toString()
SystemUITool.refreshSystemUI(context) { context.snake(msg = "设置将在新通知推送或状态栏刷新后自动生效") }
}.onFailure { snake(msg = "数值格式无效") }
else -> snake(msg = "请输入有效数值")
@@ -306,7 +286,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
}
/** 自动更新在线规则修改时间按钮点击事件 */
binding.notifyIconAutoSyncButton.setOnClickListener {
showTimePicker(notifyIconAutoSyncTime) {
showTimePicker(ConfigData.notifyIconFixAutoTime) {
showDialog {
title = "每天 $it 自动更新"
msg = "设置保存后将在每天 $it 自动同步名单到最新云端数据,若数据已是最新则不会显示任何提示,否则会发送一条通知。\n\n" +
@@ -316,9 +296,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
"3.模块的系统通知权限已开启\n\n" +
"模块无需保持在后台运行,到达同步时间后会自动启动,如果到达时间后模块正在运行则会自动取消本次计划任务。"
confirmButton(text = "保存设置") {
notifyIconAutoSyncTime = it
ConfigData.notifyIconFixAutoTime = it
this@MainActivity.binding.notifyIconAutoSyncText.text = it
modulePrefs.put(DataConst.NOTIFY_ICON_FIX_AUTO_TIME, it)
SystemUITool.refreshSystemUI(context, isRefreshCacheOnly = true)
}
cancelButton()
@@ -334,6 +313,12 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
binding.linkWithFollowMe.setOnClickListener {
openBrowser(url = "https://www.coolapk.com/u/876977", packageName = "com.coolapk.market")
}
/** 设置桌面图标显示隐藏 */
binding.hideIconInLauncherSwitch.isChecked = isLauncherIconShowing.not()
binding.hideIconInLauncherSwitch.setOnCheckedChangeListener { btn, b ->
if (btn.isPressed.not()) return@setOnCheckedChangeListener
hideOrShowLauncherIcon(b)
}
}
/** 前往项目地址 */
@@ -345,19 +330,20 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
private fun refreshModuleStatus() {
binding.mainLinStatus.setBackgroundResource(
when {
YukiHookAPI.Status.isXposedModuleActive && (isModuleRegular.not() || isModuleValied.not()) -> R.drawable.bg_yellow_round
YukiHookAPI.Status.isXposedModuleActive &&
(isModuleRegular.not() || isModuleValied.not() || ConfigData.isEnableModule.not()) -> R.drawable.bg_yellow_round
YukiHookAPI.Status.isXposedModuleActive -> R.drawable.bg_green_round
else -> R.drawable.bg_dark_round
}
)
binding.mainImgStatus.setImageResource(
when {
YukiHookAPI.Status.isXposedModuleActive -> R.drawable.ic_success
YukiHookAPI.Status.isXposedModuleActive && ConfigData.isEnableModule -> R.drawable.ic_success
else -> R.drawable.ic_warn
}
)
binding.mainTextStatus.text = when {
YukiHookAPI.Status.isXposedModuleActive && isModuleRegular.not() && modulePrefs.get(DataConst.ENABLE_MODULE).not() -> "模块已停用"
YukiHookAPI.Status.isXposedModuleActive && ConfigData.isEnableModule.not() -> "模块已停用"
YukiHookAPI.Status.isXposedModuleActive && isModuleRegular.not() -> "模块已激活,请重启系统界面"
YukiHookAPI.Status.isXposedModuleActive && isModuleValied.not() -> "模块已更新,请重启系统界面"
YukiHookAPI.Status.isXposedModuleActive -> "模块已激活"

View File

@@ -39,18 +39,15 @@ import androidx.core.content.getSystemService
import androidx.core.view.isVisible
import androidx.core.widget.doOnTextChanged
import com.fankes.miui.notify.R
import com.fankes.miui.notify.data.DataConst
import com.fankes.miui.notify.const.IconRuleSourceSyncType
import com.fankes.miui.notify.data.ConfigData
import com.fankes.miui.notify.databinding.DiaSourceFromBinding
import com.fankes.miui.notify.databinding.DiaSourceFromStringBinding
import com.fankes.miui.notify.hook.HookConst.TYPE_SOURCE_SYNC_WAY_1
import com.fankes.miui.notify.hook.HookConst.TYPE_SOURCE_SYNC_WAY_2
import com.fankes.miui.notify.hook.HookConst.TYPE_SOURCE_SYNC_WAY_3
import com.fankes.miui.notify.params.IconPackParams
import com.fankes.miui.notify.ui.activity.ConfigureActivity
import com.fankes.miui.notify.utils.factory.safeOfNull
import com.fankes.miui.notify.utils.factory.showDialog
import com.fankes.miui.notify.utils.factory.snake
import com.highcapable.yukihookapi.hook.factory.modulePrefs
import com.highcapable.yukihookapi.hook.log.loggerD
import okhttp3.*
import java.io.IOException
@@ -70,7 +67,13 @@ object IconRuleManagerTool {
private const val OS_TAG = "MIUI"
/** 当前规则的通知图标颜色 */
private const val OS_COLOR = 0xFFE06818
private const val OS_COLOR = 0xFFE06818.toInt()
/** 同步地址 - Github Raw (代理) */
private const val SYNC_URL_PROXY = "https://raw.githubusercontentS.com/fankes/AndroidNotifyIconAdapt/main"
/** 同步地址 - Github Raw (直连) */
private const val SYNC_URL_DIRECT = "https://raw.githubusercontent.com/fankes/AndroidNotifyIconAdapt/main"
/**
* 从在线地址手动同步规则
@@ -80,8 +83,8 @@ object IconRuleManagerTool {
fun syncByHand(context: Context, callback: () -> Unit) =
context.showDialog<DiaSourceFromBinding> {
title = "同步列表"
var sourceType = context.modulePrefs.get(DataConst.SOURCE_SYNC_WAY)
var customUrl = context.modulePrefs.get(DataConst.SOURCE_SYNC_WAY_CUSTOM_URL)
var sourceType = ConfigData.iconRuleSourceSyncType
var customUrl = ConfigData.iconRuleSourceSyncCustomUrl
binding.sourceUrlEdit.apply {
if (customUrl.isNotBlank()) {
setText(customUrl)
@@ -89,25 +92,25 @@ object IconRuleManagerTool {
}
doOnTextChanged { text, _, _, _ -> customUrl = text.toString() }
}
binding.sourceFromTextLin.isVisible = sourceType == TYPE_SOURCE_SYNC_WAY_3
binding.sourceRadio1.isChecked = sourceType == TYPE_SOURCE_SYNC_WAY_1
binding.sourceRadio2.isChecked = sourceType == TYPE_SOURCE_SYNC_WAY_2
binding.sourceRadio3.isChecked = sourceType == TYPE_SOURCE_SYNC_WAY_3
binding.sourceFromTextLin.isVisible = sourceType == IconRuleSourceSyncType.CUSTOM_URL
binding.sourceRadio1.isChecked = sourceType == IconRuleSourceSyncType.GITHUB_RAW_PROXY
binding.sourceRadio2.isChecked = sourceType == IconRuleSourceSyncType.GITHUB_RAW_DIRECT
binding.sourceRadio3.isChecked = sourceType == IconRuleSourceSyncType.CUSTOM_URL
binding.sourceRadio1.setOnClickListener {
binding.sourceFromTextLin.isVisible = false
sourceType = TYPE_SOURCE_SYNC_WAY_1
sourceType = IconRuleSourceSyncType.GITHUB_RAW_PROXY
}
binding.sourceRadio2.setOnClickListener {
binding.sourceFromTextLin.isVisible = false
sourceType = TYPE_SOURCE_SYNC_WAY_2
sourceType = IconRuleSourceSyncType.GITHUB_RAW_DIRECT
}
binding.sourceRadio3.setOnClickListener {
binding.sourceFromTextLin.isVisible = true
sourceType = TYPE_SOURCE_SYNC_WAY_3
sourceType = IconRuleSourceSyncType.CUSTOM_URL
}
confirmButton {
context.modulePrefs.put(DataConst.SOURCE_SYNC_WAY, sourceType)
context.modulePrefs.put(DataConst.SOURCE_SYNC_WAY_CUSTOM_URL, customUrl)
ConfigData.iconRuleSourceSyncType = sourceType
ConfigData.iconRuleSourceSyncCustomUrl = customUrl
sync(context, sourceType, customUrl, callback)
}
cancelButton()
@@ -165,16 +168,14 @@ object IconRuleManagerTool {
*/
fun sync(
context: Context,
sourceType: Int = context.modulePrefs.get(DataConst.SOURCE_SYNC_WAY),
customUrl: String = context.modulePrefs.get(DataConst.SOURCE_SYNC_WAY_CUSTOM_URL),
sourceType: Int = ConfigData.iconRuleSourceSyncType,
customUrl: String = ConfigData.iconRuleSourceSyncCustomUrl,
callback: () -> Unit
) {
when (sourceType) {
TYPE_SOURCE_SYNC_WAY_1 ->
onRefreshing(context, url = "https://raw.githubusercontentS.com/fankes/AndroidNotifyIconAdapt/main", callback)
TYPE_SOURCE_SYNC_WAY_2 ->
onRefreshing(context, url = "https://raw.githubusercontent.com/fankes/AndroidNotifyIconAdapt/main", callback)
TYPE_SOURCE_SYNC_WAY_3 ->
IconRuleSourceSyncType.GITHUB_RAW_PROXY -> onRefreshing(context, SYNC_URL_PROXY, callback)
IconRuleSourceSyncType.GITHUB_RAW_DIRECT -> onRefreshing(context, SYNC_URL_DIRECT, callback)
IconRuleSourceSyncType.CUSTOM_URL ->
if (customUrl.isNotBlank())
if (customUrl.startsWith("http://") || customUrl.startsWith("https://"))
onRefreshingCustom(context, customUrl, callback)
@@ -384,7 +385,7 @@ object IconRuleManagerTool {
notify(0, NotificationCompat.Builder(context, NOTIFY_CHANNEL).apply {
setContentTitle(title)
setContentText(msg)
color = OS_COLOR.toInt()
color = OS_COLOR
setAutoCancel(true)
setSmallIcon(R.drawable.ic_nf_icon_update)
setSound(null)

View File

@@ -24,7 +24,7 @@ package com.fankes.miui.notify.utils.tool
import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import com.fankes.miui.notify.hook.HookConst.SYSTEMUI_PACKAGE_NAME
import com.fankes.miui.notify.const.PackageName
import com.fankes.miui.notify.utils.factory.delayedRun
import com.fankes.miui.notify.utils.factory.execShell
import com.fankes.miui.notify.utils.factory.showDialog
@@ -64,7 +64,7 @@ object SystemUITool {
* @param result 成功后回调
*/
fun checkingActivated(context: Context, result: (Boolean) -> Unit) =
context.dataChannel(SYSTEMUI_PACKAGE_NAME).checkingVersionEquals(result = result)
context.dataChannel(PackageName.SYSTEMUI).checkingVersionEquals(result = result)
/**
* 重启系统界面
@@ -108,7 +108,7 @@ object SystemUITool {
* @param result 回调结果
*/
fun doRefresh(result: (Boolean) -> Unit) {
context?.dataChannel(SYSTEMUI_PACKAGE_NAME)?.with {
context?.dataChannel(PackageName.SYSTEMUI)?.with {
wait(CALL_MODULE_REFRESH_RESULT) { result(it) }
put(CALL_HOST_REFRESH_CACHING, isRefreshCacheOnly)
}