Merge code

This commit is contained in:
2022-03-20 14:11:08 +08:00
parent b610eca3b2
commit e509f0e6db
10 changed files with 224 additions and 39 deletions

1
.idea/misc.xml generated
View File

@@ -9,6 +9,7 @@
<entry key="app/src/main/res/drawable/bg_dark_round.xml" value="0.2325" />
<entry key="app/src/main/res/drawable/bg_dialog_background.xml" value="0.2325" />
<entry key="app/src/main/res/drawable/bg_green_round.xml" value="0.255" />
<entry key="app/src/main/res/drawable/bg_orange_round.xml" value="0.2325" />
<entry key="app/src/main/res/drawable/bg_warn_round.xml" value="0.2325" />
<entry key="app/src/main/res/drawable/bg_yellow_round.xml" value="0.255" />
<entry key="app/src/main/res/drawable/permotion_round.xml" value="0.256" />

View File

@@ -4,6 +4,7 @@
package="com.fankes.miui.notify">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:name=".application.MNNApplication"

View File

@@ -302,16 +302,16 @@ class HookEntry : YukiHookXposedInitProxy {
expandedNf: StatusBarNotification?,
iconDrawable: Drawable?,
it: (Bitmap) -> Unit
) = runSafe(msg = "GetSmallIconOnSet") {
if (iconDrawable == null) return@runSafe
) = runInSafe(msg = "GetSmallIconOnSet") {
if (iconDrawable == null) return@runInSafe
/** 如果没开启修复 APP 的彩色图标 */
if (!prefs.getBoolean(ENABLE_COLOR_ICON_HOOK, default = true)) return@runSafe
if (!prefs.getBoolean(ENABLE_COLOR_ICON_HOOK, default = true)) return@runInSafe
/** 获取通知对象 - 由于 MIUI 的版本迭代不规范性可能是空的 */
expandedNf?.also { notifyInstance ->
/** 判断是 MIUI 样式就停止 Hook */
if (context.isMiuiNotifyStyle) {
it(notifyInstance.findAppIcon(context).toBitmap())
return@runSafe
return@runInSafe
}
/** 判断是否不是灰度图标 */
val isNotGrayscaleIcon = notifyInstance.isXmsf || !isGrayscaleIcon(context, iconDrawable)
@@ -343,11 +343,11 @@ class HookEntry : YukiHookXposedInitProxy {
expandedNf: StatusBarNotification?,
iconImageView: ImageView,
isExpanded: Boolean
) = runSafe(msg = "AutoSetAppIconOnSet") {
) = runInSafe(msg = "AutoSetAppIconOnSet") {
/** 判断是 MIUI 样式就停止 Hook */
if (context.isMiuiNotifyStyle) return@runSafe
if (context.isMiuiNotifyStyle) return@runInSafe
/** 如果没开启修复 APP 的彩色图标 */
if (!prefs.getBoolean(ENABLE_COLOR_ICON_HOOK, default = true)) return@runSafe
if (!prefs.getBoolean(ENABLE_COLOR_ICON_HOOK, default = true)) return@runInSafe
/** 获取通知对象 - 由于 MIUI 的版本迭代不规范性可能是空的 */
expandedNf?.let { notifyInstance ->

View File

@@ -46,6 +46,7 @@ import com.fankes.miui.notify.hook.HookConst.HOOK_STATUS_ICON_COUNT
import com.fankes.miui.notify.params.IconPackParams
import com.fankes.miui.notify.ui.activity.base.BaseActivity
import com.fankes.miui.notify.utils.factory.*
import com.fankes.miui.notify.utils.tool.GithubReleaseTool
import com.fankes.miui.notify.utils.tool.SystemUITool
import com.highcapable.yukihookapi.hook.factory.isXposedModuleActive
import com.highcapable.yukihookapi.hook.factory.modulePrefs
@@ -65,6 +66,14 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
/** 设置文本 */
binding.mainTextVersion.text = "模块版本:$moduleVersion"
binding.mainTextMiuiVersion.text = "系统版本:$miuiFullVersion"
/** 检查更新 */
GithubReleaseTool.checkingForUpdate(context = this, moduleVersion) { version, function ->
binding.mainTextReleaseVersion.apply {
text = "点击更新 $version"
isVisible = true
setOnClickListener { function() }
}
}
when {
/** 判断是否为 MIUI 系统 */
isNotMIUI ->
@@ -233,9 +242,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
/** 重启按钮点击事件 */
binding.titleRestartIcon.setOnClickListener { SystemUITool.restartSystemUI(context = this) }
/** 项目地址按钮点击事件 */
binding.titleGithubIcon.setOnClickListener {
openBrowser(url = "https://github.com/fankes/MIUINativeNotifyIcon")
}
binding.titleGithubIcon.setOnClickListener { openBrowser(url = "https://github.com/fankes/MIUINativeNotifyIcon") }
/** 恰饭! */
binding.linkWithFollowMe.setOnClickListener {
openBrowser(url = "https://www.coolapk.com/u/876977", packageName = "com.coolapk.market")
@@ -286,9 +293,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
/** 防止顶栈一样重叠在自己的 APP 中 */
flags = Intent.FLAG_ACTIVITY_NEW_TASK
})
}.onFailure {
toast(msg = "启动失败,请手动调整设置")
}
}.onFailure { toast(msg = "启动失败,请手动调整设置") }
isWarnDialogShowing = false
}
cancelButton { isWarnDialogShowing = false }

View File

@@ -73,8 +73,8 @@ class DialogBuilder(val context: Context, private val isUseBlackTheme: Boolean)
init {
if (isUsingAndroidX)
runCatching { instanceAndroidX = MaterialAlertDialogBuilder(context) }
else runCatching {
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
@@ -85,8 +85,8 @@ class DialogBuilder(val context: Context, private val isUseBlackTheme: Boolean)
/** 设置对话框不可关闭 */
fun noCancelable() {
if (isUsingAndroidX)
runCatching { instanceAndroidX?.setCancelable(false) }
else runCatching { instanceAndroid?.setCancelable(false) }
runInSafe { instanceAndroidX?.setCancelable(false) }
else runInSafe { instanceAndroid?.setCancelable(false) }
}
/** 设置对话框标题 */
@@ -94,8 +94,8 @@ class DialogBuilder(val context: Context, private val isUseBlackTheme: Boolean)
get() = ""
set(value) {
if (isUsingAndroidX)
runCatching { instanceAndroidX?.setTitle(value) }
else runCatching { instanceAndroid?.setTitle(value) }
runInSafe { instanceAndroidX?.setTitle(value) }
else runInSafe { instanceAndroid?.setTitle(value) }
}
/** 设置对话框消息内容 */
@@ -103,8 +103,8 @@ class DialogBuilder(val context: Context, private val isUseBlackTheme: Boolean)
get() = ""
set(value) {
if (isUsingAndroidX)
runCatching { instanceAndroidX?.setMessage(value) }
else runCatching { instanceAndroid?.setMessage(value) }
runInSafe { instanceAndroidX?.setMessage(value) }
else runInSafe { instanceAndroid?.setMessage(value) }
}
/** 设置进度条对话框消息内容 */
@@ -145,8 +145,8 @@ class DialogBuilder(val context: Context, private val isUseBlackTheme: Boolean)
*/
fun confirmButton(text: String = "确定", it: () -> Unit = {}) {
if (isUsingAndroidX)
runCatching { instanceAndroidX?.setPositiveButton(text) { _, _ -> it() } }
else runCatching { instanceAndroid?.setPositiveButton(text) { _, _ -> it() } }
runInSafe { instanceAndroidX?.setPositiveButton(text) { _, _ -> it() } }
else runInSafe { instanceAndroid?.setPositiveButton(text) { _, _ -> it() } }
}
/**
@@ -156,8 +156,8 @@ class DialogBuilder(val context: Context, private val isUseBlackTheme: Boolean)
*/
fun cancelButton(text: String = "取消", it: () -> Unit = {}) {
if (isUsingAndroidX)
runCatching { instanceAndroidX?.setNegativeButton(text) { _, _ -> it() } }
else runCatching { instanceAndroid?.setNegativeButton(text) { _, _ -> it() } }
runInSafe { instanceAndroidX?.setNegativeButton(text) { _, _ -> it() } }
else runInSafe { instanceAndroid?.setNegativeButton(text) { _, _ -> it() } }
}
/**
@@ -167,21 +167,21 @@ class DialogBuilder(val context: Context, private val isUseBlackTheme: Boolean)
*/
fun neutralButton(text: String = "更多", it: () -> Unit = {}) {
if (isUsingAndroidX)
runCatching { instanceAndroidX?.setNeutralButton(text) { _, _ -> it() } }
else runCatching { instanceAndroid?.setNeutralButton(text) { _, _ -> it() } }
runInSafe { instanceAndroidX?.setNeutralButton(text) { _, _ -> it() } }
else runInSafe { instanceAndroid?.setNeutralButton(text) { _, _ -> it() } }
}
/** 取消对话框 */
fun cancel() = dialogInstance?.cancel()
/** 显示对话框 */
internal fun show() {
if (isUsingAndroidX) runCatching {
internal fun show() =
if (isUsingAndroidX) runInSafe {
instanceAndroidX?.create()?.apply {
customLayoutView?.let { setView(it) }
dialogInstance = this
}?.show()
} else runCatching {
} else runInSafe {
instanceAndroid?.create()?.apply {
customLayoutView?.let { setView(it) }
window?.setBackgroundDrawable(
@@ -197,5 +197,4 @@ class DialogBuilder(val context: Context, private val isUseBlackTheme: Boolean)
dialogInstance = this
}?.show()
}
}
}

View File

@@ -78,6 +78,6 @@ inline fun <T> safeOf(default: T, result: () -> T) = try {
* @param msg 出错输出的消息 - 默认为空
* @param block 正常回调
*/
inline fun <T> T.runSafe(msg: String = "", block: () -> Unit) {
inline fun <T> T.runInSafe(msg: String = "", block: () -> Unit) {
runCatching(block).onFailure { if (msg.isNotBlank()) loggerE(msg = msg, e = it) }
}

View File

@@ -35,12 +35,14 @@ import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color
import android.net.ConnectivityManager
import android.net.Uri
import android.os.Build
import android.provider.Settings
import android.util.Base64
import android.widget.Toast
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.getSystemService
import com.fankes.miui.notify.application.MNNApplication.Companion.appContext
import com.google.android.material.snackbar.Snackbar
import com.highcapable.yukihookapi.hook.factory.classOf
@@ -221,6 +223,13 @@ val Context.versionCode get() = packageInfo.versionCode
*/
val isNotNoificationEnabled get() = !NotificationManagerCompat.from(appContext).areNotificationsEnabled()
/**
* 网络连接是否正常
* @return [Boolean] 网络是否连接
*/
val isNetWorkSuccess
get() = safeOfFalse { appContext.getSystemService<ConnectivityManager>()?.activeNetworkInfo != null }
/**
* dp 转换为 pxInt
* @param context 使用的实例
@@ -352,11 +361,25 @@ fun Context.openBrowser(url: String, packageName: String = "") = runCatching {
else snake(msg = "启动系统浏览器失败")
}
/**
* 跳转 APP 自身设置界面
* @param packageName 包名
*/
fun Context.openSelfSetting(packageName: String = appContext.packageName) = runCatching {
if (packageName.isInstall)
startActivity(Intent().apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
data = Uri.fromParts("package", packageName, null)
})
else toast(msg = "你没有安装此应用")
}.onFailure { toast(msg = "启动 $packageName 应用信息失败") }
/**
* 复制到剪贴板
* @param content 要复制的文本
*/
fun Context.copyToClipboard(content: String) = runSafe {
fun Context.copyToClipboard(content: String) = runInSafe {
(getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager).apply {
setPrimaryClip(ClipData.newPlainText(null, content))
(primaryClip?.getItemAt(0)?.text ?: "").also {

View File

@@ -0,0 +1,128 @@
/*
* MIUINativeNotifyIcon - Fix the native notification bar icon function abandoned by the MIUI development team.
* Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com)
* https://github.com/fankes/MIUINativeNotifyIcon
*
* This software is non-free but opensource software: you can redistribute it
* and/or modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
* <p>
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* and eula along with this software. If not, see
* <https://www.gnu.org/licenses/>
*
* This file is Created by fankes on 2022/3/20.
*/
package com.fankes.miui.notify.utils.tool
import android.app.Activity
import android.content.Context
import com.fankes.miui.notify.utils.factory.*
import okhttp3.*
import org.json.JSONObject
import java.io.IOException
import java.io.Serializable
/**
* 获取 Github Release 最新版本工具类
*/
object GithubReleaseTool {
/** 仓库作者 */
private const val repoAuthor = "fankes"
/** 仓库名称 */
private const val repoName = "MIUINativeNotifyIcon"
/**
* 获取最新版本信息
* @param context 实例
* @param version 当前版本
* @param it 成功后回调 - ([String] 最新版本,[Function] 更新对话框方法体)
*/
fun checkingForUpdate(context: Context, version: String, it: (String, () -> Unit) -> Unit) = checkingInternetConnect(context) {
OkHttpClient().newBuilder().build().newCall(
Request.Builder()
.url("https://api.github.com/repos/$repoAuthor/$repoName/releases/latest")
.get()
.build()
).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {}
override fun onResponse(call: Call, response: Response) = runInSafe {
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 = "")
).apply {
fun showUpdate() = context.showDialog {
title = "最新版本 $name"
msg = "发布于 $date\n\n" +
"更新日志\n\n" + content
confirmButton(text = "更新") { context.openBrowser(htmlUrl) }
cancelButton()
}
if (name != version) (context as? Activity?)?.runOnUiThread {
showUpdate()
it(name) { showUpdate() }
}
}
}
}
})
}
/**
* 检查网络连接情况
* @param context 实例
* @param it 已连接回调
*/
private fun checkingInternetConnect(context: Context, it: () -> Unit) = runInSafe {
if (isNetWorkSuccess)
OkHttpClient().newBuilder().build().newCall(
Request.Builder()
.url("https://www.baidu.com")
.get()
.build()
).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
(context as? Activity?)?.runOnUiThread {
context.showDialog {
title = "网络不可用"
msg = "模块的联网权限可能已被禁用,请开启联网权限以定期检查更新。"
confirmButton(text = "去开启") { context.openSelfSetting() }
cancelButton()
noCancelable()
}
}
}
override fun onResponse(call: Call, response: Response) = runInSafe {
(context as? Activity?)?.runOnUiThread { runInSafe { it() } }
}
})
}
/**
* Github Release bean
* @param name 版本名称
* @param htmlUrl 网页地址
* @param content 更新日志
* @param date 发布时间
*/
private data class GithubReleaseBean(
var name: String,
var htmlUrl: String,
var content: String,
var date: String
) : Serializable
}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FF7043" />
<corners android:radius="15dp" />
</shape>

View File

@@ -91,15 +91,37 @@
android:textColor="@color/white"
android:textSize="18sp" />
<TextView
android:id="@+id/main_text_version"
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:alpha="0.8"
android:text="模块版本:%1"
android:textColor="@color/white"
android:textSize="13sp" />
android:gravity="center|start"
android:orientation="horizontal">
<TextView
android:id="@+id/main_text_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0.8"
android:text="模块版本:%1"
android:textColor="@color/white"
android:textSize="13sp" />
<TextView
android:id="@+id/main_text_release_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:background="@drawable/bg_orange_round"
android:paddingLeft="5dp"
android:paddingTop="2dp"
android:paddingRight="5dp"
android:paddingBottom="2dp"
android:text="点击更新 %1"
android:textColor="@color/white"
android:textSize="11sp"
android:visibility="gone" />
</LinearLayout>
<TextView
android:id="@+id/main_text_miui_version"