mirror of
https://github.com/fankes/MIUINativeNotifyIcon.git
synced 2025-09-06 02:35:32 +08:00
Compare commits
27 Commits
Author | SHA1 | Date | |
---|---|---|---|
4703d339b7
|
|||
76b1cc2f0b
|
|||
62ec1d16ae
|
|||
7db010c9a1
|
|||
e6fa34d7fd
|
|||
d4661abb71
|
|||
744d028160
|
|||
3f3a92f192
|
|||
49f18ef8c3
|
|||
73173cd7ab
|
|||
c181530ad7
|
|||
883325dc2f
|
|||
6fe1f0572c
|
|||
be8f558bf5
|
|||
175263c9aa
|
|||
f95fe45ce3
|
|||
42b0fa69b7
|
|||
d0a9554a28
|
|||
c500bdad43
|
|||
9bded26604
|
|||
c687c755f2
|
|||
b9e1d1abe7
|
|||
27cfcbada6
|
|||
f0c6dabf76
|
|||
208862bf62
|
|||
ee948f5327
|
|||
d62d0f99a2
|
6
.secret/key_store_secret.json
Normal file
6
.secret/key_store_secret.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"keyAlias": "public",
|
||||
"keyPassword": "123456",
|
||||
"storeFileName": "universal.p12",
|
||||
"storePassword": "123456"
|
||||
}
|
@@ -2,7 +2,7 @@
|
||||
|
||||
[](https://github.com/fankes/MIUINativeNotifyIcon)
|
||||
[](https://github.com/fankes/MIUINativeNotifyIcon/blob/master/LICENSE)
|
||||
[](https://github.com/fankes/MIUINativeNotifyIcon/releases)
|
||||
[](https://github.com/fankes/MIUINativeNotifyIcon/releases)
|
||||
[](https://github.com/fankes/MIUINativeNotifyIcon/releases)
|
||||
[](https://github.com/Xposed-Modules-Repo/com.fankes.miui.notify/releases)
|
||||
[](https://t.me/XiaofangInternet)
|
||||
@@ -54,7 +54,7 @@ Fix the native notification bar icon function abandoned by the MIUI development
|
||||
|
||||
- [Automatic Build on Commit](https://github.com/fankes/MIUINativeNotifyIcon/actions/workflows/commit_ci.yml)
|
||||
|
||||
上述更新为代码 `commit` 后自动触发,具体更新内容可点击上方的文字前往 **Github Actions** 进行查看,本更新由开源的流程自动编译发布,**不保证其稳定性**,所发布的版本**仅供测试**,且不会特殊说明甚至可能会变更版本号或保持与当前稳定版相同的版本号。
|
||||
上述更新为代码 `commit` 后自动触发,具体更新内容可点击上方的文字前往 **GitHub Actions** 进行查看,本更新由开源的流程自动编译发布,**不保证其稳定性**,所发布的版本**仅供测试**,且不会特殊说明甚至可能会变更版本号或保持与当前稳定版相同的版本号。
|
||||
|
||||
- [Release](https://github.com/fankes/MIUINativeNotifyIcon/releases)
|
||||
- [Xposed-Modules-Repo](https://github.com/Xposed-Modules-Repo/com.fankes.miui.notify/releases)
|
||||
|
@@ -1,39 +1,51 @@
|
||||
import groovy.json.JsonSlurper
|
||||
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'kotlin-android'
|
||||
id 'com.google.devtools.ksp' version '1.7.22-1.0.8'
|
||||
id 'org.jetbrains.kotlin.android'
|
||||
id 'com.google.devtools.ksp'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk 33
|
||||
|
||||
signingConfigs {
|
||||
debug {
|
||||
storeFile file('../keystore/public')
|
||||
storePassword '123456'
|
||||
keyAlias 'public'
|
||||
keyPassword '123456'
|
||||
universal {
|
||||
def dirPath = rootProject.ext.app.signingConfigs.secretConfigsDirPath
|
||||
def fileName = rootProject.ext.app.signingConfigs.secretConfigsFileName
|
||||
def configs = new JsonSlurper().parse(file("${dirPath}/${fileName}"))
|
||||
keyAlias configs.keyAlias
|
||||
keyPassword configs.keyPassword
|
||||
storeFile file("${dirPath}/${configs.storeFileName}")
|
||||
storePassword configs.storePassword
|
||||
v1SigningEnabled true
|
||||
v2SigningEnabled true
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.fankes.miui.notify"
|
||||
minSdk 28
|
||||
targetSdk 33
|
||||
versionCode rootProject.ext.appVersionCode
|
||||
versionName rootProject.ext.appVersionName
|
||||
namespace 'com.fankes.miui.notify'
|
||||
compileSdk rootProject.ext.android.compileSdk
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
defaultConfig {
|
||||
applicationId 'com.fankes.miui.notify'
|
||||
|
||||
minSdk rootProject.ext.android.minSdk
|
||||
targetSdk rootProject.ext.android.targetSdk
|
||||
|
||||
versionCode rootProject.ext.app.versionCode
|
||||
versionName rootProject.ext.app.versionName
|
||||
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
minifyEnabled false
|
||||
signingConfig signingConfigs.universal
|
||||
}
|
||||
release {
|
||||
minifyEnabled rootProject.ext.enableR8
|
||||
shrinkResources rootProject.ext.enableR8
|
||||
zipAlignEnabled rootProject.ext.enableR8
|
||||
signingConfig signingConfigs.debug
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
zipAlignEnabled true
|
||||
signingConfig signingConfigs.universal
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
@@ -60,14 +72,14 @@ android {
|
||||
|
||||
dependencies {
|
||||
compileOnly 'de.robv.android.xposed:api:82'
|
||||
implementation 'com.highcapable.yukihookapi:api:1.1.8'
|
||||
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.1.8'
|
||||
implementation 'com.highcapable.yukihookapi:api:1.1.11'
|
||||
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.1.11'
|
||||
implementation 'com.github.duanhong169:drawabletoolbox:1.0.7'
|
||||
implementation "com.github.topjohnwu.libsu:core:3.1.2"
|
||||
implementation 'androidx.annotation:annotation:1.5.0'
|
||||
implementation "com.github.topjohnwu.libsu:core:5.0.4"
|
||||
implementation 'androidx.annotation:annotation:1.6.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.7'
|
||||
implementation 'androidx.core:core-ktx:1.9.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.0'
|
||||
implementation 'androidx.core:core-ktx:1.10.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'com.google.android.material:material:1.8.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
|
@@ -36,10 +36,13 @@ object PackageName {
|
||||
*/
|
||||
object IconRuleSourceSyncType {
|
||||
|
||||
/** Github Raw (代理) */
|
||||
const val GITHUB_RAW_PROXY = 1000
|
||||
/** GitHub Raw (代理 - GitHub Proxy) */
|
||||
const val GITHUB_RAW_PROXY_1 = 500
|
||||
|
||||
/** Github Raw (直连) */
|
||||
/** GitHub Raw (代理 - 7ED Services) */
|
||||
const val GITHUB_RAW_PROXY_2 = 1000
|
||||
|
||||
/** GitHub Raw (直连) */
|
||||
const val GITHUB_RAW_DIRECT = 2000
|
||||
|
||||
/** 自定义地址 */
|
||||
|
@@ -26,7 +26,7 @@ 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.factory.prefs
|
||||
import com.highcapable.yukihookapi.hook.log.loggerW
|
||||
import com.highcapable.yukihookapi.hook.param.PackageParam
|
||||
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
|
||||
@@ -60,6 +60,9 @@ object ConfigData {
|
||||
/** 通知栏中的通知图标圆角程度 */
|
||||
val NOTIFY_ICON_CORNER_SIZE = PrefsData("_notify_icon_corner", 15)
|
||||
|
||||
/** 强制通知栏中的通知图标使用系统着色 */
|
||||
val ENABLE_NOTIFY_ICON_FORCE_SYSTEM_COLOR = PrefsData("_notify_icon_force_system_color", false)
|
||||
|
||||
/** 强制通知栏中的通知图标为 APP 图标 */
|
||||
val ENABLE_NOTIFY_ICON_FORCE_APP_ICON = PrefsData("_notify_icon_force_app_icon", false)
|
||||
|
||||
@@ -82,7 +85,7 @@ object ConfigData {
|
||||
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_TYPE = PrefsData("_rule_source_sync_way", IconRuleSourceSyncType.GITHUB_RAW_PROXY_1)
|
||||
|
||||
/** 通知图标优化名单同步地址 */
|
||||
val ICON_RULE_SOURCE_SYNC_CUSTOM_URL = PrefsData("_rule_source_sync_way_custom_url", "")
|
||||
@@ -111,7 +114,7 @@ object ConfigData {
|
||||
* @return [String]
|
||||
*/
|
||||
private fun getString(data: PrefsData<String>) = when (instance) {
|
||||
is Context -> (instance as Context).modulePrefs.get(data)
|
||||
is Context -> (instance as Context).prefs().get(data)
|
||||
is PackageParam -> (instance as PackageParam).prefs.get(data)
|
||||
else -> error("Unknown type for get prefs data")
|
||||
}
|
||||
@@ -123,7 +126,7 @@ object ConfigData {
|
||||
*/
|
||||
private fun putString(data: PrefsData<String>, value: String) {
|
||||
when (instance) {
|
||||
is Context -> (instance as Context).modulePrefs.put(data, value)
|
||||
is Context -> (instance as Context).prefs().edit { put(data, value) }
|
||||
is PackageParam -> loggerW(msg = "Not support for this method")
|
||||
else -> error("Unknown type for put prefs data")
|
||||
}
|
||||
@@ -135,7 +138,7 @@ object ConfigData {
|
||||
* @return [Int]
|
||||
*/
|
||||
internal fun getInt(data: PrefsData<Int>) = when (instance) {
|
||||
is Context -> (instance as Context).modulePrefs.get(data)
|
||||
is Context -> (instance as Context).prefs().get(data)
|
||||
is PackageParam -> (instance as PackageParam).prefs.get(data)
|
||||
else -> error("Unknown type for get prefs data")
|
||||
}
|
||||
@@ -147,7 +150,7 @@ object ConfigData {
|
||||
*/
|
||||
internal fun putInt(data: PrefsData<Int>, value: Int) {
|
||||
when (instance) {
|
||||
is Context -> (instance as Context).modulePrefs.put(data, value)
|
||||
is Context -> (instance as Context).prefs().edit { put(data, value) }
|
||||
is PackageParam -> loggerW(msg = "Not support for this method")
|
||||
else -> error("Unknown type for put prefs data")
|
||||
}
|
||||
@@ -159,7 +162,7 @@ object ConfigData {
|
||||
* @return [Boolean]
|
||||
*/
|
||||
internal fun getBoolean(data: PrefsData<Boolean>) = when (instance) {
|
||||
is Context -> (instance as Context).modulePrefs.get(data)
|
||||
is Context -> (instance as Context).prefs().get(data)
|
||||
is PackageParam -> (instance as PackageParam).prefs.get(data)
|
||||
else -> error("Unknown type for get prefs data")
|
||||
}
|
||||
@@ -171,7 +174,7 @@ object ConfigData {
|
||||
*/
|
||||
internal fun putBoolean(data: PrefsData<Boolean>, value: Boolean) {
|
||||
when (instance) {
|
||||
is Context -> (instance as Context).modulePrefs.put(data, value)
|
||||
is Context -> (instance as Context).prefs().edit { put(data, value) }
|
||||
is PackageParam -> loggerW(msg = "Not support for this method")
|
||||
else -> error("Unknown type for put prefs data")
|
||||
}
|
||||
@@ -257,6 +260,16 @@ object ConfigData {
|
||||
putInt(NOTIFY_ICON_CORNER_SIZE, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否强制通知栏中的通知图标使用系统着色
|
||||
* @return [Boolean]
|
||||
*/
|
||||
var isEnableNotifyIconForceSystemColor
|
||||
get() = getBoolean(ENABLE_NOTIFY_ICON_FORCE_SYSTEM_COLOR)
|
||||
set(value) {
|
||||
putBoolean(ENABLE_NOTIFY_ICON_FORCE_SYSTEM_COLOR, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否强制通知栏中的通知图标为 APP 图标
|
||||
* @return [Boolean]
|
||||
|
@@ -54,6 +54,7 @@ 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.ActivationPromptTool
|
||||
import com.fankes.miui.notify.utils.tool.BitmapCompatTool
|
||||
import com.fankes.miui.notify.utils.tool.IconAdaptationTool
|
||||
import com.fankes.miui.notify.utils.tool.SystemUITool
|
||||
@@ -63,9 +64,7 @@ import com.highcapable.yukihookapi.hook.factory.*
|
||||
import com.highcapable.yukihookapi.hook.log.loggerD
|
||||
import com.highcapable.yukihookapi.hook.log.loggerW
|
||||
import com.highcapable.yukihookapi.hook.type.android.*
|
||||
import com.highcapable.yukihookapi.hook.type.defined.VagueType
|
||||
import com.highcapable.yukihookapi.hook.type.java.BooleanType
|
||||
import com.highcapable.yukihookapi.hook.type.java.FloatType
|
||||
import com.highcapable.yukihookapi.hook.type.java.IntType
|
||||
import top.defaults.drawabletoolbox.DrawableBuilder
|
||||
|
||||
@@ -142,9 +141,6 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
/** 缓存的通知图标优化数组 */
|
||||
private var iconDatas = ArrayList<IconDataBean>()
|
||||
|
||||
/** 已缓存的灰度图标 (单色图标) 判断结果数组 */
|
||||
private val grayscaleIconResults = HashMap<String, Boolean>()
|
||||
|
||||
/** 当前是否处于深色图标模式 - 跟随 Hook 保存 */
|
||||
private var isDarkIconMode = false
|
||||
|
||||
@@ -251,22 +247,15 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为灰度图标 (单色图标)
|
||||
* - 这个是修复彩色图标的关键核心代码判断
|
||||
*
|
||||
* 判断是否为灰度图标 - 反射执行系统方法
|
||||
* @param context 实例
|
||||
* @param drawable 要判断的图标
|
||||
* @param instance 用于标识缓存的实例
|
||||
* @return [Boolean]
|
||||
*/
|
||||
private fun isGrayscaleIcon(context: Context, drawable: Drawable, instance: Any): Boolean {
|
||||
/** 从缓存中读取的结果 */
|
||||
val cachedResult = when (instance) {
|
||||
is StatusBarNotification -> grayscaleIconResults[instance.notification.toString()]
|
||||
is Notification -> grayscaleIconResults[instance.toString()]
|
||||
else -> null
|
||||
}
|
||||
|
||||
/** 当前实时获取的结果 */
|
||||
val currentResult = if (ConfigData.isEnableColorIconCompat.not()) safeOfFalse {
|
||||
private fun isGrayscaleIcon(context: Context, drawable: Drawable) =
|
||||
if (ConfigData.isEnableColorIconCompat.not()) safeOfFalse {
|
||||
ContrastColorUtilClass.toClass().let {
|
||||
it.method {
|
||||
name = "isGrayscaleIcon"
|
||||
@@ -277,13 +266,6 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
}.get().invoke(context)).boolean(drawable)
|
||||
}
|
||||
} else BitmapCompatTool.isGrayscaleDrawable(drawable)
|
||||
return cachedResult ?: currentResult.also {
|
||||
when (instance) {
|
||||
is StatusBarNotification -> grayscaleIconResults[instance.notification.toString()] = it
|
||||
is Notification -> grayscaleIconResults[instance.toString()] = it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理为圆角图标
|
||||
@@ -362,7 +344,7 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
}
|
||||
}
|
||||
if (isGrayscaleIcon.not() && ConfigData.isEnableNotifyIconFixPlaceholder)
|
||||
customPair = Triple(context.resources.drawableOf(R.drawable.ic_unsupported), 0, true)
|
||||
customPair = Triple(context.resources.drawableOf(R.drawable.ic_message), 0, true)
|
||||
}
|
||||
return customPair ?: Triple(null, 0, false)
|
||||
}
|
||||
@@ -379,7 +361,7 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
private fun compatStatusIcon(context: Context, nf: StatusBarNotification?, iconDrawable: Drawable?) = nf?.let { notifyInstance ->
|
||||
if (iconDrawable == null) return@let Pair(null, false)
|
||||
/** 判断是否不是灰度图标 */
|
||||
val isGrayscaleIcon = notifyInstance.isXmsf.not() && isGrayscaleIcon(context, iconDrawable, notifyInstance)
|
||||
val isGrayscaleIcon = notifyInstance.isXmsf.not() && isGrayscaleIcon(context, iconDrawable)
|
||||
|
||||
/** 目标彩色通知 APP 图标 */
|
||||
val customTriple = compatCustomIcon(context, isGrayscaleIcon, notifyInstance.nfPkgName)
|
||||
@@ -457,10 +439,10 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
val iconColor = notifyInstance.notification.color
|
||||
|
||||
/** 是否有通知栏图标颜色 */
|
||||
val hasIconColor = iconColor != 0
|
||||
val hasIconColor = iconColor != 0 && ConfigData.isEnableNotifyIconForceSystemColor.not()
|
||||
|
||||
/** 通知图标适配颜色 */
|
||||
val supportColor = iconColor.let {
|
||||
val supportColor = (iconColor.takeIf { ConfigData.isEnableNotifyIconForceSystemColor.not() } ?: 0).let {
|
||||
when {
|
||||
isUseMaterial3Style -> newStyle
|
||||
it == 0 || isExpanded.not() -> oldStyle
|
||||
@@ -473,7 +455,7 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
?: return@let loggerW(msg = "compatNotifyIcon got null smallIcon")
|
||||
|
||||
/** 判断图标风格 */
|
||||
val isGrayscaleIcon = notifyInstance.isXmsf.not() && isGrayscaleIcon(context, iconDrawable, notifyInstance)
|
||||
val isGrayscaleIcon = notifyInstance.isXmsf.not() && isGrayscaleIcon(context, iconDrawable)
|
||||
|
||||
/** 自定义默认小图标 */
|
||||
var customIcon: Drawable? = null
|
||||
@@ -485,7 +467,8 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
if (it.third) return@also
|
||||
customIcon = it.first
|
||||
customIconColor = if (isUseMaterial3Style || isExpanded)
|
||||
(it.second.takeIf { e -> e != 0 } ?: (if (isUseMaterial3Style) context.systemAccentColor else 0)) else 0
|
||||
(it.second.takeIf { e -> e != 0 && ConfigData.isEnableNotifyIconForceSystemColor.not() }
|
||||
?: (if (isUseMaterial3Style) context.systemAccentColor else 0)) else 0
|
||||
}
|
||||
/** 打印日志 */
|
||||
loggerDebug(tag = "Notification Panel Icon", context, notifyInstance, isCustom = customIcon != null, isGrayscaleIcon)
|
||||
@@ -553,7 +536,7 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
?: return loggerW(msg = "isGrayscaleIcon got null smallIcon").let { false }
|
||||
|
||||
/** 判断是否不是灰度图标 */
|
||||
val isGrayscaleIcon = notifyInstance.isXmsf.not() && isGrayscaleIcon(context, iconDrawable, notifyInstance)
|
||||
val isGrayscaleIcon = notifyInstance.isXmsf.not() && isGrayscaleIcon(context, iconDrawable)
|
||||
|
||||
/** 获取目标修复彩色图标的 APP */
|
||||
val isTargetFixApp = compatCustomIcon(context, isGrayscaleIcon, notifyInstance.nfPkgName).first != null
|
||||
@@ -601,6 +584,37 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook 原生通知包装纸实例内容
|
||||
* @param wrapper 通知包装纸实例
|
||||
*/
|
||||
private fun hookNotificationViewWrapper(wrapper: Any) {
|
||||
/** 忽略较旧版本 - 在没有 MIUI 通知栏样式的时候可能出现奇怪的问题 */
|
||||
if (isNotHasAbsoluteMiuiStyle && isShowMiuiStyle) return
|
||||
|
||||
/** 获取小图标 */
|
||||
val iconImageView = NotificationHeaderViewWrapperClass.toClassOrNull()
|
||||
?.field { name = "mIcon" }?.get(wrapper)?.cast<ImageView>() ?: return
|
||||
|
||||
/** 获取 [ExpandableNotificationRowClass] */
|
||||
val rowPair = wrapper.getRowPair()
|
||||
|
||||
/** 获取 [StatusBarNotification] */
|
||||
val expandedNf = rowPair.second.getSbn()
|
||||
|
||||
/** 通知是否展开 */
|
||||
var isExpanded = rowPair.first
|
||||
|
||||
/** 获取优先级 */
|
||||
val importance =
|
||||
(iconImageView.context.getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager?)
|
||||
?.getNotificationChannel(expandedNf?.notification?.channelId)?.importance ?: 0
|
||||
/** 非最小化优先级的通知全部设置为展开状态 */
|
||||
if (importance != 1) isExpanded = true
|
||||
/** 执行 Hook */
|
||||
compatNotifyIcon(iconImageView.context, expandedNf, iconImageView, isExpanded)
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 [NotificationViewWrapperClass] 中获取 [ExpandableNotificationRowClass]
|
||||
* @return [Pair] - ([Boolean] 通知是否展开,[Any] 通知 Row 实例)
|
||||
@@ -680,11 +694,12 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
addAction(Intent.ACTION_PACKAGE_REPLACED)
|
||||
addAction(Intent.ACTION_PACKAGE_REMOVED)
|
||||
}) { context, intent ->
|
||||
if (intent.action.equals(Intent.ACTION_PACKAGE_REPLACED).not() &&
|
||||
intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)
|
||||
) return@registerReceiver
|
||||
if (ConfigData.isEnableNotifyIconFix && ConfigData.isEnableNotifyIconFixNotify)
|
||||
intent.data?.schemeSpecificPart?.also { packageName ->
|
||||
intent.data?.schemeSpecificPart?.also { packageName ->
|
||||
if (intent.action.equals(Intent.ACTION_PACKAGE_REPLACED)) ActivationPromptTool.prompt(context, packageName)
|
||||
if (intent.action.equals(Intent.ACTION_PACKAGE_REPLACED).not() &&
|
||||
intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)
|
||||
) return@registerReceiver
|
||||
if (ConfigData.isEnableNotifyIconFix && ConfigData.isEnableNotifyIconFixNotify)
|
||||
when (intent.action) {
|
||||
Intent.ACTION_PACKAGE_ADDED -> {
|
||||
if (iconDatas.takeIf { e -> e.isNotEmpty() }
|
||||
@@ -694,7 +709,7 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
}
|
||||
Intent.ACTION_PACKAGE_REMOVED -> IconAdaptationTool.removeNewAppSupportNotify(context, packageName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 注入模块资源 */
|
||||
onCreate { injectModuleAppResources() }
|
||||
@@ -706,7 +721,6 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
/** 缓存图标数据 */
|
||||
private fun cachingIconDatas() {
|
||||
iconDatas.clear()
|
||||
grayscaleIconResults.clear()
|
||||
IconPackParams(param = this).iconDatas.apply { if (isNotEmpty()) forEach { iconDatas.add(it) } }
|
||||
}
|
||||
|
||||
@@ -721,7 +735,6 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
/** 获取可读写状态 */
|
||||
return prefs.isPreferencesAvailable.also {
|
||||
isUsingCachingMethod = true
|
||||
prefs.clearCache()
|
||||
cachingIconDatas()
|
||||
if (isRefreshCacheOnly) return@also
|
||||
refreshStatusBarIcons()
|
||||
@@ -739,9 +752,9 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
/** 强制回写系统的状态栏图标样式为原生 */
|
||||
injectMember {
|
||||
method {
|
||||
name = "shouldSubstituteSmallIcon"
|
||||
param(ExpandedNotificationClass)
|
||||
}
|
||||
name { it == "shouldSubstituteSmallIcon" || it == "shouldSubstituteSmallIconForStatusBarNotification" }
|
||||
param { it[0] extends StatusBarNotificationClass }
|
||||
}.all()
|
||||
replaceToFalse()
|
||||
}
|
||||
/** 强制回写系统的状态栏图标样式为原生 */
|
||||
@@ -749,7 +762,7 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
var isUseLegacy = false
|
||||
method {
|
||||
name = "getSmallIcon"
|
||||
param(ExpandedNotificationClass, IntType)
|
||||
param { it[0] extends StatusBarNotificationClass && it[1] == IntType }
|
||||
}.remedys {
|
||||
method {
|
||||
name = "getSmallIcon"
|
||||
@@ -779,7 +792,7 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
injectMember {
|
||||
method {
|
||||
name = "onDarkChanged"
|
||||
param(VagueType, FloatType, IntType)
|
||||
paramCount { it > 0 }
|
||||
}
|
||||
afterHook {
|
||||
field { name = "mNotificationIcons" }.get(instance).cast<ViewGroup>()?.also {
|
||||
@@ -794,7 +807,7 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
isDarkIconMode = false
|
||||
updateStatusBarIconColor(it, isDarkIconMode = false)
|
||||
}
|
||||
else -> updateStatusBarIconColor(it, isDarkIconMode = false, args().last().int())
|
||||
else -> updateStatusBarIconColor(it, isDarkIconMode = false, args(index = 2).int())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -891,35 +904,13 @@ object SystemUIHooker : YukiBaseHooker() {
|
||||
}
|
||||
/** 注入原生通知包装纸实例 */
|
||||
NotificationHeaderViewWrapperClass.hook {
|
||||
/** 修复下拉通知图标自动设置回 APP 图标的方法 */
|
||||
injectMember {
|
||||
method { name { it == "resolveHeaderViews" || it == "handleHeaderViews" || it == "resolveViews" } }
|
||||
afterHook {
|
||||
/** 忽略较旧版本 - 在没有 MIUI 通知栏样式的时候可能出现奇怪的问题 */
|
||||
if (isNotHasAbsoluteMiuiStyle && isShowMiuiStyle) return@afterHook
|
||||
|
||||
/** 获取小图标 */
|
||||
val iconImageView = NotificationHeaderViewWrapperClass.toClassOrNull()
|
||||
?.field { name = "mIcon" }?.get(instance)?.cast<ImageView>() ?: return@afterHook
|
||||
|
||||
/** 获取 [ExpandableNotificationRowClass] */
|
||||
val rowPair = instance.getRowPair()
|
||||
|
||||
/** 获取 [StatusBarNotification] */
|
||||
val expandedNf = rowPair.second.getSbn()
|
||||
|
||||
/** 通知是否展开 */
|
||||
var isExpanded = rowPair.first
|
||||
|
||||
/** 获取优先级 */
|
||||
val importance =
|
||||
(iconImageView.context.getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager?)
|
||||
?.getNotificationChannel(expandedNf?.notification?.channelId)?.importance ?: 0
|
||||
/** 非最小化优先级的通知全部设置为展开状态 */
|
||||
if (importance != 1) isExpanded = true
|
||||
/** 执行 Hook */
|
||||
compatNotifyIcon(iconImageView.context, expandedNf, iconImageView, isExpanded)
|
||||
}
|
||||
afterHook { hookNotificationViewWrapper(instance) }
|
||||
}
|
||||
injectMember {
|
||||
method { name = "onContentUpdated" }
|
||||
afterHook { hookNotificationViewWrapper(instance) }
|
||||
}
|
||||
}
|
||||
/** 修改 MIUI 风格通知栏的通知图标 */
|
||||
|
@@ -29,7 +29,7 @@ import android.graphics.Color
|
||||
import com.fankes.miui.notify.bean.IconDataBean
|
||||
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.factory.prefs
|
||||
import com.highcapable.yukihookapi.hook.param.PackageParam
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
@@ -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(ConfigData.NOTIFY_ICONS_DATA)
|
||||
internal val storageDataJson get() = (context?.prefs() ?: param?.prefs)?.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(ConfigData.NOTIFY_ICONS_DATA, dataJson)
|
||||
fun save(dataJson: String) = context?.prefs()?.edit { put(ConfigData.NOTIFY_ICONS_DATA, dataJson) }
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ package com.fankes.miui.notify.params.factory
|
||||
|
||||
import android.content.Context
|
||||
import com.fankes.miui.notify.bean.IconDataBean
|
||||
import com.highcapable.yukihookapi.hook.factory.modulePrefs
|
||||
import com.highcapable.yukihookapi.hook.factory.prefs
|
||||
import com.highcapable.yukihookapi.hook.param.PackageParam
|
||||
|
||||
/**
|
||||
@@ -38,14 +38,14 @@ fun PackageParam.isAppNotifyHookOf(bean: IconDataBean) = prefs.getBoolean(bean.t
|
||||
* 获取此 APP 的通知图标是否被 Hook
|
||||
* @param bean 图标 bean
|
||||
*/
|
||||
fun Context.isAppNotifyHookOf(bean: IconDataBean) = modulePrefs.getBoolean(bean.toEnabledName(), bean.isEnabled)
|
||||
fun Context.isAppNotifyHookOf(bean: IconDataBean) = prefs().getBoolean(bean.toEnabledName(), bean.isEnabled)
|
||||
|
||||
/**
|
||||
* 设置 Hook 此 APP 的通知图标
|
||||
* @param bean 图标 bean
|
||||
* @param isHook 是否 Hook
|
||||
*/
|
||||
fun Context.putAppNotifyHookOf(bean: IconDataBean, isHook: Boolean) = modulePrefs.putBoolean(bean.toEnabledName(), isHook)
|
||||
fun Context.putAppNotifyHookOf(bean: IconDataBean, isHook: Boolean) = prefs().edit { putBoolean(bean.toEnabledName(), isHook) }
|
||||
|
||||
/**
|
||||
* 获取此 APP 的通知图标是否被全部 Hook
|
||||
@@ -57,11 +57,11 @@ fun PackageParam.isAppNotifyHookAllOf(bean: IconDataBean) = prefs.getBoolean(bea
|
||||
* 获取此 APP 的通知图标是否被全部 Hook
|
||||
* @param bean 图标 bean
|
||||
*/
|
||||
fun Context.isAppNotifyHookAllOf(bean: IconDataBean) = modulePrefs.getBoolean(bean.toEnabledAllName(), bean.isEnabledAll)
|
||||
fun Context.isAppNotifyHookAllOf(bean: IconDataBean) = prefs().getBoolean(bean.toEnabledAllName(), bean.isEnabledAll)
|
||||
|
||||
/**
|
||||
* 设置全部 Hook 此 APP 的通知图标
|
||||
* @param bean 图标 bean
|
||||
* @param isHook 是否 Hook
|
||||
*/
|
||||
fun Context.putAppNotifyHookAllOf(bean: IconDataBean, isHook: Boolean) = modulePrefs.putBoolean(bean.toEnabledAllName(), isHook)
|
||||
fun Context.putAppNotifyHookAllOf(bean: IconDataBean, isHook: Boolean) = prefs().edit { putBoolean(bean.toEnabledAllName(), isHook) }
|
@@ -158,13 +158,12 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
binding.mainTextVersion.text = "模块版本:$moduleVersion $pendingFlag"
|
||||
binding.mainTextMiuiVersion.text = "系统版本:[$androidVersionCodeName] $miuiFullVersion"
|
||||
binding.warnSCountDisTip.isGone = miuiVersionCode > 12.5
|
||||
binding.warnMiuiNotifyStyleTip.isGone = miuiVersionCode > 12
|
||||
binding.warnMiuiNotifyStyleTip.isGone = miuiVersionCode > 11
|
||||
binding.statusIconCountText.text = ConfigData.liftedStatusIconCount.toString()
|
||||
binding.notifyIconAutoSyncText.text = ConfigData.notifyIconFixAutoTime
|
||||
binding.moduleEnableSwitch.bind(ConfigData.ENABLE_MODULE) {
|
||||
onInitialize {
|
||||
binding.moduleEnableLogSwitch.isVisible = it
|
||||
binding.expAllDebugLogButton.isVisible = it && ConfigData.isEnableModuleLog
|
||||
binding.moduleEnableLogItem.isVisible = it
|
||||
binding.colorIconHookItem.isVisible = it
|
||||
binding.statusIconCountItem.isVisible = isLowerAndroidR.not() && it
|
||||
binding.notifyStyleConfigItem.isVisible = it
|
||||
@@ -177,7 +176,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
}
|
||||
}
|
||||
binding.moduleEnableLogSwitch.bind(ConfigData.ENABLE_MODULE_LOG) {
|
||||
onInitialize { binding.expAllDebugLogButton.isVisible = it && ConfigData.isEnableModule }
|
||||
onInitialize { binding.expAllDebugLogButton.isVisible = it }
|
||||
onChanged {
|
||||
reinitialize()
|
||||
SystemUITool.refreshSystemUI(context = this@MainActivity, isRefreshCacheOnly = true)
|
||||
@@ -209,9 +208,32 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
} else applyChangesAndRefresh()
|
||||
}
|
||||
}
|
||||
binding.notifyIconForceSystemColorSwitch.bind(ConfigData.ENABLE_NOTIFY_ICON_FORCE_SYSTEM_COLOR) {
|
||||
isAutoApplyChanges = false
|
||||
onChanged {
|
||||
/** 应用更改并刷新系统界面 */
|
||||
fun applyChangesAndRefresh() {
|
||||
applyChangesAndReinitialize()
|
||||
SystemUITool.refreshSystemUI(context = this@MainActivity)
|
||||
}
|
||||
if (it) showDialog {
|
||||
title = "破坏性功能警告"
|
||||
msg = "开启这个功能后,任何通知栏中的通知图标都会忽略图标自身的着色属性,全部使用系统默认颜色 (系统提供的统一色调) 着色。\n\n" +
|
||||
"此功能仅面向一些追求图标美观度的用户,我们不推荐开启这个功能,且发生任何 BUG 都不会去修复,仍然继续开启吗?"
|
||||
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() }
|
||||
onInitialize {
|
||||
arrayOf(
|
||||
binding.notifyIconCustomCornerItem,
|
||||
binding.notifyIconForceSystemColorItem
|
||||
).forEach { e -> e.isVisible = isLowerAndroidR.not() && it.not() }
|
||||
}
|
||||
onChanged {
|
||||
/** 应用更改并刷新系统界面 */
|
||||
fun applyChangesAndRefresh() {
|
||||
|
@@ -356,12 +356,12 @@ val Context.systemAccentColor
|
||||
|
||||
/**
|
||||
* 获取系统壁纸颜色
|
||||
* @return [Int] 无法获取时返回透明色
|
||||
* @return [Int] 无法获取时返回默认颜色
|
||||
*/
|
||||
val Context.wallpaperColor
|
||||
get() = safeOfNan {
|
||||
WallpaperManager.getInstance(this).getWallpaperColors(WallpaperManager.FLAG_SYSTEM)?.primaryColor?.toArgb() ?: 0
|
||||
}
|
||||
get() = runCatching {
|
||||
WallpaperManager.getInstance(this).getWallpaperColors(WallpaperManager.FLAG_SYSTEM)?.primaryColor?.toArgb()
|
||||
}.getOrNull() ?: (if (isSystemInDarkMode) 0xFFD8D8D8.toInt() else 0xFF707173.toInt())
|
||||
|
||||
/**
|
||||
* 获取较浅的颜色
|
||||
|
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
|
||||
* Copyright (C) 2017-2023 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/4/17.
|
||||
*/
|
||||
package com.fankes.miui.notify.utils.tool
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Build
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import com.fankes.miui.notify.BuildConfig
|
||||
import com.fankes.miui.notify.R
|
||||
import com.fankes.miui.notify.utils.factory.appIconOf
|
||||
|
||||
/**
|
||||
* 模块更新激活提醒通知工具类
|
||||
*/
|
||||
object ActivationPromptTool {
|
||||
|
||||
/** 当前模块的包名 */
|
||||
private const val MODULE_PACKAGE_NAME = BuildConfig.APPLICATION_ID
|
||||
|
||||
/** 推送通知的渠道名称 */
|
||||
private const val NOTIFY_CHANNEL = "activationPromptId"
|
||||
|
||||
/**
|
||||
* 推送提醒通知
|
||||
* @param context 当前实例
|
||||
* @param packageName 当前 APP 包名
|
||||
*/
|
||||
fun prompt(context: Context, packageName: String) {
|
||||
if (packageName != BuildConfig.APPLICATION_ID) return
|
||||
context.getSystemService(NotificationManager::class.java)?.apply {
|
||||
createNotificationChannel(
|
||||
NotificationChannel(
|
||||
NOTIFY_CHANNEL, "MIUI 原生通知图标 - 版本更新",
|
||||
NotificationManager.IMPORTANCE_DEFAULT
|
||||
).apply { enableLights(false) }
|
||||
)
|
||||
notify(packageName.hashCode(), Notification.Builder(context, NOTIFY_CHANNEL).apply {
|
||||
setShowWhen(true)
|
||||
setContentTitle("模块已更新")
|
||||
setContentText("点按通知打开模块以完成新版本激活。")
|
||||
setColor(0xFFE06818.toInt())
|
||||
setAutoCancel(true)
|
||||
setSmallIcon(Icon.createWithResource(MODULE_PACKAGE_NAME, R.drawable.ic_notify_update))
|
||||
setLargeIcon(context.appIconOf(packageName)?.toBitmap())
|
||||
setContentIntent(
|
||||
PendingIntent.getActivity(
|
||||
context, packageName.hashCode(),
|
||||
Intent().apply {
|
||||
component = ComponentName(MODULE_PACKAGE_NAME, "${MODULE_PACKAGE_NAME}.ui.activity.MainActivity")
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
}, if (Build.VERSION.SDK_INT < 31) PendingIntent.FLAG_UPDATE_CURRENT else PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
)
|
||||
}.build())
|
||||
}
|
||||
}
|
||||
}
|
@@ -35,7 +35,7 @@ import java.io.Serializable
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* 获取 Github Release 最新版本工具类
|
||||
* 获取 GitHub Release 最新版本工具类
|
||||
*/
|
||||
object GithubReleaseTool {
|
||||
|
||||
@@ -129,7 +129,7 @@ object GithubReleaseTool {
|
||||
}
|
||||
|
||||
/**
|
||||
* Github Release bean
|
||||
* GitHub Release bean
|
||||
* @param name 版本名称
|
||||
* @param htmlUrl 网页地址
|
||||
* @param content 更新日志
|
||||
|
@@ -24,7 +24,7 @@ package com.fankes.miui.notify.utils.tool
|
||||
|
||||
import android.content.Context
|
||||
import com.fankes.miui.notify.utils.factory.showDialog
|
||||
import com.highcapable.yukihookapi.hook.factory.modulePrefs
|
||||
import com.highcapable.yukihookapi.hook.factory.prefs
|
||||
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
|
||||
import java.util.*
|
||||
|
||||
@@ -41,8 +41,8 @@ object I18nWarnTool {
|
||||
* @param context 实例
|
||||
*/
|
||||
fun checkingOrShowing(context: Context) {
|
||||
fun saveReaded() = context.modulePrefs.put(LOCALE_WARN_READED, value = true)
|
||||
if (Locale.getDefault().language.startsWith("zh").not() && context.modulePrefs.get(LOCALE_WARN_READED).not())
|
||||
fun saveReaded() = context.prefs().edit { put(LOCALE_WARN_READED, value = true) }
|
||||
if (Locale.getDefault().language.startsWith("zh").not() && context.prefs().get(LOCALE_WARN_READED).not())
|
||||
context.showDialog {
|
||||
title = "Notice of I18n Support"
|
||||
msg = "This Xposed Module is only for Chinese and the Chinese region.\n\n" +
|
||||
|
@@ -67,12 +67,15 @@ object IconRuleManagerTool {
|
||||
/** 当前规则的通知图标颜色 */
|
||||
private const val OS_COLOR = 0xFFE06818.toInt()
|
||||
|
||||
/** 同步地址 - Github Raw (代理) */
|
||||
private const val SYNC_PROXY_URL = "https://raw.githubusercontentS.com/fankes/AndroidNotifyIconAdapt/main"
|
||||
|
||||
/** 同步地址 - Github Raw (直连) */
|
||||
/** 同步地址 - GitHub Raw (直连) */
|
||||
private const val SYNC_DIRECT_URL = "https://raw.githubusercontent.com/fankes/AndroidNotifyIconAdapt/main"
|
||||
|
||||
/** 同步地址 - GitHub Raw (代理 - GitHub Proxy) */
|
||||
private const val SYNC_PROXY_1_URL = "https://ghproxy.com/$SYNC_DIRECT_URL"
|
||||
|
||||
/** 同步地址 - GitHub Raw (代理 - 7ED Services) */
|
||||
private const val SYNC_PROXY_2_URL = "https://raw.githubusercontentS.com/fankes/AndroidNotifyIconAdapt/main"
|
||||
|
||||
/** 云端规则展示地址 (OS) */
|
||||
private const val RULES_TRAVELER_OS_URL = "https://fankes.github.io/AndroidNotifyIconAdapt/?notify-rules-miui"
|
||||
|
||||
@@ -104,13 +107,19 @@ object IconRuleManagerTool {
|
||||
}
|
||||
binding.sourceFromTextLin.isVisible = sourceType == IconRuleSourceSyncType.CUSTOM_URL
|
||||
binding.sourceTravelerLin.isVisible = sourceType != IconRuleSourceSyncType.CUSTOM_URL
|
||||
binding.sourceRadio1.isChecked = sourceType == IconRuleSourceSyncType.GITHUB_RAW_PROXY
|
||||
binding.sourceRadio0.isChecked = sourceType == IconRuleSourceSyncType.GITHUB_RAW_PROXY_1
|
||||
binding.sourceRadio1.isChecked = sourceType == IconRuleSourceSyncType.GITHUB_RAW_PROXY_2
|
||||
binding.sourceRadio2.isChecked = sourceType == IconRuleSourceSyncType.GITHUB_RAW_DIRECT
|
||||
binding.sourceRadio3.isChecked = sourceType == IconRuleSourceSyncType.CUSTOM_URL
|
||||
binding.sourceRadio0.setOnClickListener {
|
||||
binding.sourceFromTextLin.isVisible = false
|
||||
binding.sourceTravelerLin.isVisible = true
|
||||
sourceType = IconRuleSourceSyncType.GITHUB_RAW_PROXY_1
|
||||
}
|
||||
binding.sourceRadio1.setOnClickListener {
|
||||
binding.sourceFromTextLin.isVisible = false
|
||||
binding.sourceTravelerLin.isVisible = true
|
||||
sourceType = IconRuleSourceSyncType.GITHUB_RAW_PROXY
|
||||
sourceType = IconRuleSourceSyncType.GITHUB_RAW_PROXY_2
|
||||
}
|
||||
binding.sourceRadio2.setOnClickListener {
|
||||
binding.sourceFromTextLin.isVisible = false
|
||||
@@ -189,7 +198,8 @@ object IconRuleManagerTool {
|
||||
callback: () -> Unit
|
||||
) {
|
||||
when (sourceType) {
|
||||
IconRuleSourceSyncType.GITHUB_RAW_PROXY -> onRefreshing(context, SYNC_PROXY_URL, callback)
|
||||
IconRuleSourceSyncType.GITHUB_RAW_PROXY_1 -> onRefreshing(context, SYNC_PROXY_1_URL, callback)
|
||||
IconRuleSourceSyncType.GITHUB_RAW_PROXY_2 -> onRefreshing(context, SYNC_PROXY_2_URL, callback)
|
||||
IconRuleSourceSyncType.GITHUB_RAW_DIRECT -> onRefreshing(context, SYNC_DIRECT_URL, callback)
|
||||
IconRuleSourceSyncType.CUSTOM_URL ->
|
||||
if (customUrl.isNotBlank())
|
||||
|
@@ -27,7 +27,7 @@ import com.fankes.miui.notify.BuildConfig
|
||||
import com.fankes.miui.notify.utils.factory.openBrowser
|
||||
import com.fankes.miui.notify.utils.factory.showDialog
|
||||
import com.highcapable.yukihookapi.YukiHookAPI
|
||||
import com.highcapable.yukihookapi.hook.factory.modulePrefs
|
||||
import com.highcapable.yukihookapi.hook.factory.prefs
|
||||
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
|
||||
|
||||
/**
|
||||
@@ -43,8 +43,8 @@ object YukiPromoteTool {
|
||||
* @param context 实例
|
||||
*/
|
||||
fun promote(context: Context) {
|
||||
fun saveReaded() = context.modulePrefs.put(YUKI_PROMOTE_READED, value = true)
|
||||
if (context.modulePrefs.get(YUKI_PROMOTE_READED).not())
|
||||
fun saveReaded() = context.prefs().edit { put(YUKI_PROMOTE_READED, value = true) }
|
||||
if (context.prefs().get(YUKI_PROMOTE_READED).not())
|
||||
context.showDialog {
|
||||
title = "面向开发者的推广"
|
||||
msg = "你想快速拥有一个自己的 Xposed 模块吗,你只需要拥有基础的 Android 开发经验以及使用 Kotlin 编程语言即可。\n\n" +
|
||||
|
10
app/src/main/res/drawable/ic_message.xml
Normal file
10
app/src/main/res/drawable/ic_message.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="48dp"
|
||||
android:height="48dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="m522.8,93.9c-244.2,0 -442.1,173.2 -442.1,386.9 0,122.1 64.9,230.9 165.8,301.7v195.7l193.7,-117.5c26.8,4.4 54.3,7 82.6,7 244.2,0 442.1,-173.2 442.1,-386.9C965,267.1 767.1,93.9 522.8,93.9Z"
|
||||
android:strokeWidth="1.10883" />
|
||||
</vector>
|
9
app/src/main/res/drawable/ic_notify_update.xml
Normal file
9
app/src/main/res/drawable/ic_notify_update.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="50dp"
|
||||
android:height="50dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M906.4,791.6a247.9,247.9 0,0 0,-98.1 -186.5L808.3,399.4c0,-118.8 -85.1,-218.9 -197.4,-242.5v-4.7c0,-54.2 -44.5,-98.6 -98.8,-98.6 -54.3,0 -98.8,44.4 -98.8,98.6v4.7C300.8,180.5 215.7,280.4 215.7,399.4v205.8a247.7,247.7 0,0 0,-98.1 186.5h98.1v0.6h592.5v-0.6h98.1v-0.1zM491.1,970.4h24.5c64.3,0 117.8,-48.5 125.6,-110.7L383,859.8a126.8,126.8 0,0 0,125.6 110.7h-17.5z" />
|
||||
</vector>
|
@@ -253,33 +253,8 @@
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:text="启用模块"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<com.fankes.miui.notify.ui.widget.MaterialSwitch
|
||||
android:id="@+id/module_enable_log_switch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:text="启用调试日志"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/exp_all_debug_log_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="13dp"
|
||||
android:layout_marginRight="13dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="@drawable/bg_button_round"
|
||||
android:gravity="center"
|
||||
android:padding="10dp"
|
||||
android:singleLine="true"
|
||||
android:text="导出全部调试日志"
|
||||
android:text="启用模块"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
|
||||
@@ -294,6 +269,51 @@
|
||||
android:text="模块关闭后一切功能都将彻底停止工作。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/module_enable_log_item"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.fankes.miui.notify.ui.widget.MaterialSwitch
|
||||
android:id="@+id/module_enable_log_switch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="启用调试日志"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/exp_all_debug_log_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="13dp"
|
||||
android:layout_marginRight="13dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="@drawable/bg_button_round"
|
||||
android:gravity="center"
|
||||
android:padding="10dp"
|
||||
android:singleLine="true"
|
||||
android:text="导出全部调试日志"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:alpha="0.6"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:text="默认情况下不建议开启此选项,仅在模块故障时开启,此时你可以发送调试日志给开发者帮助我们快速定位问题。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@@ -767,7 +787,7 @@
|
||||
android:layout_marginRight="15dp"
|
||||
android:alpha="0.6"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:text="⚠️ 在 MIUI 11、12 上可能需要 Root 权限才能打开。"
|
||||
android:text="⚠️ 在 MIUI 11 上可能需要 Root 权限才能打开。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold" />
|
||||
@@ -862,6 +882,34 @@
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/notify_icon_force_system_color_item"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.fankes.miui.notify.ui.widget.MaterialSwitch
|
||||
android:id="@+id/notify_icon_force_system_color_switch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="15dp"
|
||||
android:paddingRight="15dp"
|
||||
android:text="通知栏中的图标使用系统默认着色"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0.6"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:paddingLeft="15dp"
|
||||
android:paddingRight="15dp"
|
||||
android:text="此选项默认关闭,开启后下拉通知栏中的通知图标将忽略图标自身的着色属性,全部使用系统默认颜色 (系统提供的统一色调) 着色,这是一个破坏原生通知图标的行为,仅针对部分有需要的用户而添加,我们不推荐开启这个功能,请根据个人偏好进行选择是否需要开启。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@@ -24,18 +24,25 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.radiobutton.MaterialRadioButton
|
||||
android:id="@+id/source_radio_0"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="GitHub Raw (GitHub Proxy)"
|
||||
app:buttonTint="@color/colorPrimaryAccent" />
|
||||
|
||||
<com.google.android.material.radiobutton.MaterialRadioButton
|
||||
android:id="@+id/source_radio_1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Github Raw (7ED Services)"
|
||||
android:text="GitHub Raw (7ED Services)"
|
||||
app:buttonTint="@color/colorPrimaryAccent" />
|
||||
|
||||
<com.google.android.material.radiobutton.MaterialRadioButton
|
||||
android:id="@+id/source_radio_2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Github Raw (直连)"
|
||||
android:text="GitHub Raw (直连)"
|
||||
app:buttonTint="@color/colorPrimaryAccent" />
|
||||
|
||||
<com.google.android.material.radiobutton.MaterialRadioButton
|
||||
|
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
<background android:drawable="@color/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
19
build.gradle
19
build.gradle
@@ -1,13 +1,24 @@
|
||||
plugins {
|
||||
id 'com.android.application' version '7.4.1' apply false
|
||||
id 'com.android.library' version '7.4.1' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.7.22' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.8.20' apply false
|
||||
id 'com.google.devtools.ksp' version '1.8.20-1.0.10' apply false
|
||||
}
|
||||
|
||||
ext {
|
||||
appVersionName = "2.9"
|
||||
appVersionCode = 35
|
||||
enableR8 = true
|
||||
android = [
|
||||
compileSdk: 33,
|
||||
minSdk : 28,
|
||||
targetSdk : 33
|
||||
]
|
||||
app = [
|
||||
versionName : '2.101',
|
||||
versionCode : 41,
|
||||
signingConfigs: [
|
||||
secretConfigsDirPath : "${projectDir.getAbsolutePath()}/.secret",
|
||||
secretConfigsFileName: "key_store_secret.json"
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
#Wed May 25 04:36:53 CST 2022
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
Reference in New Issue
Block a user