mirror of
https://github.com/fankes/MIUINativeNotifyIcon.git
synced 2025-09-06 10:45:20 +08:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
83c98b2ad3 | |||
0d7f323232 | |||
0d63b0a14d | |||
6684d7f376 | |||
89321af1ce | |||
d7a9f1e413 | |||
edf199d9a6 | |||
8d6a05e02c | |||
c7d9b2661b | |||
d0a32e08d9 |
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/app/src/main/ic_launcher-playstore.png" width = "100" height = "100"/>
|
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/app/src/main/ic_launcher-playstore.png" width = "100" height = "100"/>
|
||||||
<br/>
|
<br/>
|
||||||
@@ -12,7 +12,7 @@ Fix the native notification bar icon function abandoned by the MIUI development
|
|||||||
# 开始使用
|
# 开始使用
|
||||||
|
|
||||||
点击下载最新版本
|
点击下载最新版本
|
||||||
<a href='https://github.com/fankes/MIUINativeNotifyIcon/releases'></a>
|
<a href='https://github.com/fankes/MIUINativeNotifyIcon/releases'></a>
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
⚠️ 适配说明<br/>
|
⚠️ 适配说明<br/>
|
||||||
|
|
||||||
|
@@ -68,8 +68,8 @@ dependencies {
|
|||||||
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
|
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
|
||||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
|
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
|
||||||
compileOnly 'de.robv.android.xposed:api:82'
|
compileOnly 'de.robv.android.xposed:api:82'
|
||||||
implementation 'com.highcapable.yukihookapi:api:1.0.2'
|
implementation 'com.highcapable.yukihookapi:api:1.0.3'
|
||||||
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.0.2'
|
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.0.3'
|
||||||
implementation 'com.geyifeng.immersionbar:immersionbar:3.2.0'
|
implementation 'com.geyifeng.immersionbar:immersionbar:3.2.0'
|
||||||
implementation 'com.geyifeng.immersionbar:immersionbar-ktx:3.2.0'
|
implementation 'com.geyifeng.immersionbar:immersionbar-ktx:3.2.0'
|
||||||
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
|
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
android:value="true" />
|
android:value="true" />
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="xposeddescription"
|
android:name="xposeddescription"
|
||||||
android:value="MIUI 原生通知图标,修复 12.5、13 后期被破坏的彩色图标。\n开发者:酷安 @星夜不荟" />
|
android:value="为金凡教我做事的 MIUI 修复 12.5、13 后期被破坏的彩色图标。\n开发者:酷安 @星夜不荟" />
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="xposedminversion"
|
android:name="xposedminversion"
|
||||||
android:value="93" />
|
android:value="93" />
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.fankes.miui.notify.hook
|
package com.fankes.miui.notify.hook
|
||||||
|
|
||||||
|
import android.app.NotificationManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
@@ -55,6 +56,7 @@ import com.highcapable.yukihookapi.hook.param.PackageParam
|
|||||||
import com.highcapable.yukihookapi.hook.type.android.ContextClass
|
import com.highcapable.yukihookapi.hook.type.android.ContextClass
|
||||||
import com.highcapable.yukihookapi.hook.type.android.DrawableClass
|
import com.highcapable.yukihookapi.hook.type.android.DrawableClass
|
||||||
import com.highcapable.yukihookapi.hook.type.android.ImageViewClass
|
import com.highcapable.yukihookapi.hook.type.android.ImageViewClass
|
||||||
|
import com.highcapable.yukihookapi.hook.type.java.BooleanType
|
||||||
import com.highcapable.yukihookapi.hook.type.java.IntType
|
import com.highcapable.yukihookapi.hook.type.java.IntType
|
||||||
import com.highcapable.yukihookapi.hook.xposed.proxy.YukiHookXposedInitProxy
|
import com.highcapable.yukihookapi.hook.xposed.proxy.YukiHookXposedInitProxy
|
||||||
|
|
||||||
@@ -259,11 +261,31 @@ class HookEntry : YukiHookXposedInitProxy {
|
|||||||
*/
|
*/
|
||||||
private val PackageParam.globalContext
|
private val PackageParam.globalContext
|
||||||
get() = safeOfNull {
|
get() = safeOfNull {
|
||||||
if (SystemUIApplicationClass.clazz.hasMethod(name = "getContext"))
|
SystemUIApplicationClass.clazz.method { name = "getContext" }.ignoredError().get().invoke<Context>()
|
||||||
SystemUIApplicationClass.clazz.method { name = "getContext" }.get().invoke<Context>()
|
|
||||||
else null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动适配状态栏、通知栏自定义小图标
|
||||||
|
* @param isGrayscaleIcon 是否为灰度图标
|
||||||
|
* @param packageName APP 包名
|
||||||
|
* @return [Pair] - ([Bitmap] 位图,[Int] 颜色)
|
||||||
|
*/
|
||||||
|
private fun PackageParam.compatCustomIcon(isGrayscaleIcon: Boolean, packageName: String): Pair<Bitmap?, Int> {
|
||||||
|
var customPair: Pair<Bitmap?, Int>? = null
|
||||||
|
if (prefs.getBoolean(ENABLE_NOTIFY_ICON_FIX, default = true))
|
||||||
|
run {
|
||||||
|
if (iconDatas.isNotEmpty())
|
||||||
|
iconDatas.forEach {
|
||||||
|
if (packageName == it.packageName && isAppNotifyHookOf(it)) {
|
||||||
|
if (!isGrayscaleIcon || isAppNotifyHookAllOf(it))
|
||||||
|
customPair = Pair(it.iconBitmap, it.iconColor)
|
||||||
|
return@run
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return customPair ?: Pair(null, 0)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook 状态栏小图标
|
* Hook 状态栏小图标
|
||||||
*
|
*
|
||||||
@@ -293,23 +315,12 @@ class HookEntry : YukiHookXposedInitProxy {
|
|||||||
val isNotGrayscaleIcon = notifyInstance.isXmsf || !isGrayscaleIcon(context, iconDrawable)
|
val isNotGrayscaleIcon = notifyInstance.isXmsf || !isGrayscaleIcon(context, iconDrawable)
|
||||||
|
|
||||||
/** 目标彩色通知 APP 图标 */
|
/** 目标彩色通知 APP 图标 */
|
||||||
var customIcon: Bitmap? = null
|
val customIcon = compatCustomIcon(!isNotGrayscaleIcon, notifyInstance.opPkgName).first
|
||||||
if (prefs.getBoolean(ENABLE_NOTIFY_ICON_FIX, default = true))
|
|
||||||
run {
|
|
||||||
if (iconDatas.isNotEmpty())
|
|
||||||
iconDatas.forEach {
|
|
||||||
if (notifyInstance.opPkgName == it.packageName && isAppNotifyHookOf(it)) {
|
|
||||||
if (isNotGrayscaleIcon || isAppNotifyHookAllOf(it))
|
|
||||||
customIcon = it.iconBitmap
|
|
||||||
return@run
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/** 打印日志 */
|
/** 打印日志 */
|
||||||
printLogcat(tag = "StatusIcon", context, notifyInstance, isCustom = customIcon != null, !isNotGrayscaleIcon)
|
printLogcat(tag = "StatusIcon", context, notifyInstance, isCustom = customIcon != null, !isNotGrayscaleIcon)
|
||||||
when {
|
when {
|
||||||
/** 处理自定义通知图标优化 */
|
/** 处理自定义通知图标优化 */
|
||||||
customIcon != null -> it(customIcon!!)
|
customIcon != null -> it(customIcon)
|
||||||
/** 若不是灰度图标自动处理为圆角 */
|
/** 若不是灰度图标自动处理为圆角 */
|
||||||
isNotGrayscaleIcon -> it(notifyInstance.compatNotifyIcon(context, iconDrawable).toBitmap())
|
isNotGrayscaleIcon -> it(notifyInstance.compatNotifyIcon(context, iconDrawable).toBitmap())
|
||||||
}
|
}
|
||||||
@@ -323,108 +334,102 @@ class HookEntry : YukiHookXposedInitProxy {
|
|||||||
* @param context 实例
|
* @param context 实例
|
||||||
* @param expandedNf 通知实例
|
* @param expandedNf 通知实例
|
||||||
* @param iconImageView 通知图标实例
|
* @param iconImageView 通知图标实例
|
||||||
|
* @param isExpanded 通知是否展开 - 可做最小化通知处理
|
||||||
*/
|
*/
|
||||||
private fun PackageParam.hookNotifyIconOnSet(context: Context, expandedNf: StatusBarNotification?, iconImageView: ImageView) =
|
private fun PackageParam.hookNotifyIconOnSet(
|
||||||
safeRun(msg = "AutoSetAppIconOnSet") {
|
context: Context,
|
||||||
/** 判断是 MIUI 样式就停止 Hook */
|
expandedNf: StatusBarNotification?,
|
||||||
if (context.isMiuiNotifyStyle) return@safeRun
|
iconImageView: ImageView,
|
||||||
/** 如果没开启修复 APP 的彩色图标 */
|
isExpanded: Boolean
|
||||||
if (!prefs.getBoolean(ENABLE_COLOR_ICON_HOOK, default = true)) return@safeRun
|
) = safeRun(msg = "AutoSetAppIconOnSet") {
|
||||||
/** 获取通知对象 - 由于 MIUI 的版本迭代不规范性可能是空的 */
|
/** 判断是 MIUI 样式就停止 Hook */
|
||||||
expandedNf?.let { notifyInstance ->
|
if (context.isMiuiNotifyStyle) return@safeRun
|
||||||
/** 是否开启修复 APP 的彩色图标 */
|
/** 如果没开启修复 APP 的彩色图标 */
|
||||||
val isNotifyIconFix = prefs.getBoolean(ENABLE_NOTIFY_ICON_FIX, default = true)
|
if (!prefs.getBoolean(ENABLE_COLOR_ICON_HOOK, default = true)) return@safeRun
|
||||||
|
/** 获取通知对象 - 由于 MIUI 的版本迭代不规范性可能是空的 */
|
||||||
|
expandedNf?.let { notifyInstance ->
|
||||||
|
|
||||||
/** 新版风格反色 */
|
/** 新版风格反色 */
|
||||||
val newStyle = if (context.isSystemInDarkMode) 0xFF2D2D2D.toInt() else Color.WHITE
|
val newStyle = if (context.isSystemInDarkMode) 0xFF2D2D2D.toInt() else Color.WHITE
|
||||||
|
|
||||||
/** 旧版风格反色 */
|
/** 旧版风格反色 */
|
||||||
val oldStyle = if (context.isNotSystemInDarkMode) 0xFF707070.toInt() else Color.WHITE
|
val oldStyle = if (context.isNotSystemInDarkMode) 0xFF707070.toInt() else Color.WHITE
|
||||||
|
|
||||||
/** 通知图标原始颜色 */
|
/** 通知图标原始颜色 */
|
||||||
val iconColor = notifyInstance.notification.color
|
val iconColor = notifyInstance.notification.color
|
||||||
|
|
||||||
/** 是否有通知栏图标颜色 */
|
/** 是否有通知栏图标颜色 */
|
||||||
val hasIconColor = iconColor != 0
|
val hasIconColor = iconColor != 0
|
||||||
|
|
||||||
/** 通知图标适配颜色 */
|
/** 通知图标适配颜色 */
|
||||||
val supportColor = iconColor.let {
|
val supportColor = iconColor.let {
|
||||||
when {
|
when {
|
||||||
isUpperOfAndroidS -> newStyle
|
isUpperOfAndroidS -> newStyle
|
||||||
it == 0 -> oldStyle
|
it == 0 || !isExpanded -> oldStyle
|
||||||
else -> it
|
else -> it
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 获取通知小图标 */
|
/** 获取通知小图标 */
|
||||||
val iconDrawable = notifyInstance.notification.smallIcon.loadDrawable(context)
|
val iconDrawable = notifyInstance.notification.smallIcon.loadDrawable(context)
|
||||||
|
|
||||||
/** 判断图标风格 */
|
/** 判断图标风格 */
|
||||||
val isGrayscaleIcon = !notifyInstance.isXmsf && isGrayscaleIcon(context, iconDrawable)
|
val isGrayscaleIcon = !notifyInstance.isXmsf && isGrayscaleIcon(context, iconDrawable)
|
||||||
|
|
||||||
/** 自定义默认小图标 */
|
/** 自定义默认小图标 */
|
||||||
var customIcon: Bitmap? = null
|
var customIcon: Bitmap?
|
||||||
|
|
||||||
/** 自定义默认小图标颜色 */
|
/** 自定义默认小图标颜色 */
|
||||||
var customIconColor = 0
|
var customIconColor: Int
|
||||||
|
compatCustomIcon(isGrayscaleIcon, notifyInstance.opPkgName).also {
|
||||||
if (isNotifyIconFix) run {
|
customIcon = it.first
|
||||||
if (iconDatas.isNotEmpty())
|
customIconColor = if (isUpperOfAndroidS || isExpanded) it.second else 0
|
||||||
iconDatas.forEach {
|
}
|
||||||
if (notifyInstance.opPkgName == it.packageName && isAppNotifyHookOf(it)) {
|
/** 打印日志 */
|
||||||
if (!isGrayscaleIcon || isAppNotifyHookAllOf(it)) {
|
printLogcat(tag = "NotifyIcon", context, notifyInstance, isCustom = customIcon != null, isGrayscaleIcon)
|
||||||
customIcon = it.iconBitmap
|
/** 处理自定义通知图标优化 */
|
||||||
customIconColor = it.iconColor
|
if (customIcon != null)
|
||||||
return@run
|
iconImageView.apply {
|
||||||
}
|
/** 设置自定义小图标 */
|
||||||
}
|
setImageBitmap(customIcon)
|
||||||
}
|
/** 上色 */
|
||||||
|
setColorFilter(if (isUpperOfAndroidS || customIconColor == 0) supportColor else customIconColor)
|
||||||
|
/** Android 12 设置图标外圈颜色 */
|
||||||
|
if (isUpperOfAndroidS && customIconColor != 0)
|
||||||
|
background = DrawableBuilder().rounded().solidColor(customIconColor).build()
|
||||||
}
|
}
|
||||||
/** 打印日志 */
|
else {
|
||||||
printLogcat(tag = "NotifyIcon", context, notifyInstance, isCustom = customIcon != null, isGrayscaleIcon)
|
/** 重新设置图标 - 防止系统更改它 */
|
||||||
/** 处理自定义通知图标优化 */
|
iconImageView.setImageDrawable(iconDrawable)
|
||||||
if (customIcon != null)
|
/** 判断如果是灰度图标就给他设置一个白色颜色遮罩 */
|
||||||
iconImageView.apply {
|
if (isGrayscaleIcon) iconImageView.apply {
|
||||||
/** 设置自定义小图标 */
|
/** 设置图标着色 */
|
||||||
setImageBitmap(customIcon)
|
setColorFilter(supportColor)
|
||||||
/** 上色 */
|
/** Android 12 设置图标外圈颜色 */
|
||||||
setColorFilter(if (isUpperOfAndroidS || customIconColor == 0) supportColor else customIconColor)
|
if (isUpperOfAndroidS && hasIconColor)
|
||||||
/** Android 12 设置图标外圈颜色 */
|
background = DrawableBuilder().rounded().solidColor(iconColor).build()
|
||||||
if (isUpperOfAndroidS && customIconColor != 0)
|
} else iconImageView.apply {
|
||||||
background = DrawableBuilder().rounded().solidColor(customIconColor).build()
|
/** 重新设置图标 */
|
||||||
}
|
setImageDrawable(notifyInstance.compatNotifyIcon(context, iconDrawable))
|
||||||
else {
|
/** 设置裁切到边界 */
|
||||||
/** 重新设置图标 - 防止系统更改它 */
|
clipToOutline = true
|
||||||
iconImageView.setImageDrawable(iconDrawable)
|
/** 设置一个圆角轮廓裁切 */
|
||||||
/** 判断如果是灰度图标就给他设置一个白色颜色遮罩 */
|
outlineProvider = object : ViewOutlineProvider() {
|
||||||
if (isGrayscaleIcon) iconImageView.apply {
|
override fun getOutline(view: View, out: Outline) {
|
||||||
/** 设置图标着色 */
|
out.setRoundRect(
|
||||||
setColorFilter(supportColor)
|
0, 0,
|
||||||
/** Android 12 设置图标外圈颜色 */
|
view.width, view.height, 5.dp(context)
|
||||||
if (isUpperOfAndroidS && hasIconColor)
|
)
|
||||||
background = DrawableBuilder().rounded().solidColor(iconColor).build()
|
|
||||||
} else iconImageView.apply {
|
|
||||||
/** 重新设置图标 */
|
|
||||||
setImageDrawable(notifyInstance.compatNotifyIcon(context, iconDrawable))
|
|
||||||
/** 设置裁切到边界 */
|
|
||||||
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) background = null
|
|
||||||
}
|
}
|
||||||
|
/** 清除原生的背景边距设置 */
|
||||||
|
if (isUpperOfAndroidS) setPadding(0, 0, 0, 0)
|
||||||
|
/** 清除原生的主题色背景圆圈颜色 */
|
||||||
|
if (isUpperOfAndroidS) background = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook 通知栏小图标颜色
|
* Hook 通知栏小图标颜色
|
||||||
@@ -446,18 +451,7 @@ class HookEntry : YukiHookXposedInitProxy {
|
|||||||
val isNotGrayscaleIcon = notifyInstance.isXmsf || !isGrayscaleIcon(context, iconDrawable)
|
val isNotGrayscaleIcon = notifyInstance.isXmsf || !isGrayscaleIcon(context, iconDrawable)
|
||||||
|
|
||||||
/** 获取目标修复彩色图标的 APP */
|
/** 获取目标修复彩色图标的 APP */
|
||||||
var isTargetFixApp = false
|
val isTargetFixApp = compatCustomIcon(!isNotGrayscaleIcon, notifyInstance.opPkgName).first != null
|
||||||
/** 如果开启了自定义通知图标优化 */
|
|
||||||
if (prefs.getBoolean(ENABLE_NOTIFY_ICON_FIX, default = true))
|
|
||||||
run {
|
|
||||||
if (iconDatas.isNotEmpty())
|
|
||||||
iconDatas.forEach {
|
|
||||||
if (notifyInstance.opPkgName == it.packageName && isAppNotifyHookOf(it)) {
|
|
||||||
if (isNotGrayscaleIcon || isAppNotifyHookAllOf(it)) isTargetFixApp = true
|
|
||||||
return@run
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 只要不是灰度就返回彩色图标
|
* 只要不是灰度就返回彩色图标
|
||||||
* 否则不对颜色进行反色处理防止一些系统图标出现异常
|
* 否则不对颜色进行反色处理防止一些系统图标出现异常
|
||||||
@@ -509,7 +503,7 @@ class HookEntry : YukiHookXposedInitProxy {
|
|||||||
replaceAny {
|
replaceAny {
|
||||||
hookIgnoreStatusBarIconColor(
|
hookIgnoreStatusBarIconColor(
|
||||||
context = globalContext ?: error("GlobalContext got null"),
|
context = globalContext ?: error("GlobalContext got null"),
|
||||||
expandedNf = args[0] as? StatusBarNotification?
|
expandedNf = firstArgs as? StatusBarNotification?
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -530,7 +524,7 @@ class HookEntry : YukiHookXposedInitProxy {
|
|||||||
}.onFind { isUseLegacy = true }
|
}.onFind { isUseLegacy = true }
|
||||||
}
|
}
|
||||||
afterHook {
|
afterHook {
|
||||||
(globalContext ?: args[0] as Context).also { context ->
|
(globalContext ?: firstArgs as Context).also { context ->
|
||||||
hookSmallIconOnSet(
|
hookSmallIconOnSet(
|
||||||
context = context,
|
context = context,
|
||||||
args[if (isUseLegacy) 1 else 0] as? StatusBarNotification?,
|
args[if (isUseLegacy) 1 else 0] as? StatusBarNotification?,
|
||||||
@@ -552,6 +546,9 @@ class HookEntry : YukiHookXposedInitProxy {
|
|||||||
NotificationHeaderViewWrapperClass.clazz
|
NotificationHeaderViewWrapperClass.clazz
|
||||||
.field { name = "mIcon" }.of<ImageView>(instance) ?: return@afterHook
|
.field { name = "mIcon" }.of<ImageView>(instance) ?: return@afterHook
|
||||||
|
|
||||||
|
/** 通知是否展开 */
|
||||||
|
var isExpanded = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从父类中得到 mRow 变量 - [ExpandableNotificationRowClass]
|
* 从父类中得到 mRow 变量 - [ExpandableNotificationRowClass]
|
||||||
* 获取其中的得到通知方法
|
* 获取其中的得到通知方法
|
||||||
@@ -560,7 +557,12 @@ class HookEntry : YukiHookXposedInitProxy {
|
|||||||
.method { name = "getEntry" }
|
.method { name = "getEntry" }
|
||||||
.get(NotificationViewWrapperClass.clazz.field {
|
.get(NotificationViewWrapperClass.clazz.field {
|
||||||
name = "mRow"
|
name = "mRow"
|
||||||
}.get(instance).self).call()?.let {
|
}.get(instance).self?.also {
|
||||||
|
isExpanded = ExpandableNotificationRowClass.clazz.method {
|
||||||
|
name = "isExpanded"
|
||||||
|
returnType = BooleanType
|
||||||
|
}.get(it).invoke<Boolean>() == true
|
||||||
|
}).call()?.let {
|
||||||
it.javaClass.method {
|
it.javaClass.method {
|
||||||
name = "getSbn"
|
name = "getSbn"
|
||||||
}.get(it).invoke<StatusBarNotification>()
|
}.get(it).invoke<StatusBarNotification>()
|
||||||
@@ -568,8 +570,15 @@ class HookEntry : YukiHookXposedInitProxy {
|
|||||||
.method { name = "getStatusBarNotification" }
|
.method { name = "getStatusBarNotification" }
|
||||||
.get(NotificationViewWrapperClass.clazz.field { name = "mRow" }.get(instance).self)
|
.get(NotificationViewWrapperClass.clazz.field { name = "mRow" }.get(instance).self)
|
||||||
.invoke<StatusBarNotification>()
|
.invoke<StatusBarNotification>()
|
||||||
|
|
||||||
|
/** 获取优先级 */
|
||||||
|
val importance =
|
||||||
|
(iconImageView.context.getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager?)
|
||||||
|
?.getNotificationChannel(expandedNf?.notification?.channelId)?.importance ?: 0
|
||||||
|
/** 非最小化优先级的通知全部设置为展开状态 */
|
||||||
|
if (importance != 1) isExpanded = true
|
||||||
/** 执行 Hook */
|
/** 执行 Hook */
|
||||||
hookNotifyIconOnSet(iconImageView.context, expandedNf, iconImageView)
|
hookNotifyIconOnSet(iconImageView.context, expandedNf, iconImageView, isExpanded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -586,15 +595,15 @@ class HookEntry : YukiHookXposedInitProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
intercept()
|
intercept()
|
||||||
}.ignoredAllFailure()
|
}.ignoredHookingFailure()
|
||||||
injectMember {
|
injectMember {
|
||||||
method {
|
method {
|
||||||
name = "resetIconBgAndPaddings"
|
name = "resetIconBgAndPaddings"
|
||||||
param(ImageViewClass, ExpandedNotificationClass.clazz)
|
param(ImageViewClass, ExpandedNotificationClass.clazz)
|
||||||
}
|
}
|
||||||
intercept()
|
intercept()
|
||||||
}.ignoredAllFailure()
|
}.ignoredHookingFailure()
|
||||||
}
|
}.ignoredHookClassNotFoundFailure()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -56,7 +56,7 @@ class IconPackParams(private val context: Context? = null, private val param: Pa
|
|||||||
val iconDatas
|
val iconDatas
|
||||||
get() = ArrayList<IconDataBean>().apply {
|
get() = ArrayList<IconDataBean>().apply {
|
||||||
storageDataJson?.also {
|
storageDataJson?.also {
|
||||||
if (it.isNotBlank())
|
if (it.isNotBlank()) runCatching {
|
||||||
JSONArray(it).also { array ->
|
JSONArray(it).also { array ->
|
||||||
for (i in 0 until array.length()) runCatching {
|
for (i in 0 until array.length()) runCatching {
|
||||||
(array.get(i) as JSONObject).apply {
|
(array.get(i) as JSONObject).apply {
|
||||||
@@ -74,6 +74,7 @@ class IconPackParams(private val context: Context? = null, private val param: Pa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,8 +25,6 @@
|
|||||||
package com.fankes.miui.notify.ui
|
package com.fankes.miui.notify.ui
|
||||||
|
|
||||||
import android.app.ProgressDialog
|
import android.app.ProgressDialog
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@@ -51,6 +49,9 @@ import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus
|
|||||||
|
|
||||||
class ConfigureActivity : BaseActivity() {
|
class ConfigureActivity : BaseActivity() {
|
||||||
|
|
||||||
|
/** 访问请求链接 */
|
||||||
|
private var rawGithubUrl = "https://raw.githubusercontent.com/fankes/AndroidNotifyIconAdapt/main"
|
||||||
|
|
||||||
/** 当前筛选条件 */
|
/** 当前筛选条件 */
|
||||||
private var filterText = ""
|
private var filterText = ""
|
||||||
|
|
||||||
@@ -192,16 +193,7 @@ class ConfigureActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
/** 设置点击事件 */
|
/** 设置点击事件 */
|
||||||
findViewById<View>(R.id.config_cbr_button).setOnClickListener {
|
findViewById<View>(R.id.config_cbr_button).setOnClickListener {
|
||||||
runCatching {
|
openBrowser(url = "https://github.com/fankes/AndroidNotifyIconAdapt/blob/main/CONTRIBUTING.md")
|
||||||
startActivity(Intent().apply {
|
|
||||||
action = "android.intent.action.VIEW"
|
|
||||||
data = Uri.parse("https://github.com/fankes/AndroidNotifyIconAdapt/blob/main/CONTRIBUTING.md")
|
|
||||||
/** 防止顶栈一样重叠在自己的 APP 中 */
|
|
||||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
||||||
})
|
|
||||||
}.onFailure {
|
|
||||||
toast(msg = "无法启动系统默认浏览器")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/** 装载数据 */
|
/** 装载数据 */
|
||||||
mockLocalData()
|
mockLocalData()
|
||||||
@@ -227,7 +219,7 @@ class ConfigureActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 开始更新数据 */
|
/** 开始更新数据 */
|
||||||
private fun onRefreshing() {
|
private fun onRefreshing() = ClientRequestTool.checkingInternetConnect(context = this) {
|
||||||
ProgressDialog(this).apply {
|
ProgressDialog(this).apply {
|
||||||
setDefaultStyle(context = this@ConfigureActivity)
|
setDefaultStyle(context = this@ConfigureActivity)
|
||||||
setCancelable(false)
|
setCancelable(false)
|
||||||
@@ -237,12 +229,12 @@ class ConfigureActivity : BaseActivity() {
|
|||||||
}.also {
|
}.also {
|
||||||
ClientRequestTool.wait(
|
ClientRequestTool.wait(
|
||||||
context = this,
|
context = this,
|
||||||
url = "https://raw.githubusercontent.com/fankes/AndroidNotifyIconAdapt/main/OS/MIUI/NotifyIconsSupportConfig.json"
|
url = "$rawGithubUrl/OS/MIUI/NotifyIconsSupportConfig.json"
|
||||||
) { isDone1, ctOS ->
|
) { isDone1, ctOS ->
|
||||||
it.setMessage("正在同步 APP 数据")
|
it.setMessage("正在同步 APP 数据")
|
||||||
ClientRequestTool.wait(
|
ClientRequestTool.wait(
|
||||||
context = this,
|
context = this,
|
||||||
url = "https://raw.githubusercontent.com/fankes/AndroidNotifyIconAdapt/main/APP/NotifyIconsSupportConfig.json"
|
url = "$rawGithubUrl/APP/NotifyIconsSupportConfig.json"
|
||||||
) { isDone2, ctAPP ->
|
) { isDone2, ctAPP ->
|
||||||
it.cancel()
|
it.cancel()
|
||||||
IconPackParams(context = this).also { params ->
|
IconPackParams(context = this).also { params ->
|
||||||
@@ -253,12 +245,14 @@ class ConfigureActivity : BaseActivity() {
|
|||||||
mockLocalData()
|
mockLocalData()
|
||||||
SystemUITool.showNeedUpdateApplySnake(context = this)
|
SystemUITool.showNeedUpdateApplySnake(context = this)
|
||||||
} else snake(msg = "列表数据已是最新")
|
} else snake(msg = "列表数据已是最新")
|
||||||
} else
|
} else showDialog {
|
||||||
showDialog {
|
title = "连接失败"
|
||||||
title = "连接失败"
|
msg = "连接失败,错误如下:\n${if (!isDone1) ctOS else ctAPP}"
|
||||||
msg = "连接失败,错误如下:\n${if (!isDone1) ctOS else ctAPP}"
|
confirmButton(text = "解决方案") {
|
||||||
confirmButton(text = "我知道了")
|
openBrowser(url = "https://www.baidu.com/s?wd=github%2Braw%2B%E6%97%A0%E6%B3%95%E8%AE%BF%E9%97%AE")
|
||||||
}
|
}
|
||||||
|
cancelButton()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,6 @@ package com.fankes.miui.notify.ui
|
|||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
@@ -177,30 +176,11 @@ class MainActivity : BaseActivity() {
|
|||||||
findViewById<View>(R.id.title_restart_icon).setOnClickListener { SystemUITool.restartSystemUI(context = this) }
|
findViewById<View>(R.id.title_restart_icon).setOnClickListener { SystemUITool.restartSystemUI(context = this) }
|
||||||
/** 恰饭! */
|
/** 恰饭! */
|
||||||
findViewById<View>(R.id.link_with_follow_me).setOnClickListener {
|
findViewById<View>(R.id.link_with_follow_me).setOnClickListener {
|
||||||
runCatching {
|
openBrowser(url = "https://www.coolapk.com/u/876977", packageName = "com.coolapk.market")
|
||||||
startActivity(Intent().apply {
|
|
||||||
setPackage("com.coolapk.market")
|
|
||||||
action = "android.intent.action.VIEW"
|
|
||||||
data = Uri.parse("https://www.coolapk.com/u/876977")
|
|
||||||
/** 防止顶栈一样重叠在自己的 APP 中 */
|
|
||||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
||||||
})
|
|
||||||
}.onFailure {
|
|
||||||
toast(msg = "你可能没有安装酷安")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/** 项目地址点击事件 */
|
/** 项目地址点击事件 */
|
||||||
findViewById<View>(R.id.link_with_project_address).setOnClickListener {
|
findViewById<View>(R.id.link_with_project_address).setOnClickListener {
|
||||||
runCatching {
|
openBrowser(url = "https://github.com/fankes/MIUINativeNotifyIcon")
|
||||||
startActivity(Intent().apply {
|
|
||||||
action = "android.intent.action.VIEW"
|
|
||||||
data = Uri.parse("https://github.com/fankes/MIUINativeNotifyIcon")
|
|
||||||
/** 防止顶栈一样重叠在自己的 APP 中 */
|
|
||||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
||||||
})
|
|
||||||
}.onFailure {
|
|
||||||
toast(msg = "无法启动系统默认浏览器")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -20,11 +20,15 @@
|
|||||||
*
|
*
|
||||||
* This file is Created by fankes on 2022/2/25.
|
* This file is Created by fankes on 2022/2/25.
|
||||||
*/
|
*/
|
||||||
@file:Suppress("TrustAllX509TrustManager", "CustomX509TrustManager")
|
@file:Suppress("TrustAllX509TrustManager", "CustomX509TrustManager", "DEPRECATION")
|
||||||
|
|
||||||
package com.fankes.miui.notify.utils
|
package com.fankes.miui.notify.utils
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import android.app.ProgressDialog
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import android.provider.Settings
|
||||||
import com.highcapable.yukihookapi.hook.log.loggerD
|
import com.highcapable.yukihookapi.hook.log.loggerD
|
||||||
import okhttp3.*
|
import okhttp3.*
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
@@ -37,6 +41,38 @@ import javax.net.ssl.*
|
|||||||
*/
|
*/
|
||||||
object ClientRequestTool {
|
object ClientRequestTool {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查网络连接情况
|
||||||
|
* @param context 实例
|
||||||
|
* @param it 已连接回调
|
||||||
|
*/
|
||||||
|
fun checkingInternetConnect(context: Activity, it: () -> Unit) =
|
||||||
|
ProgressDialog(context).apply {
|
||||||
|
setDefaultStyle(context)
|
||||||
|
setCancelable(false)
|
||||||
|
setTitle("准备中")
|
||||||
|
setMessage("正在检查网络连接情况")
|
||||||
|
}.apply {
|
||||||
|
wait(context, url = "https://www.baidu.com") { isDone, _ ->
|
||||||
|
cancel()
|
||||||
|
if (isDone) it() else
|
||||||
|
context.showDialog {
|
||||||
|
title = "网络不可用"
|
||||||
|
msg = "无法连接到互联网,请检查你当前的设备是否可以上网,且没有在手机管家中禁用本模块的联网权限。"
|
||||||
|
confirmButton(text = "检查设置") {
|
||||||
|
runCatching {
|
||||||
|
context.startActivity(Intent().apply {
|
||||||
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
|
||||||
|
data = Uri.fromParts("package", context.packageName, null)
|
||||||
|
})
|
||||||
|
}.onFailure { context.snake(msg = "启动应用信息页面失败") }
|
||||||
|
}
|
||||||
|
cancelButton()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.show()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送 GET 请求内容并等待
|
* 发送 GET 请求内容并等待
|
||||||
* @param context 实例
|
* @param context 实例
|
||||||
|
@@ -27,6 +27,7 @@ package com.fankes.miui.notify.utils
|
|||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.content.pm.PackageInfo
|
import android.content.pm.PackageInfo
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
@@ -34,6 +35,7 @@ import android.graphics.Bitmap
|
|||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.drawable.GradientDrawable
|
import android.graphics.drawable.GradientDrawable
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
@@ -276,6 +278,26 @@ fun Context.snake(msg: String, actionText: String = "", it: () -> Unit = {}) =
|
|||||||
setAction(actionText) { it() }
|
setAction(actionText) { it() }
|
||||||
}.show()
|
}.show()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启动系统浏览器
|
||||||
|
* @param url 网址
|
||||||
|
* @param packageName 指定包名 - 可不填
|
||||||
|
*/
|
||||||
|
fun Context.openBrowser(url: String, packageName: String = "") =
|
||||||
|
runCatching {
|
||||||
|
startActivity(Intent().apply {
|
||||||
|
if (packageName.isNotBlank()) setPackage(packageName)
|
||||||
|
action = Intent.ACTION_VIEW
|
||||||
|
data = Uri.parse(url)
|
||||||
|
/** 防止顶栈一样重叠在自己的 APP 中 */
|
||||||
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
})
|
||||||
|
}.onFailure {
|
||||||
|
if (packageName.isNotBlank())
|
||||||
|
snake(msg = "启动 $packageName 失败")
|
||||||
|
else snake(msg = "启动系统浏览器失败")
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 忽略异常返回值
|
* 忽略异常返回值
|
||||||
* @param it 回调 - 如果异常为空
|
* @param it 回调 - 如果异常为空
|
||||||
|
@@ -5,8 +5,8 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
appVersionName = "1.85"
|
appVersionName = "1.87"
|
||||||
appVersionCode = 18
|
appVersionCode = 20
|
||||||
}
|
}
|
||||||
|
|
||||||
task clean(type: Delete) {
|
task clean(type: Delete) {
|
||||||
|
Reference in New Issue
Block a user