mirror of
https://github.com/fankes/MIUINativeNotifyIcon.git
synced 2025-09-05 10:15:31 +08:00
更新通知图标优化名单功能并优化代码和相关功能
This commit is contained in:
1
.idea/misc.xml
generated
1
.idea/misc.xml
generated
@@ -8,6 +8,7 @@
|
||||
<entry key="app/src/main/res/drawable-v24/ic_launcher_foreground.xml" value="0.44871794871794873" />
|
||||
<entry key="app/src/main/res/drawable/permotion_round.xml" value="0.256" />
|
||||
<entry key="app/src/main/res/drawable/white_round.xml" value="0.256" />
|
||||
<entry key="app/src/main/res/layout/activity_config.xml" value="0.42168674698795183" />
|
||||
<entry key="app/src/main/res/layout/activity_main.xml" value="0.4036346245815399" />
|
||||
<entry key="app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml" value="0.44871794871794873" />
|
||||
</map>
|
||||
|
@@ -4,7 +4,7 @@
|
||||
package="com.fankes.miui.notify">
|
||||
|
||||
<application
|
||||
android:name=".application.MNvApplication"
|
||||
android:name=".application.MNNApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
@@ -31,7 +31,6 @@
|
||||
<activity
|
||||
android:name="com.fankes.miui.notify.ui.MainActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:screenOrientation="behind">
|
||||
|
||||
<intent-filter>
|
||||
@@ -53,5 +52,10 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity-alias>
|
||||
|
||||
<activity
|
||||
android:name="com.fankes.miui.notify.ui.ConfigureActivity"
|
||||
android:exported="false"
|
||||
android:screenOrientation="behind" />
|
||||
</application>
|
||||
</manifest>
|
@@ -25,19 +25,24 @@ package com.fankes.miui.notify.application
|
||||
import android.app.Application
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
|
||||
class MNvApplication : Application() {
|
||||
class MNNApplication : Application() {
|
||||
|
||||
companion object {
|
||||
|
||||
/** 全局静态实例 */
|
||||
private var context: MNvApplication? = null
|
||||
private var context: MNNApplication? = null
|
||||
|
||||
/** 调用全局静态实例 */
|
||||
val appContext get() = context ?: error("App is death")
|
||||
|
||||
/** 自身 APP 是否已启动 */
|
||||
var isMineStarted = false
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
/** 设置状态 */
|
||||
isMineStarted = true
|
||||
/** 设置静态实例 */
|
||||
context = this
|
||||
/** 跟随系统夜间模式 */
|
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
*
|
||||
* This file is part of MIUINativeNotifyIcon.
|
||||
*
|
||||
* MIUINativeNotifyIcon is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MIUINativeNotifyIcon 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This file is Created by fankes on 2022/1/30.
|
||||
*/
|
||||
package com.fankes.miui.notify.bean
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* 通知栏小图标 bean
|
||||
* @param appName APP 名称 - 仅限默认语言区域
|
||||
* @param packageName 包名
|
||||
* @param iconBitmap 图标位图
|
||||
* @param contributorName 贡献者昵称
|
||||
*/
|
||||
data class IconDataBean(
|
||||
var appName: String,
|
||||
var packageName: String,
|
||||
var iconBitmap: Bitmap,
|
||||
var contributorName: String
|
||||
) : Serializable
|
@@ -23,6 +23,7 @@
|
||||
package com.fankes.miui.notify.hook
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import android.graphics.Outline
|
||||
import android.graphics.drawable.Drawable
|
||||
@@ -33,11 +34,10 @@ import android.view.View
|
||||
import android.view.ViewOutlineProvider
|
||||
import android.widget.ImageView
|
||||
import androidx.annotation.Keep
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import com.fankes.miui.notify.hook.HookMedium.QQ_PACKAGE_NAME
|
||||
import com.fankes.miui.notify.hook.HookMedium.SELF_PACKAGE_NAME
|
||||
import com.fankes.miui.notify.hook.HookMedium.SYSTEMUI_PACKAGE_NAME
|
||||
import com.fankes.miui.notify.params.IconPackParams
|
||||
import com.fankes.miui.notify.utils.*
|
||||
import de.robv.android.xposed.*
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||
@@ -142,6 +142,17 @@ class HookMain : IXposedHookLoadPackage {
|
||||
.apply { isAccessible = true }.invoke(instance, icon) as Boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 [ExpandedNotificationClass] 的应用名称
|
||||
* @param instance 通知实例
|
||||
* @return [String]
|
||||
*/
|
||||
private fun XC_LoadPackage.LoadPackageParam.findAppName(instance: Any?) =
|
||||
findClass(ExpandedNotificationClass).getDeclaredMethod("getAppName").let {
|
||||
it.isAccessible = true
|
||||
it.invoke(instance) as? String ?: ""
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全局上下文
|
||||
* @return [Context]
|
||||
@@ -162,15 +173,23 @@ class HookMain : IXposedHookLoadPackage {
|
||||
val iconDrawable = (param.result as Icon).loadDrawable(globalContext)
|
||||
/** 获取通知对象 - 由于 MIUI 的版本迭代不规范性可能是空的 */
|
||||
(param.args?.get(0) as? StatusBarNotification?)?.also { notifyInstance ->
|
||||
/** 判断要设置的图标 */
|
||||
/** 目标彩色通知 APP 图标 */
|
||||
var customIcon: Icon? = null
|
||||
run {
|
||||
IconPackParams.iconDatas.forEach {
|
||||
if ((notifyInstance.opPkgName == it.packageName ||
|
||||
findAppName(notifyInstance) == it.appName) &&
|
||||
HookMedium.isAppNotifyHookOf(it.packageName)
|
||||
) {
|
||||
customIcon = Icon.createWithBitmap(it.iconBitmap)
|
||||
return@run
|
||||
}
|
||||
}
|
||||
}
|
||||
when {
|
||||
/** 如果开启了修复聊天 APP 的图标 */
|
||||
notifyInstance.opPkgName == QQ_PACKAGE_NAME &&
|
||||
XPrefUtils.getBoolean(
|
||||
HookMedium.ENABLE_CHAT_ICON_HOOK,
|
||||
default = true
|
||||
) ->
|
||||
param.result = Icon.createWithBitmap(IconPackParams.qqSmallIcon)
|
||||
/** 如果开启了修复 APP 的彩色图标 */
|
||||
customIcon != null && HookMedium.getBoolean(HookMedium.ENABLE_NOTIFY_ICON_HOOK, default = true) ->
|
||||
param.result = customIcon
|
||||
/** 若不是灰度图标自动处理为圆角 */
|
||||
!isGrayscaleIcon(globalContext, iconDrawable) ->
|
||||
param.result = Icon.createWithBitmap(
|
||||
@@ -205,15 +224,24 @@ class HookMain : IXposedHookLoadPackage {
|
||||
/** 获取通知小图标 */
|
||||
val iconDrawable = notifyInstance.notification.smallIcon.loadDrawable(context)
|
||||
|
||||
/** 获取发送通知的 APP */
|
||||
val packageName = notifyInstance.opPkgName
|
||||
/** 如果开启了修复聊天 APP 的图标 */
|
||||
if (packageName == QQ_PACKAGE_NAME &&
|
||||
XPrefUtils.getBoolean(HookMedium.ENABLE_CHAT_ICON_HOOK, default = true)
|
||||
)
|
||||
/** 自定义默认小图标 */
|
||||
var customIcon: Bitmap? = null
|
||||
run {
|
||||
IconPackParams.iconDatas.forEach {
|
||||
if ((notifyInstance.opPkgName == it.packageName ||
|
||||
findAppName(notifyInstance) == it.appName) &&
|
||||
HookMedium.isAppNotifyHookOf(it.packageName)
|
||||
) {
|
||||
customIcon = it.iconBitmap
|
||||
return@run
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 如果开启了修复 APP 的彩色图标 */
|
||||
if (customIcon != null && HookMedium.getBoolean(HookMedium.ENABLE_NOTIFY_ICON_HOOK, default = true))
|
||||
iconImageView.apply {
|
||||
/** 设置自定义小图标 */
|
||||
setImageBitmap(IconPackParams.qqSmallIcon)
|
||||
setImageBitmap(customIcon)
|
||||
/** 上色 */
|
||||
setColorFilter(if (isUpperOfAndroidS) newStyle else oldStyle)
|
||||
}
|
||||
@@ -265,7 +293,7 @@ class HookMain : IXposedHookLoadPackage {
|
||||
/** 系统版本过低直接停止 Hook */
|
||||
if (isLowerAndroidP) return
|
||||
/** 若没开启模块直接停止 Hook */
|
||||
if (!XPrefUtils.getBoolean(HookMedium.ENABLE_MODULE, default = true)) return
|
||||
if (!HookMedium.getBoolean(HookMedium.ENABLE_MODULE, default = true)) return
|
||||
/** 强制回写系统的状态栏图标样式为原生 */
|
||||
runWithoutError(error = "SubstituteSmallIcon") {
|
||||
XposedHelpers.findAndHookMethod(
|
||||
@@ -285,19 +313,30 @@ class HookMain : IXposedHookLoadPackage {
|
||||
lpparam.findClass(ExpandedNotificationClass),
|
||||
object : XC_MethodReplacement() {
|
||||
override fun replaceHookedMethod(param: MethodHookParam) =
|
||||
if (XPrefUtils.getBoolean(HookMedium.ENABLE_COLOR_ICON_HOOK, default = true))
|
||||
if (HookMedium.getBoolean(HookMedium.ENABLE_COLOR_ICON_HOOK, default = true))
|
||||
try {
|
||||
/** 获取通知对象 - 由于 MIUI 的版本迭代不规范性可能是空的 */
|
||||
(param.args?.get(0) as? StatusBarNotification?)?.let { notifyInstance ->
|
||||
/** 获取发送通知的 APP */
|
||||
val packageName = notifyInstance.opPkgName
|
||||
NotificationCompat()
|
||||
/** 获取通知小图标 */
|
||||
val iconDrawable =
|
||||
notifyInstance.notification.smallIcon.loadDrawable(lpparam.globalContext)
|
||||
/** 如果开启了修复聊天 APP 的图标 */
|
||||
if (packageName == QQ_PACKAGE_NAME &&
|
||||
XPrefUtils.getBoolean(HookMedium.ENABLE_CHAT_ICON_HOOK, default = true)
|
||||
|
||||
/** 获取目标修复彩色图标的 APP */
|
||||
var isTargetApp = false
|
||||
run {
|
||||
IconPackParams.iconDatas.forEach {
|
||||
if ((notifyInstance.opPkgName == it.packageName ||
|
||||
lpparam.findAppName(notifyInstance) == it.appName) &&
|
||||
HookMedium.isAppNotifyHookOf(it.packageName)
|
||||
) {
|
||||
isTargetApp = true
|
||||
return@run
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 如果开启了修复 APP 的彩色图标 */
|
||||
if (isTargetApp &&
|
||||
HookMedium.getBoolean(HookMedium.ENABLE_NOTIFY_ICON_HOOK, default = true)
|
||||
) false
|
||||
/** 只要不是灰度就返回彩色图标 */
|
||||
else !lpparam.isGrayscaleIcon(lpparam.globalContext, iconDrawable)
|
||||
|
@@ -18,10 +18,20 @@
|
||||
*
|
||||
* This file is Created by fankes on 2022/1/24.
|
||||
*/
|
||||
@file:Suppress("DEPRECATION", "SetWorldReadable")
|
||||
|
||||
package com.fankes.miui.notify.hook
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.Keep
|
||||
import com.fankes.miui.notify.application.MNNApplication.Companion.appContext
|
||||
import com.fankes.miui.notify.application.MNNApplication.Companion.isMineStarted
|
||||
import com.fankes.miui.notify.utils.FileUtils
|
||||
import com.fankes.miui.notify.utils.XPrefUtils
|
||||
import java.io.File
|
||||
|
||||
@Keep
|
||||
object HookMedium {
|
||||
@@ -29,11 +39,10 @@ object HookMedium {
|
||||
const val ENABLE_MODULE = "_enable_module"
|
||||
const val ENABLE_HIDE_ICON = "_hide_icon"
|
||||
const val ENABLE_COLOR_ICON_HOOK = "_color_icon_hook"
|
||||
const val ENABLE_CHAT_ICON_HOOK = "_chat_icon_hook"
|
||||
const val ENABLE_NOTIFY_ICON_HOOK = "_notify_icon_hook"
|
||||
|
||||
const val SELF_PACKAGE_NAME = "com.fankes.miui.notify"
|
||||
const val SYSTEMUI_PACKAGE_NAME = "com.android.systemui"
|
||||
const val QQ_PACKAGE_NAME = "com.tencent.mobileqq"
|
||||
|
||||
/**
|
||||
* 判断模块是否激活
|
||||
@@ -44,4 +53,70 @@ object HookMedium {
|
||||
Log.d("MIUINativeNotifyIcon", "isHooked: true")
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取此 APP 的通知图标是否被 Hook
|
||||
* @param packageName 包名
|
||||
*/
|
||||
fun isAppNotifyHookOf(packageName: String) = getBoolean(key = "${packageName}_icon", default = true)
|
||||
|
||||
/**
|
||||
* 设置 Hook 此 APP 的通知图标
|
||||
* @param packageName 包名
|
||||
* @param isHook 是否 Hook
|
||||
*/
|
||||
fun putAppNotifyHookOf(packageName: String, isHook: Boolean) = putBoolean(key = "${packageName}_icon", bool = isHook)
|
||||
|
||||
/**
|
||||
* 获取保存的值
|
||||
* @param key 名称
|
||||
* @param default 默认值
|
||||
* @return [Boolean] 保存的值
|
||||
*/
|
||||
fun getBoolean(key: String, default: Boolean = false) =
|
||||
if (isMineStarted)
|
||||
appContext.getSharedPreferences(
|
||||
appContext.packageName + "_preferences",
|
||||
Context.MODE_PRIVATE
|
||||
).getBoolean(key, default)
|
||||
else XPrefUtils.getBoolean(key, default)
|
||||
|
||||
/**
|
||||
* 保存值
|
||||
* @param key 名称
|
||||
* @param bool 值
|
||||
*/
|
||||
fun putBoolean(key: String, bool: Boolean) {
|
||||
appContext.getSharedPreferences(
|
||||
appContext.packageName + "_preferences",
|
||||
Context.MODE_PRIVATE
|
||||
).edit().putBoolean(key, bool).apply()
|
||||
setWorldReadable(appContext)
|
||||
/** 延迟继续设置强制允许 SP 可读可写 */
|
||||
Handler().postDelayed({ setWorldReadable(appContext) }, 500)
|
||||
Handler().postDelayed({ setWorldReadable(appContext) }, 1000)
|
||||
Handler().postDelayed({ setWorldReadable(appContext) }, 1500)
|
||||
}
|
||||
|
||||
/**
|
||||
* 强制设置 Sp 存储为全局可读可写
|
||||
* 以供模块使用
|
||||
* @param context 实例
|
||||
*/
|
||||
fun setWorldReadable(context: Context) {
|
||||
try {
|
||||
if (FileUtils.getDefaultPrefFile(context).exists()) {
|
||||
for (file in arrayOf<File>(
|
||||
FileUtils.getDataDir(context),
|
||||
FileUtils.getPrefDir(context),
|
||||
FileUtils.getDefaultPrefFile(context)
|
||||
)) {
|
||||
file.setReadable(true, false)
|
||||
file.setExecutable(true, false)
|
||||
}
|
||||
}
|
||||
} catch (_: Exception) {
|
||||
Toast.makeText(context, "无法写入模块设置,请检查权限\n如果此提示一直显示,请不要双开模块", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,59 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
*
|
||||
* This file is part of MIUINativeNotifyIcon.
|
||||
*
|
||||
* MIUINativeNotifyIcon is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MIUINativeNotifyIcon 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This file is Created by fankes on 2022/1/24.
|
||||
*/
|
||||
package com.fankes.miui.notify.hook
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import com.fankes.miui.notify.utils.bitmap
|
||||
import com.fankes.miui.notify.utils.unbase64
|
||||
|
||||
object IconPackParams {
|
||||
|
||||
/**
|
||||
* QQ 通知栏小图标
|
||||
* @return [Bitmap]
|
||||
*/
|
||||
val qqSmallIcon by lazy {
|
||||
("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\n" +
|
||||
"HWRiiAAAAABJRU5ErkJggg==").unbase64.bitmap
|
||||
}
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
*
|
||||
* This file is part of MIUINativeNotifyIcon.
|
||||
*
|
||||
* MIUINativeNotifyIcon is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MIUINativeNotifyIcon 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This file is Created by fankes on 2022/1/24.
|
||||
*/
|
||||
package com.fankes.miui.notify.params
|
||||
|
||||
import com.fankes.miui.notify.bean.IconDataBean
|
||||
import com.fankes.miui.notify.utils.bitmap
|
||||
|
||||
/**
|
||||
* 通知栏小图标适配类
|
||||
* 国内 APP 不规范的图标将由这里完成其自定义黑白小图标绘制
|
||||
*/
|
||||
object IconPackParams {
|
||||
|
||||
/**
|
||||
* 通知栏小图标数组
|
||||
* 默认使用包名进行匹配 - 若失败则使用 APP 名称进行匹配
|
||||
* @return [Array]
|
||||
*/
|
||||
val iconDatas by lazy {
|
||||
arrayOf(
|
||||
IconDataBean(
|
||||
appName = "QQ",
|
||||
packageName = "com.tencent.mobileqq",
|
||||
iconBitmap = ("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\n" +
|
||||
"HWRiiAAAAABJRU5ErkJggg==").bitmap,
|
||||
contributorName = "fankes"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
*
|
||||
* This file is part of MIUINativeNotifyIcon.
|
||||
*
|
||||
* MIUINativeNotifyIcon is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MIUINativeNotifyIcon 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This file is Created by fankes on 2022/01/30.
|
||||
*/
|
||||
package com.fankes.miui.notify.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import com.fankes.miui.notify.R
|
||||
import com.fankes.miui.notify.ui.base.BaseActivity
|
||||
|
||||
class ConfigureActivity : BaseActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_config)
|
||||
/** 返回按钮点击事件 */
|
||||
findViewById<View>(R.id.title_back_icon).setOnClickListener { onBackPressed() }
|
||||
}
|
||||
}
|
@@ -18,32 +18,28 @@
|
||||
*
|
||||
* This file is Created by fankes on 2022/01/24.
|
||||
*/
|
||||
@file:Suppress("DEPRECATION", "SetWorldReadable", "SetTextI18n")
|
||||
@file:Suppress("SetTextI18n")
|
||||
|
||||
package com.fankes.miui.notify.ui
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.SwitchCompat
|
||||
import androidx.constraintlayout.utils.widget.ImageFilterView
|
||||
import com.fankes.miui.notify.BuildConfig
|
||||
import com.fankes.miui.notify.R
|
||||
import com.fankes.miui.notify.hook.HookMedium
|
||||
import com.fankes.miui.notify.ui.base.BaseActivity
|
||||
import com.fankes.miui.notify.utils.*
|
||||
import com.gyf.immersionbar.ktx.immersionBar
|
||||
import java.io.File
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
class MainActivity : BaseActivity() {
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -54,17 +50,6 @@ class MainActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
/** 隐藏系统的标题栏 */
|
||||
supportActionBar?.hide()
|
||||
/** 初始化沉浸状态栏 */
|
||||
immersionBar {
|
||||
statusBarColor(R.color.colorThemeBackground)
|
||||
autoDarkModeEnable(true)
|
||||
statusBarDarkFont(isNotSystemInDarkMode)
|
||||
navigationBarColor(R.color.colorThemeBackground)
|
||||
navigationBarDarkIcon(isNotSystemInDarkMode)
|
||||
fitsSystemWindows(true)
|
||||
}
|
||||
/** 设置文本 */
|
||||
findViewById<TextView>(R.id.main_text_version).text = "当前版本:$moduleVersion"
|
||||
findViewById<TextView>(R.id.main_text_miui_version).text = "MIUI 版本:$miuiVersion"
|
||||
@@ -108,12 +93,12 @@ class MainActivity : AppCompatActivity() {
|
||||
val moduleEnableSwitch = findViewById<SwitchCompat>(R.id.module_enable_switch)
|
||||
val hideIconInLauncherSwitch = findViewById<SwitchCompat>(R.id.hide_icon_in_launcher_switch)
|
||||
val colorIconHookSwitch = findViewById<SwitchCompat>(R.id.color_icon_fix_switch)
|
||||
val chatIconHookSwitch = findViewById<SwitchCompat>(R.id.chat_icon_fix_switch)
|
||||
val notifyIconHookSwitch = findViewById<SwitchCompat>(R.id.notify_icon_fix_switch)
|
||||
/** 获取 Sp 存储的信息 */
|
||||
moduleEnableSwitch.isChecked = getBoolean(HookMedium.ENABLE_MODULE, default = true)
|
||||
hideIconInLauncherSwitch.isChecked = getBoolean(HookMedium.ENABLE_HIDE_ICON)
|
||||
colorIconHookSwitch.isChecked = getBoolean(HookMedium.ENABLE_COLOR_ICON_HOOK, default = true)
|
||||
chatIconHookSwitch.isChecked = getBoolean(HookMedium.ENABLE_CHAT_ICON_HOOK, default = true)
|
||||
notifyIconHookSwitch.isChecked = getBoolean(HookMedium.ENABLE_NOTIFY_ICON_HOOK, default = true)
|
||||
moduleEnableSwitch.setOnCheckedChangeListener { btn, b ->
|
||||
if (!btn.isPressed) return@setOnCheckedChangeListener
|
||||
putBoolean(HookMedium.ENABLE_MODULE, b)
|
||||
@@ -131,9 +116,9 @@ class MainActivity : AppCompatActivity() {
|
||||
if (!btn.isPressed) return@setOnCheckedChangeListener
|
||||
putBoolean(HookMedium.ENABLE_COLOR_ICON_HOOK, b)
|
||||
}
|
||||
chatIconHookSwitch.setOnCheckedChangeListener { btn, b ->
|
||||
notifyIconHookSwitch.setOnCheckedChangeListener { btn, b ->
|
||||
if (!btn.isPressed) return@setOnCheckedChangeListener
|
||||
putBoolean(HookMedium.ENABLE_CHAT_ICON_HOOK, b)
|
||||
putBoolean(HookMedium.ENABLE_NOTIFY_ICON_HOOK, b)
|
||||
}
|
||||
/** 重启按钮点击事件 */
|
||||
findViewById<View>(R.id.title_restart_icon).setOnClickListener {
|
||||
@@ -144,6 +129,10 @@ class MainActivity : AppCompatActivity() {
|
||||
cancelButton()
|
||||
}
|
||||
}
|
||||
/** 通知图标优化名单按钮点击事件 */
|
||||
findViewById<View>(R.id.config_notify_app_button).setOnClickListener {
|
||||
startActivity(Intent(this, ConfigureActivity::class.java))
|
||||
}
|
||||
/** 恰饭! */
|
||||
findViewById<View>(R.id.link_with_follow_me).setOnClickListener {
|
||||
try {
|
||||
@@ -187,73 +176,18 @@ class MainActivity : AppCompatActivity() {
|
||||
else Toast.makeText(this, "ROOT 权限获取失败", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
setWorldReadable()
|
||||
}
|
||||
|
||||
override fun onRestart() {
|
||||
super.onRestart()
|
||||
setWorldReadable()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
setWorldReadable()
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取保存的值
|
||||
* @param key 名称
|
||||
* @param default 默认值
|
||||
* @return [Boolean] 保存的值
|
||||
*/
|
||||
private fun getBoolean(key: String, default: Boolean = false) =
|
||||
getSharedPreferences(
|
||||
packageName + "_preferences",
|
||||
Context.MODE_PRIVATE
|
||||
).getBoolean(key, default)
|
||||
private fun getBoolean(key: String, default: Boolean = false) = HookMedium.getBoolean(key, default)
|
||||
|
||||
/**
|
||||
* 保存值
|
||||
* @param key 名称
|
||||
* @param bool 值
|
||||
*/
|
||||
private fun putBoolean(key: String, bool: Boolean) {
|
||||
getSharedPreferences(
|
||||
packageName + "_preferences",
|
||||
Context.MODE_PRIVATE
|
||||
).edit().putBoolean(key, bool).apply()
|
||||
setWorldReadable()
|
||||
/** 延迟继续设置强制允许 SP 可读可写 */
|
||||
Handler().postDelayed({ setWorldReadable() }, 500)
|
||||
Handler().postDelayed({ setWorldReadable() }, 1000)
|
||||
Handler().postDelayed({ setWorldReadable() }, 1500)
|
||||
}
|
||||
|
||||
/**
|
||||
* 强制设置 Sp 存储为全局可读可写
|
||||
* 以供模块使用
|
||||
*/
|
||||
private fun setWorldReadable() {
|
||||
try {
|
||||
if (FileUtils.getDefaultPrefFile(this).exists()) {
|
||||
for (file in arrayOf<File>(
|
||||
FileUtils.getDataDir(this),
|
||||
FileUtils.getPrefDir(this),
|
||||
FileUtils.getDefaultPrefFile(this)
|
||||
)) {
|
||||
file.setReadable(true, false)
|
||||
file.setExecutable(true, false)
|
||||
}
|
||||
}
|
||||
} catch (_: Exception) {
|
||||
Toast.makeText(this, "无法写入模块设置,请检查权限\n如果此提示一直显示,请不要双开模块", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
setWorldReadable()
|
||||
super.onBackPressed()
|
||||
}
|
||||
private fun putBoolean(key: String, bool: Boolean) = HookMedium.putBoolean(key, bool)
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
*
|
||||
* This file is part of MIUINativeNotifyIcon.
|
||||
*
|
||||
* MIUINativeNotifyIcon is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MIUINativeNotifyIcon 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This file is Created by fankes on 2022/01/30.
|
||||
*/
|
||||
package com.fankes.miui.notify.ui.base
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.fankes.miui.notify.R
|
||||
import com.fankes.miui.notify.hook.HookMedium
|
||||
import com.fankes.miui.notify.utils.isNotSystemInDarkMode
|
||||
import com.gyf.immersionbar.ktx.immersionBar
|
||||
|
||||
abstract class BaseActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
/** 隐藏系统的标题栏 */
|
||||
supportActionBar?.hide()
|
||||
/** 初始化沉浸状态栏 */
|
||||
immersionBar {
|
||||
statusBarColor(R.color.colorThemeBackground)
|
||||
autoDarkModeEnable(true)
|
||||
statusBarDarkFont(isNotSystemInDarkMode)
|
||||
navigationBarColor(R.color.colorThemeBackground)
|
||||
navigationBarDarkIcon(isNotSystemInDarkMode)
|
||||
fitsSystemWindows(true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
HookMedium.setWorldReadable(this)
|
||||
}
|
||||
|
||||
override fun onRestart() {
|
||||
super.onRestart()
|
||||
HookMedium.setWorldReadable(this)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
HookMedium.setWorldReadable(this)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
HookMedium.setWorldReadable(this)
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
@@ -31,7 +31,7 @@ import android.graphics.Bitmap.createBitmap
|
||||
import android.os.Build
|
||||
import android.service.notification.StatusBarNotification
|
||||
import android.util.Base64
|
||||
import com.fankes.miui.notify.application.MNvApplication.Companion.appContext
|
||||
import com.fankes.miui.notify.application.MNNApplication.Companion.appContext
|
||||
import java.io.DataInputStream
|
||||
import java.io.DataOutputStream
|
||||
|
||||
@@ -177,6 +177,12 @@ val String.unbase64 get() = Base64.decode(this, Base64.DEFAULT) ?: ByteArray(0)
|
||||
*/
|
||||
val ByteArray.bitmap: Bitmap get() = BitmapFactory.decodeByteArray(this, 0, size)
|
||||
|
||||
/**
|
||||
* 字符串解析为位图
|
||||
* @return [Bitmap]
|
||||
*/
|
||||
val String.bitmap: Bitmap get() = unbase64.bitmap
|
||||
|
||||
/**
|
||||
* 圆角图片
|
||||
* @param radius 圆角度
|
||||
|
42
app/src/main/res/layout/activity_config.xml
Normal file
42
app/src/main/res/layout/activity_config.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/colorThemeBackground"
|
||||
android:orientation="vertical"
|
||||
tools:context=".ui.MainActivity"
|
||||
tools:ignore="HardcodedText,UseCompoundDrawables,ContentDescription">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="0dp"
|
||||
android:gravity="center|start"
|
||||
android:paddingLeft="15dp"
|
||||
android:paddingTop="13dp"
|
||||
android:paddingRight="15dp"
|
||||
android:paddingBottom="5dp">
|
||||
|
||||
<androidx.constraintlayout.utils.widget.ImageFilterView
|
||||
android:id="@+id/title_back_icon"
|
||||
style="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginEnd="15dp"
|
||||
android:src="@mipmap/back"
|
||||
android:tint="@color/colorTextGray" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:singleLine="true"
|
||||
android:text="通知图标优化名单"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="25sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
@@ -210,9 +210,9 @@
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginTop="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:background="@drawable/permotion_round"
|
||||
android:elevation="0dp"
|
||||
android:gravity="center"
|
||||
@@ -221,20 +221,37 @@
|
||||
android:paddingRight="15dp">
|
||||
|
||||
<com.fankes.miui.notify.view.MaterialSwitch
|
||||
android:id="@+id/chat_icon_fix_switch"
|
||||
android:id="@+id/notify_icon_fix_switch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="优化社交应用通知图标"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:text="启用通知图标优化"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/config_notify_app_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="@drawable/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="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:alpha="0.6"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:text="此选项默认开启,开启后将对 QQ 和微信的消息图标进行色彩修复,使得它们的图标看起来更加美观。"
|
||||
android:text="此选项默认开启,开启后将对优化名单内 APP 通知小图标进行色彩修复,使得它们的图标看起来更加美观。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
|
Reference in New Issue
Block a user