mirror of
https://github.com/fankes/ColorOSNotifyIcon.git
synced 2025-09-09 20:14:11 +08:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
b06ecaa5e0 | |||
df5090faac | |||
ffb706864a | |||
70eadb83e8 | |||
6d7d7290e2 | |||
1191c77986 | |||
2f4539d8f6 | |||
030a1590ae | |||
52820c0b07 |
32
README.md
32
README.md
@@ -2,50 +2,55 @@
|
|||||||
|
|
||||||
[](https://github.com/fankes/ColorOSNotifyIcon)
|
[](https://github.com/fankes/ColorOSNotifyIcon)
|
||||||
[](https://github.com/fankes/ColorOSNotifyIcon/blob/master/LICENSE)
|
[](https://github.com/fankes/ColorOSNotifyIcon/blob/master/LICENSE)
|
||||||
[](https://github.com/fankes/ColorOSNotifyIcon/releases)
|
[](https://github.com/fankes/ColorOSNotifyIcon/releases)
|
||||||
[](https://github.com/fankes/ColorOSNotifyIcon/releases)
|
[](https://github.com/fankes/ColorOSNotifyIcon/releases)
|
||||||
[](https://github.com/Xposed-Modules-Repo/com.fankes.coloros.notify/releases)
|
[](https://github.com/Xposed-Modules-Repo/com.fankes.coloros.notify/releases)
|
||||||
[](https://t.me/XiaofangInternet)
|
[](https://t.me/XiaofangInternet)
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
<img src="https://github.com/fankes/ColorOSNotifyIcon/blob/master/app/src/main/ic_launcher-playstore.png" width = "100" height = "100"/>
|
<img src="https://github.com/fankes/ColorOSNotifyIcon/blob/master/app/src/main/ic_launcher-playstore.png" width = "100" height = "100"/>
|
||||||
<br/>
|
<br/>
|
||||||
Optimize notification icons for ColorOS and adapt to native notification icon specifications.<br/>
|
Optimize notification icons for ColorOS and adapt to native notification icon specifications.
|
||||||
|
|
||||||
为 ColorOS 优化通知图标以及适配原生通知图标规范,理论支持 OxygenOS 和 RealmeUI。
|
为 ColorOS 优化通知图标以及适配原生通知图标规范,理论支持 OxygenOS 和 RealmeUI。
|
||||||
|
|
||||||
# Developer
|
## Developer
|
||||||
|
|
||||||
[酷安 @星夜不荟](http://www.coolapk.com/u/876977)
|
[酷安 @星夜不荟](http://www.coolapk.com/u/876977)
|
||||||
|
|
||||||
# 适配说明
|
## 适配说明
|
||||||
|
|
||||||
- 此模块仅支持 <b>LSPosed</b>(作用域“系统界面”)、<b>~~EdXposed(随时停止支持)~~</b>、不支持<b>太极、无极</b>
|
- 此模块仅支持 <b>LSPosed</b>(作用域“系统界面”)、<b>~~EdXposed(随时停止支持)~~</b>、不支持<b>太极、无极</b>
|
||||||
|
|
||||||
- 目前仅在 ColorOS 12 for OnePlus 上测试通过,如有问题请提交 `issues`
|
- 目前仅在 ColorOS 12 for OnePlus 上测试通过,如有问题请提交 `issues`
|
||||||
|
|
||||||
- 建议在不低于 ColorOS 11 的版本上使用
|
- 建议在不低于 ColorOS 11 的版本上使用
|
||||||
|
|
||||||
# 请勿用于非法用途
|
## 请勿用于非法用途
|
||||||
|
|
||||||
- 本模块完全开源免费,如果好用你可以打赏支持开发,但是请不要用于非法用途。
|
- 本模块完全开源免费,如果好用你可以打赏支持开发,但是请不要用于非法用途。
|
||||||
|
|
||||||
- 本模块发布地址仅有 [Xposed-Modules-Repo](https://github.com/Xposed-Modules-Repo/com.fankes.coloros.notify/releases)、
|
- 本模块发布地址仅有 [Xposed-Modules-Repo](https://github.com/Xposed-Modules-Repo/com.fankes.coloros.notify/releases)、
|
||||||
[Release](https://github.com/fankes/ColorOSNotifyIcon/releases)
|
[Release](https://github.com/fankes/ColorOSNotifyIcon/releases)
|
||||||
及 [蓝奏云](https://fankes.lanzouy.com/b030rvjyf),从其他非正规渠道下载到的版本或对您造成任何影响均与我们无关。
|
及 [蓝奏云](https://fankes.lanzouy.com/b030rvjyf),从其他非正规渠道下载到的版本或对您造成任何影响均与我们无关。
|
||||||
|
|
||||||
# 贡献通知图标优化名单
|
## 贡献通知图标优化名单
|
||||||
|
|
||||||
此项目是 `AndroidNotifyIconAdapt` 项目的一部分,详情请参考下方。<br/>
|
此项目是 `AndroidNotifyIconAdapt` 项目的一部分,详情请参考下方。
|
||||||
|
|
||||||
- [Android 通知图标规范适配计划](https://github.com/fankes/AndroidNotifyIconAdapt)
|
- [Android 通知图标规范适配计划](https://github.com/fankes/AndroidNotifyIconAdapt)
|
||||||
|
|
||||||
# 历史背景
|
## 历史背景
|
||||||
|
|
||||||
|
继 MIUI 之后的第二大系统 ColorOS 虽然支持原生通知图标,但是第三方推送五颜六色的图标系统并没有做适配,甚至系统自己的图标都是彩色的,极其不友好。
|
||||||
|
|
||||||
继 MIUI 之后的第二大系统 ColorOS 虽然支持原生通知图标,但是第三方推送五颜六色的图标系统并没有做适配,甚至系统自己的图标都是彩色的,极其不友好。<br/>
|
|
||||||
而且从 ColorOS 12 开始,原生图标丢失了着色属性,这也是一种对原生 Android 生态的破坏。
|
而且从 ColorOS 12 开始,原生图标丢失了着色属性,这也是一种对原生 Android 生态的破坏。
|
||||||
|
|
||||||
# 捐赠支持
|
## 捐赠支持
|
||||||
|
|
||||||
- 工作不易,无意外情况此项目将继续维护下去,提供更多可能,欢迎打赏。<br/><br/>
|
- 工作不易,无意外情况此项目将继续维护下去,提供更多可能,欢迎打赏。<br/><br/>
|
||||||
<img src="https://github.com/fankes/YuKiHookAPI/blob/master/img-src/wechat_code.jpg" width = "200" height = "200"/>
|
<img src="https://github.com/fankes/YuKiHookAPI/blob/master/img-src/wechat_code.jpg" width = "200" height = "200"/>
|
||||||
|
|
||||||
# 许可证
|
## 许可证
|
||||||
|
|
||||||
- [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.html)
|
- [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.html)
|
||||||
|
|
||||||
@@ -66,5 +71,6 @@ You should have received a copy of the GNU Affero General Public License
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
```
|
```
|
||||||
|
|
||||||
Powered by [YukiHookAPI](https://github.com/fankes/YukiHookAPI)<br/><br/>
|
Powered by [YukiHookAPI](https://github.com/fankes/YukiHookAPI)
|
||||||
|
|
||||||
版权所有 © 2019-2022 Fankes Studio(qzmmcn@163.com)
|
版权所有 © 2019-2022 Fankes Studio(qzmmcn@163.com)
|
@@ -38,7 +38,7 @@ android {
|
|||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
minifyEnabled true
|
minifyEnabled rootProject.ext.enableR8
|
||||||
signingConfig signingConfigs.debug
|
signingConfig signingConfigs.debug
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
@@ -72,8 +72,8 @@ tasks.whenTaskAdded {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly 'de.robv.android.xposed:api:82'
|
compileOnly 'de.robv.android.xposed:api:82'
|
||||||
implementation 'com.highcapable.yukihookapi:api:1.0.71'
|
implementation 'com.highcapable.yukihookapi:api:1.0.75'
|
||||||
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.0.71'
|
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.0.75'
|
||||||
implementation 'com.github.tiann:FreeReflection:3.1.0'
|
implementation 'com.github.tiann:FreeReflection:3.1.0'
|
||||||
implementation "com.github.topjohnwu.libsu:core:3.1.2"
|
implementation "com.github.topjohnwu.libsu:core:3.1.2"
|
||||||
implementation 'androidx.annotation:annotation:1.3.0'
|
implementation 'androidx.annotation:annotation:1.3.0'
|
||||||
|
@@ -41,7 +41,7 @@ object Const {
|
|||||||
const val MODULE_VERSION_CODE = BuildConfig.VERSION_CODE
|
const val MODULE_VERSION_CODE = BuildConfig.VERSION_CODE
|
||||||
|
|
||||||
/** 当前模块的版本校验 */
|
/** 当前模块的版本校验 */
|
||||||
const val MODULE_VERSION_VERIFY = "${MODULE_VERSION_NAME}_${MODULE_VERSION_CODE}_202204042319"
|
const val MODULE_VERSION_VERIFY = "${MODULE_VERSION_NAME}_${MODULE_VERSION_CODE}_202204140318"
|
||||||
|
|
||||||
/** 当前模块的版本校验标签 */
|
/** 当前模块的版本校验标签 */
|
||||||
const val MODULE_VERSION_VERIFY_TAG = "module_version_verify"
|
const val MODULE_VERSION_VERIFY_TAG = "module_version_verify"
|
||||||
|
@@ -36,7 +36,6 @@ import android.graphics.drawable.Icon
|
|||||||
import android.graphics.drawable.VectorDrawable
|
import android.graphics.drawable.VectorDrawable
|
||||||
import android.service.notification.StatusBarNotification
|
import android.service.notification.StatusBarNotification
|
||||||
import android.util.ArrayMap
|
import android.util.ArrayMap
|
||||||
import android.util.ArraySet
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewOutlineProvider
|
import android.view.ViewOutlineProvider
|
||||||
@@ -56,6 +55,7 @@ import com.fankes.coloros.notify.utils.factory.*
|
|||||||
import com.fankes.coloros.notify.utils.tool.IconAdaptationTool
|
import com.fankes.coloros.notify.utils.tool.IconAdaptationTool
|
||||||
import com.highcapable.yukihookapi.hook.bean.VariousClass
|
import com.highcapable.yukihookapi.hook.bean.VariousClass
|
||||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||||
|
import com.highcapable.yukihookapi.hook.factory.current
|
||||||
import com.highcapable.yukihookapi.hook.factory.field
|
import com.highcapable.yukihookapi.hook.factory.field
|
||||||
import com.highcapable.yukihookapi.hook.factory.method
|
import com.highcapable.yukihookapi.hook.factory.method
|
||||||
import com.highcapable.yukihookapi.hook.log.loggerD
|
import com.highcapable.yukihookapi.hook.log.loggerD
|
||||||
@@ -144,6 +144,12 @@ class SystemUIHooker : YukiBaseHooker() {
|
|||||||
"com.coloros.systemui.common.receiver.AbstractReceiver"
|
"com.coloros.systemui.common.receiver.AbstractReceiver"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/** 根据多个版本存在不同的包名相同的类 */
|
||||||
|
private val StatusBarNotificationPresenterClass = VariousClass(
|
||||||
|
"$SYSTEMUI_PACKAGE_NAME.statusbar.phone.StatusBarNotificationPresenter",
|
||||||
|
"$SYSTEMUI_PACKAGE_NAME.statusbar.phone.StatusBar"
|
||||||
|
)
|
||||||
|
|
||||||
/** 根据多个版本存在不同的包名相同的类 */
|
/** 根据多个版本存在不同的包名相同的类 */
|
||||||
private val ExpandableNotificationRowClass = VariousClass(
|
private val ExpandableNotificationRowClass = VariousClass(
|
||||||
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.row.ExpandableNotificationRow",
|
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.row.ExpandableNotificationRow",
|
||||||
@@ -175,8 +181,8 @@ class SystemUIHooker : YukiBaseHooker() {
|
|||||||
/** 状态栏通知图标数组 */
|
/** 状态栏通知图标数组 */
|
||||||
private var notificationIconInstances = ArrayList<View>()
|
private var notificationIconInstances = ArrayList<View>()
|
||||||
|
|
||||||
/** 缓存的通知小图标包装纸实例 */
|
/** 通知栏通知控制器 */
|
||||||
private var notificationViewWrappers = ArraySet<Any>()
|
private var notificationPresenter: Any? = null
|
||||||
|
|
||||||
/** 仅监听一次主题壁纸颜色变化 */
|
/** 仅监听一次主题壁纸颜色变化 */
|
||||||
private var isWallpaperColorListenerSetUp = false
|
private var isWallpaperColorListenerSetUp = false
|
||||||
@@ -334,8 +340,11 @@ class SystemUIHooker : YukiBaseHooker() {
|
|||||||
|
|
||||||
/** 刷新通知小图标 */
|
/** 刷新通知小图标 */
|
||||||
private fun refreshNotificationIcons() = runInSafe {
|
private fun refreshNotificationIcons() = runInSafe {
|
||||||
NotificationHeaderViewWrapperClass.clazz.method { name = "resolveHeaderViews" }.also { result ->
|
notificationPresenter?.current {
|
||||||
notificationViewWrappers.takeIf { it.isNotEmpty() }?.forEach { result.get(it).call() }
|
method {
|
||||||
|
name = "updateNotificationsOnDensityOrFontScaleChanged"
|
||||||
|
emptyParam()
|
||||||
|
}.call()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -549,7 +558,7 @@ class SystemUIHooker : YukiBaseHooker() {
|
|||||||
}
|
}
|
||||||
beforeHook {
|
beforeHook {
|
||||||
/** 是否移除 */
|
/** 是否移除 */
|
||||||
if (args().int() == 7 && prefs.get(DataConst.REMOVE_CHANGECP_NOTIFY)) resultNull()
|
if (args().first().int() == 7 && prefs.get(DataConst.REMOVE_CHANGECP_NOTIFY)) resultNull()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -573,7 +582,7 @@ class SystemUIHooker : YukiBaseHooker() {
|
|||||||
name = "isGrayscaleOplus"
|
name = "isGrayscaleOplus"
|
||||||
param(ImageViewClass, OplusContrastColorUtilClass)
|
param(ImageViewClass, OplusContrastColorUtilClass)
|
||||||
}
|
}
|
||||||
replaceAny { firstArgs<ImageView>()?.let { isGrayscaleIcon(it.context, it.drawable) } }
|
replaceAny { args().first().cast<ImageView>()?.let { isGrayscaleIcon(it.context, it.drawable) } }
|
||||||
}.ignoredHookingFailure()
|
}.ignoredHookingFailure()
|
||||||
}
|
}
|
||||||
/** 替换状态栏图标 */
|
/** 替换状态栏图标 */
|
||||||
@@ -588,7 +597,7 @@ class SystemUIHooker : YukiBaseHooker() {
|
|||||||
.get(field { name = "iconBuilder" }.get(instance).cast()).cast<Context>()?.also { context ->
|
.get(field { name = "iconBuilder" }.get(instance).cast()).cast<Context>()?.also { context ->
|
||||||
NotificationEntryClass.clazz.method {
|
NotificationEntryClass.clazz.method {
|
||||||
name = "getSbn"
|
name = "getSbn"
|
||||||
}.get(firstArgs).invoke<StatusBarNotification>()?.also { nf ->
|
}.get(args[0]).invoke<StatusBarNotification>()?.also { nf ->
|
||||||
nf.notification.smallIcon.loadDrawable(context).also { iconDrawable ->
|
nf.notification.smallIcon.loadDrawable(context).also { iconDrawable ->
|
||||||
compatStatusIcon(
|
compatStatusIcon(
|
||||||
context = context,
|
context = context,
|
||||||
@@ -620,7 +629,7 @@ class SystemUIHooker : YukiBaseHooker() {
|
|||||||
param(StatusBarNotificationClass)
|
param(StatusBarNotificationClass)
|
||||||
}
|
}
|
||||||
afterHook {
|
afterHook {
|
||||||
if (firstArgs != null) instance<ImageView>().also {
|
if (args[0] != null) instance<ImageView>().also {
|
||||||
/** 注册壁纸颜色监听 */
|
/** 注册壁纸颜色监听 */
|
||||||
registerWallpaperColorChanged(it)
|
registerWallpaperColorChanged(it)
|
||||||
/** 注册广播 */
|
/** 注册广播 */
|
||||||
@@ -629,6 +638,13 @@ class SystemUIHooker : YukiBaseHooker() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/** 注入通知控制器实例 */
|
||||||
|
StatusBarNotificationPresenterClass.hook {
|
||||||
|
injectMember {
|
||||||
|
allConstructors()
|
||||||
|
afterHook { notificationPresenter = instance }
|
||||||
|
}
|
||||||
|
}
|
||||||
/** 注入状态栏通知图标容器实例 */
|
/** 注入状态栏通知图标容器实例 */
|
||||||
OplusNotificationIconAreaControllerClass.hook {
|
OplusNotificationIconAreaControllerClass.hook {
|
||||||
injectMember {
|
injectMember {
|
||||||
@@ -684,11 +700,6 @@ class SystemUIHooker : YukiBaseHooker() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** 记录实例 */
|
|
||||||
injectMember {
|
|
||||||
constructor { param(ContextClass, ViewClass, ExpandableNotificationRowClass) }
|
|
||||||
afterHook { notificationViewWrappers.add(instance) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/** 发送适配新的 APP 图标通知 */
|
/** 发送适配新的 APP 图标通知 */
|
||||||
PluginManagerImplClass.hook {
|
PluginManagerImplClass.hook {
|
||||||
@@ -698,7 +709,7 @@ class SystemUIHooker : YukiBaseHooker() {
|
|||||||
param(ContextClass, IntentClass)
|
param(ContextClass, IntentClass)
|
||||||
}
|
}
|
||||||
afterHook {
|
afterHook {
|
||||||
if (isEnableHookColorNotifyIcon()) (lastArgs as? Intent)?.also {
|
if (isEnableHookColorNotifyIcon()) args().last().cast<Intent>()?.also {
|
||||||
if (it.action.equals(Intent.ACTION_PACKAGE_REPLACED).not() &&
|
if (it.action.equals(Intent.ACTION_PACKAGE_REPLACED).not() &&
|
||||||
it.getBooleanExtra(Intent.EXTRA_REPLACING, false)
|
it.getBooleanExtra(Intent.EXTRA_REPLACING, false)
|
||||||
) return@also
|
) return@also
|
||||||
@@ -708,11 +719,11 @@ class SystemUIHooker : YukiBaseHooker() {
|
|||||||
if (iconDatas.takeIf { e -> e.isNotEmpty() }
|
if (iconDatas.takeIf { e -> e.isNotEmpty() }
|
||||||
?.filter { e -> e.packageName == newPkgName }
|
?.filter { e -> e.packageName == newPkgName }
|
||||||
.isNullOrEmpty()
|
.isNullOrEmpty()
|
||||||
) IconAdaptationTool.pushNewAppSupportNotify(firstArgs()!!, newPkgName)
|
) IconAdaptationTool.pushNewAppSupportNotify(args().first().cast()!!, newPkgName)
|
||||||
}
|
}
|
||||||
Intent.ACTION_PACKAGE_REMOVED ->
|
Intent.ACTION_PACKAGE_REMOVED ->
|
||||||
IconAdaptationTool.removeNewAppSupportNotify(
|
IconAdaptationTool.removeNewAppSupportNotify(
|
||||||
context = firstArgs()!!,
|
context = args().first().cast()!!,
|
||||||
packageName = it.data?.schemeSpecificPart ?: ""
|
packageName = it.data?.schemeSpecificPart ?: ""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -728,7 +739,7 @@ class SystemUIHooker : YukiBaseHooker() {
|
|||||||
param(ContextClass, IntentClass)
|
param(ContextClass, IntentClass)
|
||||||
}
|
}
|
||||||
afterHook {
|
afterHook {
|
||||||
firstArgs<Context>()?.also {
|
args().first().cast<Context>()?.also {
|
||||||
/** 注册广播 */
|
/** 注册广播 */
|
||||||
registerReceiver(it)
|
registerReceiver(it)
|
||||||
/** 注册定时监听 */
|
/** 注册定时监听 */
|
||||||
|
@@ -33,6 +33,7 @@ import android.content.ClipData
|
|||||||
import android.content.ClipboardManager
|
import android.content.ClipboardManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.pm.ApplicationInfo
|
||||||
import android.content.pm.PackageInfo
|
import android.content.pm.PackageInfo
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
@@ -193,6 +194,14 @@ fun Context.findAppName(name: String) =
|
|||||||
fun Context.findAppIcon(name: String) =
|
fun Context.findAppIcon(name: String) =
|
||||||
safeOfNull { packageManager?.getPackageInfo(name, 0)?.applicationInfo?.loadIcon(packageManager) }
|
safeOfNull { packageManager?.getPackageInfo(name, 0)?.applicationInfo?.loadIcon(packageManager) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 APP 是否为 DEBUG 版本
|
||||||
|
* @param name APP 包名
|
||||||
|
* @return [Boolean]
|
||||||
|
*/
|
||||||
|
fun Context.isAppDebuggable(name: String) =
|
||||||
|
safeOfFalse { (packageManager?.getPackageInfo(name, 0)?.applicationInfo?.flags?.and(ApplicationInfo.FLAG_DEBUGGABLE) ?: 0) != 0 }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对数值自动补零
|
* 对数值自动补零
|
||||||
* @return [String]
|
* @return [String]
|
||||||
@@ -320,12 +329,19 @@ fun findPropString(key: String, default: String = "") = safeOf(default) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行命令 - su
|
* 是否有 Root 权限
|
||||||
|
* @return [Boolean]
|
||||||
|
*/
|
||||||
|
val isRootAccess get() = safeOfFalse { Shell.rootAccess() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行命令
|
||||||
* @param cmd 命令
|
* @param cmd 命令
|
||||||
|
* @param isSu 是否使用 Root 权限执行 - 默认:是
|
||||||
* @return [String] 执行结果
|
* @return [String] 执行结果
|
||||||
*/
|
*/
|
||||||
fun execShellSu(cmd: String) = safeOfNothing {
|
fun execShell(cmd: String, isSu: Boolean = true) = safeOfNothing {
|
||||||
Shell.su(cmd).exec().out.let {
|
(if (isSu) Shell.su(cmd) else Shell.sh(cmd)).exec().out.let {
|
||||||
if (it.isNotEmpty()) it[0].trim() else ""
|
if (it.isNotEmpty()) it[0].trim() else ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -116,6 +116,7 @@ object IconAdaptationTool {
|
|||||||
* @param packageName 安装的 APP 包名
|
* @param packageName 安装的 APP 包名
|
||||||
*/
|
*/
|
||||||
fun pushNewAppSupportNotify(context: Context, packageName: String) {
|
fun pushNewAppSupportNotify(context: Context, packageName: String) {
|
||||||
|
if (context.isAppDebuggable(packageName)) return
|
||||||
context.getSystemService(NotificationManager::class.java)?.apply {
|
context.getSystemService(NotificationManager::class.java)?.apply {
|
||||||
createNotificationChannel(
|
createNotificationChannel(
|
||||||
NotificationChannel(
|
NotificationChannel(
|
||||||
|
@@ -86,9 +86,9 @@ object SystemUITool {
|
|||||||
msg = "你确定要立即重启系统界面吗?\n\n" +
|
msg = "你确定要立即重启系统界面吗?\n\n" +
|
||||||
"重启过程会黑屏并等待进入锁屏重新解锁。"
|
"重启过程会黑屏并等待进入锁屏重新解锁。"
|
||||||
confirmButton {
|
confirmButton {
|
||||||
execShellSu(cmd = "pgrep systemui").also { pid ->
|
execShell(cmd = "pgrep systemui").also { pid ->
|
||||||
if (pid.isNotBlank())
|
if (pid.isNotBlank())
|
||||||
execShellSu(cmd = "kill -9 $pid")
|
execShell(cmd = "kill -9 $pid")
|
||||||
else toast(msg = "ROOT 权限获取失败")
|
else toast(msg = "ROOT 权限获取失败")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,12 +1,13 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application' version '7.1.2' apply false
|
id 'com.android.application' version '7.1.3' apply false
|
||||||
id 'com.android.library' version '7.1.2' apply false
|
id 'com.android.library' version '7.1.3' apply false
|
||||||
id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
|
id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
appVersionName = "1.53"
|
appVersionName = "1.6"
|
||||||
appVersionCode = 10
|
appVersionCode = 11
|
||||||
|
enableR8 = true
|
||||||
}
|
}
|
||||||
|
|
||||||
task clean(type: Delete) {
|
task clean(type: Delete) {
|
||||||
|
Reference in New Issue
Block a user