mirror of
https://github.com/fankes/MIUINativeNotifyIcon.git
synced 2025-09-07 03:05:51 +08:00
Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
b82e6d8bff | |||
d117a9a6e9 | |||
850a382025 | |||
5623f5f261 | |||
c706ee377a | |||
547d90c01f | |||
f0391b1875 | |||
7faa4ede7d | |||
c865b39c97 | |||
b8b23c3398 | |||
bdd53eba88 | |||
83a15171e2 | |||
|
12485db355 | ||
1d0b97e8a3 | |||
18ce5f66c5 | |||
8725dabe85 | |||
44e68ceca1 |
4
.idea/misc.xml
generated
4
.idea/misc.xml
generated
@@ -9,8 +9,10 @@
|
||||
<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/layout/activity_login.xml" value="0.4375" />
|
||||
<entry key="app/src/main/res/layout/activity_main.xml" value="0.37516748548459133" />
|
||||
<entry key="app/src/main/res/layout/adapter_config.xml" value="0.4375" />
|
||||
<entry key="app/src/main/res/layout/dia_icon_search.xml" value="0.4307692307692308" />
|
||||
<entry key="app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml" value="0.44871794871794873" />
|
||||
</map>
|
||||
</option>
|
||||
|
87
README.md
87
README.md
@@ -1,8 +1,8 @@
|
||||
# MIUI 原生通知图标
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
<br/><br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/app/src/main/ic_launcher-playstore.png" width = "100" height = "100"/>
|
||||
<br/>
|
||||
@@ -12,7 +12,7 @@ Fix the native notification bar icon function abandoned by the MIUI development
|
||||
# 开始使用
|
||||
|
||||
点击下载最新版本
|
||||
<a href='https://github.com/fankes/MIUINativeNotifyIcon/releases'></a>
|
||||
<a href='https://github.com/fankes/MIUINativeNotifyIcon/releases'></a>
|
||||
<br/><br/>
|
||||
⚠️ 适配说明<br/>
|
||||
|
||||
@@ -20,9 +20,12 @@ Fix the native notification bar icon function abandoned by the MIUI development
|
||||
- 目前最低支持基于 Android 9 版本的 MIUI 12 或 MIUI 12.5(最低建议)
|
||||
- 请始终保持最新版本的 LSPosed,旧版本可能会出现 Hook 不生效的问题
|
||||
|
||||
# 禁止任何商业用途
|
||||
# 请勿用于非法用途
|
||||
|
||||
本模块完全开源免费,如果好用你可以打赏支持开发,严禁未经许可进行二改贩卖,违者必惩必究。
|
||||
- 本模块完全开源免费,如果好用你可以打赏支持开发,但是请不要用于非法用途。
|
||||
- 本模块发布地址仅有 [Xposed-Modules-Repo](https://github.com/Xposed-Modules-Repo/com.fankes.miui.notify/releases)、
|
||||
[Release](https://github.com/fankes/MIUINativeNotifyIcon/releases)
|
||||
及[蓝奏云](https://fankes.lanzouy.com/b030o2e8h),从其他非正规渠道下载到的版本或对您造成任何影响均与我们无关。
|
||||
|
||||
# 开始贡献
|
||||
|
||||
@@ -33,62 +36,72 @@ Fix the native notification bar icon function abandoned by the MIUI development
|
||||
|
||||
# 历史背景
|
||||
|
||||
这个模块诞生来源于 MIUI 的乱改和不规范,本来 MIUI 9 之后,官方给出了原生通知图标样式,后面由于用户反应通知栏经常出现黑白块。 这当然不是系统的错,而是国内 APP 极其不规范的通知图标设计,于是 MIUI
|
||||
选择直接忽略这个问题把全部图标都改成了 APP 的彩色图标, 使得之前拥有自有样式的原生图标也被破坏,通知中“setSmallIcon”不再有效,这个模块就是为了修复被 MIUI 开发组忽略的图标问题, 并完美地给 MIUI 修复了黑白块图标的问题。
|
||||
这个模块诞生来源于 MIUI 的乱改和不规范,本来 MIUI 9 之后,官方给出了原生通知图标样式,后面由于用户反应通知栏经常出现黑白块。<br/><br/>
|
||||
这当然不是系统的错,而是国内 APP 和 `MIPUSH` 的通知极其不规范的通知图标设计。<br/><br/>
|
||||
但是呢,接到反馈后 MIUI 开发组选择直接忽略这个问题,在 `2021-5-18` 的开发版开始,把全部通知图标都改成了 APP 的彩色图标,使得之前拥有自有样式的原生图标也被破坏。<br/><br/>
|
||||
对于 Android 开发者来说,官方文档中的 `setSmallIcon` 不再适用于魔改后的 MIUI,这将会严重破坏非常多的状态图标。<br/><br/>
|
||||
当然,国内的手机生态除了 `MIPUSH` 的营销通知就是社交软件的通知,可能大部分人都不会在意这件事情。<br/><br/>
|
||||
但是,这个模块就是为了修复被 MIUI 开发组忽略的图标问题才诞生的,并完美地给 MIUI 修复了黑白块图标的问题。
|
||||
<br/>
|
||||
|
||||
# 探索历程
|
||||
|
||||
- 原生 Android 的小图标和通知图标具有状态性<br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/native.jpg" height = "35"/><br/>
|
||||
- 而 MIUI 最近的版本直接破坏了这一状态性,全部设置为 APP 的图标,不仅难看而且你无法下拉通知栏区别这些图标代表什么<br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/miui.jpg" height = "40"/><br/>
|
||||
- 同样地,通知面板的图标同样遵守这一状态性<br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/native_n_1.jpg" height = "100"/><br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/native_n_2.jpg" height = "100"/><br/>
|
||||
- 而 MIUI 做了什么呢<br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/miui_n_1.jpg" height = "100"/><br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/miui_n_2.jpg" height = "100"/><br/>
|
||||
- 不曾记得是什么版本开始,MIUI 把通知图标改成了这个鬼样子,寻找开发组提案也是无人问津,最后转念一想,自己干吧。
|
||||
- 由于目前大量通知图标都来自 MIPUSH 发出的营销通知,而 MIPUSH 的图标都是统一的彩色应用图标,很多应用也没有适配这一特性, 在通知栏广告满天飞的情况下,MIUI
|
||||
选择放弃原生通知功能,而做出这种违反原生通知规则的做法,而这些彩色图标被设置为单色调图标,也确实会发生黑白块的问题,但是同时又会破坏遵守规范的图标。
|
||||
- 真的没有办法了吗?在不断探索下,我找到了原生支持色彩判断的类
|
||||
原生 Android 的小图标和通知图标具有状态性。<br/><br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/native.jpg" height = "35"/><br/><br/>
|
||||
而 MIUI 最近的版本直接破坏了这一状态性,全部设置为 APP 的图标,不仅难看而且你无法下拉通知栏区别这些图标代表什么。<br/><br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/miui.jpg" height = "40"/><br/><br/>
|
||||
同样地,通知面板的图标同样遵守这一状态性。<br/><br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/native_n_1.jpg" height = "100"/><br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/native_n_2.jpg" height = "100"/><br/><br/>
|
||||
而 MIUI 做了什么呢?<br/><br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/miui_n_1.jpg" height = "100"/><br/>
|
||||
<img src="https://github.com/fankes/MIUINativeNotifyIcon/blob/master/images/miui_n_2.jpg" height = "100"/><br/><br/>
|
||||
不曾记得是什么版本开始,MIUI 把通知图标改成了这个鬼样子,寻找开发组提案也是无人问津,最后转念一想,自己干吧。<br/><br/>
|
||||
由于目前大量通知图标都来自 `MIPUSH` 发出的营销通知,而 `MIPUSH` 的图标都是统一的彩色应用图标,很多应用也没有适配这一特性, 在通知栏广告满天飞的情况下,MIUI
|
||||
选择放弃原生通知功能,而做出这种违反原生通知规则的做法,而这些彩色图标被设置为单色调图标,也确实会发生黑白块的问题,但是同时又会破坏遵守规范的图标。<br/><br/>
|
||||
真的没有办法了吗?在不断探索下,我找到了原生支持色彩判断的类。
|
||||
|
||||
```
|
||||
com.android.internal.util.ContrastColorUtil
|
||||
```
|
||||
|
||||
- 这个类中有一个方法可以拿出来判断图标的灰度效果
|
||||
这个类中有一个方法可以拿出来判断图标的灰度效果。
|
||||
|
||||
```
|
||||
ContrastColorUtil.getInstance().isGrayscaleIcon(drawable);
|
||||
ContrastColorUtil.getInstance().isGrayscaleIcon(drawable)
|
||||
```
|
||||
|
||||
- 问题就被解决了,顺便修了一下被 MIUI 破坏的通知图标以及优化了一下应用本身方块图标的圆角...
|
||||
- 最后,我想大声问一句 MIUI 开发组:“就这?” 就这么简单的问题为什么拖了这么长时间也没有结论,还要交给用户去修复,这真的是一种负责任的表现吗?
|
||||
- 后来一想,也是啊,被国内生态毒害的用户,怎么可能会去想到这些问题呢,最后只能是我自作多情,还对 MIUI 留有一点情怀吧。
|
||||
- ——来自一个无可奈何的 MIUI 老用户
|
||||
问题就被解决了,顺便修了一下被 MIUI 破坏的通知图标以及优化了一下应用本身方块图标的圆角......<br/><br/>
|
||||
最后,我想大声问一句 MIUI 开发组:“就这?” 就这么简单的问题为什么拖了这么长时间也没有结论,还要交给用户去修复,这真的是一种负责任的表现吗?<br/><br/>
|
||||
后来一想,也是啊,被国内生态毒害的用户,怎么可能会去想到这些问题呢,最后只能是我自作多情,还对 MIUI 留有一点情怀吧。<br/><br/>
|
||||
——来自一个无可奈何的 MIUI 老用户
|
||||
|
||||
# 后记
|
||||
|
||||
- 近期重新适配了 MIUI 12、12.5、13 版本,每个版本的图标设置方法都不一样,而且改的乱七八糟的,我都要无语了,只能用了很多折中方案,毕竟我也没有那么大精力每个版本去修复,实在是累了
|
||||
- 特地的把自己能有的小米手机刷成各种 MIUI 版本去为酷友做专项适配,我也是很累了,也希望你们能够多多支持,也能让 MIUI 做得更好
|
||||
- MIUI 再不重写,怕是永远会变成安卓之光。雷军,金凡!!
|
||||
近期重新适配了 MIUI 12、12.5、13 版本,每个版本的图标设置方法都不一样,而且改的乱七八糟的,我都要无语了,只能用了很多折中方案,毕竟我也没有那么大精力每个版本去修复,实在是累了。<br/><br/>
|
||||
特地的把自己能有的小米手机刷成各种 MIUI 版本去为酷友做专项适配,我也是很累了,也希望你们能够多多支持,也能让 MIUI 做得更好。<br/><br/>
|
||||
MIUI 再不重写,怕是永远会变成安卓之光。雷军,金凡!!
|
||||
|
||||
# 许可证
|
||||
|
||||
- [GPL-3.0](https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
- [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.html)
|
||||
|
||||
```
|
||||
Copyright (C) 2020-2022 Fankes Studio(qzmmcn@163.com)
|
||||
Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com)
|
||||
|
||||
This program 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.
|
||||
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 (at your option) any later version.
|
||||
|
||||
This program 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.
|
||||
```
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
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/>.
|
||||
```
|
||||
|
||||
Powered by [YukiHookAPI](https://github.com/fankes/YukiHookAPI)<br/><br/>
|
||||
版权所有 © 2019-2022 Fankes Studio(qzmmcn@163.com)
|
||||
|
@@ -1,6 +1,7 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'kotlin-android'
|
||||
id 'com.google.devtools.ksp' version '1.6.10-1.0.2'
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -19,10 +20,10 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.fankes.miui.notify"
|
||||
minSdk 26
|
||||
targetSdk 26
|
||||
versionCode 8
|
||||
versionName "1.36"
|
||||
minSdk 28
|
||||
targetSdk 31
|
||||
versionCode rootProject.ext.appVersionCode
|
||||
versionName rootProject.ext.appVersionName
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
@@ -41,23 +42,37 @@ android {
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
}
|
||||
|
||||
/** 移除无效耗时 lint Task */
|
||||
tasks.whenTaskAdded {
|
||||
task -> if (task.name == "lintVitalRelease") task.enabled = false
|
||||
}
|
||||
tasks.whenTaskAdded {
|
||||
task -> if (task.name == "lintVitalAnalyzeRelease") task.enabled = false
|
||||
}
|
||||
tasks.whenTaskAdded {
|
||||
task -> if (task.name == "lintVitalReportRelease") task.enabled = false
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly 'de.robv.android.xposed:api:82'
|
||||
implementation "com.github.topjohnwu.libsu:core:3.1.2"
|
||||
// 基础依赖包
|
||||
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
|
||||
// Fragment 快速实现
|
||||
implementation 'com.gyf.immersionbar:immersionbar-components:3.0.0'
|
||||
// Kotlin 扩展
|
||||
implementation 'com.gyf.immersionbar:immersionbar-ktx:3.0.0'
|
||||
implementation 'androidx.annotation:annotation:1.3.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
|
||||
compileOnly 'de.robv.android.xposed:api:82'
|
||||
implementation 'com.highcapable.yukihookapi:api:1.0.1'
|
||||
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.0.1'
|
||||
implementation 'com.geyifeng.immersionbar:immersionbar:3.2.0'
|
||||
implementation 'com.geyifeng.immersionbar:immersionbar-ktx:3.2.0'
|
||||
implementation 'androidx.core:core-ktx:1.7.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||
implementation 'com.google.android.material:material:1.5.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
||||
//noinspection GradleDynamicVersion
|
||||
testImplementation 'junit:junit:4.+'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
}
|
@@ -13,49 +13,45 @@
|
||||
android:theme="@style/Theme.MIUINativeNotifyIcon"
|
||||
tools:ignore="AllowBackup">
|
||||
|
||||
<!-- 是否是xposed模块 -->
|
||||
<meta-data
|
||||
android:name="xposedmodule"
|
||||
android:value="true" />
|
||||
|
||||
<!-- 模块描述 -->
|
||||
<meta-data
|
||||
android:name="xposeddescription"
|
||||
android:value="MIUI 状态栏原生图标,修复 12.5、13 后期被破坏的彩色图标。\n开发者:酷安 @星夜不荟" />
|
||||
|
||||
<!-- 最低xposed版本号 -->
|
||||
<meta-data
|
||||
android:name="xposedminversion"
|
||||
android:value="82" />
|
||||
android:value="93" />
|
||||
|
||||
<activity
|
||||
android:name="com.fankes.miui.notify.ui.MainActivity"
|
||||
android:name=".ui.MainActivity"
|
||||
android:exported="true"
|
||||
android:screenOrientation="behind">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="de.robv.android.xposed.category.MODULE_SETTINGS" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity-alias
|
||||
android:name="com.fankes.miui.notify.Home"
|
||||
android:name=".Home"
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:screenOrientation="behind"
|
||||
android:targetActivity="com.fankes.miui.notify.ui.MainActivity">
|
||||
|
||||
android:targetActivity=".ui.MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity-alias>
|
||||
|
||||
<activity
|
||||
android:name="com.fankes.miui.notify.ui.ConfigureActivity"
|
||||
android:name=".ui.ConfigureActivity"
|
||||
android:exported="false"
|
||||
android:screenOrientation="behind" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
@@ -1 +1 @@
|
||||
com.fankes.miui.notify.hook.HookMain
|
||||
com.fankes.miui.notify.hook.HookEntry_YukiHookXposedInit
|
1
app/src/main/assets/yukihookapi_init
Normal file
1
app/src/main/assets/yukihookapi_init
Normal file
@@ -0,0 +1 @@
|
||||
com.fankes.miui.notify.hook.HookEntry
|
@@ -1,22 +1,24 @@
|
||||
/**
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
/*
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/01/24.
|
||||
* This file is Created by fankes on 2022/1/24.
|
||||
*/
|
||||
@file:Suppress("unused")
|
||||
|
||||
|
@@ -1,20 +1,22 @@
|
||||
/**
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
/*
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/30.
|
||||
*/
|
||||
|
@@ -0,0 +1,24 @@
|
||||
package com.fankes.miui.notify.data
|
||||
|
||||
import com.fankes.miui.notify.data.model.LoggedInUser
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* Class that handles authentication w/ login credentials and retrieves user information.
|
||||
*/
|
||||
class LoginDataSource {
|
||||
|
||||
fun login(username: String, password: String): Result<LoggedInUser> {
|
||||
try {
|
||||
// TODO: handle loggedInUser authentication
|
||||
val fakeUser = LoggedInUser(java.util.UUID.randomUUID().toString(), "Jane Doe")
|
||||
return Result.Success(fakeUser)
|
||||
} catch (e: Throwable) {
|
||||
return Result.Error(IOException("Error logging in", e))
|
||||
}
|
||||
}
|
||||
|
||||
fun logout() {
|
||||
// TODO: revoke authentication
|
||||
}
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
package com.fankes.miui.notify.data
|
||||
|
||||
import com.fankes.miui.notify.data.model.LoggedInUser
|
||||
|
||||
/**
|
||||
* Class that requests authentication and user information from the remote data source and
|
||||
* maintains an in-memory cache of login status and user credentials information.
|
||||
*/
|
||||
|
||||
class LoginRepository(val dataSource: LoginDataSource) {
|
||||
|
||||
// in-memory cache of the loggedInUser object
|
||||
var user: LoggedInUser? = null
|
||||
private set
|
||||
|
||||
val isLoggedIn: Boolean
|
||||
get() = user != null
|
||||
|
||||
init {
|
||||
// If user credentials will be cached in local storage, it is recommended it be encrypted
|
||||
// @see https://developer.android.com/training/articles/keystore
|
||||
user = null
|
||||
}
|
||||
|
||||
fun logout() {
|
||||
user = null
|
||||
dataSource.logout()
|
||||
}
|
||||
|
||||
fun login(username: String, password: String): Result<LoggedInUser> {
|
||||
// handle login
|
||||
val result = dataSource.login(username, password)
|
||||
|
||||
if (result is Result.Success) {
|
||||
setLoggedInUser(result.data)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun setLoggedInUser(loggedInUser: LoggedInUser) {
|
||||
this.user = loggedInUser
|
||||
// If user credentials will be cached in local storage, it is recommended it be encrypted
|
||||
// @see https://developer.android.com/training/articles/keystore
|
||||
}
|
||||
}
|
18
app/src/main/java/com/fankes/miui/notify/data/Result.kt
Normal file
18
app/src/main/java/com/fankes/miui/notify/data/Result.kt
Normal file
@@ -0,0 +1,18 @@
|
||||
package com.fankes.miui.notify.data
|
||||
|
||||
/**
|
||||
* A generic class that holds a value with its loading status.
|
||||
* @param <T>
|
||||
*/
|
||||
sealed class Result<out T : Any> {
|
||||
|
||||
data class Success<out T : Any>(val data: T) : Result<T>()
|
||||
data class Error(val exception: Exception) : Result<Nothing>()
|
||||
|
||||
override fun toString(): String {
|
||||
return when (this) {
|
||||
is Success<*> -> "Success[data=$data]"
|
||||
is Error -> "Error[exception=$exception]"
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
package com.fankes.miui.notify.data.model
|
||||
|
||||
/**
|
||||
* Data class that captures user information for logged in users retrieved from LoginRepository
|
||||
*/
|
||||
data class LoggedInUser(
|
||||
val userId: String,
|
||||
val displayName: String
|
||||
)
|
36
app/src/main/java/com/fankes/miui/notify/hook/HookConst.kt
Normal file
36
app/src/main/java/com/fankes/miui/notify/hook/HookConst.kt
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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/1/24.
|
||||
*/
|
||||
@file:Suppress("DEPRECATION", "SetWorldReadable")
|
||||
|
||||
package com.fankes.miui.notify.hook
|
||||
|
||||
object HookConst {
|
||||
|
||||
const val ENABLE_MODULE = "_enable_module"
|
||||
const val ENABLE_MODULE_LOG = "_enable_module_log"
|
||||
const val ENABLE_HIDE_ICON = "_hide_icon"
|
||||
const val ENABLE_COLOR_ICON_HOOK = "_color_icon_hook"
|
||||
const val ENABLE_NOTIFY_ICON_HOOK = "_notify_icon_hook"
|
||||
|
||||
const val SYSTEMUI_PACKAGE_NAME = "com.android.systemui"
|
||||
}
|
491
app/src/main/java/com/fankes/miui/notify/hook/HookEntry.kt
Normal file
491
app/src/main/java/com/fankes/miui/notify/hook/HookEntry.kt
Normal file
@@ -0,0 +1,491 @@
|
||||
/*
|
||||
* 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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/2/15.
|
||||
*/
|
||||
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
|
||||
import android.graphics.drawable.Icon
|
||||
import android.service.notification.StatusBarNotification
|
||||
import android.view.View
|
||||
import android.view.ViewOutlineProvider
|
||||
import android.widget.ImageView
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import com.fankes.miui.notify.hook.HookConst.ENABLE_COLOR_ICON_HOOK
|
||||
import com.fankes.miui.notify.hook.HookConst.ENABLE_MODULE
|
||||
import com.fankes.miui.notify.hook.HookConst.ENABLE_MODULE_LOG
|
||||
import com.fankes.miui.notify.hook.HookConst.ENABLE_NOTIFY_ICON_HOOK
|
||||
import com.fankes.miui.notify.hook.HookConst.SYSTEMUI_PACKAGE_NAME
|
||||
import com.fankes.miui.notify.hook.factory.isAppNotifyHookAllOf
|
||||
import com.fankes.miui.notify.hook.factory.isAppNotifyHookOf
|
||||
import com.fankes.miui.notify.params.IconPackParams
|
||||
import com.fankes.miui.notify.utils.*
|
||||
import com.highcapable.yukihookapi.annotation.xposed.InjectYukiHookWithXposed
|
||||
import com.highcapable.yukihookapi.hook.bean.VariousClass
|
||||
import com.highcapable.yukihookapi.hook.factory.*
|
||||
import com.highcapable.yukihookapi.hook.log.loggerW
|
||||
import com.highcapable.yukihookapi.hook.param.PackageParam
|
||||
import com.highcapable.yukihookapi.hook.type.android.ContextClass
|
||||
import com.highcapable.yukihookapi.hook.type.android.DrawableClass
|
||||
import com.highcapable.yukihookapi.hook.type.android.ImageViewClass
|
||||
import com.highcapable.yukihookapi.hook.type.java.IntType
|
||||
import com.highcapable.yukihookapi.hook.xposed.proxy.YukiHookXposedInitProxy
|
||||
|
||||
@InjectYukiHookWithXposed
|
||||
class HookEntry : YukiHookXposedInitProxy {
|
||||
|
||||
companion object {
|
||||
|
||||
/** MIUI 新版本存在的类 */
|
||||
private const val SystemUIApplicationClass = "$SYSTEMUI_PACKAGE_NAME.SystemUIApplication"
|
||||
|
||||
/** MIUI 新版本存在的类 */
|
||||
private const val NotificationHeaderViewWrapperInjectorClass =
|
||||
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.row.wrapper.NotificationHeaderViewWrapperInjector"
|
||||
|
||||
/** MIUI 新版本存在的类 */
|
||||
private const val NotificationHeaderViewWrapperClass =
|
||||
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.NotificationHeaderViewWrapper"
|
||||
|
||||
/** MIUI 新版本存在的类 */
|
||||
private const val NotificationViewWrapperClass =
|
||||
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.NotificationViewWrapper"
|
||||
|
||||
/** 原生存在的类 */
|
||||
private const val StatusBarIconViewClass = "$SYSTEMUI_PACKAGE_NAME.statusbar.StatusBarIconView"
|
||||
|
||||
/** 原生存在的类 */
|
||||
private const val ContrastColorUtilClass = "com.android.internal.util.ContrastColorUtil"
|
||||
|
||||
/** 未确定是否只有旧版本存在的类 */
|
||||
private const val ExpandableNotificationRowClass = "$SYSTEMUI_PACKAGE_NAME.statusbar.ExpandableNotificationRow"
|
||||
|
||||
/** 根据多个版本存在不同的包名相同的类 */
|
||||
private val NotificationUtilClass = VariousClass(
|
||||
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.NotificationUtil",
|
||||
"$SYSTEMUI_PACKAGE_NAME.miui.statusbar.notification.NotificationUtil"
|
||||
)
|
||||
|
||||
/** 根据多个版本存在不同的包名相同的类 */
|
||||
private val ExpandedNotificationClass = VariousClass(
|
||||
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.ExpandedNotification",
|
||||
"$SYSTEMUI_PACKAGE_NAME.miui.statusbar.ExpandedNotification"
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* - 这个是修复彩色图标的关键核心代码判断
|
||||
*
|
||||
* 判断是否为灰度图标 - 反射执行系统方法
|
||||
* @param context 实例
|
||||
* @param drawable 要判断的图标
|
||||
* @return [Boolean]
|
||||
*/
|
||||
private fun PackageParam.isGrayscaleIcon(context: Context, drawable: Drawable) = safeOfFalse {
|
||||
ContrastColorUtilClass.clazz.let {
|
||||
it.method(name = "isGrayscaleIcon", DrawableClass)
|
||||
?.call<Boolean>(it.method(name = "getInstance", ContextClass)?.callStatic(context), drawable) ?: false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前通知栏的样式
|
||||
* @return [Boolean]
|
||||
*/
|
||||
private fun PackageParam.isShowMiuiStyle() = safeOfFalse {
|
||||
NotificationUtilClass.clazz.method(name = "showMiuiStyle")?.callStatic() ?: false
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为新版本 MIUI 方案
|
||||
*
|
||||
* 拥有状态栏图标颜色检查功能
|
||||
* @return [Boolean]
|
||||
*/
|
||||
private fun PackageParam.hasIgnoreStatusBarIconColor() = safeOfFalse {
|
||||
NotificationUtilClass.clazz.hasMethod(name = "ignoreStatusBarIconColor", ExpandedNotificationClass.clazz)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 [ExpandedNotificationClass] 的应用名称
|
||||
* @param instance 通知实例
|
||||
* @return [String]
|
||||
*/
|
||||
private fun PackageParam.findAppName(instance: Any?) = safeOf(default = "<unknown>") {
|
||||
ExpandedNotificationClass.clazz.method(name = "getAppName")?.call(instance) ?: "<empty>"
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断通知是否来自 MIPUSH
|
||||
* @return [Boolean]
|
||||
*/
|
||||
private val StatusBarNotification.isXmsf get() = opPkgName == "com.xiaomi.xmsf"
|
||||
|
||||
/**
|
||||
* 获取全局上下文
|
||||
* @return [Context] or null
|
||||
*/
|
||||
private val PackageParam.globalContext
|
||||
get() = safeOfNull {
|
||||
SystemUIApplicationClass.clazz.method(name = "getContext")?.callStatic<Context>()
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook 状态栏小图标
|
||||
*
|
||||
* 区分系统版本 - 由于每个系统版本的方法不一样这里单独拿出来进行 Hook
|
||||
* @param context 实例
|
||||
* @param expandedNf 通知实例
|
||||
* @param iconDrawable 小图标 [Drawable]
|
||||
* @param it 回调小图标 - ([Bitmap] 小图标)
|
||||
*/
|
||||
private fun PackageParam.hookSmallIconOnSet(
|
||||
context: Context,
|
||||
expandedNf: StatusBarNotification?,
|
||||
iconDrawable: Drawable?,
|
||||
it: (Bitmap) -> Unit
|
||||
) = safeRun(msg = "GetSmallIconOnSet") {
|
||||
if (iconDrawable == null) return@safeRun
|
||||
/** 判断是否不是灰度图标 */
|
||||
val isNotGrayscaleIcon = !isGrayscaleIcon(context, iconDrawable)
|
||||
/** 获取通知对象 - 由于 MIUI 的版本迭代不规范性可能是空的 */
|
||||
expandedNf?.also { notifyInstance ->
|
||||
/** 目标彩色通知 APP 图标 */
|
||||
var customIcon: Bitmap? = null
|
||||
if (prefs.getBoolean(ENABLE_COLOR_ICON_HOOK, default = true))
|
||||
run {
|
||||
IconPackParams.iconDatas.forEach {
|
||||
if ((notifyInstance.opPkgName == it.packageName ||
|
||||
findAppName(notifyInstance) == it.appName) &&
|
||||
isAppNotifyHookOf(it)
|
||||
) {
|
||||
if (isNotGrayscaleIcon || isAppNotifyHookAllOf(it))
|
||||
customIcon = it.iconBitmap
|
||||
return@run
|
||||
}
|
||||
}
|
||||
}
|
||||
when {
|
||||
/** 如果开启了修复 APP 的彩色图标 */
|
||||
customIcon != null && prefs.getBoolean(ENABLE_NOTIFY_ICON_HOOK, default = true) -> it(customIcon!!)
|
||||
/** 若不是灰度图标自动处理为圆角 */
|
||||
isNotGrayscaleIcon -> it(iconDrawable.toBitmap().round(15.dp(context)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook 通知栏小图标
|
||||
*
|
||||
* 区分系统版本 - 由于每个系统版本的方法不一样这里单独拿出来进行 Hook
|
||||
* @param context 实例
|
||||
* @param expandedNf 通知实例
|
||||
* @param iconImageView 通知图标实例
|
||||
*/
|
||||
private fun PackageParam.hookNotifyIconOnSet(context: Context, expandedNf: StatusBarNotification?, iconImageView: ImageView) =
|
||||
safeRun(msg = "AutoSetAppIconOnSet") {
|
||||
/** 获取通知对象 - 由于 MIUI 的版本迭代不规范性可能是空的 */
|
||||
expandedNf?.let { notifyInstance ->
|
||||
/** 是否 Hook 彩色通知图标 */
|
||||
val isHookColorIcon = prefs.getBoolean(ENABLE_COLOR_ICON_HOOK, default = true)
|
||||
|
||||
/** 新版风格反色 */
|
||||
val newStyle = if (context.isSystemInDarkMode) 0xFF2D2D2D.toInt() else Color.WHITE
|
||||
|
||||
/** 旧版风格反色 */
|
||||
val oldStyle = if (context.isNotSystemInDarkMode) 0xFF707070.toInt() else Color.WHITE
|
||||
|
||||
/** 获取通知小图标 */
|
||||
val iconDrawable = notifyInstance.notification.smallIcon.loadDrawable(context)
|
||||
|
||||
/** 判断图标风格 */
|
||||
val isGrayscaleIcon = isGrayscaleIcon(context, iconDrawable)
|
||||
|
||||
/** 自定义默认小图标 */
|
||||
var customIcon: Bitmap? = null
|
||||
if (isHookColorIcon) run {
|
||||
IconPackParams.iconDatas.forEach {
|
||||
if ((notifyInstance.opPkgName == it.packageName ||
|
||||
findAppName(notifyInstance) == it.appName) &&
|
||||
isAppNotifyHookOf(it)
|
||||
) {
|
||||
if (!isGrayscaleIcon || isAppNotifyHookAllOf(it))
|
||||
customIcon = it.iconBitmap
|
||||
return@run
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 如果开启了修复 APP 的彩色图标 */
|
||||
if (customIcon != null && prefs.getBoolean(ENABLE_NOTIFY_ICON_HOOK, default = true))
|
||||
iconImageView.apply {
|
||||
/** 设置自定义小图标 */
|
||||
setImageBitmap(customIcon)
|
||||
/** 上色 */
|
||||
setColorFilter(if (isUpperOfAndroidS) newStyle else oldStyle)
|
||||
}
|
||||
else {
|
||||
/** 重新设置图标 - 防止系统更改它 */
|
||||
iconImageView.setImageDrawable(iconDrawable)
|
||||
/** 判断是否开启 Hook 彩色图标 */
|
||||
if (isHookColorIcon) {
|
||||
/** 判断如果是灰度图标就给他设置一个白色颜色遮罩 */
|
||||
if (isGrayscaleIcon)
|
||||
iconImageView.setColorFilter(if (isUpperOfAndroidS) newStyle else oldStyle)
|
||||
else
|
||||
iconImageView.apply {
|
||||
clipToOutline = true
|
||||
/** 设置一个圆角轮廓裁切 */
|
||||
outlineProvider = object : ViewOutlineProvider() {
|
||||
override fun getOutline(view: View, out: Outline) {
|
||||
out.setRoundRect(
|
||||
0, 0,
|
||||
view.width, view.height, 5.dp(context)
|
||||
)
|
||||
}
|
||||
}
|
||||
/** 清除原生的背景边距设置 */
|
||||
if (isUpperOfAndroidS) setPadding(0, 0, 0, 0)
|
||||
/** 清除原生的主题色背景圆圈颜色 */
|
||||
if (isUpperOfAndroidS) background = null
|
||||
}
|
||||
/** 否则一律设置灰度图标 */
|
||||
} else iconImageView.setColorFilter(if (isUpperOfAndroidS) newStyle else oldStyle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook 通知栏小图标颜色
|
||||
*
|
||||
* 区分系统版本 - 由于每个系统版本的方法不一样这里单独拿出来进行 Hook
|
||||
* @param context 实例
|
||||
* @param expandedNf 状态栏实例
|
||||
* @return [Boolean] 是否忽略通知图标颜色
|
||||
*/
|
||||
private fun PackageParam.hookIgnoreStatusBarIconColor(context: Context, expandedNf: StatusBarNotification?) =
|
||||
if (prefs.getBoolean(ENABLE_COLOR_ICON_HOOK, default = true)) safeOfFalse {
|
||||
/** 获取通知对象 - 由于 MIUI 的版本迭代不规范性可能是空的 */
|
||||
expandedNf?.let { notifyInstance ->
|
||||
/** 获取通知小图标 */
|
||||
val iconDrawable =
|
||||
notifyInstance.notification.smallIcon.loadDrawable(context)
|
||||
|
||||
/** 判断是否不是灰度图标 */
|
||||
val isNotGrayscaleIcon = !isGrayscaleIcon(context, iconDrawable)
|
||||
|
||||
/** 获取目标修复彩色图标的 APP */
|
||||
var isTargetApp = false
|
||||
run {
|
||||
IconPackParams.iconDatas.forEach {
|
||||
if ((notifyInstance.opPkgName == it.packageName ||
|
||||
findAppName(notifyInstance) == it.appName) &&
|
||||
isAppNotifyHookOf(it)
|
||||
) {
|
||||
if (isNotGrayscaleIcon || isAppNotifyHookAllOf(it)) isTargetApp = true
|
||||
return@run
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 如果开启了修复 APP 的彩色图标
|
||||
* 只要不是灰度就返回彩色图标
|
||||
* 否则不对颜色进行反色处理防止一些系统图标出现异常
|
||||
*/
|
||||
if (isTargetApp && prefs.getBoolean(ENABLE_NOTIFY_ICON_HOOK, default = true))
|
||||
false
|
||||
else isNotGrayscaleIcon
|
||||
} ?: true
|
||||
} else false
|
||||
|
||||
override fun onHook() = encase {
|
||||
configs {
|
||||
debugTag = "MIUINativeNotifyIcon"
|
||||
isDebug = prefs.getBoolean(ENABLE_MODULE_LOG)
|
||||
}
|
||||
loadApp(SYSTEMUI_PACKAGE_NAME) {
|
||||
when {
|
||||
/** 不是 MIUI 系统停止 Hook */
|
||||
isNotMIUI -> loggerW(msg = "Aborted Hook -> This System is not MIUI")
|
||||
/** 系统版本低于 Android P 停止 Hook */
|
||||
isLowerAndroidP -> loggerW(msg = "Aborted Hook -> This System is lower than Android P")
|
||||
/** 不是支持的 MIUI 系统停止 Hook */
|
||||
isNotSupportMiuiVersion -> loggerW(msg = "Aborted Hook -> This MIUI Version $miuiVersion not supported")
|
||||
/** Hook 被手动关闭停止 Hook */
|
||||
!prefs.getBoolean(ENABLE_MODULE, default = true) -> loggerW(msg = "Aborted Hook -> Hook Closed")
|
||||
/** 开始 Hook */
|
||||
else -> {
|
||||
NotificationUtilClass.hook {
|
||||
/** 强制回写系统的状态栏图标样式为原生 */
|
||||
injectMember {
|
||||
method {
|
||||
name = "shouldSubstituteSmallIcon"
|
||||
param(ExpandedNotificationClass.clazz)
|
||||
}
|
||||
/**
|
||||
* 因为之前的 MIUI 版本的状态栏图标颜色会全部设置为白色的 - 找不到修复的地方就直接判断版本了
|
||||
* 对于之前没有通知图标色彩判断功能的版本判断是 MIUI 样式就停止 Hook
|
||||
*/
|
||||
replaceAny { if (hasIgnoreStatusBarIconColor()) false else isShowMiuiStyle() }
|
||||
}
|
||||
if (hasIgnoreStatusBarIconColor())
|
||||
injectMember {
|
||||
method {
|
||||
name = "ignoreStatusBarIconColor"
|
||||
param(ExpandedNotificationClass.clazz)
|
||||
}
|
||||
replaceAny {
|
||||
hookIgnoreStatusBarIconColor(
|
||||
context = globalContext ?: error("GlobalContext got null"),
|
||||
expandedNf = args[0] as? StatusBarNotification?
|
||||
)
|
||||
}
|
||||
}
|
||||
/** 强制回写系统的状态栏图标样式为原生 */
|
||||
injectMember {
|
||||
var isUseLegacy = false
|
||||
method {
|
||||
name = "getSmallIcon"
|
||||
param(ExpandedNotificationClass.clazz, IntType)
|
||||
}.remedys {
|
||||
method {
|
||||
name = "getSmallIcon"
|
||||
param(ExpandedNotificationClass.clazz)
|
||||
}
|
||||
method {
|
||||
name = "getSmallIcon"
|
||||
param(ContextClass, ExpandedNotificationClass.clazz)
|
||||
}.onFind { isUseLegacy = true }
|
||||
}
|
||||
afterHook {
|
||||
/** 对于之前没有通知图标色彩判断功能的版本判断是 MIUI 样式就停止 Hook */
|
||||
if (hasIgnoreStatusBarIconColor() || !isShowMiuiStyle())
|
||||
(globalContext ?: args[0] as Context).also { context ->
|
||||
hookSmallIconOnSet(
|
||||
context = context,
|
||||
args[if (isUseLegacy) 1 else 0] as? StatusBarNotification?,
|
||||
(result as Icon).loadDrawable(context)
|
||||
) { icon -> result = Icon.createWithBitmap(icon) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
findClass(StatusBarIconViewClass).hook {
|
||||
/** 修复通知图标为彩色 - MIPUSH 修复 */
|
||||
injectMember {
|
||||
method { name = "updateIconColor" }
|
||||
afterHook {
|
||||
/** 获取自身 */
|
||||
val iconImageView = instance<ImageView?>() ?: return@afterHook
|
||||
|
||||
/** 获取通知实例 */
|
||||
val expandedNf = field { name = "mNotification" }.of<StatusBarNotification>(instance)
|
||||
|
||||
/**
|
||||
* 强制设置图标 - 防止 MIPUSH 不生效
|
||||
* 由于之前版本没有 [hasIgnoreStatusBarIconColor] 判断 - MIPUSH 的图标颜色也是白色的
|
||||
* 所以之前的版本取消这个 Hook - 实在找不到设置图标的地方 - 状态栏图标就彩色吧
|
||||
*/
|
||||
if (hasIgnoreStatusBarIconColor() && expandedNf?.isXmsf == true)
|
||||
hookSmallIconOnSet(
|
||||
context = iconImageView.context,
|
||||
expandedNf,
|
||||
expandedNf.notification?.smallIcon?.loadDrawable(iconImageView.context)
|
||||
) { icon -> iconImageView.setImageBitmap(icon) }
|
||||
}
|
||||
}
|
||||
}
|
||||
if (NotificationHeaderViewWrapperInjectorClass.hasClass)
|
||||
findClass(NotificationHeaderViewWrapperInjectorClass).hook {
|
||||
/** 修复下拉通知图标自动设置回 APP 图标的方法 */
|
||||
injectMember {
|
||||
var isUseLegacy = false
|
||||
method {
|
||||
name = "setAppIcon"
|
||||
param(ContextClass, ImageViewClass, ExpandedNotificationClass.clazz)
|
||||
}.remedys {
|
||||
method {
|
||||
name = "setAppIcon"
|
||||
param(ImageViewClass, ExpandedNotificationClass.clazz)
|
||||
}.onFind { isUseLegacy = true }
|
||||
}
|
||||
replaceUnit {
|
||||
if (isUseLegacy)
|
||||
hookNotifyIconOnSet(
|
||||
context = globalContext ?: error("GlobalContext got null"),
|
||||
args[1] as? StatusBarNotification?,
|
||||
args[0] as ImageView
|
||||
)
|
||||
else
|
||||
hookNotifyIconOnSet(
|
||||
context = args[0] as? Context ?: globalContext ?: error("GlobalContext got null"),
|
||||
args[2] as? StatusBarNotification?,
|
||||
args[1] as ImageView
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
/** 干掉下拉通知图标自动设置回 APP 图标的方法 - Android 12 */
|
||||
if (isUpperOfAndroidS)
|
||||
injectMember {
|
||||
method {
|
||||
name = "resetIconBgAndPaddings"
|
||||
param(ImageViewClass, ExpandedNotificationClass.clazz)
|
||||
}
|
||||
intercept()
|
||||
}
|
||||
}
|
||||
else
|
||||
findClass(NotificationHeaderViewWrapperClass).hook {
|
||||
/** 之前的版本解决方案 */
|
||||
injectMember {
|
||||
method { name = "handleHeaderViews" }
|
||||
afterHook {
|
||||
/** 对于之前没有通知图标色彩判断功能的版本判断是 MIUI 样式就停止 Hook */
|
||||
if (!hasIgnoreStatusBarIconColor() && isShowMiuiStyle()) return@afterHook
|
||||
/** 获取小图标 */
|
||||
val iconImageView = field {
|
||||
classSet = NotificationHeaderViewWrapperClass.clazz
|
||||
name = "mIcon"
|
||||
}.of<ImageView>(instance) ?: return@afterHook
|
||||
/** 从父类中得到 mRow 变量 - [ExpandableNotificationRowClass] */
|
||||
field {
|
||||
classSet = NotificationViewWrapperClass.clazz
|
||||
name = "mRow"
|
||||
}.get(instance).apply {
|
||||
/** 获取其中的得到通知方法 */
|
||||
val expandedNf =
|
||||
ExpandableNotificationRowClass.clazz.method(name = "getStatusBarNotification")
|
||||
?.call<StatusBarNotification>(instance = self)
|
||||
/** 执行 Hook */
|
||||
hookNotifyIconOnSet(iconImageView.context, expandedNf, iconImageView)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,842 +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/01/24.
|
||||
*/
|
||||
@file:Suppress("SameParameterValue", "DEPRECATION")
|
||||
|
||||
package com.fankes.miui.notify.hook
|
||||
|
||||
import android.app.Notification
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import android.graphics.Outline
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.Icon
|
||||
import android.service.notification.StatusBarNotification
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.ViewOutlineProvider
|
||||
import android.widget.ImageView
|
||||
import androidx.annotation.Keep
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
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
|
||||
|
||||
@Keep
|
||||
class HookMain : IXposedHookLoadPackage {
|
||||
|
||||
companion object {
|
||||
|
||||
/** 一直存在的类 */
|
||||
private const val SystemUIApplicationClass = "$SYSTEMUI_PACKAGE_NAME.SystemUIApplication"
|
||||
|
||||
/** MIUI 新版本存在的类 */
|
||||
private const val NotificationHeaderViewWrapperInjectorClass =
|
||||
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.row.wrapper.NotificationHeaderViewWrapperInjector"
|
||||
|
||||
/** 一直存在的类 */
|
||||
private const val NotificationHeaderViewWrapperClass =
|
||||
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.NotificationHeaderViewWrapper"
|
||||
|
||||
/** 一直存在的类 */
|
||||
private const val NotificationViewWrapperClass =
|
||||
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.NotificationViewWrapper"
|
||||
|
||||
/** 原生存在的类 */
|
||||
private const val StatusBarIconViewClass = "$SYSTEMUI_PACKAGE_NAME.statusbar.StatusBarIconView"
|
||||
|
||||
/** 原生存在的类 */
|
||||
private const val ContrastColorUtilClass = "com.android.internal.util.ContrastColorUtil"
|
||||
|
||||
/** 未确定是否只有旧版本存在的类 */
|
||||
private const val ExpandableNotificationRowClass = "$SYSTEMUI_PACKAGE_NAME.statusbar.ExpandableNotificationRow"
|
||||
|
||||
/** 根据多个版本存在不同的包名相同的类 */
|
||||
private val NotificationUtilClass = Pair(
|
||||
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.NotificationUtil",
|
||||
"$SYSTEMUI_PACKAGE_NAME.miui.statusbar.notification.NotificationUtil"
|
||||
)
|
||||
|
||||
/** 根据多个版本存在不同的包名相同的类 */
|
||||
private val ExpandedNotificationClass = Pair(
|
||||
"$SYSTEMUI_PACKAGE_NAME.statusbar.notification.ExpandedNotification",
|
||||
"$SYSTEMUI_PACKAGE_NAME.miui.statusbar.ExpandedNotification"
|
||||
)
|
||||
}
|
||||
|
||||
/** 仅作用于替换的 Hook 方法体 */
|
||||
private val replaceToNull = object : XC_MethodReplacement() {
|
||||
override fun replaceHookedMethod(param: MethodHookParam?): Any? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/** 仅作用于替换的 Hook 方法体 */
|
||||
private val replaceToTrue = object : XC_MethodReplacement() {
|
||||
override fun replaceHookedMethod(param: MethodHookParam?): Any {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
/** 仅作用于替换的 Hook 方法体 */
|
||||
@Suppress("unused")
|
||||
private val replaceToFalse = object : XC_MethodReplacement() {
|
||||
override fun replaceHookedMethod(param: MethodHookParam?): Any {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 忽略异常运行
|
||||
* @param error 错误信息
|
||||
* @param it 正常回调
|
||||
*/
|
||||
private fun runWithoutError(error: String = "", it: () -> Unit) {
|
||||
try {
|
||||
it()
|
||||
} catch (e: Throwable) {
|
||||
logE(content = "hookFailed: $error", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the log
|
||||
* @param content
|
||||
* @param it 继续执行的方法
|
||||
*/
|
||||
private fun logD(content: String, it: () -> Unit = {}) {
|
||||
it()
|
||||
if (!HookMedium.getBoolean(HookMedium.ENABLE_MODULE_LOG, default = false)) return
|
||||
XposedBridge.log("[MIUINativeNotifyIcon][D]>$content")
|
||||
Log.d("MIUINativeNotifyIcon", content)
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the log
|
||||
* @param content
|
||||
* @param it 继续执行的方法
|
||||
*/
|
||||
private fun logW(content: String, it: () -> Unit = {}) {
|
||||
it()
|
||||
if (!HookMedium.getBoolean(HookMedium.ENABLE_MODULE_LOG, default = false)) return
|
||||
XposedBridge.log("[MIUINativeNotifyIcon][W]>$content")
|
||||
Log.d("MIUINativeNotifyIcon", content)
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the log
|
||||
* @param content
|
||||
* @param e 异常
|
||||
* @param it 继续执行的方法
|
||||
*/
|
||||
private fun logE(content: String, e: Throwable? = null, it: () -> Unit = {}) {
|
||||
it()
|
||||
XposedBridge.log("[MIUINativeNotifyIcon][E]>$content")
|
||||
XposedBridge.log(e)
|
||||
Log.e("MIUINativeNotifyIcon", content, e)
|
||||
}
|
||||
|
||||
/**
|
||||
* 目标类是否存在
|
||||
* @param name 类名
|
||||
* @return [Boolean]
|
||||
*/
|
||||
private fun XC_LoadPackage.LoadPackageParam.isClassExist(name: String) = try {
|
||||
classLoader.loadClass(name)
|
||||
true
|
||||
} catch (_: Throwable) {
|
||||
false
|
||||
}
|
||||
|
||||
/**
|
||||
* 目标方法是否存在
|
||||
* @param classPair 类数组
|
||||
* @param name 方法名
|
||||
* @param param 方法参数类型数组
|
||||
* @return [Boolean]
|
||||
*/
|
||||
private fun XC_LoadPackage.LoadPackageParam.isMethodExist(
|
||||
classPair: Pair<String, String>,
|
||||
name: String, vararg param: Class<*>
|
||||
) = try {
|
||||
(try {
|
||||
classLoader.loadClass(classPair.first)
|
||||
} catch (_: Throwable) {
|
||||
try {
|
||||
classLoader.loadClass(classPair.second)
|
||||
} catch (_: Throwable) {
|
||||
null
|
||||
}
|
||||
})?.getDeclaredMethod(name, *param)
|
||||
true
|
||||
} catch (_: Throwable) {
|
||||
false
|
||||
}
|
||||
|
||||
/**
|
||||
* 目标方法是否存在
|
||||
* @param className 类名
|
||||
* @param name 方法名
|
||||
* @param param 方法参数类型数组
|
||||
* @return [Boolean]
|
||||
*/
|
||||
private fun XC_LoadPackage.LoadPackageParam.isMethodExist(className: String, name: String, vararg param: Class<*>) =
|
||||
try {
|
||||
(try {
|
||||
classLoader.loadClass(className)
|
||||
} catch (_: Throwable) {
|
||||
null
|
||||
})?.getDeclaredMethod(name, *param)
|
||||
true
|
||||
} catch (_: Throwable) {
|
||||
false
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找目标类
|
||||
* @param name 类名
|
||||
* @return [Class]
|
||||
*/
|
||||
private fun XC_LoadPackage.LoadPackageParam.findClass(name: String) =
|
||||
classLoader.loadClass(name)
|
||||
|
||||
/**
|
||||
* 查找目标类 - 两个类都没找到才会报错
|
||||
* @param pair 类名数组
|
||||
* @return [Class]
|
||||
*/
|
||||
private fun XC_LoadPackage.LoadPackageParam.findClass(pair: Pair<String, String>) = try {
|
||||
classLoader.loadClass(pair.first)
|
||||
} catch (_: Throwable) {
|
||||
try {
|
||||
classLoader.loadClass(pair.second)
|
||||
} catch (e: Throwable) {
|
||||
logE(content = "Cannot find Class ${pair.first} and ${pair.second}", e)
|
||||
error("[Throwable] Cannot find Class ${pair.first} and ${pair.second}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 存在目标类的类名 - 两个类都没找到会抛出异常
|
||||
* @param pair 类名数组
|
||||
* @return [String] 目标类名
|
||||
*/
|
||||
private fun XC_LoadPackage.LoadPackageParam.existClass(pair: Pair<String, String>) = try {
|
||||
classLoader.loadClass(pair.first)
|
||||
pair.first
|
||||
} catch (_: Throwable) {
|
||||
try {
|
||||
classLoader.loadClass(pair.second)
|
||||
pair.second
|
||||
} catch (_: Throwable) {
|
||||
logE(content = "Cannot find Class ${pair.first} and ${pair.second}")
|
||||
error("[Throwable] Cannot find Class ${pair.first} and ${pair.second}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* - ⚡这个是修复彩色图标的关键核心代码判断
|
||||
*
|
||||
* 判断是否为灰度图标 - 反射执行系统方法
|
||||
* @param context 实例
|
||||
* @param icon 要判断的图标
|
||||
* @return [Boolean]
|
||||
*/
|
||||
private fun XC_LoadPackage.LoadPackageParam.isGrayscaleIcon(context: Context, icon: Drawable) =
|
||||
findClass(ContrastColorUtilClass).let {
|
||||
val instance = it.getDeclaredMethod("getInstance", Context::class.java)
|
||||
.apply { isAccessible = true }.invoke(null, context)
|
||||
it.getDeclaredMethod("isGrayscaleIcon", Drawable::class.java)
|
||||
.apply { isAccessible = true }.invoke(instance, icon) as Boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前通知栏的样式
|
||||
* @return [Boolean]
|
||||
*/
|
||||
private fun XC_LoadPackage.LoadPackageParam.isShowMiuiStyle() = try {
|
||||
findClass(NotificationUtilClass).let {
|
||||
it.getDeclaredMethod("showMiuiStyle")
|
||||
.apply { isAccessible = true }.invoke(null) as Boolean
|
||||
}
|
||||
} catch (_: Throwable) {
|
||||
false
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为新版本 MIUI 方案
|
||||
*
|
||||
* 拥有状态栏图标颜色检查功能
|
||||
* @return [Boolean]
|
||||
*/
|
||||
private fun XC_LoadPackage.LoadPackageParam.hasIgnoreStatusBarIconColor() = try {
|
||||
isMethodExist(NotificationUtilClass, name = "ignoreStatusBarIconColor", findClass(ExpandedNotificationClass))
|
||||
} catch (_: Throwable) {
|
||||
false
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 [ExpandedNotificationClass] 的应用名称
|
||||
* @param instance 通知实例
|
||||
* @return [String]
|
||||
*/
|
||||
private fun XC_LoadPackage.LoadPackageParam.findAppName(instance: Any?) = try {
|
||||
findClass(ExpandedNotificationClass).getDeclaredMethod("getAppName").let {
|
||||
it.isAccessible = true
|
||||
it.invoke(instance) as? String ?: "<empty>"
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
"<unknown>"
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全局上下文
|
||||
* @return [Context] or null
|
||||
*/
|
||||
private val XC_LoadPackage.LoadPackageParam.globalContext
|
||||
get() = try {
|
||||
findClass(SystemUIApplicationClass)
|
||||
.getDeclaredMethod("getContext").apply { isAccessible = true }
|
||||
.invoke(null) as? Context?
|
||||
} catch (_: Throwable) {
|
||||
null
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook 状态栏小图标
|
||||
*
|
||||
* 区分系统版本 - 由于每个系统版本的方法不一样这里单独拿出来进行 Hook
|
||||
* @param context 实例
|
||||
* @param expandedNf 通知实例
|
||||
* @param iconDrawable 小图标 [Drawable]
|
||||
* @param isLegacyWay 旧版本 Hook 方式
|
||||
* @param it 回调小图标 - ([Bitmap] 小图标)
|
||||
*/
|
||||
private fun XC_LoadPackage.LoadPackageParam.hookSmallIconOnSet(
|
||||
context: Context,
|
||||
expandedNf: StatusBarNotification?,
|
||||
iconDrawable: Drawable,
|
||||
isLegacyWay: Boolean,
|
||||
it: (Bitmap) -> Unit
|
||||
) {
|
||||
runWithoutError(error = "GetSmallIconOnSet") {
|
||||
/** 判断是否不是灰度图标 */
|
||||
val isNotGrayscaleIcon = !isGrayscaleIcon(context, iconDrawable)
|
||||
/** 获取通知对象 - 由于 MIUI 的版本迭代不规范性可能是空的 */
|
||||
expandedNf?.also { notifyInstance ->
|
||||
/** 目标彩色通知 APP 图标 */
|
||||
var customIcon: Bitmap? = null
|
||||
if (HookMedium.getBoolean(HookMedium.ENABLE_COLOR_ICON_HOOK, default = true))
|
||||
run {
|
||||
if (findAppName(notifyInstance).startsWith("Android") &&
|
||||
(notifyInstance.notification.extras.getCharSequence(Notification.EXTRA_TITLE)
|
||||
?.startsWith("Xposed 模块") == true ||
|
||||
notifyInstance.notification.extras.getCharSequence(Notification.EXTRA_TITLE)
|
||||
?.startsWith("Xposed Module") == true)
|
||||
) customIcon = IconPackParams.lsposedIcon
|
||||
else IconPackParams.iconDatas.forEach {
|
||||
if ((notifyInstance.opPkgName == it.packageName ||
|
||||
findAppName(notifyInstance) == it.appName) &&
|
||||
HookMedium.isAppNotifyHookOf(it)
|
||||
) {
|
||||
if (isNotGrayscaleIcon || HookMedium.isAppNotifyHookAllOf(it))
|
||||
customIcon = it.iconBitmap
|
||||
return@run
|
||||
}
|
||||
}
|
||||
}
|
||||
when {
|
||||
/** 如果开启了修复 APP 的彩色图标 */
|
||||
customIcon != null && HookMedium.getBoolean(HookMedium.ENABLE_NOTIFY_ICON_HOOK, default = true) ->
|
||||
logD(
|
||||
content = "GetSmallIconOnSet -> " +
|
||||
"hook Custom AppIcon [pkgName] ${notifyInstance.opPkgName} " +
|
||||
"[appName] ${findAppName(notifyInstance)} " +
|
||||
"[legacyWay] $isLegacyWay"
|
||||
) { it(customIcon!!) }
|
||||
/** 若不是灰度图标自动处理为圆角 */
|
||||
isNotGrayscaleIcon ->
|
||||
logD(
|
||||
content = "GetSmallIconOnSet -> " +
|
||||
"hook Color AppIcon [pkgName] ${notifyInstance.opPkgName} " +
|
||||
"[appName] ${findAppName(notifyInstance)} " +
|
||||
"[legacyWay] $isLegacyWay"
|
||||
) {
|
||||
it(iconDrawable.toBitmap().round(15.dp(context)))
|
||||
}
|
||||
}
|
||||
} ?: logW(content = "GetSmallIconOnSet -> StatusBarNotification got null [legacyWay] $isLegacyWay")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook 通知栏小图标
|
||||
*
|
||||
* 区分系统版本 - 由于每个系统版本的方法不一样这里单独拿出来进行 Hook
|
||||
* @param context 实例
|
||||
* @param expandedNf 通知实例
|
||||
* @param iconImageView 通知图标实例
|
||||
*/
|
||||
private fun XC_LoadPackage.LoadPackageParam.hookNotifyIconOnSet(
|
||||
context: Context,
|
||||
expandedNf: StatusBarNotification?,
|
||||
iconImageView: ImageView
|
||||
) {
|
||||
runWithoutError(error = "AutoSetAppIconOnSet") {
|
||||
/** 获取通知对象 - 由于 MIUI 的版本迭代不规范性可能是空的 */
|
||||
expandedNf?.let { notifyInstance ->
|
||||
/** 是否 Hook 彩色通知图标 */
|
||||
val isHookColorIcon = HookMedium.getBoolean(HookMedium.ENABLE_COLOR_ICON_HOOK, default = true)
|
||||
|
||||
/** 新版风格反色 */
|
||||
val newStyle = if (context.isSystemInDarkMode) 0xFF2D2D2D.toInt() else Color.WHITE
|
||||
|
||||
/** 旧版风格反色 */
|
||||
val oldStyle = if (context.isNotSystemInDarkMode) 0xFF707070.toInt() else Color.WHITE
|
||||
|
||||
/** 获取通知小图标 */
|
||||
val iconDrawable = notifyInstance.notification.smallIcon.loadDrawable(context)
|
||||
|
||||
/** 判断图标风格 */
|
||||
val isGrayscaleIcon = isGrayscaleIcon(context, iconDrawable)
|
||||
|
||||
/** 自定义默认小图标 */
|
||||
var customIcon: Bitmap? = null
|
||||
if (isHookColorIcon) run {
|
||||
if (findAppName(notifyInstance).startsWith("Android") &&
|
||||
(notifyInstance.notification.extras.getCharSequence(Notification.EXTRA_TITLE)
|
||||
?.startsWith("Xposed 模块") == true ||
|
||||
notifyInstance.notification.extras.getCharSequence(Notification.EXTRA_TITLE)
|
||||
?.startsWith("Xposed Module") == true)
|
||||
) customIcon = IconPackParams.lsposedIcon
|
||||
else IconPackParams.iconDatas.forEach {
|
||||
if ((notifyInstance.opPkgName == it.packageName ||
|
||||
findAppName(notifyInstance) == it.appName) &&
|
||||
HookMedium.isAppNotifyHookOf(it)
|
||||
) {
|
||||
if (!isGrayscaleIcon || HookMedium.isAppNotifyHookAllOf(it))
|
||||
customIcon = it.iconBitmap
|
||||
return@run
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 如果开启了修复 APP 的彩色图标 */
|
||||
if (customIcon != null && HookMedium.getBoolean(HookMedium.ENABLE_NOTIFY_ICON_HOOK, default = true))
|
||||
iconImageView.apply {
|
||||
/** 设置自定义小图标 */
|
||||
setImageBitmap(customIcon)
|
||||
/** 上色 */
|
||||
setColorFilter(if (isUpperOfAndroidS) newStyle else oldStyle)
|
||||
/** 输出调试日志 */
|
||||
logD(
|
||||
content = "AutoSetAppIconOnSet -> " +
|
||||
"hook Custom AppIcon [pkgName] ${notifyInstance.opPkgName} " +
|
||||
"[appName] ${findAppName(notifyInstance)}"
|
||||
)
|
||||
}
|
||||
else {
|
||||
/** 重新设置图标 - 防止系统更改它 */
|
||||
iconImageView.setImageDrawable(iconDrawable)
|
||||
/** 判断是否开启 Hook 彩色图标 */
|
||||
if (isHookColorIcon) {
|
||||
/** 判断如果是灰度图标就给他设置一个白色颜色遮罩 */
|
||||
if (isGrayscaleIcon)
|
||||
logD(
|
||||
content = "AutoSetAppIconOnSet -> " +
|
||||
"hook Grayscale AppIcon [pkgName] ${notifyInstance.opPkgName} " +
|
||||
"[appName] ${findAppName(notifyInstance)}"
|
||||
) { iconImageView.setColorFilter(if (isUpperOfAndroidS) newStyle else oldStyle) }
|
||||
else
|
||||
iconImageView.apply {
|
||||
clipToOutline = true
|
||||
/** 设置一个圆角轮廓裁切 */
|
||||
outlineProvider = object : ViewOutlineProvider() {
|
||||
override fun getOutline(view: View, out: Outline) {
|
||||
out.setRoundRect(
|
||||
0, 0,
|
||||
view.width, view.height, 5.dp(context)
|
||||
)
|
||||
}
|
||||
}
|
||||
/** 清除原生的背景边距设置 */
|
||||
if (isUpperOfAndroidS) setPadding(0, 0, 0, 0)
|
||||
/** 清除原生的主题色背景圆圈颜色 */
|
||||
if (isUpperOfAndroidS) background = null
|
||||
/** 输出调试日志 */
|
||||
logD(
|
||||
content = "AutoSetAppIconOnSet -> " +
|
||||
"hook Color AppIcon [pkgName] ${notifyInstance.opPkgName} " +
|
||||
"[appName] ${findAppName(notifyInstance)}"
|
||||
)
|
||||
}
|
||||
/** 否则一律设置灰度图标 */
|
||||
} else
|
||||
logD(
|
||||
content = "AutoSetAppIconOnSet -> " +
|
||||
"hook NonColor AppIcon [pkgName] ${notifyInstance.opPkgName} " +
|
||||
"[appName] ${findAppName(notifyInstance)}"
|
||||
) { iconImageView.setColorFilter(if (isUpperOfAndroidS) newStyle else oldStyle) }
|
||||
}
|
||||
} ?: logW(content = "AutoSetAppIconOnSet -> StatusBarNotification got null")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook 通知栏小图标颜色
|
||||
*
|
||||
* 区分系统版本 - 由于每个系统版本的方法不一样这里单独拿出来进行 Hook
|
||||
* @param context 实例
|
||||
* @param expandedNf 状态栏实例
|
||||
* @return [Boolean] 是否忽略通知图标颜色
|
||||
*/
|
||||
private fun XC_LoadPackage.LoadPackageParam.hookIgnoreStatusBarIconColor(
|
||||
context: Context,
|
||||
expandedNf: StatusBarNotification?
|
||||
) = if (HookMedium.getBoolean(HookMedium.ENABLE_COLOR_ICON_HOOK, default = true))
|
||||
try {
|
||||
/** 获取通知对象 - 由于 MIUI 的版本迭代不规范性可能是空的 */
|
||||
expandedNf?.let { notifyInstance ->
|
||||
/** 获取通知小图标 */
|
||||
val iconDrawable =
|
||||
notifyInstance.notification.smallIcon.loadDrawable(context)
|
||||
|
||||
/** 判断是否不是灰度图标 */
|
||||
val isNotGrayscaleIcon = !isGrayscaleIcon(context, iconDrawable)
|
||||
|
||||
/** 获取目标修复彩色图标的 APP */
|
||||
var isTargetApp = false
|
||||
run {
|
||||
IconPackParams.iconDatas.forEach {
|
||||
if ((notifyInstance.opPkgName == it.packageName ||
|
||||
findAppName(notifyInstance) == it.appName) &&
|
||||
HookMedium.isAppNotifyHookOf(it)
|
||||
) {
|
||||
if (isNotGrayscaleIcon || HookMedium.isAppNotifyHookAllOf(it)) isTargetApp = true
|
||||
return@run
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 如果开启了修复 APP 的彩色图标 */
|
||||
if (isTargetApp && HookMedium.getBoolean(HookMedium.ENABLE_NOTIFY_ICON_HOOK, default = true)) let {
|
||||
logD(
|
||||
content = "IgnoreStatusBarIconColor -> " +
|
||||
"hook Color AppIcon [pkgName] ${notifyInstance.opPkgName} " +
|
||||
"[appName] ${findAppName(notifyInstance)}"
|
||||
)
|
||||
false
|
||||
}
|
||||
else let {
|
||||
logD(
|
||||
content = "IgnoreStatusBarIconColor -> " +
|
||||
"hook Grayscale[${!isNotGrayscaleIcon}] AppIcon " +
|
||||
"[pkgName] ${notifyInstance.opPkgName} " +
|
||||
"[appName] ${findAppName(notifyInstance)}"
|
||||
)
|
||||
/** 只要不是灰度就返回彩色图标 */
|
||||
isNotGrayscaleIcon
|
||||
}
|
||||
} ?: let {
|
||||
logW(content = "IgnoreStatusBarIconColor -> StatusBarNotification got null")
|
||||
/** 否则不对颜色进行反色处理防止一些系统图标出现异常 */
|
||||
true
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logE("Failed to hook ignoreStatusBarIconColor", e)
|
||||
false
|
||||
}
|
||||
else let {
|
||||
logD(content = "IgnoreStatusBarIconColor -> hook NonColor AppIcon")
|
||||
false
|
||||
}
|
||||
|
||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {
|
||||
if (lpparam == null) return
|
||||
when (lpparam.packageName) {
|
||||
/** Hook 自身 */
|
||||
SELF_PACKAGE_NAME ->
|
||||
runWithoutError(error = "HookModuleSelf") {
|
||||
XposedHelpers.findAndHookMethod(
|
||||
"$SELF_PACKAGE_NAME.hook.HookMedium",
|
||||
lpparam.classLoader,
|
||||
"isHooked",
|
||||
replaceToTrue
|
||||
)
|
||||
}
|
||||
/** Hook 系统 UI */
|
||||
SYSTEMUI_PACKAGE_NAME ->
|
||||
when {
|
||||
/** 不是 MIUI 系统停止 Hook */
|
||||
isNotMIUI ->
|
||||
logW(content = "Aborted Hook -> This System is not MIUI")
|
||||
/** 系统版本低于 Android P 停止 Hook */
|
||||
isLowerAndroidP ->
|
||||
logW(content = "Aborted Hook -> This System is lower than Android P")
|
||||
/** 不是支持的 MIUI 系统停止 Hook */
|
||||
isNotSupportMiuiVersion ->
|
||||
logW(content = "Aborted Hook -> This MIUI Version $miuiVersion not supported")
|
||||
/** Hook 被手动关闭停止 Hook */
|
||||
!HookMedium.getBoolean(HookMedium.ENABLE_MODULE, default = true) ->
|
||||
logW(content = "Aborted Hook -> Hook Closed")
|
||||
else -> {
|
||||
/** 强制回写系统的状态栏图标样式为原生 */
|
||||
runWithoutError(error = "SubstituteSmallIcon") {
|
||||
XposedHelpers.findAndHookMethod(
|
||||
lpparam.existClass(NotificationUtilClass),
|
||||
lpparam.classLoader,
|
||||
"shouldSubstituteSmallIcon",
|
||||
lpparam.findClass(ExpandedNotificationClass),
|
||||
object : XC_MethodReplacement() {
|
||||
override fun replaceHookedMethod(param: MethodHookParam) =
|
||||
/**
|
||||
* 因为之前的 MIUI 版本的状态栏图标颜色会全部设置为白色的 - 找不到修复的地方就直接判断版本了
|
||||
* 对于之前没有通知图标色彩判断功能的版本判断是 MIUI 样式就停止 Hook
|
||||
*/
|
||||
if (lpparam.hasIgnoreStatusBarIconColor()) false else lpparam.isShowMiuiStyle()
|
||||
}
|
||||
)
|
||||
}
|
||||
/** 修复通知图标为彩色 */
|
||||
if (lpparam.hasIgnoreStatusBarIconColor())
|
||||
runWithoutError(error = "IgnoreStatusBarIconColor") {
|
||||
XposedHelpers.findAndHookMethod(
|
||||
lpparam.existClass(NotificationUtilClass),
|
||||
lpparam.classLoader,
|
||||
"ignoreStatusBarIconColor",
|
||||
lpparam.findClass(ExpandedNotificationClass),
|
||||
object : XC_MethodReplacement() {
|
||||
override fun replaceHookedMethod(param: MethodHookParam) =
|
||||
lpparam.hookIgnoreStatusBarIconColor(
|
||||
context = lpparam.globalContext ?: error("GlobalContext got null"),
|
||||
param.args?.get(0) as? StatusBarNotification?
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
/** 修复通知图标为彩色 - MIPUSH 修复 */
|
||||
runWithoutError(error = "UpdateIconColor") {
|
||||
XposedHelpers.findAndHookMethod(
|
||||
StatusBarIconViewClass,
|
||||
lpparam.classLoader, "updateIconColor",
|
||||
object : XC_MethodHook() {
|
||||
override fun afterHookedMethod(param: MethodHookParam) =
|
||||
runWithoutError(error = "UpdateIconColorOnSet") hook@{
|
||||
/** 获取自身 */
|
||||
val iconImageView = param.thisObject as ImageView
|
||||
|
||||
/** 获取通知实例 */
|
||||
val expandedNf =
|
||||
param.thisObject.javaClass.getDeclaredField("mNotification").apply {
|
||||
isAccessible = true
|
||||
}[param.thisObject] as? StatusBarNotification?
|
||||
|
||||
/**
|
||||
* 强制设置图标 - 防止 MIPUSH 不生效
|
||||
* 由于之前版本没有 [hasIgnoreStatusBarIconColor] 判断 - MIPUSH 的图标颜色也是白色的
|
||||
* 所以之前的版本取消这个 Hook - 实在找不到设置图标的地方 - 状态栏图标就彩色吧
|
||||
*/
|
||||
if (lpparam.hasIgnoreStatusBarIconColor())
|
||||
lpparam.hookSmallIconOnSet(
|
||||
context = iconImageView.context,
|
||||
expandedNf,
|
||||
iconImageView.drawable,
|
||||
isLegacyWay = true
|
||||
) { icon -> iconImageView.setImageBitmap(icon) }
|
||||
|
||||
/**
|
||||
* 对于之前没有通知图标色彩判断功能的版本判断是 MIUI 样式就停止 Hook
|
||||
* 新版本不需要下面的代码设置颜色 - 同样停止 Hook
|
||||
*/
|
||||
if (lpparam.hasIgnoreStatusBarIconColor() || lpparam.isShowMiuiStyle()) return@hook
|
||||
|
||||
/** 是否忽略图标颜色 */
|
||||
val isIgnoredColor =
|
||||
lpparam.hookIgnoreStatusBarIconColor(iconImageView.context, expandedNf)
|
||||
|
||||
/** 当前着色颜色 */
|
||||
val currentColor =
|
||||
param.thisObject.javaClass.getDeclaredField("mCurrentSetColor").apply {
|
||||
isAccessible = true
|
||||
}[param.thisObject] as? Int ?: Color.WHITE
|
||||
/** 判断并设置颜色 */
|
||||
if (isIgnoredColor)
|
||||
iconImageView.colorFilter = null
|
||||
else iconImageView.setColorFilter(currentColor)
|
||||
logD(content = "IgnoreStatusBarIconColor[UseOldWay] -> isIgnored[$isIgnoredColor]")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
/** 强制回写系统的状态栏图标样式为原生 */
|
||||
runWithoutError(error = "GetSmallIcon") {
|
||||
var isTooOld: Boolean
|
||||
try {
|
||||
isTooOld = false
|
||||
/** 新版方法 */
|
||||
lpparam.findClass(NotificationUtilClass)
|
||||
.getDeclaredMethod(
|
||||
"getSmallIcon",
|
||||
lpparam.findClass(ExpandedNotificationClass),
|
||||
Int::class.java
|
||||
).apply { isAccessible = true }
|
||||
} catch (_: Throwable) {
|
||||
try {
|
||||
isTooOld = false
|
||||
/** 旧版方法 */
|
||||
lpparam.findClass(NotificationUtilClass)
|
||||
.getDeclaredMethod("getSmallIcon", lpparam.findClass(ExpandedNotificationClass))
|
||||
.apply { isAccessible = true }
|
||||
} catch (_: Throwable) {
|
||||
isTooOld = true
|
||||
/** 超旧版方法 */
|
||||
lpparam.findClass(NotificationUtilClass)
|
||||
.getDeclaredMethod(
|
||||
"getSmallIcon",
|
||||
Context::class.java,
|
||||
lpparam.findClass(ExpandedNotificationClass)
|
||||
).apply { isAccessible = true }
|
||||
}
|
||||
}.also {
|
||||
XposedBridge.hookMethod(it, object : XC_MethodHook() {
|
||||
override fun afterHookedMethod(param: MethodHookParam) {
|
||||
/** 对于之前没有通知图标色彩判断功能的版本判断是 MIUI 样式就停止 Hook */
|
||||
if (!lpparam.hasIgnoreStatusBarIconColor() && lpparam.isShowMiuiStyle()) return
|
||||
runWithoutError(error = "GetSmallIconDoing") {
|
||||
(lpparam.globalContext ?: param.args[0] as Context).also { context ->
|
||||
lpparam.hookSmallIconOnSet(
|
||||
context = context,
|
||||
param.args?.get(if (isTooOld) 1 else 0) as? StatusBarNotification?,
|
||||
(param.result as Icon).loadDrawable(context),
|
||||
isLegacyWay = isTooOld
|
||||
) { icon -> param.result = Icon.createWithBitmap(icon) }
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
/** 修复下拉通知图标自动设置回 APP 图标的方法 */
|
||||
if (lpparam.isClassExist(NotificationHeaderViewWrapperInjectorClass))
|
||||
runWithoutError(error = "AutoSetAppIcon") {
|
||||
var isNewWay = true
|
||||
try {
|
||||
/** 新版方法 */
|
||||
lpparam.findClass(NotificationHeaderViewWrapperInjectorClass)
|
||||
.getDeclaredMethod(
|
||||
"setAppIcon",
|
||||
Context::class.java,
|
||||
ImageView::class.java,
|
||||
lpparam.findClass(ExpandedNotificationClass)
|
||||
).apply { isAccessible = true }
|
||||
} catch (_: Throwable) {
|
||||
isNewWay = false
|
||||
/** 旧版方法 */
|
||||
lpparam.findClass(NotificationHeaderViewWrapperInjectorClass)
|
||||
.getDeclaredMethod(
|
||||
"setAppIcon",
|
||||
ImageView::class.java,
|
||||
lpparam.findClass(ExpandedNotificationClass)
|
||||
).apply { isAccessible = true }
|
||||
}.also {
|
||||
XposedBridge.hookMethod(it, object : XC_MethodReplacement() {
|
||||
override fun replaceHookedMethod(param: MethodHookParam): Any? {
|
||||
runWithoutError(error = "AutoSetAppIconDoing") {
|
||||
if (isNewWay)
|
||||
lpparam.hookNotifyIconOnSet(
|
||||
context = param.args?.get(0) as? Context ?: lpparam.globalContext
|
||||
?: error("GlobalContext got null"),
|
||||
param.args?.get(2) as? StatusBarNotification?,
|
||||
param.args?.get(1) as ImageView
|
||||
)
|
||||
else
|
||||
lpparam.hookNotifyIconOnSet(
|
||||
context = lpparam.globalContext ?: error("GlobalContext got null"),
|
||||
param.args?.get(1) as? StatusBarNotification?,
|
||||
param.args?.get(0) as ImageView
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
/** 之前的版本解决方案 */
|
||||
else runWithoutError(error = "AutoSetAppIconOldWay") {
|
||||
XposedHelpers.findAndHookMethod(
|
||||
NotificationHeaderViewWrapperClass,
|
||||
lpparam.classLoader, "handleHeaderViews",
|
||||
object : XC_MethodHook() {
|
||||
override fun afterHookedMethod(param: MethodHookParam) {
|
||||
runWithoutError(error = "AutoSetAppIconOldWayOnSet") hook@{
|
||||
/** 对于之前没有通知图标色彩判断功能的版本判断是 MIUI 样式就停止 Hook */
|
||||
if (!lpparam.hasIgnoreStatusBarIconColor() && lpparam.isShowMiuiStyle()) return@hook
|
||||
/** 从父类中得到 mRow 变量 - [ExpandableNotificationRowClass] */
|
||||
lpparam.findClass(NotificationViewWrapperClass).getDeclaredField("mRow")
|
||||
.apply {
|
||||
isAccessible = true
|
||||
}[param.thisObject].apply {
|
||||
/** 获取小图标 */
|
||||
val iconImageView = lpparam.findClass(NotificationHeaderViewWrapperClass)
|
||||
.getDeclaredField("mIcon")
|
||||
.apply {
|
||||
isAccessible = true
|
||||
}[param.thisObject] as ImageView
|
||||
|
||||
/** 获取其中的得到通知方法 */
|
||||
val expandedNf =
|
||||
javaClass.getDeclaredMethod("getStatusBarNotification").apply {
|
||||
isAccessible = true
|
||||
}.invoke(this) as? StatusBarNotification?
|
||||
/** 执行 Hook */
|
||||
lpparam.hookNotifyIconOnSet(
|
||||
iconImageView.context,
|
||||
expandedNf, iconImageView
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
/** 干掉下拉通知图标自动设置回 APP 图标的方法 - Android 12 */
|
||||
if (isUpperOfAndroidS &&
|
||||
lpparam.isMethodExist(
|
||||
NotificationHeaderViewWrapperInjectorClass,
|
||||
name = "resetIconBgAndPaddings"
|
||||
)
|
||||
) runWithoutError(error = "ResetIconBgAndPaddings") {
|
||||
XposedHelpers.findAndHookMethod(
|
||||
NotificationHeaderViewWrapperInjectorClass,
|
||||
lpparam.classLoader,
|
||||
"resetIconBgAndPaddings",
|
||||
ImageView::class.java,
|
||||
lpparam.findClass(ExpandedNotificationClass),
|
||||
replaceToNull
|
||||
)
|
||||
}
|
||||
logD(content = "hook Completed!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,139 +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.
|
||||
*/
|
||||
@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.bean.IconDataBean
|
||||
import com.fankes.miui.notify.utils.FileUtils
|
||||
import com.fankes.miui.notify.utils.XPrefUtils
|
||||
import java.io.File
|
||||
|
||||
@Keep
|
||||
object HookMedium {
|
||||
|
||||
const val ENABLE_MODULE = "_enable_module"
|
||||
const val ENABLE_MODULE_LOG = "_enable_module_log"
|
||||
const val ENABLE_HIDE_ICON = "_hide_icon"
|
||||
const val ENABLE_COLOR_ICON_HOOK = "_color_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"
|
||||
|
||||
/**
|
||||
* 判断模块是否激活
|
||||
*
|
||||
* 在 [HookMain] 中 Hook 掉此方法
|
||||
* @return [Boolean] 激活状态
|
||||
*/
|
||||
fun isHooked(): Boolean {
|
||||
Log.d("MIUINativeNotifyIcon", "isHooked: true")
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取此 APP 的通知图标是否被 Hook
|
||||
* @param bean 图标 bean
|
||||
*/
|
||||
fun isAppNotifyHookOf(bean: IconDataBean) = getBoolean(key = bean.toEnabledName(), default = bean.isEnabled)
|
||||
|
||||
/**
|
||||
* 设置 Hook 此 APP 的通知图标
|
||||
* @param bean 图标 bean
|
||||
* @param isHook 是否 Hook
|
||||
*/
|
||||
fun putAppNotifyHookOf(bean: IconDataBean, isHook: Boolean) = putBoolean(key = bean.toEnabledName(), bool = isHook)
|
||||
|
||||
/**
|
||||
* 获取此 APP 的通知图标是否被全部 Hook
|
||||
* @param bean 图标 bean
|
||||
*/
|
||||
fun isAppNotifyHookAllOf(bean: IconDataBean) = getBoolean(key = bean.toEnabledAllName(), default = bean.isEnabledAll)
|
||||
|
||||
/**
|
||||
* 设置全部 Hook 此 APP 的通知图标
|
||||
* @param bean 图标 bean
|
||||
* @param isHook 是否 Hook
|
||||
*/
|
||||
fun putAppNotifyHookAllOf(bean: IconDataBean, isHook: Boolean) = putBoolean(key = bean.toEnabledAllName(), 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()
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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/2/15.
|
||||
*/
|
||||
package com.fankes.miui.notify.hook.factory
|
||||
|
||||
import android.content.Context
|
||||
import com.fankes.miui.notify.bean.IconDataBean
|
||||
import com.highcapable.yukihookapi.hook.factory.modulePrefs
|
||||
import com.highcapable.yukihookapi.hook.param.PackageParam
|
||||
|
||||
/**
|
||||
* 获取此 APP 的通知图标是否被 Hook
|
||||
* @param bean 图标 bean
|
||||
*/
|
||||
fun PackageParam.isAppNotifyHookOf(bean: IconDataBean) = prefs.getBoolean(key = bean.toEnabledName(), default = bean.isEnabled)
|
||||
|
||||
/**
|
||||
* 获取此 APP 的通知图标是否被 Hook
|
||||
* @param bean 图标 bean
|
||||
*/
|
||||
fun Context.isAppNotifyHookOf(bean: IconDataBean) = modulePrefs.getBoolean(key = bean.toEnabledName(), default = bean.isEnabled)
|
||||
|
||||
/**
|
||||
* 设置 Hook 此 APP 的通知图标
|
||||
* @param bean 图标 bean
|
||||
* @param isHook 是否 Hook
|
||||
*/
|
||||
fun Context.putAppNotifyHookOf(bean: IconDataBean, isHook: Boolean) =
|
||||
modulePrefs.putBoolean(key = bean.toEnabledName(), value = isHook)
|
||||
|
||||
/**
|
||||
* 获取此 APP 的通知图标是否被全部 Hook
|
||||
* @param bean 图标 bean
|
||||
*/
|
||||
fun PackageParam.isAppNotifyHookAllOf(bean: IconDataBean) =
|
||||
prefs.getBoolean(key = bean.toEnabledAllName(), default = bean.isEnabledAll)
|
||||
|
||||
/**
|
||||
* 获取此 APP 的通知图标是否被全部 Hook
|
||||
* @param bean 图标 bean
|
||||
*/
|
||||
fun Context.isAppNotifyHookAllOf(bean: IconDataBean) =
|
||||
modulePrefs.getBoolean(key = bean.toEnabledAllName(), default = bean.isEnabledAll)
|
||||
|
||||
/**
|
||||
* 设置全部 Hook 此 APP 的通知图标
|
||||
* @param bean 图标 bean
|
||||
* @param isHook 是否 Hook
|
||||
*/
|
||||
fun Context.putAppNotifyHookAllOf(bean: IconDataBean, isHook: Boolean) =
|
||||
modulePrefs.putBoolean(key = bean.toEnabledAllName(), value = isHook)
|
@@ -1,26 +1,27 @@
|
||||
/**
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
/*
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/24.
|
||||
*/
|
||||
package com.fankes.miui.notify.params
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import com.fankes.miui.notify.bean.IconDataBean
|
||||
import com.fankes.miui.notify.utils.bitmap
|
||||
|
||||
@@ -30,53 +31,6 @@ import com.fankes.miui.notify.utils.bitmap
|
||||
*/
|
||||
object IconPackParams {
|
||||
|
||||
/**
|
||||
* 通知栏 LSPosed 激活模块的图标
|
||||
* @return [Bitmap]
|
||||
*/
|
||||
val lsposedIcon by lazy {
|
||||
("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\n" +
|
||||
"ja7y/c/pL9mciVUiPOsiAAAAAElFTkSuQmCC").bitmap
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知栏小图标数组
|
||||
* 默认使用包名进行匹配 - 若失败则使用 APP 名称进行匹配
|
||||
@@ -2337,6 +2291,391 @@ object IconPackParams {
|
||||
"vQX8J+XSR1NWBQAAAABJRU5ErkJggg==").bitmap,
|
||||
contributorName = "fankes"
|
||||
),
|
||||
IconDataBean(
|
||||
isEnabled = true,
|
||||
isEnabledAll = false,
|
||||
appName = "huazz145专用推送",
|
||||
packageName = "com.huazz145push",
|
||||
iconBitmap = ("iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARzQklUCAgI\n" +
|
||||
"CHwIZIgAAAHlSURBVGiB7ZqtbhtBFIW/syqrZFKFlAW3oKQ/KDXKGwQF5AlaXhSzqq9QGCmopLwk\n" +
|
||||
"CqoTEhIWJSwkUkHU4FPgdeVsbGt2Z+2ZXfmTVpbGnjvn2Ds71zNXBGJ7COwBb4Gt8noe2j+QB+Cu\n" +
|
||||
"vM6BH5JOoqPaHtj+ZPvM6TgrNQyamhjZvk5ooMq17VETE7kSZsZ5m5iy3Iztw9QKa3DYBxNT/v8y\n" +
|
||||
"Kk0MgAtgO3Aa5cIN8EbSfVE2HNA9EzDRfAAwNbKfTks0+wCy/R74nVhMLB8KJmlH19krgJ3UKlpg\n" +
|
||||
"p2CS/HWdLdn+S/tZ7Lp5kG3X6BCTUr8AXpavobGHwdHrLKMNxM8bb1EuN6p8blhHW7FowFUhaQTs\n" +
|
||||
"th137UYAJP0CvrYZ81lM5+rtsIBbSd/ntP8EvsSMP0uUEeAjARPS9mdJryvNV5FjP2Jdt9Yr299m\n" +
|
||||
"GyT9aXOAdc6Rd6sM3qaRE1Ugbt2pRZKn1irYGMmNjZHc2BjJjY2R3OiNkdi/utXMN+b9SyYnVcv6\n" +
|
||||
"L6Q3mw8FT7+FLnLXKyOnqVW0wGl/NrEljYFxaiURjCWNp+vIcVIpcRxD347eJN0DR2k1NeKo1P6Y\n" +
|
||||
"JfuyOTL/eHrGTBeOqYOrH3I206gepdtFNTNmOlPmpBqmsi48+wccWLnZenD1xAAAAABJRU5ErkJg\n" +
|
||||
"gg==").bitmap,
|
||||
contributorName = "fankes"
|
||||
),
|
||||
IconDataBean(
|
||||
isEnabled = true,
|
||||
isEnabledAll = false,
|
||||
appName = "游戏高能时刻",
|
||||
packageName = "com.xiaomi.migameservice",
|
||||
iconBitmap = ("iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARzQklUCAgI\n" +
|
||||
"CHwIZIgAAARNSURBVGiB3ZpPaB1VFMZ/JwRBYqQboS/FkEhAE6GIwUYXYoIbG/wDQhaVQhDERdoI\n" +
|
||||
"glB3iRREBKloIkiwSxdxY0WDCPqiIGppjUJTW5EKYvuKGERfA27kczHzePPuezNz7/vb9oMwb+69\n" +
|
||||
"55zvu3cm988Zo02QNADMAlPAEFBIXAFKwJXE9Ttgw8x228WhaUgalfScpHU1j/XYx2gvBIxLWmmB\n" +
|
||||
"fBpWJI13Q8CwpNcklTsgooJyHGO4UyIWJJU6KMBFSdJCu0WsdVGAizUfjuYh4ixwf8u90Rq+N7PJ\n" +
|
||||
"rAaZQiSpvXxag5ml8u1Lq5D0YWfoNI9gTpKO9fCdyMMxXxHzvWbqgXmXtzkihomWDnuDhrD7uApM\n" +
|
||||
"mdlvlYJ+p8ECYSL+Bt4HzgCXgAeBR4DHPGw/Bb4EvgXuBO4Cnidan+Vhb8z15boaRcuOkBn7E6XM\n" +
|
||||
"vpIOS9pKsduSdDjFrhD79UFZjZYzCls7/ShpX1aXSdoj6YRjd0LSnhy7fbF/H6y4xmMBIiRpNouM\n" +
|
||||
"43tE0rKkkQCb2QAuY0nDxQDDZV9CrUDSkiefRahOiAcDYnzeftoN8YVnu4MAJmkQ+MfT6KKZ3ZMs\n" +
|
||||
"kHQr8BQwAlwGzpnZlqc/KiNsZnUjLekCcLeHm9uRdCjgsVp1Aj0kacdpsytpKUBI6uMqadWT16E+\n" +
|
||||
"IHNV6eAD534N+A94k6jnngX+AJYlPRPg1zdeGib78ZuAAP41s83KjaI55F7gHTN7MS7+WVIBeBV4\n" +
|
||||
"lGiyrIGk6UbOk+WVOGa2KWkXGMjhNoSkoufwbbuB4/I6YnF5MY1wTpyi0/60B7diyIj86txfjK9L\n" +
|
||||
"QHKkXop/XsjwNZP4XQReSfpwsA08kMNtqJ/quVMeaoSYWUnSJjAt6SvgJPAE8DRQBt5r5CT5eAIo\n" +
|
||||
"3ru55Qmc9+BWcBeNWXBHBDObkfQWsAg8HBd/DbxuZmcCfGdhO79JtPotAYMebS81KjSzFySdBKaB\n" +
|
||||
"HzJ6Ng0zOfU+I1IKedkPBBJsG3xe9j6iEfHBn50k2yJK/UQHyj7Y8fWqaKl+H3BH4m+HqDN2gPNm\n" +
|
||||
"djmMayauIGnO89G6xUPAEaVvqFz8IukNH5YevuaQNOAZOPMsVtGeoxk0nDgTfgsePgYqjX3SAlMZ\n" +
|
||||
"wfJm6zwczfA9mWO7DtX9yGdZvRLjyZRAE8C7HvZZeFvSXEpd3qK2yl1RwiYP11wPkiYknWttMGpQ\n" +
|
||||
"J0bSRzk2o5A411K0kT+So/534Buijdh+YIL8lWkotokmwb+Ijpf2Z7RdNbOjUCtkHDgN3NZmYp3C\n" +
|
||||
"NeCAmf0EiUPsuGA1zeo6xGpFBNxER6Y1aYW44ni3WTWB40kRqVBvU215aJiKS80A6fpIublITcHd\n" +
|
||||
"/Km3hOGptjMKx6ksEd5Qb1Nxfqm2ADHz6v4HA3UptnaJufE/4XAE3dgf1TQQNKYot7LRAvmN2MdY\n" +
|
||||
"fsR0tP6foCpqEHicaP/g8+HZWeBjMyu3I/7/yvcaMeUIKhcAAAAASUVORK5CYII=").bitmap,
|
||||
contributorName = "fankes"
|
||||
),
|
||||
IconDataBean(
|
||||
isEnabled = true,
|
||||
isEnabledAll = false,
|
||||
appName = "风筝守护",
|
||||
packageName = "com.kiteguard",
|
||||
iconBitmap = ("iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARzQklUCAgI\n" +
|
||||
"CHwIZIgAAAMwSURBVGiB7ZlLiI1hHMafP7JiSC7NxAZRbAZlksQKI03KZSMLC7KgLERsZqTUZGc2\n" +
|
||||
"lB0LTbkmTBozGWSjIaGxYGpcIgkjC6mfxXfo853vPee7vXOk89ucc97L/32e733P996kOnW8YFkr\n" +
|
||||
"Ag2SZkuaIumdpLdm9iNljImSmiQ1Svoi6bWZfc2qKU3DS4DjwHPi6QbaEsTZAfQ4YgwCR4Alvkwc\n" +
|
||||
"BkYdjUe5A8yNiTETuJIwxihwuGgT3Qkbj7IiFGNNxhjdtTbxm0U5TBRjBujIKQBgBPhQQJz2rCY2\n" +
|
||||
"FtB40Wx06R1XwcvuTE/AL05NsfMIsE7STW9y8rHBzG5EE109ssqzmDy0xiW6jGzyKCQvsUbKhhYw\n" +
|
||||
"WZL/ZUI+GsxsNJwQ1yONYyQmD2Ua44w0jYGQvJRpjDPydAyE5GUomuB6/X6QNMO7nGx8NLMyba63\n" +
|
||||
"1r/cK2W9IbmNXPMoJC+pjNz3KCQvd1OVBvpquz6Mxbmcd+7ZgTWS+lK5989SMxuMy3Cufs2sX9JR\n" +
|
||||
"b5LS0+kykQjgYsZhcBXYAzQXaCYfwK2UJrbXWrMT4FRCE1210JfqgA44KKmzQpEeM1sfKt8iaZek\n" +
|
||||
"+ZLGS5pQ5TNJmceSrphZRxrtcWY2V+iN9lC5ZSmHY1q2hnVV2rPHYmYXJK1wZD8Mfd+WNnZK/jpV\n" +
|
||||
"qWiE4EyqHTgH/NmZmdkDSfMk/YxUCS+vl+dVWoXFiUoBK2O68xIwNVRmEjAUyj8TypsGfPU5tsJ6\n" +
|
||||
"K83sXZL2xmT1S9ppZsOhstcV7KW/SWoxs2el9FZJayW55pIFyrGRM7PqL6vS03cxSGSiA06X8u4l\n" +
|
||||
"EUEwZAvrkUoNVTsufUWwHgvXOVbKOwc49/4Eb7Q3RRqp2DVAj4Kh4eKzgmF2OVRnn6STkj5JGlBw\n" +
|
||||
"CfQ+Um+/gguiXISHVtUxBnRKOlilWK+Czdij0u9Zks5nFRjDgKTb0cTUkyLBDVOtOEFwRVcMQNsY\n" +
|
||||
"G3gBbCnMQMTMaoI/uW/OAnO8mAiZaQZ6PRkYAeLmLq+GDlHczP0EOABMz6on8z17yUyzpKWSFipY\n" +
|
||||
"qk9LWPW7gmOdl5KGJd00s+i6rU6dOnX+Y34BelGWTLj6gEEAAAAASUVORK5CYII=").bitmap,
|
||||
contributorName = "fankes"
|
||||
),
|
||||
IconDataBean(
|
||||
isEnabled = true,
|
||||
isEnabledAll = false,
|
||||
appName = "醒图",
|
||||
packageName = "com.xt.retouch",
|
||||
iconBitmap = ("iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARzQklUCAgI\n" +
|
||||
"CHwIZIgAAAL9SURBVGiB7Zg/SBxBFMbfRhCvCyJE0RSBiGAhgnhG0opNQIgg2JxwmLSCjRARki42\n" +
|
||||
"imAjQiClXGGwCCpRESQSkBQHBxYWAa3sgoJJo78UN4d7sjczO7vrErkPtrl57/uzO/eYXZEEAOxS\n" +
|
||||
"G7tJaD5KglRE/jiuOaMexIC/jmvOqD8RA+pBXJFGkP/qP6Iz+2CeSD2IDvUgBlw5rjnj4T0R4D3Q\n" +
|
||||
"FxNv4kGAPuBD0EIRuAIKQA7IRBAZ0BzjByLwZpS3gvJavFvQHSBYAj4CWQfBHk2QHge+rPJSCuDr\n" +
|
||||
"9hdOaYRvgA3gDdBoKdyp4eu05GhUmhvKQy1M+Zt0b3R+nACLGP5LQLuGo93Q26c0Tiw97VYas5YN\n" +
|
||||
"d7EF5IGGADPNmr7mgPoGxbXl6CUrwKxjcwWnlO9gr89YRlOf8dX1qt7TiB5mBdiLSOLHN2BCmQyE\n" +
|
||||
"WptQtXFhzwOei8ioiLwWkRe6/RsC5yLyxGEtLH6IyBcRWff8vwKPpRxqVERexSQWN76KyLqIrHue\n" +
|
||||
"99uqAxgBPgMXMW6DsLhQHkZ0Xj3d4p1QL+V2Cz6z7XPEL6lsGc/7npgK0AW8A45ivPNHirMrMeOG\n" +
|
||||
"UC3AW2DTwfym6m1JxbwOwLlFgPO0fWoB7IR4Gjtp+w0EsOSwtZbS9l0FYNIhRAWTafsXERFg0GD0\n" +
|
||||
"k7p0GEw7RAdwqTF4DDxV17Gm7hLoSDPIoeFOj/tqxw21h2mFWDUYWw7oWTb0rN53iGmDoZ9AU0Bf\n" +
|
||||
"k1rTYfq+QowZjIDmgEf5IGrCWNIhBoFrg4l5C555A8c1SU0yyhOqaDBwEILvwMBVJIlJRvmjmA43\n" +
|
||||
"QH8Ivn70n3kACnGHWDQIAsw58M5Z8C7GFcI0oQC2I/BvW/BHm2TYTahLoC2CRhv600EFbpOM8oQ6\n" +
|
||||
"sxDIu4bwaeUtdM5wmWRAK7BvIF+LGsKnt2bQ2gdaowis1CCO/S2P2m+XK3EJzASQD8dCXq0zHKAz\n" +
|
||||
"E7dIjtvvWwuxklfrLCiNCyCXlMgQUEqEvFqnBAyF6fkH9qu11MPcAhUAAAAASUVORK5CYII=").bitmap,
|
||||
contributorName = "fankes"
|
||||
),
|
||||
IconDataBean(
|
||||
isEnabled = true,
|
||||
isEnabledAll = false,
|
||||
appName = "小米运动健康",
|
||||
packageName = "com.mi.health",
|
||||
iconBitmap = ("iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARzQklUCAgI\n" +
|
||||
"CHwIZIgAAAM3SURBVGiB3ZoxbBxFFIa/OaUiJAUN2IUlS44gDZGwRNpQuAClQ64o3LhylA4p5dlK\n" +
|
||||
"Q+HSqdJSWRQEIRepaImUSCBFxoImFHEiIQobEN1HsbvJ5bjd2303dxfnl1ar3Z15838z2tndeZvI\n" +
|
||||
"JPU88BlwFVgEFgb2AMfA04H9j8BBSunvXB7CUpfVTXXfuPbLGMvzALis7k1gvk576uVZACypX6mn\n" +
|
||||
"U4CodFq2sTQtiC31eIoAwzpWt3JD3J0hwLDutvGYWkA8BD6auDcm06OU0mpTgUYQ1bx+JlNKqdZv\n" +
|
||||
"r+6C+u107MTV2ZN6a473xDjdaguxMW+nLbQx7DsNQSxRvDq812kIZ69nwNWU0u/VieF7ZIvXHwIK\n" +
|
||||
"j688Y16MiMWrwQPg7Rmbiuov4OOU0iG8OiI3ODsQUHi9UR0kAHUF+DUY8B+gD/wM/FSeuwJ8CHwJ\n" +
|
||||
"vFueew7s1pTbAd4Ktn8ppfQbAOrN4OzxRK194qoL6nflttBQbrWMFdHNwUAHgQCHwR6slXoY8HEA\n" +
|
||||
"kNQLwEmg3Q9SSkeZQd4HfglUvdgDrgcq7uSGAChjbgeqXu8BjW+VNYr0Wlv9Eaiz2qNYIOiqR20L\n" +
|
||||
"WnyT73eI/SzgZ/EcL1c5uqhLr613jP1vx/IAC9ER+XRcAfWaeq3uuEFXAn4WUU8CU97XYyC2G+o2\n" +
|
||||
"3szqNwE/J7UfVmP0hbrWcP0x8EO5VaqOHzdArAGfhxypR4EeUL3fMr7a7pNZvR/0ctSjWL6MaE3t\n" +
|
||||
"B+uOgugDTaPcpKfnKNZio9pWSSntNJT5ZFyQEiLyIKx0jLobHM5BhUdG7Wdofxd1PUMgDcDYPLt1\n" +
|
||||
"0Trq+UzBtAOM+SC0SGm8eI3IpbEw5oXYHwy8mTGwNsCYF0J1czD4cubgOgLG/BA6nCByOomb/pQh\n" +
|
||||
"9qr4s1gO+rPcv5M57ujloPLEncyNQQGQGwLgTgUBb+qSaXnh9qxdBXR7EKJWzjfVNk4jU3G1GSBf\n" +
|
||||
"j5TbsGpTcG9+6m2g4r3sjrrrXhNEaznfVFy7VFsHmA1n/8PA/1JsuWDO/i8cQ0Bn+6eaEUArFrmV\n" +
|
||||
"SFqi0kEZY2USL5PPBC+hLlCs7K/S7sezh8D3KaXTHO3/B+D2/g8/PXZgAAAAAElFTkSuQmCC").bitmap,
|
||||
contributorName = "fankes"
|
||||
),
|
||||
IconDataBean(
|
||||
isEnabled = true,
|
||||
isEnabledAll = false,
|
||||
appName = "王者营地",
|
||||
packageName = "com.tencent.gamehelper.smoba",
|
||||
iconBitmap = ("iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARzQklUCAgI\n" +
|
||||
"CHwIZIgAAAPnSURBVGiBzZpPiFVVHMe/Px2kUDGZEjXKUqmMmJqKolaWFlRKE6K4tM1EQS5FaNHY\n" +
|
||||
"n1VQO23RokWLJoMJWxSEDjQIZRMmWhjZWJGNoYimaWnxaXHPme68ec93fvfd+977wOHAub/f+f2+\n" +
|
||||
"73fvPecentRGgD38z8vAinbGLwVgiJmcB3YBSzqdXxLAYB0ReY4A6zqdZ1OA8SZCpm63TufaEODZ\n" +
|
||||
"RBHdLQb4zCmk+8QA1xQQEXnQE2tWVSICy1vwfcJjXLWQW1vw/dZj3K1CdpvZbo9DT8FAqUQhj0ha\n" +
|
||||
"G1qje/+KpDFJY2Y25A1khdJLBBiRNCCpz8wO58ZX1zHfb2ZXqsynMMBoeAP1Vh2r6mck8kfVAdol\n" +
|
||||
"5PqqA5T+sAOzJS2VtDg3fIOkybJjlQqwENgKfA78AJyrs0pvCrZ3AVuAWzqd9xTAKuB14JfELcfz\n" +
|
||||
"wW8zcCq8CIaAOzsp4k3gb/fuCV4K/q/VjH8AbGyngBXAgQIC8gyEuT6qc20MeKpqEZtbFBA5CFxH\n" +
|
||||
"9qOcaGCzE7i5ChHbShIReSvMW+87PnIc2FKmiI0liwD4C7gdWELjqkR2dauIyKshxtWqEvmkW0UA\n" +
|
||||
"TADzgXsT7bcXEZFS8jKIa8veRPsNjXJutNcaVLbNqJqB0H+caP8h9T8BZn6PkJ36jas9QiSpT9Jl\n" +
|
||||
"SUcT7SckPW1mR/KD9SrSrmpE1pnZ95L2J9ovl/Ri7eA0IaEag63n5mJ96EcdPoPAffmB2ooMqL3V\n" +
|
||||
"kKSHgJWS9jn9pv3gtULWtJRScfrNbFTSbw6faVWpFfJoKWn5uSf0406/qapMCQEel7SwQBJfS3pO\n" +
|
||||
"0h1mZpI2Kf11GukPvVfIkzNGgDcKLGgNH1BgA3A6cZ7J4LO6QA731wb+yjlB07cM0E+2i03htuBz\n" +
|
||||
"2ZnHVmn6M9KXVMyMbyQ908zIzA5K2pE4Z3xwU9eTyMNSEAKskjTH4fyemZ1NMTSzdyV9mWAahRx3\n" +
|
||||
"5CHlhchXjbOShp3BPk2wKSrkJmBOESHDZvarM9j7CTZRyIRzbkmaG4Xc7XDyVkNmdlTSF03M5gML\n" +
|
||||
"5K+IJM2LQpYlOpwIK3AR9iTY9KpFITcmOvxYIEjkZIJNr5lNSvrXOffcWWRntakr+jFngDwpQuJh\n" +
|
||||
"9wXn3PN65Nvt/uQMkCepIqG/IGlBneuHld0Vp0JbJGmlpPEeSZ7/gfzssK0l5TQ+LyTPDkkjZnao\n" +
|
||||
"kWOPmR0gOzDrl/R7aKclXQztUuj/DK0QZnYSaGYWb63zubEXzKz1s60yAd4BvrvKvmlnsBsBzhDO\n" +
|
||||
"ibsS4FrgMeAVsmOgSzkhw8HmH+CBTufqAlhKdkD+NrA3jLnPDf4DjheH8k6I1TQAAAAASUVORK5C\n" +
|
||||
"YII=").bitmap,
|
||||
contributorName = "fankes"
|
||||
),
|
||||
IconDataBean(
|
||||
isEnabled = true,
|
||||
isEnabledAll = false,
|
||||
appName = "小米金融",
|
||||
packageName = "com.xiaomi.jr",
|
||||
iconBitmap = ("iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARzQklUCAgI\n" +
|
||||
"CHwIZIgAAAPCSURBVGiB3ZrPaxVXFMc/5xGXRd0YQXCbRUIadBP6w0WLQcGFG/0DSim4cCMoggst\n" +
|
||||
"uGizqnTV+B/ETc1GiYgopdhFk5egYFaiIOa50KoglP74djGT1+lj7p0zM2/mNX5heI977znne+bO\n" +
|
||||
"vfece68RgKQZ4AAwAUwDM8DeUPuGsAl0gXVgA1gxs65bWtJZSa/1/8NrSWfzOFuOE8vA4WovsDXc\n" +
|
||||
"MrO5bMF/HJGkdvnUg5n1+Xe2/kj6bjR0qiPL2dKCE8DiyBjVw0kzu2aSpoFbwJ5RM6qIF8DhDjDL\n" +
|
||||
"9nUCEu6zY8BUg0bWgZ+Av0nWowlgfwN2psaAyQYUA1wHvjCzl9lCSTuBT4FDwOcki25dTCKp19Di\n" +
|
||||
"9XGRdUk7JJ2R9LimrR71+ebiUZnXKWlc0mIdg51iM5XwZ5nGZtYzs5PAtaoGm3JkUsnaVAqpM19X\n" +
|
||||
"sjiUDymMgxU5XSpryKTG46t1YC39XQfWzKzncOYq8KXbyrC7wIlLDl7jKjGbNTVGinBR0p1Yg7TX\n" +
|
||||
"vvcqbOPTihPIhOKDkLQDuI9j0RxVj/Qh6YdQnZn9QRLiFKINR56lTwhfSToVqf/ZZaXkIH2QPh6s\n" +
|
||||
"SjqesXM8LQshd2ND0m6PMa8jPyoTO0k6UdB+KfLilgIyRyIyT4bhyKqkXTnKD0ZkjkZIHQ3InI/I\n" +
|
||||
"LBeR9IyRFTP7bbDQzH4lWeAGsWlmN0LK0rrNnKoPIxw2ikh6HHkXqVvLKfvLoTOvjUcuCI8jE5G6\n" +
|
||||
"vB7Zp8wgH0Raty+n6peKHPqKi/AkIjsXkFmNyIRmrs8iMkMZ7FKSnuYZGI/ILCkz6JUM8tCMJUm5\n" +
|
||||
"GyCSdnoIeh05FnlbRSH38/SJIRhESjrmIeh1ZD5kKDV2x6knD9HgUdK8R4k3aOwCh8zsbcRgpeCz\n" +
|
||||
"7aBxBrjgILTg1AewEHMixWm820UlP4PgzJLRd8qhJxYkbukplViVzUe6wKyZ/V5AYi9JL87w74q9\n" +
|
||||
"lsp3zSxvZR/UsQj4NzBK9ogk3XYrrwhV2OOqmrNfbNCJ0jsodRyRpAUls8rInajriCTdlWMCcDgw\n" +
|
||||
"LulqHSKoeNX14BtJH1RwYFib2M9N0g0gmJ2VQBe4R5JjL5vZqwD53cAc8BHwCcM5Vrhpkr4Fzg1B\n" +
|
||||
"2SCekiREW0lRkwc982M4sq+K2J8+bZzZb3SAFeBNC8aawhtgpZPe7bg8ajY1cNnMuv2gTdvj6sYg\n" +
|
||||
"+lc53r8rHJmKK60zKo8rjhSgv5PY1GlvHfQUONKLZWfTJLcipkjO4qdo/4bEC+AB8DD9vW9meVtQ\n" +
|
||||
"/AOiEUtV2iHH4AAAAABJRU5ErkJggg==").bitmap,
|
||||
contributorName = "fankes"
|
||||
),
|
||||
IconDataBean(
|
||||
isEnabled = true,
|
||||
isEnabledAll = false,
|
||||
appName = "番茄免费小说",
|
||||
packageName = "com.dragon.read",
|
||||
iconBitmap = ("iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARzQklUCAgI\n" +
|
||||
"CHwIZIgAAAM6SURBVGiB7ZpNSBVRGIbfM0UZ2UZTC0Vq26qSiDLQTa3CaOFCiogWRe7EFkWLWhYt\n" +
|
||||
"iiCSwEX2A+76oU0Z9kOurAxSW4RJ6SZByHRRBE+LmSvXaebeuXfO9aj0gDB6zved9z1nzty531H6\n" +
|
||||
"jw9QDjwCpoBuoCVBTCNwGfgE9AMbFkNrPlHNRPMAOAFsDPq1BEanIvo2p9Vh0luRgF+S1hQZ/tsY\n" +
|
||||
"szatBi9tgoBnjmLnsWVk0FHsPKmNADWSmlKk2BbkcANQBpwBxmM2eyGMB7nKSi16fej3VuCDBQNh\n" +
|
||||
"PgCtobHW2TJxA9ga+lt/CUxk6A+NVQtcyaczdo8AVUHSdknVoeaXkgYkfZY0k3RScjAT5BoIcmdT\n" +
|
||||
"KekM0FNwVvwPuS9Zs3QhT/8yoB7YBZxMMOsdQd968uwLoD17tYAtSU3sixh4EthcwER05jDRWUCe\n" +
|
||||
"KuBzrlsvV/DjGAFPgNoCRHRF5OgqIH438CZGy8V8wadyzCT4T5WbwHFgBxDeO+F8fVmxfXn61gA7\n" +
|
||||
"gaPBGD/zaIl+P8N/OozlCY5iFhgBeiNy1gN3A2H1Ee338d+AZ4sYN/oWA64XkSxMIbfOWQvjHQsn\n" +
|
||||
"LQe+W0gMcDqBiUOWxnpeqsQZYr9c4b+K2KRZklYH+Q8kvSUS8hDolv/h9lrSH0l7JB2W1GZ5rHZJ\n" +
|
||||
"L4wkAd8lVVkeYDGpXhUsTbtrJSmZ8yTtd63CAjWeJHdfauxR7Una5FqFBapX1IqsCCOGdDWppcKc\n" +
|
||||
"J+mraxUWGPEkvXetwgLDnqQh1yosMOJJ+uRahQWGPUmjrlVYYMQzxoxKeutaSQqeGmPGM3WtW06l\n" +
|
||||
"pKNHyjofAQYlNTiTUxzvjDEN0sJK43JclTuZiwUnVstsVb5J2m6MmZb+rf1eW3w9RXM+YyIS4JLl\n" +
|
||||
"4kAp6Ehklfiy6VLgapTm2FNdYEzS1rh2RwwZY3ZENeQ8ngYmJCUuXJeYaWNMZVxjzsNQY0ydpHPW\n" +
|
||||
"JRXOvVwmEgPsBT462A8TwBELE7HATDl+VX2xuA1UWDURMtSEX7mfLIH4cfzH/96SGYgx1YZ/kpWW\n" +
|
||||
"XuBgGi22/qmmQlKjpDr5T7na0LUkTQY/E6HrV8aYHzZ0rAj+AnsRptwbFr9eAAAAAElFTkSuQmCC").bitmap,
|
||||
contributorName = "fankes"
|
||||
),
|
||||
IconDataBean(
|
||||
isEnabled = true,
|
||||
isEnabledAll = false,
|
||||
appName = "同花顺",
|
||||
packageName = "com.hexin.plat.android",
|
||||
iconBitmap = ("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\n" +
|
||||
"Kqiggv8u/gGVZUO4tuzkNQAAAABJRU5ErkJggg==").bitmap,
|
||||
contributorName = "fankes"
|
||||
),
|
||||
IconDataBean(
|
||||
isEnabled = true,
|
||||
isEnabledAll = false,
|
||||
appName = "新浪财经",
|
||||
packageName = "cn.com.sina.finance",
|
||||
iconBitmap = ("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").bitmap,
|
||||
contributorName = "fankes"
|
||||
),
|
||||
IconDataBean(
|
||||
isEnabled = true,
|
||||
isEnabledAll = false,
|
||||
appName = "雪球",
|
||||
packageName = "com.xueqiu.android",
|
||||
iconBitmap = ("iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARzQklUCAgI\n" +
|
||||
"CHwIZIgAAASRSURBVGiB3ZpPaFxFHMe/k4oHk0ArgdgeUkO2aGKpYA6l5iIeQlIkiDSFgphWg9BS\n" +
|
||||
"zz2UkooeihQPGpTQgxelNKIk0gaESC5FEGzQqC2xHkRooogKiaUBWz8e3mz3l8m+3Tdvs0nrFx47\n" +
|
||||
"O/P78/3uvjdv3m+e0zoBaJS0X9JeSTskbTefkrQoacF8fiVpyjl3c7045AbQDgwD4+THuI/RvhkC\n" +
|
||||
"OoHRGsinYRTo3AgBbcAZYLkOIopY9jna6iXiGLBYRwEhFoFj6y3i3AYKCHEuC0eXQcQVSU/V/GvU\n" +
|
||||
"hlnnXHclg4pCANaXT21wzqXybUgbACbqQyc/ojkBJzbxmqiGE1lFDG020wwYCnm7QESbkqXDI1F/\n" +
|
||||
"4WrckDQhaVbSvD9WJLX6o1fSAUlP1JDjV0l7nXO/lB0luRHlxQTwMtCShQkwAEzXkO9MWuBO8t+x\n" +
|
||||
"p/znYJm4u3zsLSl5h3PmXKbccob8a6dB71+86w8CJ4HPgT+N3T/ALPARMBLk7s+ZezQUUcgZ6NEg\n" +
|
||||
"zl8RvpeBQuCfBwWpdB/pL3u+VUbBOfez7XDObZP0bUb/HknXgSOm78kcPErcKZ3jWXHU+O4H3rSR\n" +
|
||||
"gcnIeH3GN/aamSo6Nkc6XjRJtwF/+/63AzHvRMZtNb6xs1mzgEORTi+ahO8FY+8HYt6qEmvetM8b\n" +
|
||||
"v4FITocEnI1wuAY84JO9lGLzQSDmjRS7ET++z/SdNn7XI3idbVBSIMiKC8652779bIrNYcyv65w7\n" +
|
||||
"JWk6sDntnHvdt383/fa+MBnBa4eAmQjlh4uewNdVbO2v+4zpD+8htnAxZ/qfjuA1I1afp9XQYxKt\n" +
|
||||
"VLHtNbbFa6WSCIDb+BUA0BHBa17AUoRDi0/SVcVu0JB9HrhDdRFF7PbjTRG8lmKFNPkknRVsrIg+\n" +
|
||||
"4CbZRQA87m1aIngtxZ5aHT7JFpK1Uwgrohv4A7gFNJv+sQrxbxm7nghe8w1KypdZ0SpJzrk7kr4L\n" +
|
||||
"xg465z72JHZK+kzSw5JWnHPLxu7fCvG/Me3HIngtNCipxWZFr2lfM+05I+IhSTMqTetbgVeN7buS\n" +
|
||||
"fkiJf9W0Yyo3i7H/yAHT/tG095BMl12SLksK67hjxdPOOXdV0kGVF/OlJAFbJb0QwWtBJM8PMRgo\n" +
|
||||
"epMsxWNgr6Eu4HszdsmMvRIdF2iMdJo2CfM8x6SJ2Wn6L0XGbCw6xm4LDJukRyJ9Ya2Y4+b70chY\n" +
|
||||
"4zLOeZ6b+41/Xw7/cs/3HcCNyDjDNkB7DiIEJFqB85Eh7D/TBHySg8bqiYX8xYc9QZwR4AIwR7J2\n" +
|
||||
"CjFGcrM87r+PkFxrX+TIvbr44AnUUg4aXhNQd1cAuz3x7WXGizPmbI6c5ctBPnAtBbppzNRcDV7E\n" +
|
||||
"h5QelWOxqkBXj5LpT0oeij6V9Js/HpS0S1KHpDZJA5L21ZCjcslUurvFdq8j25Ycm7vVVg1lt+JS\n" +
|
||||
"d4C4N7bcQqRuwf3/t96MY0w1o16YrCQiM9jcrbhsW20RYobY+BcG1myxrZeY+/8VjkDQ/f1STRlB\n" +
|
||||
"BeA14rclLKZ8jEL1jOmofSYoiWqW9JykbmV78eyKpItBhSU3/gP4Pjxh5shJaAAAAABJRU5ErkJg\n" +
|
||||
"gg==").bitmap,
|
||||
contributorName = "fankes"
|
||||
),
|
||||
IconDataBean(
|
||||
isEnabled = true,
|
||||
isEnabledAll = false,
|
||||
appName = "企业微信",
|
||||
packageName = "com.tencent.wework",
|
||||
iconBitmap = ("iVBORw0KGgoAAAANSUhEUgAAADwAAAAyCAYAAAAA9rgCAAAAAXNSR0IArs4c6QAAAARzQklUCAgI\n" +
|
||||
"CHwIZIgAAARHSURBVGiB3ZptiBVVGMf/z9UgZC2SwqDQwt5YyiKjNqwUqQwsgmBjDZaWXjcy+iRE\n" +
|
||||
"FG30paAghNo2ioICZaMX3MUgIZNFWiyp1ChyaUvYVgryg5EWwa8PMyPj7MzZc/bOzN3rD4Y7c+d5\n" +
|
||||
"nvP855yZM+ecMZUE0CVpg6Q1kjokLY5/k+03SdPxluy/b2YTZeVQKcACoAcYBH5l7owBTwCXtFpT\n" +
|
||||
"LsBZwJPAd02ILGI7cEerNUqSgPOBp4GJCoRm2Qrc3EqxG4GfaxCa5W1gZd1iX22B0DRHgN66xI63\n" +
|
||||
"WGyaF8vQZA6xlFFAyXxgZvc2E6CR9yews5mgFdINDJUaEXi2pQ3Xj3vmqu+UJg30Sxps+qrVw/Vm\n" +
|
||||
"9lWo00nBwAZJo6WmVC2fmdn6UKf0PdxTYjJ1cDvwaKiTSRLQKWm/pAVlZ1UxhyStNrM/fB2SGu5R\n" +
|
||||
"+4mVpEsldYc4NIAzJW2sJp9auDXEuCHpNknzc2jmR7DgdhYrSYuBtb7GDUkrKkymLs7zNTwdaliS\n" +
|
||||
"zvE1XKj2q+G/FHWheyVdIOlGBQg2mJejoiKelzRkZtNzDbBQ0kFJV5aWUnXcbWbbmw3SkHSghGSq\n" +
|
||||
"5q2sWOAKYGlooIaiGp7P/GRmDycHwADwpaQfJB0hmj29xjdYOwgeyRxvltSVOl4p6QXfYO3QpE8O\n" +
|
||||
"WYEHJS3KsbkT8BrtNcxsUtKekpKrmr8d59b4BEhGS00//SpiTNEaVMI+h63366WAy2uflXLzO/BK\n" +
|
||||
"Qa6PAScK/LryfIpEv1SbnHy+IXoCrwPOyMlvABiO928C3gEmMzF2Ax2+gs8FfqxP3yn0OfLqBEZi\n" +
|
||||
"u4Gc82uJLkbCuyG1fF/NQgFyJ+KA5cAmYCq2y3ZPWfv7gWOx7YwL43J8qkaxM7oSoBcYBo6n7KaI\n" +
|
||||
"5t1my/0WYBfwHLAE6COq/Qec/sDrNYg9milzPfB1ge0m7xqLYi1i5rrY98DFLqfR6rQCsCNT3liB\n" +
|
||||
"3XFgeaDgzQWxtrqclgH7KxCasCVVVqfDbjhEbByvaNVzOncxTZLM7LCkN0ILC+C/1P6EpH8K7JwP\n" +
|
||||
"qyzA1ZJuKDh9sFBwzOGQwgK5MNkxs38lfZJjs8/M3guM65rFdF884KGy23GKo6SGdUAH0RdBCZPA\n" +
|
||||
"ukCxAj7NKesEPl0V8EyFggE+zilzFalpV2AvsBNY5ZHvy5n440Td0rW+V+u1igXDLA8loD+2+xN4\n" +
|
||||
"xGH3eCrmEJB7Hxd+8hAH+VCSa/F5VNKbikY1SyRdldqWSTo7tUnRZMMBSd9KGjcz1+gnncegpP74\n" +
|
||||
"8HNJ2yRtM7NjKZtkMvI637h5Be0qqJUR4K45BZ1bHh3AnkwOvwBbgO5UrkELa3kFfdRKoZlc+hy3\n" +
|
||||
"hfe782xNeoWkXklLJe0ws6A+sUyAiyRNFpw+ZGaX1ZlPLThuMfBcUJvtxWO+sbvg/ykz+8InQLsJ\n" +
|
||||
"LurC8t7STg+A1UTjZYiGk0HfYf4PE9Jhxv7m5/gAAAAASUVORK5CYII=").bitmap,
|
||||
contributorName = "fankes"
|
||||
),
|
||||
IconDataBean(
|
||||
isEnabled = true,
|
||||
isEnabledAll = false,
|
||||
appName = "消息接收",
|
||||
packageName = "top.tdtt.news",
|
||||
iconBitmap = ("iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARzQklUCAgI\n" +
|
||||
"CHwIZIgAAAP8SURBVGiBzZpNqBVlGMd/z+UWRoRhkWRiUvR1C+FKZgqBC1sY14jqJmEEUlwwpIW1\n" +
|
||||
"iDYJSdBGokWLVi2MSjBB+iATJaNULE3TW1rgV18uFElSwsWvxRzzdJw5Zz7ec+0Hw4H3zPt/nv/7\n" +
|
||||
"zsw788wENVEnA48Aw61tNnAC2Af8BLwbEfvq6k8I6iL1G7tzVn1dvely55uLurGHgU72q0P9ziuq\n" +
|
||||
"7KzuBWbViHMAeCIixnvo3w4sBkbamj8DNkXE7hpxc4O8WHEmOtnVQ//ZHv3XpDAxVT3S0IjqkgL9\n" +
|
||||
"VSX7v9/UyNIEJlQ/z9EeqqjxZF6OgyW93NNoJC6yUP0UONPaTgN3VdR4Hnivs7HUyd4ayYUVA/aT\n" +
|
||||
"aRHxe3vDQMmO9/UhmSZM62woa+TvxIk05WxnQ1kjxxMn0oSTEfFDZ2NZI5tTZRERAVwP3AHMB6ou\n" +
|
||||
"dF/UDq7OTXT5XZejPVJR4+baRloB1yYwMlKgXXZBXNrIRCvYkHqygYnlPfRXqb8W9D2jjnXrX/Wm\n" +
|
||||
"cRS45PAowfqIeLyE/o3AGHALMAP4FhgH9kTEnhpxuwYbtfezSCenkiaREnVM/bKCmdX9zKfSoZWH\n" +
|
||||
"2UPT3cB04C9gCzAKvJaz+50RcbBpzAlF/SVnVtZf7rwqoz5dcIiNFuw/pC5obbPUqROdcyHqzhwj\n" +
|
||||
"4+qktn2eU492ObfWmZ2PUy6nkQUFyb2qvqye7mKgk/2mWBAbmPmwQrJlWJsXp/FVq4SRmcDhxLKn\n" +
|
||||
"IuK69oayd7+1iYgjwBuJZaeoOxJrliPx4XWBf2+X+j4jLRNv9Ul61IKqSnLUGVa7OlVlO5SYEfUa\n" +
|
||||
"s8to3QVqCTC5Zt8y3K+O5BpR56lvq3uAP4GtwB/qMbMidu4DUgEPpci2B4svaVGfKTmlG9XZ3dTV\n" +
|
||||
"G1IfRwXs6gy8raLAcbWwcKfOSZ9zLscG2oKOAw9UnNLpwMfqwwX/X11Rry5TBwDMHnqq1mAvcCXw\n" +
|
||||
"QrKU6nEq1GHga2BSr717sCwi3jF7WTO/tc0jXQG8GzsGgTk0NwHwitnCd1UCrapsHiTdiM1MpFOH\n" +
|
||||
"DQP8/yrtVfkuInYPAHP7HOg08HMf9T+C7I3VTtKZOQgcav3uBbZExG/qIuCTRDHaOQx8AID6ZqJF\n" +
|
||||
"aWu3iOqaRHEucN62xXgA2J9odLqW+yNiJWlnZVlEXHzdoQ6r5xKM0IIy0dUVCWK9VCS+uqHwhipD\n" +
|
||||
"qT5l9xJQEZvUB3uJj9c0sU29toqRVrzJ6nLL1Y+Pqiu66f2niqJuJO/evpjdwGOtAkNtzE7a24Bb\n" +
|
||||
"yV4pnAe+B34k+2TqUEScqypa5hOmw+pK9YomBlKSW9cy+6jsUeBesnuxOcBXwHayD8s2RcSJiUqy\n" +
|
||||
"DP8AdqCiPDfVYp8AAAAASUVORK5CYII=").bitmap,
|
||||
contributorName = "fankes"
|
||||
),
|
||||
IconDataBean(
|
||||
isEnabled = true,
|
||||
isEnabledAll = false,
|
||||
appName = "腾讯会议",
|
||||
packageName = "com.tencent.wemeet.app",
|
||||
iconBitmap = ("iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARzQklUCAgI\n" +
|
||||
"CHwIZIgAAAIESURBVGiB7ZgxaBRBGEa/XQLXiCQQRVCCkhRREMRCBRvBNDZpgtdZ2aVLqY1BK21s\n" +
|
||||
"bLQQQVAwSLo0pkgjYqEW2VOLCFrYCLGx0UKehW6YXG7vZv6dcxOY120xj+/BsjArJRKJRCKRSGwB\n" +
|
||||
"XI7gOAmciLHHOuAJfzHHAKeBD0DRSAzwiO0ExwBngA3HUQDHh7G3asADeuMdA5wHPvdwFMCxYe4v\n" +
|
||||
"B9yriPCOAS4AX/s4CuDQMCPuDogYGAPMAN88HAUwOoyI254RlTHAJeB7gKMAWjEjbgVG7IgBZoEf\n" +
|
||||
"BkcRK2LRGLEVA8wBP2s46sVEiCj5HcFhiyFeREzCYtidESV+MezuiJL+MeyNiJJ37vbcjZB0I+gd\n" +
|
||||
"bJZTwKvyIZf2ZETJOWBZkjLgoqTVhgfVZTGXNNH0ighM55LGawg6km5GGLIk6XmN86Mjkj4ZD3ck\n" +
|
||||
"tbMsew+MSLpu9CxlWdYGcknLkmYNjg1JEvAx8NO341oK3DF8Qp91OVrASqBjEzjrSn55Hqy8W+N/\n" +
|
||||
"X4GuCMexD3gR4Gl3C1r/6kwRjmfQDbIywnGMAWsenitVgv3AF2uE47lvjXAcB4GXfTxXBwkOAB1r\n" +
|
||||
"hON5aI1wHIeB1z08876CI8Aba4TjeWyNcBxHgbeOZyFUMFknwvE8tUY4jilgHbhmFTT3G7ML/ueP\n" +
|
||||
"u0QikUgkEonENv4AQa58WnCHXkoAAAAASUVORK5CYII=").bitmap,
|
||||
contributorName = "fankes"
|
||||
),
|
||||
IconDataBean(
|
||||
isEnabled = true,
|
||||
isEnabledAll = false,
|
||||
appName = "中国大学MOOC",
|
||||
packageName = "com.netease.edu.ucmooc",
|
||||
iconBitmap = ("iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARzQklUCAgI\n" +
|
||||
"CHwIZIgAAASnSURBVGiB7Zl9aFZlGMavO1wjNmNWpmLgaAoVBCvRGhaMIguKGhhYGiSOKal/iDFE\n" +
|
||||
"ixr0BZLIgohqmRVUjKyobK2iYYTrAykzKvGjj5VmbhHUQEP59cdz3nF2POc557wfeyO84GXnPc99\n" +
|
||||
"X/d97Tnv89zPfaQz+G/BKh0AaJTUKmlU0qCZ/VLpmGUFMBvo5nRsAi6odn6pAKYADwDDMSIK2Ae0\n" +
|
||||
"VzvXRACrgySz4i3g2mrnPQbgDmBXDgFRPA5Mq6aAG4C3MyQ5CagDXvTY7QdWTLSAK4FtKQJ6gKkx\n" +
|
||||
"vi3AVx6/HUBrpQXMAjYD/3gS2Q7MycC1Ejjl4dkCzCi3gHpgI3DEE/hDYH5O3jrgSQ/nIeCecolY\n" +
|
||||
"AXzjCfY5sLDEGPOAjz0x3gOuK5Z8EbDTQ/49sLgUATExlwF/emJ2AxdlJWsFXveQHQZWllNAJH4d\n" +
|
||||
"bvdPwo/A6jSSZz0EfwOdlRIQk8s83AqWhPdxddxpjr0ep4eAiheYccA9bkMeMWeHjVsSDLuBKdUQ\n" +
|
||||
"EAb+x+3RsOGDkcHnY6etyiD+cTsO1BYM4mbkOLChyIBzcPvDENBfjn8K0Ay8kTArjWHDpN/IHqAt\n" +
|
||||
"Y7B64H7cwhBGTwkCZgLPJOQG8Gmc01aPQy+eChVoB35N8H2tCAE1wCOefMBt1JclEbQBez3OGyL2\n" +
|
||||
"twHfeux3AxfmFLEWGE0R0UVaLRYQ+XAAt3EOemyOAOuAmhwCluA2vDTcmpXw5wxkPjxGjoMS7lzz\n" +
|
||||
"hYfvaOT7QBbS5ojTftzhKAteAS7NIaAZeNfDdxBYAzwRMzY5jbwn4tAV3J8LfOAJuoOMZTxuJXrB\n" +
|
||||
"wzWCa2BMDuwXxNjcmxbkRMj4JNAUGuvyBC9gs4e7Bv/snsIdqGbF+B6M2B7wibgpYvxSZDyLEHDL\n" +
|
||||
"8NKI7/oUn21Asye3h2N84o/EuHZOGDenCOkCvvQk1w8sx9/jepMMhybiq4/lhfGzIvZNke/J0xfA\n" +
|
||||
"zK6QtFjS7zHDCyU9J+n8mLGdkm43szYz+ygtjqShmHtj+aYJydSnNbNeM5smaX0G8z2SOsys1cy2\n" +
|
||||
"Z+EPYsTlkijk4tD1b2Y2mjVQEGyTpEskbY0Z/klSp6T5ZlZs7RUVMyZkUtKApMPFRDKzfZLacfXV\n" +
|
||||
"QkkzJfVLesfMjhbDGcKQpPCZPVHICUnnBNezgQWS/pI0IumPPBHNrE9SX+5UAwDnSZouaUbwd3qQ\n" +
|
||||
"Xxi1hYuokGOSGoLrcyV9UmwixQC3od4paYmkLIXmscJFVMiwpNQuYQjXAFeZ2Wc5fMYB965kmaRF\n" +
|
||||
"kq7O6T6cRBo98mbFy8DcIkR0kO81RBRbfOSdwEDw2QX8wPiyxYenswgCrgf6ShAArq/QkBYrGrgW\n" +
|
||||
"aMKdQbJgqYcry6yfxPXY1uA6ni1AI+HWTymIETLgSaajCBG7cc3y+rIknFNIG8n11tqMIr4mY4Oj\n" +
|
||||
"YkKC+w248jsOG1NEPEXMC6GqCAmNtwHfeZIO4xBw14QKyCoksGkhfZUbAS4vZ27RorFkmNmgpLtT\n" +
|
||||
"zG4xs73ljFt2IZJkZq9KWpUwfGMgtrpg/JLblWJ7X+SRWjdReaYCmAqsCn4v/paMxo7HA2miz+D/\n" +
|
||||
"hn8B/6EvMiR/OQcAAAAASUVORK5CYII=").bitmap,
|
||||
contributorName = "fankes"
|
||||
),
|
||||
// TODO 可继续在这里添加更多 APP
|
||||
)
|
||||
}
|
||||
|
@@ -1,22 +1,24 @@
|
||||
/**
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
/*
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/01/30.
|
||||
* This file is Created by fankes on 2022/1/30.
|
||||
*/
|
||||
@file:Suppress("SetTextI18n", "InflateParams")
|
||||
|
||||
@@ -33,25 +35,67 @@ import android.widget.ListView
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.constraintlayout.utils.widget.ImageFilterView
|
||||
import androidx.core.view.isVisible
|
||||
import com.fankes.miui.notify.R
|
||||
import com.fankes.miui.notify.hook.HookMedium
|
||||
import com.fankes.miui.notify.hook.factory.isAppNotifyHookAllOf
|
||||
import com.fankes.miui.notify.hook.factory.isAppNotifyHookOf
|
||||
import com.fankes.miui.notify.hook.factory.putAppNotifyHookAllOf
|
||||
import com.fankes.miui.notify.hook.factory.putAppNotifyHookOf
|
||||
import com.fankes.miui.notify.params.IconPackParams
|
||||
import com.fankes.miui.notify.ui.base.BaseActivity
|
||||
import com.fankes.miui.notify.utils.SystemUITool
|
||||
import com.fankes.miui.notify.utils.showDialog
|
||||
import com.fankes.miui.notify.view.MaterialSwitch
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
|
||||
class ConfigureActivity : BaseActivity() {
|
||||
|
||||
/** 当前筛选条件 */
|
||||
private var filterText = ""
|
||||
|
||||
/** 回调适配器改变 */
|
||||
private var onChanged: (() -> Unit)? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_config)
|
||||
/** 返回按钮点击事件 */
|
||||
findViewById<View>(R.id.title_back_icon).setOnClickListener { onBackPressed() }
|
||||
/** 设置标题个数文本 */
|
||||
findViewById<TextView>(R.id.config_title_count_text).text = "已适配 ${IconPackParams.iconDatas.size} 个 APP 的通知图标"
|
||||
/** 设置搜索按钮点击事件 */
|
||||
findViewById<View>(R.id.config_title_search).setOnClickListener {
|
||||
Toast.makeText(this, "后期开放", Toast.LENGTH_SHORT).show()
|
||||
/** 刷新适配器结果相关 */
|
||||
refreshAdapterResult()
|
||||
/** 设置过滤按钮点击事件 */
|
||||
findViewById<View>(R.id.config_title_filter).setOnClickListener {
|
||||
showDialog {
|
||||
title = "按条件过滤"
|
||||
var editText: TextInputEditText
|
||||
addView(R.layout.dia_icon_filter).apply {
|
||||
editText = findViewById<TextInputEditText>(R.id.dia_icon_filter_input_edit).apply {
|
||||
requestFocus()
|
||||
invalidate()
|
||||
if (filterText.isNotBlank()) {
|
||||
setText(filterText)
|
||||
setSelection(filterText.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
confirmButton {
|
||||
if (editText.text.toString().isNotBlank()) {
|
||||
filterText = editText.text.toString().trim()
|
||||
onChanged?.invoke()
|
||||
refreshAdapterResult()
|
||||
} else {
|
||||
Toast.makeText(applicationContext, "条件不能为空", Toast.LENGTH_SHORT).show()
|
||||
it.performClick()
|
||||
}
|
||||
}
|
||||
cancelButton()
|
||||
if (filterText.isNotBlank())
|
||||
neutralButton(text = "清除条件") {
|
||||
filterText = ""
|
||||
onChanged?.invoke()
|
||||
refreshAdapterResult()
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 设置列表元素和 Adapter */
|
||||
findViewById<ListView>(R.id.config_list_view).apply {
|
||||
@@ -59,9 +103,9 @@ class ConfigureActivity : BaseActivity() {
|
||||
|
||||
private val inflater = LayoutInflater.from(context)
|
||||
|
||||
override fun getCount() = IconPackParams.iconDatas.size
|
||||
override fun getCount() = iconDatas.size
|
||||
|
||||
override fun getItem(position: Int) = IconPackParams.iconDatas[position]
|
||||
override fun getItem(position: Int) = iconDatas[position]
|
||||
|
||||
override fun getItemId(position: Int) = position.toLong()
|
||||
|
||||
@@ -85,20 +129,20 @@ class ConfigureActivity : BaseActivity() {
|
||||
holder.appName.text = it.appName
|
||||
holder.pkgName.text = it.packageName
|
||||
holder.cbrName.text = "贡献者:" + it.contributorName
|
||||
HookMedium.isAppNotifyHookOf(it).also { e ->
|
||||
isAppNotifyHookOf(it).also { e ->
|
||||
holder.switchOpen.isChecked = e
|
||||
holder.switchAll.isEnabled = e
|
||||
}
|
||||
holder.switchOpen.setOnCheckedChangeListener { btn, b ->
|
||||
if (!btn.isPressed) return@setOnCheckedChangeListener
|
||||
HookMedium.putAppNotifyHookOf(it, b)
|
||||
putAppNotifyHookOf(it, b)
|
||||
holder.switchAll.isEnabled = b
|
||||
SystemUITool.showNeedRestartSnake(context = this@ConfigureActivity)
|
||||
}
|
||||
holder.switchAll.isChecked = HookMedium.isAppNotifyHookAllOf(it)
|
||||
holder.switchAll.isChecked = isAppNotifyHookAllOf(it)
|
||||
holder.switchAll.setOnCheckedChangeListener { btn, b ->
|
||||
if (!btn.isPressed) return@setOnCheckedChangeListener
|
||||
HookMedium.putAppNotifyHookAllOf(it, b)
|
||||
putAppNotifyHookAllOf(it, b)
|
||||
SystemUITool.showNeedRestartSnake(context = this@ConfigureActivity)
|
||||
}
|
||||
}
|
||||
@@ -113,20 +157,38 @@ class ConfigureActivity : BaseActivity() {
|
||||
lateinit var switchOpen: MaterialSwitch
|
||||
lateinit var switchAll: MaterialSwitch
|
||||
}
|
||||
}
|
||||
}.apply { onChanged = { notifyDataSetChanged() } }
|
||||
}
|
||||
/** 设置点击事件 */
|
||||
findViewById<View>(R.id.config_cbr_button).setOnClickListener {
|
||||
try {
|
||||
runCatching {
|
||||
startActivity(Intent().apply {
|
||||
action = "android.intent.action.VIEW"
|
||||
data = Uri.parse("https://github.com/fankes/MIUINativeNotifyIcon")
|
||||
/** 防止顶栈一样重叠在自己的 APP 中 */
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
})
|
||||
} catch (e: Exception) {
|
||||
}.onFailure {
|
||||
Toast.makeText(this, "无法启动系统默认浏览器", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 刷新适配器结果相关 */
|
||||
private fun refreshAdapterResult() {
|
||||
findViewById<TextView>(R.id.config_title_count_text).text =
|
||||
if (filterText.isBlank()) "已适配 ${iconDatas.size} 个 APP 的通知图标"
|
||||
else "“${filterText}” 匹配到 ${iconDatas.size} 个结果"
|
||||
findViewById<View>(R.id.config_list_no_data_view).isVisible = iconDatas.isEmpty()
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前结果下的图标数组
|
||||
* @return [Array]
|
||||
*/
|
||||
private val iconDatas
|
||||
get() = if (filterText.isBlank()) IconPackParams.iconDatas
|
||||
else IconPackParams.iconDatas.filter {
|
||||
it.appName.lowercase().contains(filterText.lowercase()) || it.packageName.lowercase().contains(filterText.lowercase())
|
||||
}.toTypedArray()
|
||||
}
|
@@ -1,22 +1,24 @@
|
||||
/**
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
/*
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/01/24.
|
||||
* This file is Created by fankes on 2022/1/24.
|
||||
*/
|
||||
@file:Suppress("SetTextI18n")
|
||||
|
||||
@@ -36,9 +38,15 @@ import androidx.constraintlayout.utils.widget.ImageFilterView
|
||||
import androidx.core.view.isVisible
|
||||
import com.fankes.miui.notify.BuildConfig
|
||||
import com.fankes.miui.notify.R
|
||||
import com.fankes.miui.notify.hook.HookMedium
|
||||
import com.fankes.miui.notify.hook.HookConst.ENABLE_COLOR_ICON_HOOK
|
||||
import com.fankes.miui.notify.hook.HookConst.ENABLE_HIDE_ICON
|
||||
import com.fankes.miui.notify.hook.HookConst.ENABLE_MODULE
|
||||
import com.fankes.miui.notify.hook.HookConst.ENABLE_MODULE_LOG
|
||||
import com.fankes.miui.notify.hook.HookConst.ENABLE_NOTIFY_ICON_HOOK
|
||||
import com.fankes.miui.notify.ui.base.BaseActivity
|
||||
import com.fankes.miui.notify.utils.*
|
||||
import com.highcapable.yukihookapi.hook.factory.modulePrefs
|
||||
import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus
|
||||
|
||||
class MainActivity : BaseActivity() {
|
||||
|
||||
@@ -111,27 +119,27 @@ class MainActivity : BaseActivity() {
|
||||
/** 设置旧版本警告 */
|
||||
findViewById<View>(R.id.config_notify_app_icon_warn).isVisible = miuiVersion == "12"
|
||||
/** 获取 Sp 存储的信息 */
|
||||
notifyIconConfigItem.isVisible = getBoolean(HookMedium.ENABLE_COLOR_ICON_HOOK, default = true)
|
||||
moduleEnableLogSwitch.isVisible = getBoolean(HookMedium.ENABLE_MODULE, default = true)
|
||||
moduleEnableSwitch.isChecked = getBoolean(HookMedium.ENABLE_MODULE, default = true)
|
||||
moduleEnableLogSwitch.isChecked = getBoolean(HookMedium.ENABLE_MODULE_LOG, default = false)
|
||||
hideIconInLauncherSwitch.isChecked = getBoolean(HookMedium.ENABLE_HIDE_ICON)
|
||||
colorIconHookSwitch.isChecked = getBoolean(HookMedium.ENABLE_COLOR_ICON_HOOK, default = true)
|
||||
notifyIconHookSwitch.isChecked = getBoolean(HookMedium.ENABLE_NOTIFY_ICON_HOOK, default = true)
|
||||
notifyIconConfigItem.isVisible = modulePrefs.getBoolean(ENABLE_COLOR_ICON_HOOK, default = true)
|
||||
moduleEnableLogSwitch.isVisible = modulePrefs.getBoolean(ENABLE_MODULE, default = true)
|
||||
moduleEnableSwitch.isChecked = modulePrefs.getBoolean(ENABLE_MODULE, default = true)
|
||||
moduleEnableLogSwitch.isChecked = modulePrefs.getBoolean(ENABLE_MODULE_LOG, default = false)
|
||||
hideIconInLauncherSwitch.isChecked = modulePrefs.getBoolean(ENABLE_HIDE_ICON)
|
||||
colorIconHookSwitch.isChecked = modulePrefs.getBoolean(ENABLE_COLOR_ICON_HOOK, default = true)
|
||||
notifyIconHookSwitch.isChecked = modulePrefs.getBoolean(ENABLE_NOTIFY_ICON_HOOK, default = true)
|
||||
moduleEnableSwitch.setOnCheckedChangeListener { btn, b ->
|
||||
if (!btn.isPressed) return@setOnCheckedChangeListener
|
||||
putBoolean(HookMedium.ENABLE_MODULE, b)
|
||||
modulePrefs.putBoolean(ENABLE_MODULE, b)
|
||||
moduleEnableLogSwitch.isVisible = b
|
||||
SystemUITool.showNeedRestartSnake(context = this)
|
||||
}
|
||||
moduleEnableLogSwitch.setOnCheckedChangeListener { btn, b ->
|
||||
if (!btn.isPressed) return@setOnCheckedChangeListener
|
||||
putBoolean(HookMedium.ENABLE_MODULE_LOG, b)
|
||||
modulePrefs.putBoolean(ENABLE_MODULE_LOG, b)
|
||||
SystemUITool.showNeedRestartSnake(context = this)
|
||||
}
|
||||
hideIconInLauncherSwitch.setOnCheckedChangeListener { btn, b ->
|
||||
if (!btn.isPressed) return@setOnCheckedChangeListener
|
||||
putBoolean(HookMedium.ENABLE_HIDE_ICON, b)
|
||||
modulePrefs.putBoolean(ENABLE_HIDE_ICON, b)
|
||||
packageManager.setComponentEnabledSetting(
|
||||
ComponentName(this@MainActivity, "com.fankes.miui.notify.Home"),
|
||||
if (b) PackageManager.COMPONENT_ENABLED_STATE_DISABLED else PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
||||
@@ -140,13 +148,13 @@ class MainActivity : BaseActivity() {
|
||||
}
|
||||
colorIconHookSwitch.setOnCheckedChangeListener { btn, b ->
|
||||
if (!btn.isPressed) return@setOnCheckedChangeListener
|
||||
putBoolean(HookMedium.ENABLE_COLOR_ICON_HOOK, b)
|
||||
modulePrefs.putBoolean(ENABLE_COLOR_ICON_HOOK, b)
|
||||
notifyIconConfigItem.isVisible = b
|
||||
SystemUITool.showNeedRestartSnake(context = this)
|
||||
}
|
||||
notifyIconHookSwitch.setOnCheckedChangeListener { btn, b ->
|
||||
if (!btn.isPressed) return@setOnCheckedChangeListener
|
||||
putBoolean(HookMedium.ENABLE_NOTIFY_ICON_HOOK, b)
|
||||
modulePrefs.putBoolean(ENABLE_NOTIFY_ICON_HOOK, b)
|
||||
SystemUITool.showNeedRestartSnake(context = this)
|
||||
}
|
||||
/** 重启按钮点击事件 */
|
||||
@@ -157,7 +165,7 @@ class MainActivity : BaseActivity() {
|
||||
}
|
||||
/** 恰饭! */
|
||||
findViewById<View>(R.id.link_with_follow_me).setOnClickListener {
|
||||
try {
|
||||
runCatching {
|
||||
startActivity(Intent().apply {
|
||||
setPackage("com.coolapk.market")
|
||||
action = "android.intent.action.VIEW"
|
||||
@@ -165,20 +173,20 @@ class MainActivity : BaseActivity() {
|
||||
/** 防止顶栈一样重叠在自己的 APP 中 */
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
})
|
||||
} catch (e: Exception) {
|
||||
}.onFailure {
|
||||
Toast.makeText(this, "你可能没有安装酷安", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
/** 项目地址点击事件 */
|
||||
findViewById<View>(R.id.link_with_project_address).setOnClickListener {
|
||||
try {
|
||||
runCatching {
|
||||
startActivity(Intent().apply {
|
||||
action = "android.intent.action.VIEW"
|
||||
data = Uri.parse("https://github.com/fankes/MIUINativeNotifyIcon")
|
||||
/** 防止顶栈一样重叠在自己的 APP 中 */
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
})
|
||||
} catch (e: Exception) {
|
||||
}.onFailure {
|
||||
Toast.makeText(this, "无法启动系统默认浏览器", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
@@ -202,20 +210,5 @@ class MainActivity : BaseActivity() {
|
||||
* 判断模块是否激活
|
||||
* @return [Boolean] 激活状态
|
||||
*/
|
||||
private fun isHooked() = HookMedium.isHooked()
|
||||
|
||||
/**
|
||||
* 获取保存的值
|
||||
* @param key 名称
|
||||
* @param default 默认值
|
||||
* @return [Boolean] 保存的值
|
||||
*/
|
||||
private fun getBoolean(key: String, default: Boolean = false) = HookMedium.getBoolean(key, default)
|
||||
|
||||
/**
|
||||
* 保存值
|
||||
* @param key 名称
|
||||
* @param bool 值
|
||||
*/
|
||||
private fun putBoolean(key: String, bool: Boolean) = HookMedium.putBoolean(key, bool)
|
||||
private fun isHooked() = YukiHookModuleStatus.isActive()
|
||||
}
|
@@ -1,29 +1,30 @@
|
||||
/**
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
/*
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/01/30.
|
||||
* This file is Created by fankes on 2022/1/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
|
||||
|
||||
@@ -43,24 +44,4 @@ abstract class BaseActivity : AppCompatActivity() {
|
||||
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()
|
||||
}
|
||||
}
|
@@ -1,24 +1,26 @@
|
||||
/**
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
/*
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/7.
|
||||
*/
|
||||
@file:Suppress("unused")
|
||||
@file:Suppress("unused", "DEPRECATION")
|
||||
|
||||
package com.fankes.miui.notify.utils
|
||||
|
||||
@@ -26,7 +28,11 @@ import android.app.AlertDialog
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import kotlin.math.round
|
||||
|
||||
/**
|
||||
* 构造对话框
|
||||
@@ -42,6 +48,8 @@ class DialogBuilder(private val context: Context) {
|
||||
|
||||
private var instance: AlertDialog.Builder? = null // 实例对象
|
||||
|
||||
private var customLayoutView: View? = null // 自定义布局
|
||||
|
||||
init {
|
||||
instance = AlertDialog.Builder(context, android.R.style.Theme_Material_Light_Dialog)
|
||||
}
|
||||
@@ -63,6 +71,16 @@ class DialogBuilder(private val context: Context) {
|
||||
instance?.setMessage(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置对话框自定义布局
|
||||
* @param resId 属性资源 Id
|
||||
* @return [View]
|
||||
*/
|
||||
fun addView(resId: Int): View {
|
||||
customLayoutView = LayoutInflater.from(context).inflate(resId, null)
|
||||
return customLayoutView ?: error("Inflate $resId failed")
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置对话框确定按钮
|
||||
* @param text 按钮文本内容
|
||||
@@ -89,6 +107,9 @@ class DialogBuilder(private val context: Context) {
|
||||
|
||||
/** 显示对话框 */
|
||||
internal fun show() = instance?.create()?.apply {
|
||||
val dm = DisplayMetrics()
|
||||
(context.getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay.getMetrics(dm)
|
||||
customLayoutView?.let { setView(it.apply { minimumWidth = round(dm.widthPixels / 1.3).toInt() }) }
|
||||
window?.setBackgroundDrawable(GradientDrawable(
|
||||
GradientDrawable.Orientation.TOP_BOTTOM,
|
||||
intArrayOf(Color.WHITE, Color.WHITE)
|
||||
|
@@ -1,85 +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 zpp0196 on 2019/2/9.
|
||||
*/
|
||||
package com.fankes.miui.notify.utils;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.fankes.miui.notify.BuildConfig;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
public class FileUtils {
|
||||
|
||||
private static final String FILE_PREF_NAME = BuildConfig.APPLICATION_ID + "_preferences.xml";
|
||||
|
||||
public static boolean copyFile(File srcFile, File targetFile) {
|
||||
FileInputStream ins = null;
|
||||
FileOutputStream out = null;
|
||||
try {
|
||||
if (targetFile.exists()) {
|
||||
targetFile.delete();
|
||||
}
|
||||
File targetParent = targetFile.getParentFile();
|
||||
if (!targetParent.exists()) {
|
||||
targetParent.mkdirs();
|
||||
}
|
||||
targetFile.createNewFile();
|
||||
ins = new FileInputStream(srcFile);
|
||||
out = new FileOutputStream(targetFile);
|
||||
byte[] b = new byte[1024];
|
||||
int n;
|
||||
while ((n = ins.read(b)) != -1) {
|
||||
out.write(b, 0, n);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
} finally {
|
||||
try {
|
||||
if (ins != null) {
|
||||
ins.close();
|
||||
}
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static File getDataDir(Context context) {
|
||||
return new File(context.getApplicationInfo().dataDir);
|
||||
}
|
||||
|
||||
public static File getPrefDir(Context context) {
|
||||
return new File(getDataDir(context), "shared_prefs");
|
||||
}
|
||||
|
||||
public static File getDefaultPrefFile(Context context) {
|
||||
return new File(getPrefDir(context), FILE_PREF_NAME);
|
||||
}
|
||||
}
|
@@ -1,22 +1,24 @@
|
||||
/**
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
/*
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/02/08.
|
||||
* This file is Created by fankes on 2022/2/8.
|
||||
*/
|
||||
package com.fankes.miui.notify.utils
|
||||
|
||||
|
@@ -1,20 +1,22 @@
|
||||
/**
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
/*
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/7.
|
||||
*/
|
||||
@@ -33,6 +35,12 @@ import android.provider.Settings
|
||||
import android.service.notification.StatusBarNotification
|
||||
import android.util.Base64
|
||||
import com.fankes.miui.notify.application.MNNApplication.Companion.appContext
|
||||
import com.highcapable.yukihookapi.hook.factory.callStatic
|
||||
import com.highcapable.yukihookapi.hook.factory.classOf
|
||||
import com.highcapable.yukihookapi.hook.factory.hasClass
|
||||
import com.highcapable.yukihookapi.hook.factory.method
|
||||
import com.highcapable.yukihookapi.hook.log.loggerE
|
||||
import com.highcapable.yukihookapi.hook.type.java.StringType
|
||||
import com.topjohnwu.superuser.Shell
|
||||
|
||||
/**
|
||||
@@ -58,12 +66,7 @@ val Context.isSystemInDarkMode get() = (resources.configuration.uiMode and Confi
|
||||
* 通知栏是否为 MIUI 样式
|
||||
* @return [Boolean] 是否符合条件
|
||||
*/
|
||||
val Context.isMiuiNotifyStyle
|
||||
get() = try {
|
||||
Settings.System.getInt(contentResolver, "status_bar_notification_style") == 0
|
||||
} catch (_: Throwable) {
|
||||
false
|
||||
}
|
||||
val Context.isMiuiNotifyStyle get() = safeOfFalse { Settings.System.getInt(contentResolver, "status_bar_notification_style") == 0 }
|
||||
|
||||
/**
|
||||
* 系统深色模式是否没开启
|
||||
@@ -87,14 +90,7 @@ inline val isLowerAndroidP get() = Build.VERSION.SDK_INT < Build.VERSION_CODES.P
|
||||
* 当前设备是否是 MIUI 定制 Android 系统
|
||||
* @return [Boolean] 是否符合条件
|
||||
*/
|
||||
val isMIUI by lazy {
|
||||
try {
|
||||
Class.forName("android.miui.R")
|
||||
true
|
||||
} catch (_: Exception) {
|
||||
false
|
||||
}
|
||||
}
|
||||
val isMIUI by lazy { ("android.miui.R").hasClass }
|
||||
|
||||
/**
|
||||
* 当前设备是否不是 MIUI 定制 Android 系统
|
||||
@@ -166,16 +162,13 @@ val Context.packageInfo get() = packageManager?.getPackageInfo(packageName, 0) ?
|
||||
* @return [Boolean]
|
||||
*/
|
||||
val String.isInstall
|
||||
get() =
|
||||
try {
|
||||
appContext.packageManager.getPackageInfo(
|
||||
this,
|
||||
PackageManager.GET_UNINSTALLED_PACKAGES
|
||||
)
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
false
|
||||
}
|
||||
get() = safeOfFalse {
|
||||
appContext.packageManager.getPackageInfo(
|
||||
this,
|
||||
PackageManager.GET_UNINSTALLED_PACKAGES
|
||||
)
|
||||
true
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到版本信息
|
||||
@@ -251,26 +244,116 @@ fun Bitmap.round(radius: Float): Bitmap =
|
||||
* @param default 默认值
|
||||
* @return [String]
|
||||
*/
|
||||
fun findPropString(key: String, default: String = "") =
|
||||
try {
|
||||
(Class.forName("android.os.SystemProperties").getDeclaredMethod(
|
||||
"get",
|
||||
String::class.java,
|
||||
String::class.java
|
||||
).apply { isAccessible = true }.invoke(null, key, default)) as? String? ?: default
|
||||
} catch (_: Exception) {
|
||||
default
|
||||
}
|
||||
fun findPropString(key: String, default: String = "") = safeOf(default) {
|
||||
(classOf(name = "android.os.SystemProperties").method(
|
||||
name = "get", StringType, StringType
|
||||
)?.callStatic(key, default)) ?: default
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行命令 - su
|
||||
* @param cmd 命令
|
||||
* @return [String] 执行结果
|
||||
*/
|
||||
fun execShellSu(cmd: String) = try {
|
||||
fun execShellSu(cmd: String) = safeOfNothing {
|
||||
Shell.su(cmd).exec().out.let {
|
||||
if (it.isNotEmpty()) it[0].trim() else ""
|
||||
}
|
||||
} catch (_: Throwable) {
|
||||
""
|
||||
}
|
||||
|
||||
/**
|
||||
* 忽略异常返回值
|
||||
* @param it 回调 - 如果异常为空
|
||||
* @return [T] 发生异常时返回设定值否则返回正常值
|
||||
*/
|
||||
inline fun <T> safeOfNull(it: () -> T): T? = safeOf(null, it)
|
||||
|
||||
/**
|
||||
* 忽略异常返回值
|
||||
* @param it 回调 - 如果异常为 false
|
||||
* @return [Boolean] 发生异常时返回设定值否则返回正常值
|
||||
*/
|
||||
inline fun safeOfFalse(it: () -> Boolean) = safeOf(default = false, it)
|
||||
|
||||
/**
|
||||
* 忽略异常返回值
|
||||
* @param it 回调 - 如果异常为 true
|
||||
* @return [Boolean] 发生异常时返回设定值否则返回正常值
|
||||
*/
|
||||
inline fun safeOfTrue(it: () -> Boolean) = safeOf(default = true, it)
|
||||
|
||||
/**
|
||||
* 忽略异常返回值
|
||||
* @param it 回调 - 如果异常为 false
|
||||
* @return [String] 发生异常时返回设定值否则返回正常值
|
||||
*/
|
||||
inline fun safeOfNothing(it: () -> String) = safeOf(default = "", it)
|
||||
|
||||
/**
|
||||
* 忽略异常返回值
|
||||
* @param it 回调 - 如果异常为 false
|
||||
* @return [Int] 发生异常时返回设定值否则返回正常值
|
||||
*/
|
||||
inline fun safeOfNan(it: () -> Int) = safeOf(default = 0, it)
|
||||
|
||||
/**
|
||||
* 忽略异常返回值
|
||||
* @param default 异常返回值
|
||||
* @param it 正常回调值
|
||||
* @return [T] 发生异常时返回设定值否则返回正常值
|
||||
*/
|
||||
inline fun <T> safeOf(default: T, it: () -> T): T {
|
||||
return try {
|
||||
it()
|
||||
} catch (t: NullPointerException) {
|
||||
default
|
||||
} catch (t: UnsatisfiedLinkError) {
|
||||
default
|
||||
} catch (t: UnsupportedOperationException) {
|
||||
default
|
||||
} catch (t: ClassNotFoundException) {
|
||||
default
|
||||
} catch (t: IllegalStateException) {
|
||||
default
|
||||
} catch (t: NoSuchMethodError) {
|
||||
default
|
||||
} catch (t: NoSuchFieldError) {
|
||||
default
|
||||
} catch (t: Error) {
|
||||
default
|
||||
} catch (t: Exception) {
|
||||
default
|
||||
} catch (t: Throwable) {
|
||||
default
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 忽略异常运行
|
||||
* @param msg 出错输出的消息 - 默认为空
|
||||
* @param it 正常回调
|
||||
*/
|
||||
inline fun safeRun(msg: String = "", it: () -> Unit) {
|
||||
try {
|
||||
it()
|
||||
} catch (e: NullPointerException) {
|
||||
if (msg.isNotBlank()) loggerE(msg = msg, e = e)
|
||||
} catch (e: UnsatisfiedLinkError) {
|
||||
if (msg.isNotBlank()) loggerE(msg = msg, e = e)
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
if (msg.isNotBlank()) loggerE(msg = msg, e = e)
|
||||
} catch (e: ClassNotFoundException) {
|
||||
if (msg.isNotBlank()) loggerE(msg = msg, e = e)
|
||||
} catch (e: IllegalStateException) {
|
||||
if (msg.isNotBlank()) loggerE(msg = msg, e = e)
|
||||
} catch (e: NoSuchMethodError) {
|
||||
if (msg.isNotBlank()) loggerE(msg = msg, e = e)
|
||||
} catch (e: NoSuchFieldError) {
|
||||
if (msg.isNotBlank()) loggerE(msg = msg, e = e)
|
||||
} catch (e: Error) {
|
||||
if (msg.isNotBlank()) loggerE(msg = msg, e = e)
|
||||
} catch (e: Exception) {
|
||||
if (msg.isNotBlank()) loggerE(msg = msg, e = e)
|
||||
} catch (e: Throwable) {
|
||||
}
|
||||
}
|
@@ -1,45 +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 zpp0196 on 2018/4/11.
|
||||
*/
|
||||
package com.fankes.miui.notify.utils
|
||||
|
||||
import com.fankes.miui.notify.BuildConfig
|
||||
import de.robv.android.xposed.XSharedPreferences
|
||||
|
||||
object XPrefUtils {
|
||||
|
||||
private var xPrefCacheKeyValueBooleans = HashMap<String, Boolean>()
|
||||
|
||||
fun getBoolean(key: String, default: Boolean = false) =
|
||||
xPrefCacheKeyValueBooleans[key].let {
|
||||
it ?: pref.getBoolean(key, default).let { e ->
|
||||
xPrefCacheKeyValueBooleans[key] = e
|
||||
e
|
||||
}
|
||||
}
|
||||
|
||||
private val pref: XSharedPreferences
|
||||
get() {
|
||||
val preferences = XSharedPreferences(BuildConfig.APPLICATION_ID)
|
||||
preferences.makeWorldReadable()
|
||||
preferences.reload()
|
||||
return preferences
|
||||
}
|
||||
}
|
@@ -1,20 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/8.
|
||||
*/
|
||||
|
@@ -1,24 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/8.
|
||||
*/
|
||||
|
||||
package com.fankes.miui.notify.utils.drawable.drawabletoolbox
|
||||
|
||||
class Constants {
|
||||
|
@@ -1,20 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/8.
|
||||
*/
|
||||
|
@@ -1,20 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/8.
|
||||
*/
|
||||
|
@@ -1,20 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/8.
|
||||
*/
|
||||
|
@@ -1,20 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/8.
|
||||
*/
|
||||
|
@@ -1,20 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/8.
|
||||
*/
|
||||
|
@@ -1,20 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/8.
|
||||
*/
|
||||
|
@@ -1,20 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/8.
|
||||
*/
|
||||
|
@@ -1,20 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/8.
|
||||
*/
|
||||
|
@@ -1,20 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/8.
|
||||
*/
|
||||
|
@@ -1,20 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/8.
|
||||
*/
|
||||
|
@@ -1,20 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/8.
|
||||
*/
|
||||
|
@@ -1,24 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2022. Fankes Studio(qzmmcn@163.com)
|
||||
* 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 file is part of 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 and our eula as published
|
||||
* by ferredoxin.
|
||||
*
|
||||
* 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,
|
||||
* 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 General Public License for more details.
|
||||
* 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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/1/8.
|
||||
*/
|
||||
|
||||
@file:Suppress("SameParameterValue")
|
||||
|
||||
package com.fankes.miui.notify.view
|
||||
|
@@ -26,11 +26,13 @@
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="25dp"
|
||||
android:src="@mipmap/back"
|
||||
android:tint="@color/colorTextGray" />
|
||||
android:tint="@color/colorTextGray"
|
||||
android:tooltipText="返回" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center|start"
|
||||
android:orientation="vertical">
|
||||
@@ -56,12 +58,13 @@
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.constraintlayout.utils.widget.ImageFilterView
|
||||
android:id="@+id/config_title_search"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:id="@+id/config_title_filter"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:src="@mipmap/icon_search"
|
||||
android:tint="@color/colorTextGray" />
|
||||
android:src="@mipmap/icon_filter"
|
||||
android:tint="@color/colorTextGray"
|
||||
android:tooltipText="按条件过滤" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@@ -95,18 +98,33 @@
|
||||
tools:ignore="SmallSp" />
|
||||
</LinearLayout>
|
||||
|
||||
<ListView
|
||||
android:id="@+id/config_list_view"
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:divider="@color/trans"
|
||||
android:dividerHeight="15dp"
|
||||
android:fadingEdgeLength="10dp"
|
||||
android:listSelector="@null"
|
||||
android:padding="15dp"
|
||||
android:requiresFadingEdge="vertical"
|
||||
android:scrollbars="none" />
|
||||
android:layout_weight="1">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/config_list_no_data_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="噫,竟然什么都没找到~"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="17sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/config_list_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:divider="@color/trans"
|
||||
android:dividerHeight="15dp"
|
||||
android:fadingEdgeLength="10dp"
|
||||
android:listSelector="@null"
|
||||
android:padding="15dp"
|
||||
android:requiresFadingEdge="vertical"
|
||||
android:scrollbars="none" />
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/config_cbr_button"
|
||||
|
@@ -279,7 +279,7 @@
|
||||
android:layout_marginBottom="10dp"
|
||||
android:alpha="0.6"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:text="⚠️ 由于你的系统版本过低,状态栏上 MIPUSH 的彩色图标由于不能识别反色将不会被优化为黑白小图标,仅在通知栏生效。"
|
||||
android:text="⚠️ 你的 MIUI 版本过低,状态栏上 MIPUSH 的彩色图标由于不能识别反色将不会被优化为黑白小图标,仅在通知栏生效。"
|
||||
android:textColor="#FF9800"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone" />
|
||||
@@ -359,7 +359,7 @@
|
||||
android:layout_marginBottom="10dp"
|
||||
android:alpha="0.8"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:text="Q.这个模块是如何诞生的?\nA.这个模块诞生来源于 MIUI 的乱改和不规范,本来 MIUI 9 之后,官方给出了原生通知图标样式,后面由于用户反应通知栏经常出现黑白块,这当然不是系统的错,而是国内 APP 极其不规范的通知图标设计,于是 MIUI 选择直接忽略这个问题把全部图标都改成了 APP 的彩色图标,使得之前拥有自有样式的原生图标也被破坏,通知中“setSmallIcon”不再有效,这个模块就是为了修复被 MIUI 开发组忽略的图标问题,并完美地给 MIUI 修复了黑白块图标的问题。"
|
||||
android:text="Q.这个模块是如何诞生的?\nA.这个模块诞生来源于 MIUI 的乱改和不规范,本来 MIUI 9 之后,官方给出了原生通知图标样式,后面由于用户反应通知栏经常出现黑白块。\n这当然不是系统的错,而是国内 APP 和 MIPUSH 的通知极其不规范的通知图标设计。\n但是呢,接到反馈后 MIUI 开发组选择直接忽略这个问题,在 2021-5-18 的开发版开始,把全部通知图标都改成了 APP 的彩色图标,使得之前拥有自有样式的原生图标也被破坏。\n对于 Android 开发者来说,官方文档中的 “setSmallIcon” 不再适用于魔改后的 MIUI,这将会严重破坏非常多的状态图标。\n当然,国内的手机生态除了 MIPUSH 的营销通知就是社交软件的通知,可能大部分人都不会在意这件事情。\n但是,这个模块就是为了修复被 MIUI 开发组忽略的图标问题才诞生的,并完美地给 MIUI 修复了黑白块图标的问题。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
|
||||
@@ -435,7 +435,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0.8"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:text="本软件是免费开源项目,遵循 GPL 协议,你可以点击这里前往 Github 查看源码以及获取模块更新。\n严禁以任何形式贩卖、商用本软件,否则开发者有权追究其法律责任。"
|
||||
android:text="本软件是免费开源项目,遵循 AGPL3.0 协议,你可以点击这里前往 Github 查看源码以及获取模块更新。"
|
||||
android:textColor="@color/colorTextDark"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
@@ -489,6 +489,20 @@
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="16sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:autoLink="web"
|
||||
android:background="@drawable/permotion_round"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:padding="10dp"
|
||||
android:text="此模块使用 YukiHookAPI 构建。\n点击这里了解更多 https://github.com/fankes/YukiHookAPI"
|
||||
android:textColor="@color/colorTextGray"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</LinearLayout>
|
24
app/src/main/res/layout/dia_icon_filter.xml
Normal file
24
app/src/main/res/layout/dia_icon_filter.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?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="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="15dp"
|
||||
android:paddingTop="15dp"
|
||||
android:paddingRight="15dp"
|
||||
tools:ignore="HardcodedText">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/dia_icon_filter_input_edit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:hint="可输入 APP 名称、包名"
|
||||
android:singleLine="true" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
32
build.gradle
32
build.gradle
@@ -1,30 +1,12 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
buildscript {
|
||||
ext.kotlin_version = "1.6.10"
|
||||
repositories {
|
||||
google()
|
||||
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
|
||||
maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
|
||||
maven { url "https://www.jitpack.io" }
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "com.android.tools.build:gradle:7.0.4"
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
plugins {
|
||||
id 'com.android.application' version '7.1.1' apply false
|
||||
id 'com.android.library' version '7.1.1' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
|
||||
maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
|
||||
maven { url "https://www.jitpack.io" }
|
||||
mavenCentral()
|
||||
}
|
||||
ext {
|
||||
appVersionName = "1.5"
|
||||
appVersionCode = 9
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
#Mon Jan 24 04:31:03 CST 2022
|
||||
#Tue Feb 15 02:09:05 CST 2022
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
@@ -1,2 +1,18 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
repositories {
|
||||
google()
|
||||
maven { url "https://api.xposed.info/" }
|
||||
maven { url 'https://www.jitpack.io' }
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
rootProject.name = "MIUINativeNotifyIcon"
|
||||
include ':app'
|
||||
|
Reference in New Issue
Block a user