18 Commits
2.6 ... 2.8

Author SHA1 Message Date
eb75c1c511 Update version to 2.8 2022-06-26 23:53:19 +08:00
efc192b0ee Fix MIUI 12、12.5 (Android 10) not work bug 2022-06-26 23:49:48 +08:00
7b083daa3d Update Gradle & Kotlin & PlatformSDK
- Update Kotlin version to 1.7.0
- Update Gradle dependencies
- Merge legacy code
2022-06-10 17:21:33 +08:00
6b18128a57 Merge code 2022-06-08 19:12:10 +08:00
553098f6bf Make UI to Primary Theme 2022-06-08 15:11:33 +08:00
9499727087 Merge DialogBuilderFactory with new code style 2022-06-07 16:55:51 +08:00
0036ba0090 Update version to 2.75 2022-06-04 02:49:14 +08:00
2e62939181 Fix GithubReleaseTool to LocalTime 2022-06-04 02:47:18 +08:00
30acbff3d5 更新文案 2022-06-04 02:24:47 +08:00
093529baea 修复金凡的 MIUI 通知样式的的通知图标在部分最新的开发版中出现黑白块的问题 2022-06-04 02:16:50 +08:00
d9d40ac08e Added BuildConfig.VERSION_NAME changed 2022-06-03 23:53:37 +08:00
99bd924c66 Merge ListView's adapter to BaseAdapterFactory 2022-06-03 02:01:58 +08:00
d14b2cb551 Update version to 2.7 2022-05-31 03:54:21 +08:00
a864d4aa32 Added notify icon custom corner function 2022-05-31 03:49:10 +08:00
12029cf550 Update misc 2022-05-31 03:49:03 +08:00
ac4544e992 Added lower Android version warn 2022-05-31 02:27:35 +08:00
7f0597f034 Update YukiHookAPI 2022-05-31 02:10:49 +08:00
a7c02467de Fix mi push icon wrong when open force app icon in notify panel 2022-05-30 23:32:40 +08:00
26 changed files with 470 additions and 233 deletions

2
.idea/misc.xml generated
View File

@@ -23,7 +23,7 @@
<entry key="app/src/main/res/layout-w936dp/dia_status_icon_cout.xml" value="0.935546875" />
<entry key="app/src/main/res/layout/activity_config.xml" value="0.42168674698795183" />
<entry key="app/src/main/res/layout/activity_login.xml" value="0.4375" />
<entry key="app/src/main/res/layout/activity_main.xml" value="0.32507739938080493" />
<entry key="app/src/main/res/layout/activity_main.xml" value="0.30387540746106484" />
<entry key="app/src/main/res/layout/adapter_config.xml" value="0.375" />
<entry key="app/src/main/res/layout/dia_icon_filter.xml" value="0.4307692307692308" />
<entry key="app/src/main/res/layout/dia_icon_search.xml" value="0.4307692307692308" />

View File

