diff --git a/.eslintrc.js b/.eslintrc.js
index 57d0234..35c7e4a 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -35,7 +35,6 @@ module.exports = {
YuvImage: true,
ImageFormat: true,
ui: true,
- activity: true,
View: true,
context: true,
ObjectAnimator: true,
@@ -75,7 +74,6 @@ module.exports = {
images: true,
launchApp: true,
Bitmap: true,
- className: true,
Buffer: true,
idEndsWith: true,
textEndsWith: true,
diff --git a/.gitignore b/.gitignore
index f023c6c..4860584 100644
--- a/.gitignore
+++ b/.gitignore
@@ -197,3 +197,5 @@ $RECYCLE.BIN/
# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)
+
+window_dump.xml
diff --git a/README.md b/README.md
index e4c56ab..228e093 100644
--- a/README.md
+++ b/README.md
@@ -3,15 +3,18 @@
MIUI广告清理工具
## 使用方法
-- 下载并安装[小米手机助手](http://zhushou.xiaomi.com/)或其他手机助手,确保助手可正常连接手机
-- 按手机助手的提示图文,打开手机的[USB调试模式](https://www.bilibili.com/video/BV1Ht4y1X75e)
-- 打开手机的`USB安装`选项,或者自行将`MiuiCleaner.apk`安装到手机
-- `MiuiCleaner.cmd`放在手机助手的安装目录运行
-- 在手机端打开`MiuiCleaner`,点击要执行的清理项目
-## 预装应用卸载
+- [点击下载最新版本MiuiCleaner](https://github.com/gucong3000/MiuiCleaner/releases/latest),将`MiuiCleaner.apk`安装到手机即可
+- 使用“预装应用卸载”功能能时,需要root权限或者ADB权限(亦即“开发者选项”中“USB 调试”),未root用户在使用该功能时请在电脑上按以下步骤操作:
+ - 下载并安装[小米手机助手](http://zhushou.xiaomi.com/)、其他手机助手、或者[Android SDK 平台工具](https://developer.android.google.cn/studio/releases/platform-tools?hl=zh-cn)
+ - `MiuiCleaner`手机版在需要ADB权限时会自动打开手机的“开发者选项”和“USB 调试”,这时用数据线连接电脑和手机,将`MiuiCleaner.cmd`放在手机助手的安装目录运行即可。
-勾选你想要卸载的APP,点击确定就可以一键删除了。支持以下应用的卸载:
+## 功能介绍
+### 预装应用卸载
+
+勾选你想要卸载的APP,点击确定就可以一键删除了。支持以下62款应用的卸载:
+
+点击查看详细名单
- APP 外置开屏广告
- 广告分析
@@ -88,8 +91,13 @@ MIUI广告清理工具
- 小爱视觉(扫一扫)
- 小爱翻译
- 小爱通话(AI虚拟助手)
+
+
+### 去广告应用
-## 去广告应用
+内置多款去广告应用的下载链接:
+
+点击查看详细名单
- [李跳跳](https://www.123pan.com/s/A6cA-edAJh)
> 广告自动跳过工具
@@ -108,7 +116,7 @@ MIUI广告清理工具
- [知乎](https://423down.lanzouo.com/b0f2lkafe)
> 集成“知了”,可在“知了”中关闭所有广告
- [哔哩哔哩](https://423down.lanzouv.com/b0f1gksne)
- > 集成“哔哩漫游”,可在“哔哩漫游”中关闭所有广告
+ > 集成“哔哩漫游”,可在“哔哩漫游”中关闭所有广告(需点击其版本号7次)
- [优酷视频](https://423down.lanzouv.com/b0f1avpib)
> 修改版,去广告
- [百度贴吧](https://423down.lanzouv.com/b0f1b6q8d)
@@ -118,14 +126,25 @@ MIUI广告清理工具
- [AppShare](https://appshare.muge.info/)
> 应用商店,可下载MIUI国际版中提取的APP
-## 关闭各应用广告
+
+
+### 关闭各应用广告
-支持在以下16款应用中,自动搜索到广告开关的具体位置并自动给与处置。
+支持在以下17款应用中,自动搜索50多个广告开关的具体位置,并自动给予处置。
+
+点击查看详细名单
- 小米帐号:
- 关于小米帐号:
- 系统广告:
- 系统工具广告: `关闭`
+- 系统安全:
+ - "加入“用户体验改进计划”": `关闭`,
+ - 自动发送诊断数据: `关闭`
+ - 广告服务:
+ - 个性化广告推荐: `关闭`,
+ - 网页链接调用服务:
+ - 网页链接调用服务: `关闭`,
- 手机管家:
- 在通知栏显示: `关闭`
- 在线服务: `关闭`
@@ -222,7 +241,25 @@ MIUI广告清理工具
- 通知栏快捷入口: `关闭`
- Facebook快捷通知: `关闭`
-### 常见问题
+
+
+[演示视频:MiuiCleaner新功能演示-广告全自动关闭](https://www.zhihu.com/zvideo/1555993019102552064)
+### 应用管家
+
+- 自启动管理
+ > 可管理所有应用的自启动权限
+- 通知管理
+ > 可以将所有通知栏广告一网打尽
+- 应用卸载
+ > 可批量卸载第三方应用
+- 应用信息
+ > 管理各种权限
+
+### 回收站
+
+你可以在这里重新安装已卸载的预装应用
+
+## 常见问题
- 电脑连不上手机,咋办?
> 确保数据线正常,确保驱动安装正常,可以用“360手机助手”等工具自动安装
- 删错了“XXX”,咋恢复?
@@ -230,6 +267,19 @@ MIUI广告清理工具
## CHANGELOG
+- current
+ - PC端修复bug #1
+ - 预装应用卸载
+ - 修正:卸载多个应用时报“超时”的bug
+ - 新增:无`USB调试`权限时,自动获取授权的功能
+ - 关闭各应用广告
+ - 增强:小米帐号 按需显示
+ - 新增:系统安全 按需显示
+ - 新增:广告服务 按需显示
+ - 应用管家
+ - 新增:自启动管理
+ - 新增:应用卸载
+ - 删除:应用管理
- v2022.9.21.4
- 新增手机端 GUI
- 新增广告全自动关闭功能
@@ -261,15 +311,3 @@ MIUI广告清理工具
- 提供若干内置APP卸载和恢复功能
- 提供第三方APP替换功能
-## 应用管家
-
-- 通知管理
- > 可以将所有通知栏广告一网打尽
-- 应用管理
- > 可以批量卸载非预装应用
-- 应用信息
- > 管理各种权限
-
-## 回收站
-
-你可以在这里重新安装已卸载的预装应用
diff --git a/build.cmd b/build.cmd
deleted file mode 100644
index 1590a25..0000000
--- a/build.cmd
+++ /dev/null
@@ -1,11 +0,0 @@
-CHCP 65001
-.\bin\Bat_To_Exe_Converter.exe ^
-/bat .\src\main.cmd ^
-/exe .\dist\MiuiCleaner.exe ^
-/ico .\favicon.ico ^
-/productversion "2022.9.10.2" ^
-/productname MiuiCleaner ^
-/description "MIUI广告清理工具" ^
-/copyright GuCong ^
-/overwrite ^
-/upx ^
diff --git a/package.json b/package.json
index adc8090..7a0ad4e 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,7 @@
"test:fix": "npm run test -- --fix",
"start": "npx webpack --config webpack.config.js --watch --mode=development",
"build:app": "npx webpack --config webpack.config.js --mode=production",
- "build:cmd": "cat src/miui_cleaner_cmd/main.cmd | iconv --from-code=utf-8 --to-code=gbk > dist/miui_cleaner_cmd/main.cmd",
+ "build:cmd": "cat src/miui_cleaner_cmd/main.cmd | iconv --from-code=utf-8 --to-code=gbk > dist/miui_cleaner_cmd/MiuiCleaner.cmd",
"build:pull": "adb pull /sdcard/auto.js/miui_cleaner_app/dist/MiuiCleaner_v2022.9.21.4.apk ./dist/miui_cleaner_app/",
"build": "node project.js && npm run build:app && npm run build:cmd",
"deploy:clear": "rm -rf ./dist/miui_cleaner_app/*.map && rm -rf ./dist/miui_cleaner_app/*.apk",
diff --git a/src/miui_cleaner_app/appManager.js b/src/miui_cleaner_app/appManager.js
index 608fad8..4b43f3c 100644
--- a/src/miui_cleaner_app/appManager.js
+++ b/src/miui_cleaner_app/appManager.js
@@ -1,32 +1,44 @@
const startActivity = require("./startActivity");
module.exports = [
+ {
+ name: "自启动管理",
+ packageName: "com.miui.securitycenter",
+ className: "com.miui.permcenter.autostart.AutoStartManagementActivity",
+ },
{
name: "通知管理",
- fn: () => {
- return startActivity({
- packageName: "com.miui.notification",
- className: "miui.notification.management.activity.NotificationAppListActivity",
- });
- },
+ packageName: "com.miui.notification",
+ className: "miui.notification.management.activity.NotificationAppListActivity",
},
+ // {
+ // name: "应用管理",
+ // packageName: "com.miui.securitycenter",
+ // className: "com.miui.appmanager.AppManagerMainActivity",
+ // },
+ // {
+ // name: "应用升级",
+ // packageName: "com.xiaomi.market",
+ // className: ".ui.UpdateListActivity",
+ // },
{
- name: "应用管理",
- fn: () => {
- return startActivity({
- packageName: "com.miui.securitycenter",
- className: "com.miui.appmanager.AppManagerMainActivity",
- });
- },
+ name: "应用卸载",
+ packageName: "com.miui.cleanmaster",
+ className: "com.miui.optimizecenter.deepclean.installedapp.InstalledAppsActivity",
},
{
name: "应用信息",
- fn: () => {
- return startActivity({
- packageName: "com.android.settings",
- className: ".applications.ManageApplications",
- });
- },
-
+ packageName: "com.android.settings",
+ className: ".applications.ManageApplications",
},
-];
+].map(action => {
+ return app.getAppName(action.packageName)
+ ? {
+ name: action.name,
+ fn: () => startActivity({
+ packageName: action.packageName,
+ className: action.className,
+ }),
+ }
+ : null;
+}).filter(Boolean);
diff --git a/src/miui_cleaner_app/notification.js b/src/miui_cleaner_app/notification.js
index 7644b92..84be487 100644
--- a/src/miui_cleaner_app/notification.js
+++ b/src/miui_cleaner_app/notification.js
@@ -1,4 +1,4 @@
-const requestPermission = require("./requestPermission");
+const requestSetting = require("./requestSetting");
const blur = require("./blur");
function notification () {
@@ -13,7 +13,7 @@ function notification () {
console.error(ex.message);
return;
}
- requestPermission({
+ requestSetting({
accessibility: true,
});
blur();
diff --git a/src/miui_cleaner_app/offAppAd.js b/src/miui_cleaner_app/offAppAd.js
index 098a5e2..4e174eb 100644
--- a/src/miui_cleaner_app/offAppAd.js
+++ b/src/miui_cleaner_app/offAppAd.js
@@ -1,9 +1,11 @@
-const multiChoice = require("./multiChoice");
const findClickableParent = require("./findClickableParent");
-const requestPermission = require("./requestPermission");
+const requestSetting = require("./requestSetting");
+const multiChoice = require("./multiChoice");
+const test = require("./test/offAppAdTest");
// const instApk = require("./instApk");
// const downApp = require("./downApp");
-const test = require("./test/offAppAdTest");
+const Settings = android.provider.Settings;
+
function delay (time) {
sleep(time || 0x200);
}
@@ -27,25 +29,40 @@ function isFrameLayout (linear) {
return /\.FrameLayout$/.test(linear.className());
}
+function getDefaultValue (value, defaultValu) {
+ return value == null
+ ? defaultValu
+ : value
+ ;
+}
+
function walkListView (options = {}) {
const adCheckBoxList = [];
const adLinearList = [];
- let inNotify;
+ let inNotifyMgr;
const listView = findByClassName(/\.(RecyclerView|ListView)$/).filter(view => {
const packageName = view.packageName();
- inNotify = packageName === "com.android.settings";
- return inNotify || packageName === options.packageName;
+ return options.packageName === packageName || (inNotifyMgr = packageName === "com.android.settings");
}).findOne();
delay();
- const regSwitchOn = inNotify
+ const regSwitchOn = inNotifyMgr
? null
- : options.regSwitchOn || /^(仅在(WLAN|Wi-?Fi)下.*?|.*?广告(拦截|过滤)|去.*?广告)$/i;
- const regSwitchOff = inNotify
+ : getDefaultValue(
+ options.regSwitchOn,
+ /^(仅在(WLAN|Wi-?Fi)下.*?|.*?广告(拦截|过滤)|去.*?广告)$/i,
+ );
+ const regSwitchOff = inNotifyMgr
? /^允许通知$/
- : options.regSwitchOff || /猜你喜欢|天气视频|桌面搜索|用户体验|在线(内容)?服务|个性化|消息|广告|热[榜门]|推[荐广]|宫格[栏位]|技巧|热点|新闻|[资快]讯|推送(服务|通知)|通知栏|扫描内存|福利活动|显示天气服务/;
- const regSubPage = inNotify
+ : getDefaultValue(
+ options.regSwitchOff,
+ /猜你喜欢|天气视频|桌面搜索|用户体验|在线(内容)?服务|个性化|消息|广告|热[榜门]|推[荐广]|宫格[栏位]|技巧|热点|新闻|[资快]讯|推送(服务|通知)|通知栏|扫描内存|福利活动|显示天气服务/,
+ );
+ const regSubPage = inNotifyMgr
? null
- : options.regSubPage || /^(高级|其他|消息[与和]?推送|.*?广告(拦截|过滤)|去.*?广告|(.*?((消息)?通知|隐私|功能|个性化|信息流|用户体验|[主首]页|闹钟)(设置|管理|服务|计划|[防保]护)))$/;
+ : getDefaultValue(
+ options.regSubPage,
+ /^(高级|其他|消息[与和]?推送|.*?广告(拦截|过滤)|去.*?广告|(.*?((消息)?通知|隐私|功能|个性化|信息流|用户体验|[主首]页|闹钟)(设置|管理|服务|计划|[防保]护)))$/,
+ );
if (!options.handle) {
options.handle = {};
};
@@ -146,7 +163,7 @@ function walkListView (options = {}) {
result[adLinear.text] = subResult;
});
- if (!inNotify && !options.disableScroll && listView.scrollable() && listView.scrollForward()) {
+ if (!inNotifyMgr && !options.disableScroll && listView.scrollable() && listView.scrollForward()) {
// 判断页面是否需要下滚
console.log("页面滑动");
delay();
@@ -225,6 +242,13 @@ function startAct (packageName, activity) {
return result || true;
}
+function startIntent (options) {
+ context.startActivity(new android.content.Intent(Settings[options.intent]));
+ waitForPackage(options.packageName);
+ toastLog(`正在启动“${options.name}”`);
+ delay();
+}
+
function clickButton (btnLabelList, text) {
if (!Array.isArray(btnLabelList)) {
btnLabelList = [btnLabelList];
@@ -408,8 +432,8 @@ function startTask (options) {
threadSkipPopupPage = threads.start(skipPopupPage);
}
options = { ...options };
- if (options.start) {
- options.start();
+ if (options.intent) {
+ startIntent(options);
} else if (options.activity) {
startAct(options.packageName, options.activity);
} else {
@@ -423,6 +447,7 @@ function startTask (options) {
test(options, result);
}
}
+
function switchBroHomePage (listView, options) {
// 小米浏览器及国际版的特别控件————版式切换
Array.from(listView.children()).some(linear => {
@@ -477,6 +502,23 @@ function noop () {
//
}
+function getSysConfig (space, key) {
+ // https://developer.android.google.cn/reference/android/provider/Settings
+ return Settings[space].getInt(context.getContentResolver(), key);
+}
+
+function getGlobalConfig (key) {
+ return getSysConfig("Global", key);
+}
+
+function getSecureConfig (key) {
+ return getSysConfig("Secure", key);
+}
+
+// function getSystemConfig (key) {
+// return getSysConfig("Secure", key);
+// }
+
const cleanerList = [
{
name: "先清理后台应用(推荐)",
@@ -485,9 +527,40 @@ const cleanerList = [
{
// 小米帐号
packageName: "com.xiaomi.account",
+ // activity: ".settings.SystemAdActivity",
activity: ".ui.AccountSettingsActivity",
regSubPage: /^关于.*?[帐账]号|系统.*?广告$/,
regSwitchOff: /^系统.*?广告$/,
+ test: () => Settings.Global.getString(context.getContentResolver(), "passport_ad_status") !== "OFF",
+ entry: noop,
+ },
+ {
+ name: "系统安全",
+ packageName: "com.android.settings",
+ intent: "ACTION_SECURITY_SETTINGS",
+ regSubPage: /(广告|链接调用)/,
+ regSwitchOff: /诊断数据|广告推荐|链接调用|用户体验/,
+ test: () => [
+ // 网页链接调用服务
+ "http_invoke_app",
+ // 加入“用户体验改进计划”
+ "upload_log_pref",
+ // 自动发送诊断数据
+ "upload_debug_log_pref",
+
+ ].some(getSecureConfig),
+ entry: noop,
+ },
+ {
+ // `广告服务` 位于 `安全` 的子页面
+ name: "广告服务",
+ packageName: "com.android.settings",
+ activity: ".ad.AdServiceSettings",
+ regSwitchOff: /.*/,
+ test: () => getGlobalConfig(
+ // 个性化广告推荐
+ "personalized_ad_enabled",
+ ),
entry: noop,
},
{
@@ -640,7 +713,7 @@ const cleanerList = [
// // 打开知乎去广告插件-知了
// regSubPage: /^知了$/,
// regSwitchOn: /^(启用知了|去.*?广告)$/,
- // regSwitchOff: null,
+ // regSwitchOff: false,
// done: function (result) {
// if (!Object.keys(result.handle).length) {
// startTask(this);
@@ -665,6 +738,23 @@ const cleanerList = [
});
function offAppAd () {
+ const resolver = context.getContentResolver();
+ try {
+ // https://developer.android.google.cn/reference/android/provider/Settings
+ // 系统安全 -> 广告服务 -> 个性化广告推荐:关闭
+ Settings.Global.putInt(resolver, "personalized_ad_enabled", 0);
+ [
+ // 网页链接调用服务
+ "http_invoke_app",
+ // 加入“用户体验改进计划”
+ "upload_log_pref",
+ // 自动发送诊断数据
+ "upload_debug_log_pref",
+ ].forEach(key => Settings.Secure.putInt(resolver, key, 0));
+ } catch (ex) {
+ console.log("adb shell pm grant com.github.gucong3000.miui.cleaner android.permission.WRITE_SECURE_SETTINGS");
+ }
+
const menuItemList = cleanerList.filter((appInfo) => {
if (appInfo.packageName && !appInfo.appName && !appInfo.name) {
appInfo.appName = app.getAppName(appInfo.packageName);
@@ -672,10 +762,13 @@ function offAppAd () {
return false;
}
}
+ if (appInfo.test) {
+ return appInfo.test();
+ }
return true;
});
- requestPermission({
+ requestSetting({
accessibility: true,
drawOverlay: true,
});
@@ -692,6 +785,9 @@ function offAppAd () {
}
tasks.forEach(task => {
+ if (task.test && !task.test()) {
+ return;
+ }
task.fn ? task.fn() : startTask(task);
});
console.hide();
diff --git a/src/miui_cleaner_app/recycle.js b/src/miui_cleaner_app/recycle.js
index d72b646..9652027 100644
--- a/src/miui_cleaner_app/recycle.js
+++ b/src/miui_cleaner_app/recycle.js
@@ -1,7 +1,7 @@
+const findClickableParent = require("./findClickableParent");
+const requestSetting = require("./requestSetting");
const singleChoice = require("./singleChoice");
const instApk = require("./instApk");
-const requestPermission = require("./requestPermission");
-const findClickableParent = require("./findClickableParent");
const blur = require("./blur");
const marketPackageName = "com.xiaomi.market";
@@ -45,7 +45,7 @@ function getInstalledPackages () {
// dataDir: appInfo.dataDir,
apk: appInfo.sourceDir,
// publicSourceDir: appInfo.publicSourceDir,
- // deviceProtectedDataDir: appInfo.deviceProtectedDataDir
+ // deviceProtectedDataDir: appInfo.deviceProtectedDataDir,
};
}).filter(Boolean);
}
@@ -54,7 +54,7 @@ function recycle () {
const appInfo = singleChoice("请选择要恢复的应用", getInstalledPackages().concat({ name: "其他" }));
if (appInfo) {
console.log(appInfo);
- requestPermission({
+ requestSetting({
accessibility: true,
});
if (appInfo.apk) {
diff --git a/src/miui_cleaner_app/regtest.js b/src/miui_cleaner_app/regtest.js
deleted file mode 100644
index 5e7618c..0000000
--- a/src/miui_cleaner_app/regtest.js
+++ /dev/null
@@ -1,110 +0,0 @@
-const text = `
-内容推广
-资源推荐
-热榜推荐
-允许通知
-新手帮助
-推送消息
-点赞消息
-评论消息
-个性化服务
-天气视频卡片
-天气服务推荐
-接收小米推送
-接收置顶消息
-使用个人信息进行推荐
-消息推送
-推荐内容
-推荐内容
-资源推荐
-猜你喜欢
-个性化服务
-个性化服务
-信息流推荐
-桌面搜索框
-开启生活早报
-接受消息通知
-允许Wap推送
-猜你喜欢
-系统工具广告
-//https://zhuanlan.zhihu.com/p/509571194
-1、日历 → ┇ → 设置 → 用户体验计划 → 内容推广,关闭;
-2、文件管理 → ↓ ( 下载管理 ) → ┇ → 设置 → 信息流设置 → ,关闭;
-3、文件管理 → ↓ ( 下载管理 ) → ┇ → 设置 → 信息流设置 → ,关闭;
-4、应用商店 → 我的 → 设置 → 通知设置 → ,关闭;
-5、应用商店 → 我的 → 设置 → 通知设置 → → ,关闭;
-6、应用商店 → 我的 → 设置 → 通知设置 → ,关闭;
-7、应用商店 → 我的 → 设置 → 通知设置 → ;
-8、应用商店 → 我的 → 设置 → 隐私设置 → ,关闭;
-9、天气 → ┇ → 设置 → 用户体验计划 → ,关闭;
-10、天气 → ┇ → 设置 → 用户体验计划 → ,关闭;
-11、小米视频 → 我的 → 设置 → 消息与推送 → ,关闭;
-12、小米视频 → 我的 → 设置 → 消息与推送 → ,关闭;
-13、主题壁纸 → 我的 → 设置 → 个性化推荐,关闭;
-14、游戏中心 → 我的 → 设置 → 隐私设置 → ,关闭;
-15、小米商城 → 我的 → 设置 → 消息推送 → ,关闭;
-16、手机管家 → 安全中心 → 设置 → 垃圾清理 → ,关闭;
-17、手机管家 → 安全中心 → 设置 → ,关闭;
-18、设置 → 应用设置 → 应用管理 → ┇ → 设置 → ,关闭;
-19、打开任一桌面文件夹 → 单击文件夹名称 → ,关闭。
-20、小爱同学→设置→关于小爱→关闭“ 加入用户体验计划”→隐私开关→关闭“
-21、小米社区(可以直接卸载) →我的→设置→高级设置→关闭“详情推荐相似”&“个性化推荐”&“”
-22、桌面下方搜索栏→右上角三个点→设置→消息通知管理→关闭“允许通知”→返回→搜索快捷方式→关闭“”
-23、时钟→右上角→生活早报→关闭‘”
-24、浏览器→菜单→设置→主页设置→简洁版→关闭“宫格栏推送”→返回→接收消息通知→关闭“”
-25、短信→右上角设置→高级设置(倒数第二个) →关闭“”
-26、桌面→打开任意文件夹→点击文件夹名称→关闭“”
-27、桌面左滑打开负一屏→划到底部→设置→服务管理→选择关闭项目
-28、设置→小米账号→声明与条款→系统广告→→关闭
-
-
-热门活动
-资源推荐
-个性化广告推荐
-加入用户体验改进计划
-评论消息
-点赞消息
-个性化服务
-显示生活早报
-宫格位推送
-资源推荐
-资源推荐
-热榜推荐
-接收置顶消息
-接收置顶消息
-今日推荐
-
-// 评论区
-MIUI13.0.12(2022-06-04):
-1、设置 → 小米帐号 → 关于小米帐号 → 系统广告 → 系统工具广告,关闭;
-2、设置 → 桌面 → 桌面搜索框,关闭;
-3、设置 → 桌面 → 智能助理设置 → 实时动态 & 推荐卡片 & ,关闭;
-4、设置 → 应用设置 → 应用管理 → ┇ → 设置 → 资源推荐,关闭;
-5、设置 → 小爱同学 → 隐私管理 → 隐私设置 → & ,关闭;
-6、打开任一桌面文件夹 → 单击文件夹名称 → 今日推荐,关闭;
-7、桌面左滑打开负一屏 → 长按不想看的小部件,移除;
-8、手机管家 → 设置 → 垃圾清理 → 推荐内容,关闭;
-9、手机管家 → 设置 → 隐私设置 → 个性化推荐,关闭;
-10、应用商店 → 我的 → 设置 → 通知设置 → 新手帮助 & 应用更新通知 & & ,关闭;
-11、应用商店 → 我的 → 设置 → 隐私设置 → 个性化服务 → ,关闭;
-12、时钟 → ┇ → 生活早报 → 开启生活早报,关闭;
-13、时钟 → ┇ → 设置 → 更多闹钟设置 → ,关闭;
-14、浏览器 → 我的 → 设置 → 简洁版;,关闭;
-
-可移除:
-15、日历 → ┇ → 设置 → 用户体验计划 → 内容推广,关闭;
-16、文件管理 → ↓ ( 下载管理 ) → ┇ → 设置 → 信息流设置 → & 热榜推荐,关闭;
-17、主题壁纸 → 我的 → 设置 → 隐私设置 → 个性化推荐,关闭;
-18、小米视频 → 我的 → 设置 → 消息与推送 → 接收小米推送 & 接收置顶消息,关闭;
-
-可卸载:
-19、天气 → ┇ → 设置 → 用户体验计划 → 天气视频卡片 & 内容推广,关闭;
-20、游戏中心 → 我的 → 设置 → 隐私设置 → 个性化服务,关闭;
-21、小米商城 → 我的 → 设置 → 消息推送 → 消息推送,关闭;
-22、小米社区 → 头像 → 设置 → 隐私管理 → 详情页相似推荐 & 个性化推,关闭;
-`;
-
-const regSwitch = /通知|猜你喜欢|天气视频|桌面搜索|生活早报|用户体验|个性化|消息|广告|热[榜门]|推[荐广送]/gm;
-const regSubPage = /(清理垃圾|简洁版|((通知|隐私|功能|个性化|信息流|用户体验|主页设置)(设置|管理|服务|计划)))/g;
-console.log(text.match(regSwitch));
-// console.log(text.match(regSubPage));
diff --git a/src/miui_cleaner_app/requestPermission.js b/src/miui_cleaner_app/requestPermission.js
deleted file mode 100644
index ab23834..0000000
--- a/src/miui_cleaner_app/requestPermission.js
+++ /dev/null
@@ -1,110 +0,0 @@
-// https://www.coder.work/article/1171167
-
-const findClickableParent = require("./findClickableParent");
-
-/**
- * 请求 APP 的系统权限
- * @param {object} options 包名
- * @param {bool} options.accessibility 无障碍、可访问性
- * @param {bool} options.drawOverlay 悬浮窗、允许显示在其他应用的上层
- * @param {bool} options.captureScreen 截图
- */
-function requestPermission (options = {}) {
- options = {
- accessibility: true,
- ...options,
- };
-
- threads.start(() => {
- if (options.accessibility) {
- auto.waitFor();
- }
- if (options.drawOverlay) {
- setDrawOverlay();
- }
- if (options.captureScreen) {
- setCaptureScreen();
- }
- });
-}
-
-function clickCheckBox (expect, packageName) {
- let checkBox = selector().packageName(packageName).className("CheckBox").findOne();
- const value = checkBox.checked();
- if (value === expect) {
- return expect;
- } else {
- checkBox = findClickableParent(checkBox);
- if (checkBox) {
- checkBox.click();
- return expect;
- }
- }
- return value;
-}
-
-/**
- * 请求或自动化获得截图权限
- * @returns {bool}
- */
-function setDrawOverlay () {
- let value = floaty.checkPermission();
- if (!value) {
- floaty.requestPermission();
- try {
- value = clickCheckBox(true, "com.android.settings");
- } catch (ex) {
- toastLog("请打开“悬浮窗”权限,以便自动化操作");
- }
- if (value) {
- back();
- }
- }
- return value;
-}
-
-/**
- * 查询目前是否有截图权限
- * @returns {bool}
- */
-function getCaptureScreen () {
- try {
- images.captureScreen();
- } catch (ex) {
- return false;
- }
- return true;
-}
-
-/**
- * 请求或自动化获得截图权限
- * @returns {bool}
- */
-function setCaptureScreen () {
- let value = getCaptureScreen();
-
- if (!value) {
- // 先打开悬浮窗权限,因为MIUI可能有Bug,截图权限授权弹窗可能有时候不显示,先给悬浮窗权限就没问题了。
- setDrawOverlay();
-
- // 尝试使用“无障碍”权限获得的自动化操作能力自动点击,拿到截图权限
- const thread = threads.start(function () {
- try {
- const packageName = "com.android.systemui";
- clickCheckBox(true, packageName);
- findClickableParent(selector().packageName(packageName).text("立即开始").findOne()).click();
- } catch (ex) {
- //
- }
- });
- value = images.requestScreenCapture();
- thread.interrupt();
-
- if (!value) {
- toastLog("请打开“截图”权限,以便能能识别开关");
- }
- }
- return value;
-}
-
-module.exports = requestPermission;
diff --git a/src/miui_cleaner_app/requestSetting.js b/src/miui_cleaner_app/requestSetting.js
new file mode 100644
index 0000000..cd37724
--- /dev/null
+++ b/src/miui_cleaner_app/requestSetting.js
@@ -0,0 +1,181 @@
+// https://www.coder.work/article/1171167
+
+const findClickableParent = require("./findClickableParent");
+
+/**
+ * 请求 APP 的系统权限
+ * @param {object} options 包名
+ * @param {bool} options.accessibility 无障碍、可访问性
+ * @param {bool} options.drawOverlay 悬浮窗、允许显示在其他应用的上层
+ * @param {bool} options.captureScreen 截图
+ */
+function requestPermission (options = {}) {
+ if (options.accessibility) {
+ enableAccessibility();
+ }
+ if (options.drawOverlay) {
+ enableDrawOverlay();
+ }
+ if (options.captureScreen) {
+ enableCaptureScreen();
+ }
+ if (options.development) {
+ enableDevelopment();
+ }
+ if (options.adb) {
+ enableADB();
+ }
+}
+
+function clickCheckBox (expect, packageName) {
+ let checkBox = selector().packageName(packageName).checkable(true).findOne();
+ const value = checkBox.checked();
+ if (value === expect) {
+ return expect;
+ } else {
+ checkBox = findClickableParent(checkBox);
+ if (checkBox) {
+ checkBox.click();
+ return expect;
+ }
+ }
+ return value;
+}
+
+function enableAccessibility () {
+ auto.waitFor();
+}
+
+/**
+ * 开启悬浮窗权限
+ * @returns {bool}
+ */
+function enableDrawOverlay () {
+ let value = floaty.checkPermission();
+ if (!value) {
+ enableAccessibility();
+ floaty.requestPermission();
+ try {
+ value = clickCheckBox(true, "com.android.settings");
+ } catch (ex) {
+ toastLog("请打开“悬浮窗”权限,以便自动化操作");
+ }
+ if (value) {
+ back();
+ }
+ }
+ return value;
+}
+
+/**
+ * 获取Android配置信息
+ * @param {String} key 配置项名称
+ * @returns {Int}
+ */
+function getGlobalSetting (key) {
+ // https://developer.android.google.cn/reference/android/provider/Settings.Global
+ return android.provider.Settings.Global.getInt(context.getContentResolver(), key);
+}
+
+function findBtnInView (intent, text) {
+ enableAccessibility();
+ context.startActivity(new android.content.Intent(android.provider.Settings[intent]));
+ sleep(0x200);
+ const listView = selector().packageName("com.android.settings").scrollable(true).findOne();
+ sleep(0x200);
+ let btn;
+ do {
+ btn = selector().packageName("com.android.settings").text(text).findOnce();
+ if (btn) {
+ break;
+ } else {
+ sleep(0x200);
+ }
+ } while (listView.scrollForward());
+ return findClickableParent(btn);
+}
+
+/**
+ * 打开开发者选项
+ * @returns {bool}
+ */
+function enableDevelopment () {
+ let value = getGlobalSetting("development_settings_enabled");
+ if (!value) {
+ const btnMIUI = findBtnInView("ACTION_DEVICE_INFO_SETTINGS", "MIUI 版本");
+ if (btnMIUI) {
+ for (let i = 0; i < 9; i++) {
+ btnMIUI.click();
+ }
+ value = true;
+ }
+ }
+ return value;
+}
+
+/**
+ * 打开`USB调试`既ADB权限
+ * @returns {bool}
+ */
+function enableADB () {
+ let value = getGlobalSetting("adb_enabled");
+ if (!value) {
+ enableDevelopment();
+ const btnUSB = findBtnInView("ACTION_APPLICATION_DEVELOPMENT_SETTINGS", "USB 调试");
+ if (btnUSB) {
+ btnUSB.click();
+ let btnAllow;
+ do {
+ const checkBox = selector().id("check_box").packageName("com.miui.securitycenter").findOnce();
+ if (checkBox && !checkBox.checked()) {
+ findClickableParent(checkBox).click();
+ }
+ btnAllow = selector().id("intercept_warn_allow").packageName("com.miui.securitycenter").findOne(0x200);
+ if (btnAllow) {
+ findClickableParent(btnAllow).click();
+ }
+ } while (btnAllow);
+ back();
+ value = true;
+ }
+ }
+ return value;
+}
+
+/**
+ * 开启截图权限
+ * @returns {bool}
+ */
+function enableCaptureScreen () {
+ let value = true;
+ try {
+ images.captureScreen();
+ } catch (ex) {
+ value = false;
+ }
+
+ if (!value) {
+ // 尝试使用“无障碍”权限获得的自动化操作能力自动点击,拿到截图权限
+ enableAccessibility();
+ // 先打开悬浮窗权限,因为MIUI可能有Bug,截图权限授权弹窗可能有时候不显示,先给悬浮窗权限就没问题了。
+ enableDrawOverlay();
+ const thread = threads.start(function () {
+ try {
+ const packageName = "com.android.systemui";
+ clickCheckBox(true, packageName);
+ findClickableParent(selector().packageName(packageName).text("立即开始").findOne()).click();
+ } catch (ex) {
+ //
+ }
+ });
+ value = images.requestScreenCapture();
+ thread.interrupt();
+
+ if (!value) {
+ toastLog("请打开“截图”权限,以便能能识别开关");
+ }
+ }
+ return value;
+}
+
+module.exports = requestPermission;
diff --git a/src/miui_cleaner_app/startActivity.js b/src/miui_cleaner_app/startActivity.js
index d7cd4f4..0088e47 100644
--- a/src/miui_cleaner_app/startActivity.js
+++ b/src/miui_cleaner_app/startActivity.js
@@ -1,4 +1,4 @@
-const requestPermission = require("./requestPermission");
+const requestSetting = require("./requestSetting");
const blur = require("./blur");
function startActivity (options) {
@@ -9,7 +9,7 @@ function startActivity (options) {
console.error(ex.message);
return;
}
- requestPermission({
+ requestSetting({
accessibility: true,
});
blur();
diff --git a/src/miui_cleaner_app/sysAppRm.js b/src/miui_cleaner_app/sysAppRm.js
index 8a5625f..6d7b66e 100644
--- a/src/miui_cleaner_app/sysAppRm.js
+++ b/src/miui_cleaner_app/sysAppRm.js
@@ -1,6 +1,7 @@
+const findClickableParent = require("./findClickableParent");
+const requestSetting = require("./requestSetting");
const multiChoice = require("./multiChoice");
const blur = require("./blur");
-const findClickableParent = require("./findClickableParent");
function clickButton (button, text) {
button = findClickableParent(button);
@@ -238,12 +239,15 @@ module.exports = () => {
const cmd = "adb shell sh " + shFilePath;
console.log("正以等候电脑端自动执行:\n" + cmd);
toast("正以等候电脑端自动执行");
- const startTime = Date.now();
+ const timeout = Date.now() + 0x800 + tasks.length * 0x200;
let fileExist;
+ requestSetting({
+ adb: true,
+ });
do {
sleep(0x200);
fileExist = files.exists(shFilePath);
- } while (fileExist && Date.now() - startTime < 0x1000);
+ } while (fileExist && Date.now() < timeout);
if (fileExist) {
dialogs.rawInput("等候电脑端自动执行超时,请在电脑手动执行命令:", cmd);
} else {
diff --git a/src/miui_cleaner_app/test/offAppAdTest.js b/src/miui_cleaner_app/test/offAppAdTest.js
index 3670f3b..ee9bb51 100644
--- a/src/miui_cleaner_app/test/offAppAdTest.js
+++ b/src/miui_cleaner_app/test/offAppAdTest.js
@@ -9,10 +9,22 @@ const testData = {
关于小米帐号: {
系统广告: {
系统工具广告: false,
- 查看涉及应用列表: null,
},
},
},
+ 广告服务: {
+ 个性化广告推荐: false,
+ },
+ 系统安全: {
+ "加入“用户体验改进计划”": false,
+ "自动发送诊断数据": false,
+ "广告服务": {
+ 个性化广告推荐: false,
+ },
+ "网页链接调用服务": {
+ 网页链接调用服务: false,
+ },
+ },
手机管家: {
在通知栏显示: false,
在线服务: false,
@@ -195,9 +207,9 @@ module.exports = (options, result) => {
const testCaseName = options.name || options.appName || app.getAppName(options.packageName);
const data = testData[testCaseName];
+ // console.log(JSON.stringify(result.handle, 0, "\t"));
try {
if (!data) {
- // console.log(JSON.stringify(result, 0, "\t"));
const error = new Error(`广告自动关闭模块功能异常: “${testCaseName}”中,未编写测试用例`);
throw error;
}
diff --git a/src/miui_cleaner_cmd/main.cmd b/src/miui_cleaner_cmd/main.cmd
index 054824d..d4604bf 100644
--- a/src/miui_cleaner_cmd/main.cmd
+++ b/src/miui_cleaner_cmd/main.cmd
@@ -1,6 +1,4 @@
@echo off
-@REM CHCP 65001>nul 2>nul
-
title MiuiCleaner - MIUI广告清理工具
:start
@@ -31,7 +29,7 @@ call:pkg_exist "com.github.gucong3000.miui.cleaner" || (
echo 正在手机上安装 MiuiCleaner.apk, 请打开“设置 → 更多设置 → 开发者选项 → USB安装”
call:apk_install
) else (
- echo 未在手机上找到“MiuiCleaner”,请将““MiuiCleaner.apk”拷贝至“%CD%”文件夹,或直接安装在手机后,按任意键重试
+ echo 未在手机上找到“MiuiCleaner”,请将“MiuiCleaner.apk”拷贝至"%CD%"文件夹,或直接安装在手机后,按任意键重试
pause>nul 2>nul
goto:start
)
@@ -44,6 +42,7 @@ adb shell settings put secure install_non_market_apps 1
@REM adb shell settings get secure enabled_accessibility_services
adb shell pm grant com.github.gucong3000.miui.cleaner android.permission.WRITE_SETTINGS>nul 2>nul
+adb shell pm grant com.github.gucong3000.miui.cleaner android.permission.WRITE_SECURE_SETTINGS>nul 2>nul
adb shell pm grant com.github.gucong3000.miui.cleaner android.permission.SYSTEM_ALERT_WINDOW>nul 2>nul
adb shell am start -n com.github.gucong3000.miui.cleaner/com.stardust.auojs.inrt.SplashActivity>nul 2>nul