@@ -2,7 +2,7 @@
[![Blank](https://img.shields.io/badge/build-passing-brightgreen)](https://github.com/fankes/MIUINativeNotifyIcon)
[![Blank](https://img.shields.io/badge/license-AGPL3.0-blue)](https://github.com/fankes/MIUINativeNotifyIcon/blob/master/LICENSE)
[![Blank](https://img.shields.io/badge/version-v2.6-green)](https://github.com/fankes/MIUINativeNotifyIcon/releases)
[![Blank](https://img.shields.io/badge/version-v2.8-green)](https://github.com/fankes/MIUINativeNotifyIcon/releases)
[![Blank](https://img.shields.io/github/downloads/fankes/MIUINativeNotifyIcon/total?label=Release)](https://github.com/fankes/MIUINativeNotifyIcon/releases)
[![Blank](https://img.shields.io/github/downloads/Xposed-Modules-Repo/com.fankes.miui.notify/total?label=LSPosed%20Repo&logo=Android&style=flat&labelColor=F48FB1&logoColor=ffffff)](https://github.com/Xposed-Modules-Repo/com.fankes.miui.notify/releases)
[![Telegram](https://img.shields.io/badge/Follow-Telegram-blue.svg?logo=telegram)](https://t.me/XiaofangInternet)

View File

@@ -1,11 +1,11 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'com.google.devtools.ksp' version '1.6.21-1.0.5'
id 'com.google.devtools.ksp' version '1.7.0-1.0.6'
}
android {
compileSdk 31
compileSdk 32
signingConfigs {
debug {
@@ -21,7 +21,7 @@ android {
defaultConfig {
applicationId "com.fankes.miui.notify"
minSdk 28
targetSdk 31
targetSdk 32
versionCode rootProject.ext.appVersionCode
versionName rootProject.ext.appVersionName
@@ -31,6 +31,8 @@ android {
buildTypes {
release {
minifyEnabled rootProject.ext.enableR8
shrinkResources rootProject.ext.enableR8
zipAlignEnabled rootProject.ext.enableR8
signingConfig signingConfigs.debug
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
@@ -57,14 +59,14 @@ android {
dependencies {
compileOnly 'de.robv.android.xposed:api:82'
implementation 'com.highcapable.yukihookapi:api:1.0.91'
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.0.91'
implementation 'com.highcapable.yukihookapi:api:1.0.92'
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.0.92'
implementation "com.github.topjohnwu.libsu:core:3.1.2"
implementation 'androidx.annotation:annotation:1.3.0'
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.6.0'
implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.7'
implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'

View File

@@ -36,10 +36,13 @@ object DataConst {
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

@@ -35,7 +35,7 @@ import com.highcapable.yukihookapi.hook.factory.encase
import com.highcapable.yukihookapi.hook.log.loggerW
import com.highcapable.yukihookapi.hook.xposed.proxy.IYukiHookXposedInit
@InjectYukiHookWithXposed
@InjectYukiHookWithXposed(isUsingResourcesHook = false)
class HookEntry : IYukiHookXposedInit {
override fun onInit() = configs {

View File

@@ -43,6 +43,7 @@ import android.view.ViewOutlineProvider
import android.widget.ImageView
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
@@ -102,7 +103,8 @@ object SystemUIHooker : YukiBaseHooker() {
/** 根据多个版本存在不同的包名相同的类 */
private val MiuiClockClass = VariousClass(
"$SYSTEMUI_PACKAGE_NAME.statusbar.views.MiuiClock",
"$SYSTEMUI_PACKAGE_NAME.statusbar.policy.MiuiClock"
"$SYSTEMUI_PACKAGE_NAME.statusbar.policy.MiuiClock",
"$SYSTEMUI_PACKAGE_NAME.statusbar.policy.Clock"
)
/** 根据多个版本存在不同的包名相同的类 */
@@ -197,18 +199,6 @@ object SystemUIHooker : YukiBaseHooker() {
private val hasHandleHeaderViews
get() = safeOfFalse { NotificationHeaderViewWrapperClass.clazz.hasMethod { name = "handleHeaderViews" } }
/**
* 获取是否存在忽略图标色彩处理的方法
* @return [Boolean]
*/
private val hasIgnoreStatusBarIconColor
get() = safeOfFalse {
NotificationUtilClass.clazz.hasMethod {
name = "ignoreStatusBarIconColor"
param(ExpandedNotificationClass)
}
}
/**
* 处理为圆角图标
* @return [Drawable]
@@ -288,6 +278,18 @@ object SystemUIHooker : YukiBaseHooker() {
return xmsfPkg.ifBlank { targetPkg.ifBlank { packageName } }
}
/**
* 是否为 MIUI 样式通知栏 - 旧版 - 新版一律返回 false
* @return [Boolean]
*/
private val isShowMiuiStyle get() = NotificationUtilClass.clazz.method { name = "showMiuiStyle" }.ignoredError().get().boolean()
/**
* 是否没有单独的 MIUI 通知栏样式
* @return [Boolean]
*/
private val isNotHasAbsoluteMiuiStyle get() = MiuiNotificationViewWrapperClass.hasClass.not()
/**
* 获取全局上下文
* @return [Context] or null
@@ -438,6 +440,9 @@ 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
@@ -474,7 +479,7 @@ object SystemUIHooker : YukiBaseHooker() {
/** 处理自定义通知图标优化 */
when {
prefs.get(DataConst.ENABLE_NOTIFY_ICON_FORCE_APP_ICON) && isEnableHookColorNotifyIcon(isHooking = false) ->
setDefaultNotifyIcon(context.findAppIcon(notifyInstance.compatOpPkgName))
setDefaultNotifyIcon(context.findAppIcon(notifyInstance.nfPkgName))
customIcon != null -> iconImageView.apply {
/** 设置不要裁切到边界 */
clipToOutline = false
@@ -485,7 +490,8 @@ object SystemUIHooker : YukiBaseHooker() {
/** Android 12 设置图标外圈颜色 */
if (isUseAndroid12Style && customIconColor != 0)
background = DrawableBuilder()
.rounded()
.rectangle()
.cornerRadius(iconCorner.dp(context))
.solidColor(if (context.isSystemInDarkMode) customIconColor.brighter else customIconColor)
.build()
/** 设置原生的背景边距 */
@@ -504,7 +510,8 @@ object SystemUIHooker : YukiBaseHooker() {
(if (hasIconColor) iconColor else context.systemAccentColor).also {
if (isUseAndroid12Style)
background = DrawableBuilder()
.rounded()
.rectangle()
.cornerRadius(iconCorner.dp(context))
.solidColor(if (context.isSystemInDarkMode) it.brighter else it)
.build()
}
@@ -578,11 +585,34 @@ object SystemUIHooker : YukiBaseHooker() {
.get(this).call()?.let {
it.javaClass.method {
name = "getSbn"
}.get(it).invoke<StatusBarNotification>()
}.ignoredError().get(it).invoke<StatusBarNotification>()
} ?: ExpandableNotificationRowClass.clazz
.method { name = "getStatusBarNotification" }
.get(NotificationViewWrapperClass.clazz.field { name = "mRow" }.get(this).self)
.invoke<StatusBarNotification>()
.get(this).invoke<StatusBarNotification>()
/**
* 根据当前 [ImageView] 的父布局克隆一个新的 [ImageView]
* @param initiate 新的 [ImageView] 方法体 - 失败会返回当前 [ImageView]
*/
private fun ImageView.clone(initiate: ImageView.() -> Unit) {
(parent as? ViewGroup?)?.also { parent ->
/** 将之前的 [ImageView] 调为全透明且隐藏 */
alpha = 0f
isVisible = false
/** 将内容清空 */
setImageDrawable(null)
setBackgroundColor(Color.TRANSPARENT)
/** 创建一个傀儡 */
parent.findViewWithTag<ImageView?>("new_view").also { base ->
if (base == null) parent.addView(ImageView(context).also { new ->
new.tag = "new_view"
/** 克隆它的 [ViewGroup.LayoutParams] */
new.layoutParams = layoutParams
initiate(new)
}) else initiate(base)
}
} ?: initiate(this)
}
/** 注册 */
private fun register() {
@@ -684,10 +714,8 @@ object SystemUIHooker : YukiBaseHooker() {
* MIUI 12 进行单独判断
*/
field { name = "mCurrentSetColor" }.get(instance).int().also { color ->
if (hasIgnoreStatusBarIconColor) {
alpha = if (color.isWhite) 0.95f else 0.8f
setColorFilter(if (color.isWhite) color else Color.BLACK)
} else setColorFilter(color)
}
}
}
@@ -766,6 +794,9 @@ object SystemUIHooker : YukiBaseHooker() {
method { name = "handleHeaderViews" }
else method { name = "resolveHeaderViews" }
afterHook {
/** 忽略较旧版本 - 在没有 MIUI 通知栏样式的时候可能出现奇怪的问题 */
if (isNotHasAbsoluteMiuiStyle && isShowMiuiStyle) return@afterHook
/** 获取小图标 */
val iconImageView =
NotificationHeaderViewWrapperClass.clazz
@@ -797,7 +828,7 @@ object SystemUIHooker : YukiBaseHooker() {
injectMember {
method { name = "handleAppIcon" }
replaceUnit {
field { name = "mAppIcon" }.get(instance).cast<ImageView>()?.apply {
field { name = "mAppIcon" }.get(instance).cast<ImageView>()?.clone {
compatNotifyIcon(
context = context,
expandedNf = instance.getRowPair().second.getSbn(),
@@ -877,11 +908,11 @@ object SystemUIHooker : YukiBaseHooker() {
}
}
}
}
}.ignoredHookClassNotFoundFailure()
/** 自动检查通知图标优化更新的注入监听 */
MiuiClockClass.hook {
injectMember {
method { name = "updateTime" }
method { name = "updateTime" }.remedys { method { name = "updateClock" } }
afterHook {
instance<View>().context.also {
/** 注册定时监听 */
@@ -893,6 +924,6 @@ object SystemUIHooker : YukiBaseHooker() {
}
}
}
}.ignoredHookClassNotFoundFailure()
}
}
}

View File

@@ -24,10 +24,6 @@
package com.fankes.miui.notify.ui.activity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import androidx.core.view.isVisible
import com.fankes.miui.notify.R
import com.fankes.miui.notify.bean.IconDataBean
@@ -85,9 +81,9 @@ class ConfigureActivity : BaseActivity<ActivityConfigBinding>() {
}
/** 设置过滤按钮点击事件 */
binding.configTitleFilter.setOnClickListener {
showDialog {
showDialog<DiaIconFilterBinding> {
title = "按条件过滤"
val editText = bind<DiaIconFilterBinding>().diaIconFilterInputEdit.apply {
binding.iconFiltersEdit.apply {
requestFocus()
invalidate()
if (filterText.isNotBlank()) {
@@ -96,8 +92,8 @@ class ConfigureActivity : BaseActivity<ActivityConfigBinding>() {
}
}
confirmButton {
if (editText.text.toString().isNotBlank()) {
filterText = editText.text.toString().trim()
if (binding.iconFiltersEdit.text.toString().isNotBlank()) {
filterText = binding.iconFiltersEdit.text.toString().trim()
refreshAdapterResult()
} else {
toast(msg = "条件不能为空")
@@ -116,46 +112,33 @@ class ConfigureActivity : BaseActivity<ActivityConfigBinding>() {
binding.configTitleSync.setOnClickListener { onStartRefresh() }
/** 设置列表元素和 Adapter */
binding.configListView.apply {
adapter = object : BaseAdapter() {
override fun getCount() = iconDatas.size
override fun getItem(position: Int) = iconDatas[position]
override fun getItemId(position: Int) = position.toLong()
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
var cView = convertView
val holder: AdapterConfigBinding
if (convertView == null) {
holder = AdapterConfigBinding.inflate(LayoutInflater.from(context))
cView = holder.root
cView.tag = holder
} else holder = convertView.tag as AdapterConfigBinding
getItem(position).also {
holder.adpAppIcon.setImageBitmap(it.iconBitmap)
(if (it.iconColor != 0) it.iconColor else resources.getColor(R.color.colorTextGray)).also { color ->
holder.adpAppIcon.setColorFilter(color)
holder.adpAppName.setTextColor(color)
bindAdapter {
onBindDatas { iconDatas }
onBindViews<AdapterConfigBinding> { binding, position ->
iconDatas[position].also { bean ->
binding.adpAppIcon.setImageBitmap(bean.iconBitmap)
(if (bean.iconColor != 0) bean.iconColor else resources.getColor(R.color.colorTextGray)).also { color ->
binding.adpAppIcon.setColorFilter(color)
binding.adpAppName.setTextColor(color)
}
holder.adpAppName.text = it.appName
holder.adpAppPkgName.text = it.packageName
holder.adpCbrName.text = "贡献者:" + it.contributorName
isAppNotifyHookOf(it).also { e ->
holder.adpAppOpenSwitch.isChecked = e
holder.adpAppAllSwitch.isEnabled = e
binding.adpAppName.text = bean.appName
binding.adpAppPkgName.text = bean.packageName
binding.adpCbrName.text = "贡献者:" + bean.contributorName
isAppNotifyHookOf(bean).also { e ->
binding.adpAppOpenSwitch.isChecked = e
binding.adpAppAllSwitch.isEnabled = e
}
holder.adpAppOpenSwitch.setOnCheckedChangeListener { btn, b ->
binding.adpAppOpenSwitch.setOnCheckedChangeListener { btn, b ->
if (btn.isPressed.not()) return@setOnCheckedChangeListener
putAppNotifyHookOf(it, b)
holder.adpAppAllSwitch.isEnabled = b
putAppNotifyHookOf(bean, b)
binding.adpAppAllSwitch.isEnabled = b
SystemUITool.refreshSystemUI(context = this@ConfigureActivity)
}
holder.adpAppAllSwitch.isChecked = isAppNotifyHookAllOf(it)
holder.adpAppAllSwitch.setOnCheckedChangeListener { btn, b ->
binding.adpAppAllSwitch.isChecked = isAppNotifyHookAllOf(bean)
binding.adpAppAllSwitch.setOnCheckedChangeListener { btn, b ->
if (btn.isPressed.not()) return@setOnCheckedChangeListener
fun saveState() {
putAppNotifyHookAllOf(it, b)
putAppNotifyHookAllOf(bean, b)
SystemUITool.refreshSystemUI(context = this@ConfigureActivity)
}
if (b) showDialog {
@@ -169,7 +152,6 @@ class ConfigureActivity : BaseActivity<ActivityConfigBinding>() {
} else saveState()
}
}
return cView!!
}
}.apply {
setOnItemLongClickListener { _, _, p, _ ->

View File

@@ -26,6 +26,7 @@ package com.fankes.miui.notify.ui.activity
import android.content.ComponentName
import android.content.pm.PackageManager
import android.widget.SeekBar
import androidx.core.view.isGone
import androidx.core.view.isVisible
import com.fankes.miui.notify.BuildConfig
@@ -123,6 +124,14 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
cancelButton()
noCancelable()
}
if (isLowerAndroidR && modulePrefs.get(DataConst.IGNORED_ANDROID_VERSION_TO_LOW).not())
showDialog {
title = "Android 版本过低"
msg = "你当前使用的 Android 版本过低,模块的部分功能可能会发生问题," +
"由于设备有限,无法逐一调试,若有好的建议可向我们贡献代码提交适配请求,建议在 Android 11 及以上版本中使用效果最佳。"
confirmButton(text = "我知道了") { modulePrefs.put(DataConst.IGNORED_ANDROID_VERSION_TO_LOW, value = true) }
noCancelable()
}
/** 推广、恰饭 */
YukiPromoteTool.promote(context = this)
}
@@ -140,11 +149,13 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
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)
binding.statusIconCountItem.isVisible = modulePrefs.get(DataConst.ENABLE_MODULE) && isLowerAndroidR.not()
binding.notifyIconConfigItem.isVisible = modulePrefs.get(DataConst.ENABLE_MODULE)
binding.notifyIconFixButton.isVisible = modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX)
binding.notifyIconCustomCornerItem.isVisible = modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX) &&
modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FORCE_APP_ICON).not() && isLowerAndroidR.not()
binding.notifyIconForceAppIconItem.isVisible = modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX)
binding.notifyIconFixNotifyItem.isVisible = modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX)
binding.notifyIconFixNotifyItem.isVisible = modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FIX) && isLowerAndroidR.not()
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)
@@ -157,6 +168,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
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 ->
@@ -164,7 +177,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
modulePrefs.put(DataConst.ENABLE_MODULE, b)
binding.moduleEnableLogSwitch.isVisible = b
binding.colorIconHookItem.isVisible = b
binding.statusIconCountItem.isVisible = b
binding.statusIconCountItem.isVisible = b && isLowerAndroidR.not()
binding.notifyIconConfigItem.isVisible = b
SystemUITool.showNeedRestartSnake(context = this)
}
@@ -197,14 +210,17 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
if (btn.isPressed.not()) return@setOnCheckedChangeListener
modulePrefs.put(DataConst.ENABLE_NOTIFY_ICON_FIX, b)
binding.notifyIconFixButton.isVisible = b
binding.notifyIconCustomCornerItem.isVisible = b &&
modulePrefs.get(DataConst.ENABLE_NOTIFY_ICON_FORCE_APP_ICON).not() && isLowerAndroidR.not()
binding.notifyIconForceAppIconItem.isVisible = b
binding.notifyIconFixNotifyItem.isVisible = b
binding.notifyIconFixNotifyItem.isVisible = b && isLowerAndroidR.not()
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)
}
@@ -229,15 +245,27 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
binding.notifyIconAutoSyncChildItem.isVisible = b
SystemUITool.refreshSystemUI(context = this, isRefreshCacheOnly = true)
}
binding.notifyIconCustomCornerSeekbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
binding.notifyIconCustomCornerText.text = "$progress dp"
}
override fun onStopTrackingTouch(seekBar: SeekBar) {
modulePrefs.put(DataConst.NOTIFY_ICON_CORNER, seekBar.progress)
SystemUITool.refreshSystemUI(context = this@MainActivity)
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {}
})
/** 通知图标优化名单按钮点击事件 */
binding.notifyIconFixButton.setOnClickListener { navigate<ConfigureActivity>() }
/** 设置警告 */
binding.warnSCountDisTip.isGone = miuiVersionCode > 12.5
/** 修改状态栏通知图标个数按钮点击事件 */
binding.statusIconCountButton.setOnClickListener {
showDialog {
showDialog<DiaStatusIconCountBinding> {
title = "设置最多显示的图标个数"
val editText = bind<DiaStatusIconCountBinding>().diaStatusIconCountInputEdit.apply {
binding.iconCountEdit.apply {
requestFocus()
invalidate()
setText(statusBarIconCount.toString())
@@ -245,12 +273,12 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
}
confirmButton {
when {
(runCatching { editText.text.toString().toInt() }.getOrNull() ?: -1)
(runCatching { binding.iconCountEdit.text.toString().toInt() }.getOrNull() ?: -1)
!in 0..100 -> snake(msg = "请输入有效数值")
editText.text.toString().isNotBlank() -> runCatching {
statusBarIconCount = editText.text.toString().trim().toInt()
binding.iconCountEdit.text.toString().isNotBlank() -> runCatching {
statusBarIconCount = binding.iconCountEdit.text.toString().trim().toInt()
modulePrefs.put(DataConst.HOOK_STATUS_ICON_COUNT, statusBarIconCount)
binding.statusIconCountText.text = statusBarIconCount.toString()
this@MainActivity.binding.statusIconCountText.text = statusBarIconCount.toString()
SystemUITool.showNeedRestartSnake(context)
}.onFailure { snake(msg = "数值格式无效") }
else -> snake(msg = "请输入有效数值")
@@ -272,7 +300,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
"模块无需保持在后台运行,到达同步时间后会自动启动,如果到达时间后模块正在运行则会自动取消本次计划任务。"
confirmButton(text = "保存设置") {
notifyIconAutoSyncTime = it
binding.notifyIconAutoSyncText.text = it
this@MainActivity.binding.notifyIconAutoSyncText.text = it
modulePrefs.put(DataConst.NOTIFY_ICON_FIX_AUTO_TIME, it)
SystemUITool.refreshSystemUI(context, isRefreshCacheOnly = true)
}

View File

@@ -27,7 +27,7 @@ package com.fankes.miui.notify.ui.activity.base
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.res.ResourcesCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.viewbinding.ViewBinding
import com.fankes.miui.notify.R
import com.fankes.miui.notify.utils.factory.isNotSystemInDarkMode
@@ -61,7 +61,7 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
/** 隐藏系统的标题栏 */
supportActionBar?.hide()
/** 初始化沉浸状态栏 */
ViewCompat.getWindowInsetsController(window.decorView)?.apply {
WindowCompat.getInsetsController(window, window.decorView).apply {
isAppearanceLightStatusBars = isNotSystemInDarkMode
isAppearanceLightNavigationBars = isNotSystemInDarkMode
}

View File

@@ -20,7 +20,7 @@
*
* This file is Created by fankes on 2022/1/8.
*/
@file:Suppress("DEPRECATION", "CanvasSize")
@file:Suppress("DEPRECATION", "CanvasSize", "OVERRIDE_DEPRECATION")
package com.fankes.miui.notify.utils.drawable.drawabletoolbox

View File

@@ -0,0 +1,87 @@
/*
* 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/6/3.
*/
package com.fankes.miui.notify.utils.factory
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.ListView
import androidx.viewbinding.ViewBinding
import com.highcapable.yukihookapi.hook.factory.method
import com.highcapable.yukihookapi.hook.type.android.LayoutInflaterClass
/**
* 绑定 [BaseAdapter] 到 [ListView]
* @param initiate 方法体
* @return [BaseAdapter]
*/
inline fun ListView.bindAdapter(initiate: BaseAdapterCreater.() -> Unit) =
BaseAdapterCreater(context).apply(initiate).baseAdapter?.apply { adapter = this } ?: error("BaseAdapter not binded")
/**
* [BaseAdapter] 创建类
* @param context 实例
*/
class BaseAdapterCreater(val context: Context) {
/** 当前 [List] 回调 */
var listDataCallback: (() -> List<*>)? = null
/** 当前 [BaseAdapter] */
var baseAdapter: BaseAdapter? = null
/**
* 绑定 [List] 到 [ListView]
* @param result 回调数据
*/
fun onBindDatas(result: (() -> List<*>)) {
listDataCallback = result
}
/**
* 绑定 [BaseAdapter] 到 [ListView]
* @param bindViews 回调 - ([VB] 每项,[Int] 下标)
*/
inline fun <reified VB : ViewBinding> onBindViews(crossinline bindViews: (binding: VB, position: Int) -> Unit) {
baseAdapter = object : BaseAdapter() {
override fun getCount() = listDataCallback?.let { it() }?.size ?: 0
override fun getItem(position: Int) = listDataCallback?.let { it() }?.get(position)
override fun getItemId(position: Int) = position.toLong()
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
var holderView = convertView
val holder: VB
if (convertView == null) {
holder = VB::class.java.method {
name = "inflate"
param(LayoutInflaterClass)
}.get().invoke<VB>(LayoutInflater.from(context)) ?: error("ViewHolder binding failed")
holderView = holder.root.apply { tag = holder }
} else holder = convertView.tag as VB
bindViews(holder, position)
return holderView ?: error("ViewHolder binding failed")
}
}
}
}

View File

@@ -43,14 +43,6 @@ import com.highcapable.yukihookapi.annotation.CauseProblemsApi
import com.highcapable.yukihookapi.hook.factory.method
import com.highcapable.yukihookapi.hook.type.android.LayoutInflaterClass
/**
* 构造对话框
* @param isUseBlackTheme 是否使用深色主题
* @param initiate 对话框方法体
*/
fun Context.showDialog(isUseBlackTheme: Boolean = false, initiate: DialogBuilder.() -> Unit) =
DialogBuilder(context = this, isUseBlackTheme).apply(initiate).show()
/**
* 显示时间选择对话框
* @param timeSet 当前时间 - 不写将使用当前时间格式HH:mm
@@ -59,20 +51,45 @@ fun Context.showDialog(isUseBlackTheme: Boolean = false, initiate: DialogBuilder
fun Context.showTimePicker(timeSet: String = "", result: (String) -> Unit) =
TimePickerDialog(this, { _, h, m -> result("${h.autoZero}:${m.autoZero}") }, timeSet.hour, timeSet.minute, true).show()
/**
* 构造 [VB] 自定义 View 对话框
* @param initiate 对话框方法体
*/
@JvmName(name = "showDialog-VB")
inline fun <reified VB : ViewBinding> Context.showDialog(initiate: DialogBuilder<VB>.() -> Unit) =
DialogBuilder<VB>(context = this, VB::class.java).apply(initiate).show()
/**
* 构造对话框
* @param initiate 对话框方法体
*/
inline fun Context.showDialog(initiate: DialogBuilder<*>.() -> Unit) = DialogBuilder<ViewBinding>(context = this).apply(initiate).show()
/**
* 对话框构造器
* @param context 实例
* @param isUseBlackTheme 是否使用深色主题 - 对 AndroidX 风格无效
* @param bindingClass [ViewBinding] 的 [Class] 实例 or null
*/
class DialogBuilder(val context: Context, private val isUseBlackTheme: Boolean) {
class DialogBuilder<VB : ViewBinding>(val context: Context, private val bindingClass: Class<*>? = null) {
private var instanceAndroidX: androidx.appcompat.app.AlertDialog.Builder? = null // 实例对象
private var instanceAndroid: android.app.AlertDialog.Builder? = null // 实例对象
private var dialogInstance: Dialog? = null // 对话框实例
private var customLayoutView: View? = null // 自定义布局
@CauseProblemsApi
var customLayoutView: View? = null // 自定义布局
/**
* 获取 [DialogBuilder] 绑定布局对象
* @return [VB]
*/
val binding by lazy {
bindingClass?.method {
name = "inflate"
param(LayoutInflaterClass)
}?.get()?.invoke<VB>(LayoutInflater.from(context))?.apply {
customLayoutView = root
} ?: error("This dialog maybe not a custom view dialog")
}
/**
* 是否需要使用 AndroidX 风格对话框
@@ -83,12 +100,7 @@ class DialogBuilder(val context: Context, private val isUseBlackTheme: Boolean)
init {
if (isUsingAndroidX)
runInSafe { instanceAndroidX = MaterialAlertDialogBuilder(context) }
else runInSafe {
instanceAndroid = android.app.AlertDialog.Builder(
context,
if (isUseBlackTheme) android.R.style.Theme_Material_Dialog else android.R.style.Theme_Material_Light_Dialog
)
}
else runInSafe { instanceAndroid = android.app.AlertDialog.Builder(context, android.R.style.Theme_Material_Light_Dialog) }
}
/** 设置对话框不可关闭 */
@@ -135,18 +147,6 @@ class DialogBuilder(val context: Context, private val isUseBlackTheme: Boolean)
else customLayoutView?.findViewWithTag<TextView>("progressContent")?.text = value
}
/**
* 设置对话框自定义布局
* @return [ViewBinding]
*/
inline fun <reified T : ViewBinding> bind() =
T::class.java.method {
name = "inflate"
param(LayoutInflaterClass)
}.get().invoke<T>(LayoutInflater.from(context))?.apply {
customLayoutView = root
} ?: error("binding failed")
/**
* 设置对话框确定按钮
* @param text 按钮文本内容
@@ -184,7 +184,10 @@ class DialogBuilder(val context: Context, private val isUseBlackTheme: Boolean)
fun cancel() = dialogInstance?.cancel()
/** 显示对话框 */
internal fun show() =
@CauseProblemsApi
fun show() {
/** 若当前自定义 View 的对话框没有调用 [binding] 将会对其手动调用一次以确保显示布局 */
if (bindingClass != null) binding
if (isUsingAndroidX) runInSafe {
instanceAndroidX?.create()?.apply {
customLayoutView?.let { setView(it) }
@@ -196,8 +199,7 @@ class DialogBuilder(val context: Context, private val isUseBlackTheme: Boolean)
window?.setBackgroundDrawable(
GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,
if (isUseBlackTheme) intArrayOf(0xFF2D2D2D.toInt(), 0xFF2D2D2D.toInt())
else intArrayOf(Color.WHITE, Color.WHITE)
intArrayOf(Color.WHITE, Color.WHITE)
).apply {
shape = GradientDrawable.RECTANGLE
gradientType = GradientDrawable.LINEAR_GRADIENT
@@ -207,3 +209,4 @@ class DialogBuilder(val context: Context, private val isUseBlackTheme: Boolean)
}?.show()
}
}
}

View File

@@ -95,6 +95,12 @@ inline val isUpperOfAndroidS get() = Build.VERSION.SDK_INT > Build.VERSION_CODES
*/
inline val isLowerAndroidP get() = Build.VERSION.SDK_INT < Build.VERSION_CODES.P
/**
* 系统版本是否低于 Android 11
* @return [Boolean] 是否符合条件
*/
inline val isLowerAndroidR get() = Build.VERSION.SDK_INT < Build.VERSION_CODES.R
/**
* 当前设备是否是 MIUI 定制 Android 系统
* @return [Boolean] 是否符合条件

View File

@@ -24,11 +24,15 @@ package com.fankes.miui.notify.utils.tool
import android.app.Activity
import android.content.Context
import android.icu.text.SimpleDateFormat
import android.icu.util.Calendar
import android.icu.util.TimeZone
import com.fankes.miui.notify.utils.factory.*
import okhttp3.*
import org.json.JSONObject
import java.io.IOException
import java.io.Serializable
import java.util.*
/**
* 获取 Github Release 最新版本工具类
@@ -57,12 +61,12 @@ object GithubReleaseTool {
override fun onFailure(call: Call, e: IOException) {}
override fun onResponse(call: Call, response: Response) = runInSafe {
JSONObject(response.body?.string() ?: "").apply {
JSONObject(response.body.string()).apply {
GithubReleaseBean(
name = getString("name"),
htmlUrl = getString("html_url"),
content = getString("body"),
date = getString("published_at").replace(oldValue = "T", newValue = " ").replace(oldValue = "Z", newValue = "")
date = getString("published_at").localTime()
).apply {
fun showUpdate() = context.showDialog {
title = "最新版本 $name"
@@ -112,6 +116,18 @@ object GithubReleaseTool {
})
}
/**
* 格式化时间为本地时区
* @return [String] 本地时区时间
*/
private fun String.localTime() = replace(oldValue = "T", newValue = " ").replace(oldValue = "Z", newValue = "").let {
runCatching {
val local = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT).apply { timeZone = Calendar.getInstance().timeZone }
val current = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT).apply { timeZone = TimeZone.getTimeZone("GMT") }
local.format(current.parse(it))
}.getOrNull() ?: it
}
/**
* Github Release bean
* @param name 版本名称

View File

@@ -78,41 +78,33 @@ object IconRuleManagerTool {
* @param callback 成功后回调
*/
fun syncByHand(context: Context, callback: () -> Unit) =
context.showDialog {
context.showDialog<DiaSourceFromBinding> {
title = "同步列表"
var sourceType = context.modulePrefs.get(DataConst.SOURCE_SYNC_WAY)
var customUrl = context.modulePrefs.get(DataConst.SOURCE_SYNC_WAY_CUSTOM_URL)
bind<DiaSourceFromBinding>().apply {
diaSfText.apply {
binding.sourceUrlEdit.apply {
if (customUrl.isNotBlank()) {
setText(customUrl)
setSelection(customUrl.length)
}
doOnTextChanged { text, _, _, _ -> customUrl = text.toString() }
}
diaSfTextLin.isVisible = sourceType == TYPE_SOURCE_SYNC_WAY_3
diaSfRd1.isChecked = sourceType == TYPE_SOURCE_SYNC_WAY_1
diaSfRd2.isChecked = sourceType == TYPE_SOURCE_SYNC_WAY_2
diaSfRd3.isChecked = sourceType == TYPE_SOURCE_SYNC_WAY_3
diaSfRd1.setOnClickListener {
diaSfRd2.isChecked = false
diaSfRd3.isChecked = false
diaSfTextLin.isVisible = false
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.sourceRadio1.setOnClickListener {
binding.sourceFromTextLin.isVisible = false
sourceType = TYPE_SOURCE_SYNC_WAY_1
}
diaSfRd2.setOnClickListener {
diaSfRd1.isChecked = false
diaSfRd3.isChecked = false
diaSfTextLin.isVisible = false
binding.sourceRadio2.setOnClickListener {
binding.sourceFromTextLin.isVisible = false
sourceType = TYPE_SOURCE_SYNC_WAY_2
}
diaSfRd3.setOnClickListener {
diaSfRd1.isChecked = false
diaSfRd2.isChecked = false
diaSfTextLin.isVisible = true
binding.sourceRadio3.setOnClickListener {
binding.sourceFromTextLin.isVisible = true
sourceType = TYPE_SOURCE_SYNC_WAY_3
}
}
confirmButton {
context.modulePrefs.put(DataConst.SOURCE_SYNC_WAY, sourceType)
context.modulePrefs.put(DataConst.SOURCE_SYNC_WAY_CUSTOM_URL, customUrl)
@@ -120,15 +112,15 @@ object IconRuleManagerTool {
}
cancelButton()
neutralButton(text = "自定义规则") {
context.showDialog {
context.showDialog<DiaSourceFromStringBinding> {
title = "自定义规则(调试)"
val editText = bind<DiaSourceFromStringBinding>().diaSfsInputEdit.apply {
binding.jsonRuleEdit.apply {
requestFocus()
invalidate()
}
IconPackParams(context).also { params ->
confirmButton(text = "合并") {
editText.text.toString().also { jsonString ->
binding.jsonRuleEdit.text.toString().also { jsonString ->
when {
jsonString.isNotBlank() && params.isNotVaildJson(jsonString) -> context.snake(msg = "不是有效的 JSON 数据")
jsonString.isNotBlank() -> {
@@ -146,7 +138,7 @@ object IconRuleManagerTool {
}
}
cancelButton(text = "覆盖") {
editText.text.toString().also { jsonString ->
binding.jsonRuleEdit.text.toString().also { jsonString ->
when {
jsonString.isNotBlank() && params.isNotVaildJson(jsonString) -> context.snake(msg = "不是有效的 JSON 数据")
jsonString.isNotBlank() -> {
@@ -351,7 +343,7 @@ object IconRuleManagerTool {
}
override fun onResponse(call: Call, response: Response) {
val bodyString = response.body?.string() ?: ""
val bodyString = response.body.string()
(context as? Activity?)?.runOnUiThread { result(true, bodyString) } ?: result(true, bodyString)
}
})

View File

@@ -23,6 +23,7 @@
package com.fankes.miui.notify.utils.tool
import android.content.Context
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
@@ -35,7 +36,7 @@ import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
object YukiPromoteTool {
/** 推广已读存储键值 */
private val YUKI_PROMOTE_READED = PrefsData("yuki_promote_readed", false)
private val YUKI_PROMOTE_READED = PrefsData("yuki_promote_readed_${BuildConfig.VERSION_NAME}", false)
/**
* 显示推广对话框

View File

@@ -316,7 +316,7 @@
android:layout_marginBottom="10dp"
android:alpha="0.6"
android:lineSpacingExtra="6dp"
android:text="此选项默认开启MIUI 默认最多只能显示 3 个图标,其余图标将变成省略号,你可以在下方自定义最多显示的图标个数,修改为 0 则只会显示省略号代表图标个数,为防止发生异常,最大限制 100 个,超出的图标可能会被信号或网速指示器遮挡。"
android:text="此选项默认开启MIUI 默认最多只能显示 3 个图标,其余图标将变成省略号,你可以在下方自定义最多显示的图标个数,修改为 0 则只会显示省略号代表图标个数,为防止发生异常,最大限制 100 个,超出的图标可能会被信号或网速指示器遮挡。\n请注意可能无法兼容中置挖孔屏的设备。"
android:textColor="@color/colorTextDark"
android:textSize="12sp" />
@@ -465,15 +465,13 @@
android:elevation="0dp"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="10dp"
android:paddingTop="15dp"
android:paddingRight="10dp">
android:paddingTop="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:gravity="center|start">
<ImageView
@@ -496,8 +494,8 @@
android:id="@+id/notify_icon_fix_switch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:text="启用通知图标优化"
android:textColor="@color/colorTextGray"
android:textSize="15sp" />
@@ -506,8 +504,8 @@
android:id="@+id/notify_icon_fix_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_marginRight="3dp"
android:layout_marginLeft="13dp"
android:layout_marginRight="13dp"
android:layout_marginBottom="10dp"
android:background="@drawable/bg_button_round"
android:gravity="center"
@@ -520,8 +518,8 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="10dp"
android:alpha="0.6"
android:lineSpacingExtra="6dp"
@@ -532,8 +530,8 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="10dp"
android:alpha="0.6"
android:lineSpacingExtra="6dp"
@@ -541,12 +539,91 @@
android:textColor="@color/colorTextDark"
android:textSize="12sp" />
<LinearLayout
android:id="@+id/notify_icon_custom_corner_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="5dp"
android:gravity="center|start"
android:text="调整通知栏中的图标边框圆角大小"
android:textAllCaps="false"
android:textColor="@color/colorTextGray"
android:textSize="15sp" />
<androidx.appcompat.widget.AppCompatSeekBar
android:id="@+id/notify_icon_custom_corner_seekbar"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="5dp"
android:max="15"
android:min="0"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:progress="15" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:gravity="center"
android:orientation="horizontal"
android:paddingTop="5dp"
android:paddingBottom="15dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:alpha="0.75"
android:ellipsize="end"
android:gravity="center"
android:maxWidth="100dp"
android:singleLine="true"
android:text="当前"
android:textColor="@color/colorTextGray"
android:textSize="13.5sp" />
<TextView
android:id="@+id/notify_icon_custom_corner_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center"
android:maxWidth="100dp"
android:singleLine="true"
android:text="15 dp"
android:textColor="@color/colorTextGray"
android:textSize="15sp"
android:textStyle="bold" />
</LinearLayout>
<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 12 风格以及 MIUI 经典样式的通知图标。"
android:textColor="@color/colorTextDark"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/notify_icon_force_app_icon_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:orientation="vertical">
<com.fankes.miui.notify.ui.view.MaterialSwitch
@@ -573,8 +650,8 @@
android:id="@+id/notify_icon_fix_notify_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:orientation="vertical">
<com.fankes.miui.notify.ui.view.MaterialSwitch
@@ -601,8 +678,8 @@
android:id="@+id/notify_icon_auto_sync_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:animateLayoutChanges="true"
android:orientation="vertical">
@@ -808,7 +885,7 @@
android:layout_marginBottom="10dp"
android:alpha="0.8"
android:lineSpacingExtra="10dp"
android:text="Q.哪些是已知问题?\nA.以下是问题描述列表:\n(1) 动态小图标可能会在高版本系统中闪烁,这是 MIUI 自身就存在的问题,后期只能等官方修复。\n(2) 请始终保持最新版本的 LSPosed旧版本可能会出现 Hook 不生效的问题,若最新版本依然不生效请在作用域中长按“系统界面”(“系统 UI”)选择重新优化。\n(3) 建议最低从 MIUI 12.5 “2021-5-18” 开发版以后开始使用,之前的版本可能或多或少存在 MIUI 自身 BUG 不生效、黑白块问题,将不再进行适配。"
android:text="Q.哪些是已知问题?\nA.以下是问题描述列表:\n(1) 动态小图标可能会在高版本系统中闪烁,这是 MIUI 强行设置 APP 图标的问题,暂时没有找到解决方案,强行破坏修复方式会导致原生动画出现问题,后期有解决方案再研究。\n(2) 请始终保持最新版本的 LSPosed旧版本可能会出现 Hook 不生效的问题,若最新版本依然不生效请在作用域中长按“系统界面”(“系统 UI”)选择重新优化。\n(3) 建议最低从 MIUI 12.5 “2021-5-18” 开发版以后开始使用,之前的版本可能或多或少存在 MIUI 自身 BUG 不生效、黑白块问题,将不再进行适配。"
android:textColor="@color/colorTextDark"
android:textSize="12sp" />

View File

@@ -14,7 +14,7 @@
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/dia_icon_filter_input_edit"
android:id="@+id/icon_filters_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -19,32 +20,40 @@
android:text="在线规则将不定期更新,建议定期同步列表以适配更多 APP若无法同步请自行寻找解决方法或魔法上网。"
android:textSize="14sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/dia_sf_rd1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="从 FastGit 获取" />
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/dia_sf_rd2"
android:id="@+id/source_radio_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="从 Github Raw 获取" />
android:text="从 FastGit 获取"
app:buttonTint="@color/colorPrimaryAccent" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/dia_sf_rd3"
android:id="@+id/source_radio_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="从自定义地址获取" />
android:text="从 Github Raw 获取"
app:buttonTint="@color/colorPrimaryAccent" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/source_radio_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="从自定义地址获取"
app:buttonTint="@color/colorPrimaryAccent" />
</RadioGroup>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/dia_sf_text_lin"
android:id="@+id/source_from_text_lin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/dia_sf_text"
android:id="@+id/source_url_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"

View File

@@ -25,7 +25,7 @@
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/dia_sfs_input_edit"
android:id="@+id/json_rule_edit"
android:layout_width="match_parent"
android:layout_height="150dp"
android:ellipsize="end"

View File

@@ -14,7 +14,7 @@
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/dia_status_icon_count_input_edit"
android:id="@+id/icon_count_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:digits="0123456789"

View File

@@ -2,15 +2,16 @@
<!-- Base application theme. -->
<style name="Theme.MIUINativeNotifyIcon" parent="Theme.Material3.DayNight">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_200</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/black</item>
<item name="colorPrimary">@color/colorPrimaryAccent</item>
<item name="colorPrimaryVariant">@color/colorPrimaryAccent</item>
<item name="colorOnPrimary">@color/colorPrimaryAccent</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item>
<item name="colorSecondary">@color/colorPrimaryAccent</item>
<item name="colorSecondaryVariant">@color/colorPrimaryAccent</item>
<item name="colorOnSecondary">@color/colorPrimaryAccent</item>
<!-- Status bar color. -->
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
<item name="android:statusBarColor">@color/black</item>
<item name="android:windowLightStatusBar">false</item>
<!-- Customize your theme here. -->
</style>
</resources>

View File

@@ -1,10 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#656565</color>
<color name="purple_500">#656565</color>
<color name="purple_700">#656565</color>
<color name="teal_200">#656565</color>
<color name="teal_700">#656565</color>
<color name="colorPrimaryAccent">#656565</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="trans">#00000000</color>

View File

@@ -2,15 +2,16 @@
<!-- Base application theme. -->
<style name="Theme.MIUINativeNotifyIcon" parent="Theme.Material3.DayNight">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/teal_700</item>
<item name="colorPrimary">@color/colorPrimaryAccent</item>
<item name="colorPrimaryVariant">@color/colorPrimaryAccent</item>
<item name="colorOnPrimary">@color/colorPrimaryAccent</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<item name="colorSecondary">@color/colorPrimaryAccent</item>
<item name="colorSecondaryVariant">@color/colorPrimaryAccent</item>
<item name="colorOnSecondary">@color/colorPrimaryAccent</item>
<!-- Status bar color. -->
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
<item name="android:statusBarColor">@color/white</item>
<item name="android:windowLightStatusBar">true</item>
<!-- Customize your theme here. -->
</style>
</resources>

View File

@@ -1,12 +1,12 @@
plugins {
id 'com.android.application' version '7.2.0' apply false
id 'com.android.library' version '7.2.0' apply false
id 'org.jetbrains.kotlin.android' version '1.6.21' apply false
id 'com.android.application' version '7.2.1' apply false
id 'com.android.library' version '7.2.1' apply false
id 'org.jetbrains.kotlin.android' version '1.7.0' apply false
}
ext {
appVersionName = "2.6"
appVersionCode = 31
appVersionName = "2.8"
appVersionCode = 34
enableR8 = true
}

View File

@@ -6,7 +6,7 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
org.gradle.jvmargs=-XX:+UseParallelGC
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
@@ -19,3 +19,5 @@ android.useAndroidX=true
android.enableJetifier=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Incremental
kotlin.incremental.useClasspathSnapshot=true