├── .gitignore ├── AndroidFile ├── blacklist.txt ├── config.ini ├── log.txt ├── module_path ├── scheduled_tasks │ └── create_crond.sh └── whitelist.txt ├── CMakeLists.txt ├── META-INF └── com │ └── google │ └── android │ ├── update-binary │ └── updater-script ├── README.md ├── RegularlyClean.c ├── clear.sh ├── customize.sh ├── data └── crond_data ├── init.sh ├── module.prop ├── service.sh ├── state.sh ├── uninstall.sh ├── update.json ├── update.md └── utils.sh /.gitignore: -------------------------------------------------------------------------------- 1 | /cmake-build-android 2 | /cmake-build-debug 3 | /.idea -------------------------------------------------------------------------------- /AndroidFile/blacklist.txt: -------------------------------------------------------------------------------- 1 | #如果使用*通配符 记得把重要路径文件/文件夹写到白名单 2 | #使用通配符类似/*请改成/&* 3 | #只有规则最后的/*才需要改成/&* 4 | #改动示例: 5 | /data/media/0/test/* -> /data/media/0/test/&* 6 | /test/*/file/* -> /data/*/file/&* 7 | #文件示例: 本模块的.bak文件 8 | /data/media/0/Android/RegularlyClean/*.bak 9 | /data/media/0/Android/RegularlyClean/*/*.bak 10 | 11 | #文件夹示例: 12 | /data/media/0/ramdump/ 13 | 14 | #如果文件删除不了,不到万不得已才使用[ /data/media/0/"文件\文件夹" ] 15 | 16 | #下面你可以自定义了! 17 | /storage/emulated/0/Download/.common 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /AndroidFile/config.ini: -------------------------------------------------------------------------------- 1 | # 定时每多少分钟运行一次 (必填: 数字1到60) 2 | # 示例 (意思时每隔10分钟执行一次) 3 | # minute=10 4 | minute=10 5 | 6 | # 模块运行范围 7 | # 注意: 这里没有24点,只有0到23点,不要填错咯! 8 | # 示例 (意思时在7-23点间运行) 9 | # what_time=7-23 10 | what_time=7-23 11 | 12 | # 定时每隔几天运行一次 13 | # 只可以填一个数字。(范围限制:1-31) 14 | # 示例 (意思是每隔三天执行一次) 15 | # what_day=3 16 | what_day= 17 | 18 | # 面具/KSU端控制功能。 19 | # 可以在管理器端控制模块是否运行。 20 | manager_control=y 21 | 22 | # APP监测功能。 23 | # 打开此功能后,当你打开指定APP就会触发清理。 24 | # 默认包名为MT管理器,打开MT管理器即可自动清理文件,主打眼不见心不烦。 25 | 26 | # 是否开启APP监测功能。 27 | clear_mod=y 28 | 29 | # 处于目标APP中只清理一次。 30 | clear_only_once=n 31 | 32 | # 监测APP的包名,每行一个写在"号内部。 33 | # 请不要动"号! 34 | clear=" 35 | bin.mt.plus 36 | " 37 | 38 | # 大文件跳过模式 (安全模式) 39 | # 防止设置黑名单路径时删除可能的个人文件。 40 | bigfile_auto_skip=n 41 | 42 | # 当文件超过这个大小时会自动跳过清理,单位是MB。 43 | bigfile_mb=20 44 | 45 | # C 程序 Debug 模式。 46 | # 正常情况不需要开启。 47 | c_debug=n 48 | 49 | # 调试功能。 50 | # 一般情况不需要调整。 51 | 52 | # C 程序积极性。 53 | # 每次循环间隔时间(秒)。 54 | c_while=5 55 | 56 | # 在目标APP内延长的清理间隔(秒)。 57 | c_clear_sleep=120 -------------------------------------------------------------------------------- /AndroidFile/log.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HChenX/RegularlyClean/bde4fece67b0332ab863a18cf21562c1e78d1a6d/AndroidFile/log.txt -------------------------------------------------------------------------------- /AndroidFile/module_path: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HChenX/RegularlyClean/bde4fece67b0332ab863a18cf21562c1e78d1a6d/AndroidFile/module_path -------------------------------------------------------------------------------- /AndroidFile/scheduled_tasks/create_crond.sh: -------------------------------------------------------------------------------- 1 | path=${0%/*} 2 | path=$(dirname "$path") 3 | { 4 | [[ -f $path/module_path ]] && { 5 | module_path=$(cat $path/module_path) 6 | } 7 | } || { 8 | echo "-[!]: 未安装主模块!" 9 | exit 1 10 | } 11 | MODDIR=$module_path 12 | . $module_path/utils.sh 13 | config=$path/config.ini 14 | 15 | chmod -R 0777 $path 16 | chmod -R 0777 $module_path 17 | 18 | [[ ! -d $crondPath ]] && mkdir -p $crondPath 19 | { 20 | [[ -f $config ]] && { 21 | { 22 | . "$config" && { 23 | echo "- [i]: 文件读取成功" 24 | } 25 | } || { 26 | echo "- [!]: 文件读取异常,请审查(config.ini)文件内容!" && exit 1 27 | } 28 | } 29 | } || { 30 | echo "- [!]: 缺少$config文件" && exit 1 31 | } 32 | 33 | main() { 34 | case $bigfile_auto_skip in 35 | y | n) echo "- [i]: 填写正确 | bigfile_auto_skip=$bigfile_auto_skip" ;; 36 | *) echo "- [!]: 填写错误 | bigfile_auto_skip=$bigfile_auto_skip | 请填写y或n" && exit 1 ;; 37 | esac 38 | [[ $bigfile_auto_skip == y ]] && { 39 | { 40 | [[ $bigfile_mb -gt 0 ]] && { 41 | echo "- [i]: 填写正确 | bigfile_mb=$bigfile_mb" 42 | } 43 | } || { 44 | echo "- [!]: 填写错误 | bigfile_mb=$bigfile_mb | 请大于0" && exit 1 45 | } 46 | } 47 | case $clear_mod in 48 | y | n) echo "- [i]: 填写正确 | clear_mod=$clear_mod" ;; 49 | *) echo "- [!]: 填写错误 | clear_mod=$clear_mod | 请填写y或n" && exit 1 ;; 50 | esac 51 | open_value 52 | } 53 | open_value() { 54 | minute_mod() { 55 | { 56 | [[ $minute != "" ]] && { 57 | case $minute in 58 | [0-9]*) { 59 | [[ $minute -ge 1 ]] && [[ $minute -le 60 ]] && { 60 | echo "- [i]: 填写正确 | minute=$minute" 61 | } 62 | } || { 63 | echo "- [!]: 填写错误 | minute=$minute | 请重新填写" && exit 1 64 | } ;; 65 | esac 66 | minute="*/$minute" 67 | } 68 | } || { 69 | minute="*" 70 | } 71 | } 72 | time_mod() { 73 | { 74 | [[ $what_time != "" ]] && { 75 | { 76 | { 77 | ! echo "$what_time" | grep -q "-" && { 78 | what_time="*/$what_time" 79 | } 80 | } || { 81 | time_1=$(echo "$what_time" | awk -F "-" '{print $1}') 82 | time_2=$(echo "$what_time" | awk -F "-" '{print $2}') 83 | { 84 | [[ -z $time_1 ]] || [[ -z $time_2 ]] && { 85 | echo "- [!]: 填写错误 | what_time=$what_time" && exit 1 86 | } 87 | } || { 88 | { 89 | ! echo "$time_1" | grep -q "[0-9]" 90 | } || { 91 | ! echo "$time_2" | grep -q "[0-9]" 92 | } && { 93 | echo "- [!]: 填写错误 | what_time=$what_time | 填写数字" && exit 1 94 | } 95 | } || { 96 | { 97 | [[ ${#time_1} -ge 3 ]] 98 | } || { 99 | [[ ${#time_2} -ge 3 ]] 100 | } && { 101 | echo "- [!]: 填写错误 | what_time=$what_time | 不要超过3个字符" && exit 1 102 | } 103 | } || { 104 | { 105 | [[ $time_1 == "$time_2" ]] 106 | } && { 107 | echo "- [!]: 填写错误 | what_time=$what_time | 时间不能相同" && exit 1 108 | } 109 | } || { 110 | { 111 | [[ $time_1 -ge 24 ]] 112 | } || { 113 | [[ $time_2 -ge 24 ]] 114 | } && { 115 | echo "- [!]: 填写错误 | what_time=$what_time | 时间不能大于或等于24点 这里的24点是0点" && exit 1 116 | } 117 | } || { 118 | echo "- [i]: 填写正确 | what_time=$what_time" 119 | } 120 | } 121 | } 122 | } 123 | } || { 124 | what_time="*" 125 | } 126 | } 127 | day_mod() { 128 | { 129 | [[ $what_day != "" ]] && { 130 | { 131 | { 132 | [[ -z $what_day ]] 133 | } && { 134 | echo "- [!]: 填写错误 | what_day=$what_day | 格式: 数字1-31" && exit 1 135 | } 136 | } || { 137 | { 138 | ! echo "$what_day" | grep -q "[0-9]" 139 | } && { 140 | echo "- [!]: 填写错误 | what_day=$what_day | 请填写数字!" && exit 1 141 | } 142 | } || { 143 | { 144 | [[ $what_day -gt 31 ]] || [[ $what_day -lt 1 ]] 145 | } && { 146 | echo "- [!]: 填写错误 | what_day=$what_day | 范围限制:1-31" && exit 1 147 | } 148 | } || { 149 | echo "- [i]: 填写正确 | what_day=$what_day" && what_day="*/$what_day" 150 | } 151 | } 152 | } || { 153 | what_day="*" 154 | } 155 | } 156 | set_cron() { 157 | crond_rule="$minute $what_time $what_day * *" 158 | echo -n "$crond_rule" >"$module_path"/data/crond_data 159 | } 160 | kill_pid() { 161 | crond_pid="$(pgrep -f 'RegularlyClean' | grep -v $$)" 162 | [[ -n $crond_pid ]] && { 163 | for i in $crond_pid; do 164 | echo "- [i]: 杀死模块进程 | pid: $i" 165 | kill -9 "$i" 166 | done 167 | } 168 | } 169 | cron_on() { 170 | echo "$crond_rule $module_path/clear.sh" >$crondFile && crond -c "$crondPath" 171 | mPid="$(pgrep -f 'regularly.d' | grep -v $$)" 172 | { 173 | [[ $mPid == "" ]] && { 174 | echo "- [!]: 定时启动失败,运行失败" && exit 1 175 | } 176 | } || { 177 | echo "- [i]: 定时启动 | pid: $mPid" && logClear "成功修改配置,已经重新运行" 178 | { 179 | [[ -f $module_path/clear.sh ]] && { 180 | sh "$module_path"/clear.sh >/dev/null 181 | "$module_path"/RegularlyClean & 182 | echo "- [i]: 现在可以退出进程了" 183 | exit 0 184 | } 185 | } || { 186 | kill -9 "$mPid" && echo "- [!]: 模块脚本缺失!" && echo "- [!]: 已终止定时!" && logd "- [!]: 模块脚本缺失!" && logd "- [!]: 已终止定时!" 187 | } 188 | } 189 | } 190 | minute_mod 191 | time_mod 192 | day_mod 193 | set_cron 194 | kill_pid 195 | cron_on 196 | } 197 | main 198 | -------------------------------------------------------------------------------- /AndroidFile/whitelist.txt: -------------------------------------------------------------------------------- 1 | #为了防止手残 可以把不被删除的文件或者文件夹输入进来 2 | #下面是例子 一行一个 3 | 4 | # 本模块文件 5 | /data/media/0/Android/RegularlyClean/*.txt 6 | /data/media/0/Android/RegularlyClean/*.ini 7 | /data/media/0/Android/RegularlyClean/*/*.sh 8 | /data/media/0/Android/RegularlyClean/module_path 9 | 10 | # 重要目录和文件 11 | /*/ 12 | /data/ 13 | /data/*/ 14 | /data/adb/* 15 | /data/adb/*/* 16 | /data/media/0/ 17 | /data/media/0/Download/ 18 | /data/media/0/Android/ 19 | /data/media/0/Android/data/ 20 | /data/media/0/Android/media/ 21 | /data/media/0/Android/obb/ 22 | /data/media/0/DCIM/ 23 | /data/media/0/MIUI/ 24 | /data/media/0/Movies/ 25 | /data/media/0/Music/ 26 | /data/media/0/Pictures/ 27 | 28 | /storage/ 29 | /storage/emulated/0/ 30 | /storage/emulated/0/Download/ 31 | /storage/emulated/0/Android/ 32 | /storage/emulated/0/Android/data/ 33 | /storage/emulated/0/Android/media/ 34 | /storage/emulated/0/Android/obb/ 35 | /storage/emulated/0/DCIM/ 36 | /storage/emulated/0/MIUI/ 37 | /storage/emulated/0/Movies/ 38 | /storage/emulated/0/Music/ 39 | /storage/emulated/0/Pictures/ 40 | 41 | /sdcard/ 42 | /sdcard/Download/ 43 | /sdcard/Android/ 44 | /sdcard/Android/data/ 45 | /sdcard/Android/media/ 46 | /sdcard/Android/obb/ 47 | /sdcard/DCIM/ 48 | /sdcard/MIUI/ 49 | /sdcard/Movies/ 50 | /sdcard/Music/ 51 | /sdcard/Pictures/ 52 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.27) 2 | project(RegularlyClean C) 3 | 4 | set(CMAKE_C_STANDARD 23) 5 | 6 | add_executable(RegularlyClean 7 | RegularlyClean.c 8 | ) 9 | -------------------------------------------------------------------------------- /META-INF/com/google/android/update-binary: -------------------------------------------------------------------------------- 1 | #!/sbin/sh 2 | 3 | ################# 4 | # Initialization 5 | ################# 6 | 7 | umask 022 8 | 9 | # echo before loading util_functions 10 | ui_print() { echo "$1"; } 11 | 12 | require_new_magisk() { 13 | ui_print "*******************************" 14 | ui_print " Please install Magisk v20.4+! " 15 | ui_print "*******************************" 16 | exit 1 17 | } 18 | 19 | ######################### 20 | # Load util_functions.sh 21 | ######################### 22 | 23 | OUTFD=$2 24 | ZIPFILE=$3 25 | 26 | mount /data 2>/dev/null 27 | 28 | [ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk 29 | . /data/adb/magisk/util_functions.sh 30 | [ $MAGISK_VER_CODE -lt 20400 ] && require_new_magisk 31 | 32 | install_module 33 | exit 0 34 | -------------------------------------------------------------------------------- /META-INF/com/google/android/updater-script: -------------------------------------------------------------------------------- 1 | #MAGISK 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

RegularlyClean

3 | 4 | ![stars](https://img.shields.io/github/stars/HChenX/RegularlyClean?style=flat) 5 | ![downloads](https://img.shields.io/github/downloads/HChenX/RegularlyClean/total) 6 | ![Github repo size](https://img.shields.io/github/repo-size/HChenX/RegularlyClean) 7 | [![GitHub release (latest by date)](https://img.shields.io/github/v/release/HChenX/RegularlyClean)](https://github.com/HChenX/RegularlyClean/releases) 8 | [![GitHub Release Date](https://img.shields.io/github/release-date/HChenX/RegularlyClean)](https://github.com/HChenX/RegularlyClean/releases) 9 | ![last commit](https://img.shields.io/github/last-commit/HChenX/RegularlyClean?style=flat) 10 | ![language](https://img.shields.io/badge/language-shell-purple) 11 | ![language](https://img.shields.io/badge/language-c-purple) 12 | 13 | [//]: # (

English | 简体中文

) 14 |

是一个可以定时自动清理垃圾文件的模块!

15 |
16 | 17 | # ✨模块介绍 18 | 19 | - 使用 crond 进行定时的自动垃圾文件清理模块。 20 | - 拥有超自由的自定义功能,随你所想! 21 | - 使用 c 语言高效代码实现部分功能。 22 | 23 | # 💡模块说明 24 | 25 | - 首先最重要的是模块基于:[Petit-Abba](https://github.com/Petit-Abba) 26 | 的 [black_and_white_list](https://github.com/Petit-Abba/black_and_white_list) 模块。 27 | - 本模块是基于其模块的超深度自定义拓展完善而来。 28 | - 于原模块区别如下: 29 | 30 | * 比如: 31 | * 1.支持自动安全模式,`/*`将会自动被忽略,需要替换成`/&*`使用,避免手滑勿清。 32 | * 2.支持大文件跳过,比如扫描到大于“20(可自定义)”MB的文件会被自动忽略,防止可能的勿清个人文件。(可选) 33 | * 3.支持在ROOT管理器直接控制模块是否运行,禁用模块停止运行、反之恢复。(可选) 34 | * 4.支持在自定义APP界面自动触发清理,比如进入MT自动清理一遍,主打眼不见心不烦。(可选) 35 | * 5.完全支持MAGISK和KSU等ROOT管理器。 36 | * 6.超强自定义清理时间定制。 37 | * 7.等更多精彩等你发掘··· 38 | 39 | # 🙏致谢名单 40 | 41 | - 本模块代码参考了如下项目,对此表示由衷的感谢: 42 | 43 | | 项目名称 | 项目链接 | 44 | |:--------------------:|:--------------------------------------------------------------------------:| 45 | | black_and_white_list | [black_and_white_list](https://github.com/Petit-Abba/black_and_white_list) | 46 | | 翻译提供 | 提供者 | 47 | | 简体中文 | 焕晨HChen | 48 | 49 | # 📢项目声明 50 | 51 | - 任何对本项目的使用必须注明作者,抄袭是不可接受的! 52 | 53 | # 🌏免责声明 54 | 55 | - 使用本模块即代表愿意承担一切后果。 56 | - 任何由本项目衍生出的项目本项目不承担任何责任。 57 | 58 | # 🎉结尾 59 | 60 | - 感谢您愿意使用本模块!Enjoy your day! ♥️ 61 | -------------------------------------------------------------------------------- /RegularlyClean.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define MAX_MEMORY 1024 10 | 11 | static char FILE_PATH[50] = "/data/media/0/Android/RegularlyClean/"; 12 | char mMsg[200]; 13 | char **appArray = NULL; 14 | char *modulePath = NULL; 15 | bool isDebug = false; 16 | 17 | void logVa(char *msg, ...); 18 | 19 | void logStr(char *msg); 20 | 21 | void logDebug(char *msg); 22 | 23 | void logDebugVa(char *msg, ...); 24 | 25 | void logWrite(); 26 | 27 | bool killPid(char **pidArray); 28 | 29 | char **config(char *check); 30 | 31 | char *onlyReadOne(char **valueArray); 32 | 33 | char *vaPrintf(char *msg, va_list vaList); 34 | 35 | void reportErrorExit(char *log, char *msg) { // 报告错误并退出 36 | perror(msg); 37 | if (log != NULL) { 38 | logStr(log); 39 | } 40 | exit(EXIT_FAILURE); 41 | } 42 | 43 | char *getTime() { // 获取当前时间 44 | int TIME_PATH = 30; // 目测最少需要的字符数 45 | time_t curr_time; 46 | struct tm *local_time; 47 | char mTime[TIME_PATH]; 48 | curr_time = time(NULL); 49 | local_time = localtime(&curr_time); 50 | strftime(mTime, TIME_PATH, "%g/%m/%d %H:%M", local_time); 51 | return strdup(mTime); 52 | } 53 | 54 | long getVagueTime() { 55 | long vagueTime; 56 | time_t curr_time; 57 | vagueTime = time(&curr_time); 58 | return vagueTime; 59 | } 60 | 61 | char *joint(char *value) { 62 | char result[MAX_MEMORY]; 63 | strcpy(result, FILE_PATH); 64 | return strcat(result, value); 65 | } 66 | 67 | char *removeLinefeed(char *value) { // 移除换行符 68 | size_t len = strlen(value); 69 | if (len > 0 && value[len - 1] == '\n') { 70 | value[len - 1] = '\0'; 71 | } 72 | return value; 73 | } 74 | 75 | char *removeLastPath(char *value, char remove) { // 移除路径最后的字段 76 | size_t len = strlen(value); 77 | for (int i = (int) len - 1; i >= 0; i--) { 78 | if (value[i] == remove) { 79 | value[i] = '\0'; 80 | break; 81 | } 82 | } 83 | return value; 84 | } 85 | 86 | bool findCharAtEnd(char *value, char need) { 87 | size_t len = strlen(value); 88 | for (int i = (int) len - 1; i >= 0; i--) { 89 | if (value[i] == need) { 90 | return true; 91 | } 92 | } 93 | return false; 94 | } 95 | 96 | int stringLen(char *value) { 97 | size_t len = strlen(value); 98 | return (int) len; 99 | } 100 | 101 | void vaLog(char *msg, va_list vaList) { 102 | char *result = vaPrintf(msg, vaList); 103 | strcpy(mMsg, ""); 104 | strcpy(mMsg, result); 105 | free(result); 106 | result = NULL; 107 | logWrite(); 108 | } 109 | 110 | void logDebug(char *msg) { 111 | if (isDebug) { 112 | logStr(msg); 113 | } 114 | } 115 | 116 | void logDebugVa(char *msg, ...) { 117 | if (isDebug) { 118 | va_list vaList; 119 | va_start(vaList, msg); 120 | vaLog(msg, vaList); 121 | va_end(vaList); 122 | } 123 | } 124 | 125 | void logStr(char *msg) { 126 | strcpy(mMsg, ""); 127 | strcpy(mMsg, msg); 128 | logWrite(); 129 | } 130 | 131 | void logVa(char *msg, ...) { 132 | va_list vaList; 133 | va_start(vaList, msg); 134 | // vprintf(msg, vaList); 135 | vaLog(msg, vaList); 136 | va_end(vaList); 137 | } 138 | 139 | void logWrite() { 140 | FILE *fp; 141 | char *nowTime = getTime(); 142 | fp = fopen(joint("log.txt"), "a"); 143 | if (fp != NULL) { 144 | fseek(fp, 0, SEEK_END); 145 | fprintf(fp, "[%s] | %s\n", nowTime, mMsg); 146 | fclose(fp); 147 | } else { 148 | perror("Unable to write to logs"); 149 | free(nowTime); 150 | nowTime = NULL; 151 | exit(EXIT_FAILURE); 152 | } 153 | strcpy(mMsg, ""); 154 | free(nowTime); 155 | nowTime = NULL; 156 | } 157 | 158 | char *getModePath() { // 获取模块目录 159 | char *path = (char *) malloc(MAX_MEMORY); 160 | if (path == NULL) { 161 | reportErrorExit("[E] --开辟内存时失败>>>getModePath()", "malloc"); 162 | return NULL; 163 | } 164 | 165 | ssize_t len = readlink("/proc/self/exe", path, MAX_MEMORY - 1); 166 | if (len == -1) { 167 | free(path); 168 | path = NULL; 169 | reportErrorExit("[E] --获取模块目录失败>>>/proc/self/exe", "readlink"); 170 | return NULL; 171 | } 172 | 173 | // path[len] = '\0'; // 添加字符串结束符 174 | path = removeLastPath(path, '/'); 175 | return path; 176 | } 177 | 178 | char *vaPrintf(char *msg, va_list vaList) { // 格式化字符串 179 | int size = vsnprintf(NULL, 0, msg, vaList); 180 | if (size < 0) { 181 | logDebug("[E] --格式化字符串时失败>>>vaPrintf()"); 182 | reportErrorExit(NULL, "vaPrintf"); 183 | return NULL; 184 | } 185 | char *result = (char *) malloc((size + 1) * sizeof(char)); 186 | if (result == NULL) { 187 | logDebug("[E] --开辟内存时失败>>>vaPrintf()"); 188 | reportErrorExit(NULL, "vaPrintf"); 189 | return NULL; 190 | } 191 | vsnprintf(result, size + 1, msg, vaList); 192 | return result; 193 | } 194 | 195 | FILE *createShell(char *command, ...) { // 创建 Shell 196 | FILE *fp; 197 | va_list vaList; 198 | va_start(vaList, command); 199 | char *mCommand = vaPrintf(command, vaList); 200 | va_end(vaList); 201 | fp = popen(mCommand, "r"); 202 | if (fp == NULL) { 203 | free(mCommand); 204 | mCommand = NULL; 205 | reportErrorExit("[E] --执行Shell命令时失败,程序退出>>>createShell()", 206 | "createShell"); 207 | return NULL; 208 | } 209 | free(mCommand); 210 | mCommand = NULL; 211 | return fp; 212 | } 213 | 214 | char **findPid(char *find) { // 查找 PID 215 | FILE *fp; 216 | char read[10]; 217 | int count = 0; 218 | char **pidArray = (char **) malloc(20 * sizeof(char *)); 219 | if (pidArray == NULL) { 220 | logDebug("[E] --开辟内存时失败>>>findPid()"); 221 | reportErrorExit(NULL, "findPid"); 222 | return NULL; 223 | } 224 | fp = createShell("pgrep -f '%s' | grep -v $$", find); 225 | while (fgets(read, sizeof(read), fp) != NULL) { 226 | char *result = removeLinefeed(read); 227 | pidArray[count] = strdup(result); 228 | if (pidArray[count] == NULL) { 229 | logDebugVa("[E] --写入数据时失败,数据: %s>>>findPid()", result); 230 | break; 231 | // reportErrorExit(NULL, "findPid"); 232 | } 233 | count = count + 1; 234 | } 235 | pidArray[count] = NULL; 236 | pclose(fp); 237 | return pidArray; 238 | } 239 | 240 | bool killPid(char **pidArray) { // 杀死指定 PID 241 | bool result = false; 242 | for (int i = 0; pidArray[i] != NULL; i++) { 243 | pid_t pid = (pid_t) strtol(pidArray[i], NULL, 10); 244 | free(pidArray[i]); 245 | pidArray[i] = NULL; 246 | if (kill(pid, 0) == 0) { 247 | if (kill(pid, SIGTERM) == 0) { 248 | logVa("[Stop] --成功终止定时进程:%d", pid); 249 | result = true; 250 | } else { 251 | logVa("[W] --不存在指定进程:%d", pid); 252 | result = false; 253 | break; 254 | } 255 | } 256 | } 257 | free(pidArray); 258 | pidArray = NULL; 259 | return result; 260 | } 261 | 262 | void changeSed(char *path) { 263 | FILE *fp; 264 | fp = createShell( 265 | "sed -i \"/^description=/c description=CROND: [定时进程已经终止,等待恢复中···]\" \"%s/module.prop\"", 266 | path); 267 | fflush(fp); 268 | pclose(fp); 269 | } 270 | 271 | void runSh(char *path, char *value) { 272 | FILE *fp; 273 | fp = createShell("su -c \"sh %s/%s &>/dev/null\"", path, value); 274 | fflush(fp); 275 | pclose(fp); 276 | } 277 | 278 | void runModuleSh(char *value) { 279 | if (modulePath == NULL) { 280 | modulePath = getModePath(); 281 | } 282 | runSh(modulePath, value); 283 | } 284 | 285 | bool foregroundApp(char *pkg) { 286 | FILE *fp; 287 | fp = createShell("su -c \"dumpsys window | grep \"%s\" | grep \"mFocusedApp\"\"", pkg); 288 | int have = getc(fp); 289 | pclose(fp); 290 | if (have == EOF) { 291 | return false; 292 | } else { 293 | return true; 294 | } 295 | } 296 | 297 | char **config(char *check) { // 读取配置 298 | char *path = joint("config.ini"); 299 | char read[MAX_MEMORY]; 300 | char *name = NULL; 301 | char *value = NULL; 302 | int count = 0; 303 | bool keep = false; 304 | char ch = '#'; 305 | FILE *fp; 306 | fp = fopen(path, "r"); 307 | if (fp == NULL) { 308 | reportErrorExit("[W] --读取配置文件失败", "config"); 309 | } 310 | char **valueArray = (char **) malloc(20 * sizeof(char *)); 311 | if (valueArray == NULL) { 312 | fclose(fp); 313 | logDebug("[E] --开辟内存时失败>>>config()"); 314 | reportErrorExit(NULL, "config"); 315 | return NULL; 316 | } 317 | while (fgets(read, MAX_MEMORY, fp) != NULL) { 318 | strcpy(read, removeLinefeed(read)); 319 | if (strcmp(read, "") == 0) continue; 320 | logDebugVa("[D] --读取配置文件: %s", read); 321 | char *result = strchr(read, ch); 322 | free(name); 323 | free(value); 324 | name = NULL; 325 | value = NULL; 326 | if (result == NULL) { 327 | char *token = strtok(read, "="); 328 | if (token != NULL || keep) { 329 | if (token != NULL) name = strdup(token); 330 | token = strtok(NULL, "="); 331 | if (token != NULL || keep) { 332 | // printf("read: %s token: %s\n", read, token); 333 | if (token != NULL && keep) { 334 | reportErrorExit("[E] --读取clear配置错误", "clear_error"); 335 | break; 336 | } 337 | if (keep) { 338 | value = strdup(read); 339 | if (findCharAtEnd(value, '"')) { 340 | if (stringLen(value) == 1) { 341 | keep = false; 342 | continue; 343 | } 344 | value = removeLastPath(value, '"'); 345 | valueArray[count] = strdup(value); 346 | count = count + 1; 347 | keep = false; 348 | continue; 349 | } else if (strcmp(value, "\"") == 0) { 350 | keep = false; 351 | continue; 352 | } 353 | } else value = strdup(token); 354 | if (strcmp(value, "\"") == 0 && strcmp(name, check) == 0) { 355 | keep = true; 356 | continue; 357 | } else { 358 | if (keep) { 359 | valueArray[count] = strdup(read); 360 | count = count + 1; 361 | continue; 362 | } else { 363 | if (strcmp(name, check) == 0) { 364 | valueArray[0] = strdup(value); 365 | count = 1; 366 | break; 367 | } 368 | } 369 | } 370 | } 371 | } 372 | } else { 373 | continue; 374 | } 375 | } 376 | valueArray[count] = NULL; 377 | fclose(fp); 378 | return valueArray; 379 | } 380 | 381 | bool checkState(char *value) { 382 | return strcmp(onlyReadOne(config(value)), "y") == 0; 383 | } 384 | 385 | char *onlyReadOne(char **valueArray) { 386 | int len = 0; 387 | for (int i = 0; valueArray[i] != NULL; ++i) { 388 | len = len + 1; 389 | } 390 | if (len > 1) { 391 | for (int i = 0; i < len; ++i) { 392 | free(valueArray[i]); 393 | valueArray[i] = NULL; 394 | } 395 | free(valueArray); 396 | valueArray = NULL; 397 | return "n"; 398 | } 399 | char *read = valueArray[0]; 400 | if (read == NULL) { 401 | read = "n"; 402 | } 403 | free(valueArray[0]); 404 | valueArray[0] = NULL; 405 | free(valueArray); 406 | valueArray = NULL; 407 | return read; 408 | } 409 | 410 | int charToInt(char *value) { 411 | char *result = onlyReadOne(config(value)); 412 | char *endptr; 413 | long num = strtol(result, &endptr, 10); 414 | if (*endptr != '\0') { 415 | logVa("[W] --转化字符串为数字失败,未转化部分:%s", endptr); 416 | return -1; 417 | } else { 418 | logDebugVa("[D] --to long: %ld", num); 419 | } 420 | return (int) num; 421 | } 422 | 423 | _Noreturn void whenWhile(bool foregroundClear, bool clearOnce, 424 | bool stateCheck, int sleepTime, int clearSleep) { 425 | bool lastState = true; 426 | bool shouldSleep = false; 427 | bool isForeground = false; 428 | bool isCleared = false; 429 | bool isKilled = false; 430 | long lastTime = 0; 431 | while (true) { 432 | if (!isKilled) { 433 | if (foregroundClear) { 434 | if (shouldSleep) { 435 | long nowTime = getVagueTime(); 436 | if ((nowTime - lastTime) > clearSleep) { 437 | shouldSleep = false; 438 | } 439 | } else { 440 | for (int i = 0; appArray[i] != NULL; i++) { 441 | char *app = appArray[i]; 442 | if (strcmp(app, "") != 0) { 443 | isForeground = foregroundApp(app); 444 | logDebugVa("[D] --foregroundApp: %s, isForeground: %d", app, isForeground); 445 | if (isForeground) { 446 | logVa("[I] --应用: %s 进入前台,触发清理", app); 447 | break; 448 | } 449 | } 450 | } 451 | if (isForeground) { 452 | if (clearOnce) { 453 | if (!isCleared) { 454 | runModuleSh("clear.sh"); 455 | isCleared = true; 456 | } 457 | } else { 458 | runModuleSh("clear.sh"); 459 | logDebugVa("[D] --isClear"); 460 | } 461 | logDebugVa("[D] --clearOnce: %d, isCleared: %d", clearOnce, isCleared); 462 | lastTime = getVagueTime(); 463 | shouldSleep = true; 464 | } else { 465 | if (clearOnce) isCleared = false; 466 | // shouldSleep = false; 467 | } 468 | } 469 | } 470 | } 471 | if (stateCheck) { 472 | char file[MAX_MEMORY]; 473 | if (modulePath == NULL) { 474 | modulePath = getModePath(); 475 | } 476 | snprintf(file, MAX_MEMORY, "%s/disable", modulePath); 477 | if (access(file, 0) == 0 && lastState) { 478 | logDebugVa("[D] --findFile: %s, lastState: %d, isKilled: %d", file, lastState, isKilled); 479 | char **pids = findPid("regularly.d"); 480 | if (!killPid(pids)) { 481 | logStr("[E] --停止模块定时进程失败"); 482 | } else { 483 | changeSed(modulePath); 484 | lastState = false; 485 | isKilled = true; 486 | } 487 | } else if (access(file, 0) != 0 && !lastState) { 488 | logDebugVa("[D] --fileRemove: %s, lastState: %d, isKilled: %d", file, lastState, isKilled); 489 | runModuleSh("state.sh"); 490 | logStr("[Run] --成功重启进程"); 491 | lastState = true; 492 | isKilled = false; 493 | } 494 | } 495 | sleep(sleepTime); 496 | } 497 | } 498 | 499 | void cleanup() { 500 | if (appArray != NULL) { 501 | for (int i = 0; appArray[i] != NULL; i++) { 502 | free(appArray[i]); 503 | appArray[i] = NULL; 504 | } 505 | free(appArray); 506 | appArray = NULL; 507 | } 508 | if (modulePath != NULL) { 509 | free(modulePath); 510 | modulePath = NULL; 511 | } 512 | // printf("clear\n"); 513 | } 514 | 515 | int main() { 516 | atexit(cleanup); 517 | modulePath = getModePath(); 518 | isDebug = checkState("c_debug"); 519 | bool autoClear = checkState("clear_mod"); 520 | bool clearOnce = checkState("clear_only_once"); 521 | bool stateCheck = checkState("manager_control"); 522 | int sleepTime = charToInt("c_while"); 523 | int clearSleep = charToInt("c_clear_sleep"); 524 | if (sleepTime == -1) sleepTime = 5; 525 | if (clearSleep == -1) clearSleep = 120; 526 | appArray = config("clear"); 527 | logDebugVa("[D] --modulePath: %s, isDebug: %d, autoClear: %d, " 528 | "clearOnce: %d, stateCheck: %d, sleepTime: %d, clearSleep: %d", modulePath, isDebug, 529 | autoClear, clearOnce, stateCheck, sleepTime, clearSleep); 530 | for (int i = 0; appArray[i] != NULL; i++) { 531 | if (strcmp(appArray[i], "") == 0) continue; 532 | logDebugVa("[D] --app_map: %s", appArray[i]); 533 | } 534 | whenWhile(autoClear, clearOnce, stateCheck, sleepTime, clearSleep); 535 | } 536 | -------------------------------------------------------------------------------- /clear.sh: -------------------------------------------------------------------------------- 1 | #全局变量 2 | MODDIR=${0%/*} 3 | 4 | # 跳过白名单次数判断 5 | print_pd_white_list() { 6 | white_file="$MODDIR/data/whitelist/$(echo "$1" | sed 's/\///g').ini" 7 | { 8 | [[ ! -e "$white_file" ]] && { 9 | echo "1" >"$white_file" 10 | logd "[skip] -[$(cat "$white_file")]- $2" 11 | } 12 | } || { 13 | # 小于3次则打印 14 | white_files="$(cat "$white_file")" 15 | [[ "$white_files" -lt "3" ]] && { 16 | echo "$((white_files + 1))" >"$white_file" 17 | logd "[skip] -[$(cat "$white_file")]- $2" 18 | } 19 | } 20 | } 21 | 22 | # 白名单列表通配符拓展 23 | whitelist_wildcard_list() { 24 | local IFS=$'\n' 25 | for wh in $(grep -v '#' <"$White_List"); do 26 | [[ -n "$wh" ]] && { 27 | echo "$wh" 28 | } 29 | done 30 | } 31 | 32 | pathCache="" 33 | isSkip=false 34 | addCache() { 35 | { 36 | [[ $pathCache == "" ]] && { 37 | pathCache=$1 38 | } 39 | } || { 40 | pathCache="$pathCache\n$1" 41 | } 42 | } 43 | 44 | doFindBigFile() { 45 | duFind=$(du -k -d 0 $1 2>/dev/null) 46 | for f in $duFind; do 47 | big=$(echo $f | cut -f1) 48 | path=$(echo $f | cut -f2) 49 | { 50 | [[ -f $path ]] && { 51 | { 52 | [[ $big -gt $skip ]] && { 53 | logd "[big] --跳过:$path" 54 | isSkip=true 55 | } 56 | } || { 57 | addCache $path 58 | } 59 | } 60 | } || { 61 | { 62 | [[ $big -gt $skip ]] && { 63 | for t in $path; do 64 | { 65 | [[ -f $t ]] && { 66 | size=$(du -k $t | cut -f1 2>/dev/null) 67 | { 68 | [[ $size -gt $skip ]] && { 69 | logd "[big] --跳过:$t" 70 | isSkip=true 71 | } 72 | } || { 73 | addCache $path 74 | } 75 | } 76 | } || { 77 | doFindBigFile "$t/*" 78 | } 79 | done 80 | } 81 | } || { 82 | addCache $path 83 | } 84 | } 85 | done 86 | } 87 | 88 | # 黑名单列表通配符拓展 89 | blacklist_wildcard_list() { 90 | local IFS=$'\n' 91 | grep -v '#' <"$Black_List" | while read -r bl; do 92 | [[ -n "$bl" ]] && { 93 | [[ "${bl: -2}" == "/*" ]] && { 94 | logd "[W] --检测到/*,请替换成/&*" 95 | logd "[skip] --跳过:$bl" 96 | continue 97 | } 98 | #把/&*替换成/* 99 | [[ "${bl: -3}" == "/&*" ]] && { 100 | bl=${bl//\/&\*/\/\*} 101 | } 102 | { 103 | [[ $skip != -1 ]] && { 104 | isSkip=false 105 | lastBl="" 106 | lastBl=$bl 107 | { 108 | { 109 | [[ ${bl: -1} == "/" ]] && { 110 | bl="$bl*" 111 | } 112 | } 113 | } || { 114 | [[ ${bl: -1} != "*" ]] && { 115 | { 116 | { 117 | [[ -d $(echo $bl) ]] && { 118 | bl="$bl/*" 119 | } 120 | } 121 | } || { 122 | { 123 | { 124 | [[ -f $(echo $bl) ]] && { 125 | size=$(du -k $bl | cut -f1 2>/dev/null) 126 | { 127 | { 128 | [[ $size -gt $skip ]] && { 129 | logd "[big] --跳过:$t" 130 | continue 131 | } 132 | } || { 133 | echo $bl 134 | continue 135 | } 136 | } 137 | } 138 | } || { 139 | # logd "[W] --异常路径,可能文件不存在:$bl" 140 | continue 141 | } 142 | } 143 | } 144 | } 145 | } 146 | doFindBigFile "$bl" 147 | { 148 | { 149 | [[ $isSkip == "false" ]] && { 150 | echo $lastBl 151 | } 152 | } 153 | } || { 154 | echo $pathCache 155 | pathCache="" 156 | } 157 | # [[ $big != "" ]] && [[ -d $bl ]] && { 158 | # { 159 | # [[ "${bl: -1}" == "/" ]] && { 160 | # bl="$bl*" 161 | # } 162 | # } || { 163 | # [[ "${bl: -1}" != "*" ]] && { 164 | # bl="$bl/*" 165 | # } 166 | # } 167 | # } 168 | } 169 | } || { 170 | for i in $bl; do 171 | echo "$i" 172 | done 173 | } 174 | } 175 | done 176 | } 177 | 178 | #主程序 179 | main_for() { 180 | # 重新定义字段分隔符 忽略空格和制表符 181 | local IFS=$'\n' 182 | # 因为重新定义字段分隔符 所以只需要for 不再需要while read 183 | for i in $(echo "$Black_List_Expand" | grep -v -F '*'); do 184 | # 文件夹 185 | [[ -d "$i" ]] && { 186 | #跳过指定目录,防止危险 187 | case $i in 188 | *'/.') continue ;; 189 | *'/./') continue ;; 190 | *'/..') continue ;; 191 | *'/../') continue ;; 192 | esac 193 | echo "$White_List_Expand" | grep -qw "$i" && { 194 | print_pd_white_list "$i" "白名单DIR: $i" 195 | continue 196 | } 197 | rm -rf "$i" && { 198 | let DIR++ 199 | logd "[rm] --黑名单DIR: $i" 200 | echo "$DIR" >"$tmp_date"/dir 201 | } 202 | } 203 | # 文件 204 | [[ -f "$i" ]] && { 205 | echo "$White_List_Expand" | grep -qw "$i" && { 206 | print_pd_white_list "$i" "白名单FILE: $i" 207 | continue 208 | } 209 | rm -rf "$i" && { 210 | let FILE++ 211 | logd "[rm] --黑名单FILE: $i" 212 | echo "$FILE" >"$tmp_date"/file 213 | } 214 | } 215 | done 216 | } 217 | 218 | . "$MODDIR"/utils.sh 219 | { 220 | [[ -f $config ]] && { 221 | . "$config" || { 222 | logd "- [!]: 文件读取异常,请审查(config.ini)文件内容!" && exit 1 223 | } 224 | } 225 | } || { 226 | logd "- [!]: 缺少$config文件" && exit 1 227 | } 228 | 229 | Black_List="$path/blacklist.txt" 230 | White_List="$path/whitelist.txt" 231 | { 232 | [[ $bigfile_auto_skip == y ]] && { 233 | skip="$bigfile_mb" 234 | skip=$(expr $skip \* 1024) 235 | } 236 | } || { 237 | skip=-1 238 | } 239 | 240 | Screen_status="$(dumpsys window policy | grep 'mInputRestricted' | cut -d= -f2)" 241 | { 242 | [[ "$Screen_status" != "true" ]] && { 243 | logd "[状态]: [亮屏] 执行" 244 | [[ ! -d $MODDIR/data/whitelist ]] && mkdir -p "$MODDIR"/data/whitelist 245 | [[ ! -d $MODDIR/data/date ]] && mkdir -p "$MODDIR"/data/date 246 | tmp_date="$MODDIR/data/date/$(date '+%Y%m%d')" 247 | dateFile=$(ls $MODDIR/data/date) 248 | [[ ! -d "$tmp_date" ]] && { 249 | rm -rf "$MODDIR"/data/date &>/dev/null 250 | mkdir -p "$tmp_date" 251 | echo "0" >"$tmp_date"/file 252 | echo "0" >"$tmp_date"/dir 253 | [[ $dateFile != "" ]] && { 254 | logNewDay 255 | } 256 | } 257 | FILE="$(cat "$tmp_date"/file)" 258 | DIR="$(cat "$tmp_date"/dir)" 259 | White_List_Expand="$(whitelist_wildcard_list)" 260 | Black_List_Expand="$(blacklist_wildcard_list)" 261 | main_for 262 | 263 | FILE="$(cat "$tmp_date"/file)" 264 | DIR="$(cat "$tmp_date"/dir)" 265 | sed -i "/^description=/c description=CROND: [ 今日已清除: $FILE个黑名单文件 | $DIR个黑名单文件夹 ]" "$MODDIR/module.prop" 266 | } 267 | } || { 268 | logd "[状态]: [息屏] 不执行" 269 | } 270 | -------------------------------------------------------------------------------- /customize.sh: -------------------------------------------------------------------------------- 1 | outPut() { 2 | echo "$@" 3 | sleep 0.05 4 | } 5 | 6 | path="/data/media/0/Android/RegularlyClean" 7 | path_old="/data/media/0/Android/RegularlyClean_old" 8 | 9 | [[ -d $path ]] && { 10 | outPut "杀死正在运行的crond进程···" 11 | crond_pid="$(pgrep -f 'RegularlyClean' | grep -v $$)" 12 | [[ -n "$crond_pid" ]] && { 13 | for kill_pid in $crond_pid; do 14 | kill -9 "$kill_pid" && outPut "杀死crond进程: $kill_pid" 15 | done 16 | } 17 | outPut "备份历史文件···" 18 | rm -rf "$path_old" && mkdir -p "$path_old" 19 | cp -rf $path/* "$path_old" 20 | chmod -R 0777 $path_old 21 | rm -rf "$path" 22 | outPut "历史文件路径:$path_old" 23 | outPut "更新模块会导致原规则和配置被还原!!" 24 | outPut "被还原配置包括: " 25 | outPut "blacklist.txt, whitelist.txt, config.ini" 26 | outPut "劳烦从备份文件复制到规则和配置文件内!!" 27 | } 28 | 29 | mkdir -p $path 30 | cp -arf "$MODPATH"/AndroidFile/* $path/ 31 | rm -rf "$MODPATH"/AndroidFile/ 32 | outPut "安装完成!" 33 | -------------------------------------------------------------------------------- /data/crond_data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HChenX/RegularlyClean/bde4fece67b0332ab863a18cf21562c1e78d1a6d/data/crond_data -------------------------------------------------------------------------------- /init.sh: -------------------------------------------------------------------------------- 1 | MODDIR=${0%/*} 2 | 3 | . "$MODDIR"/utils.sh 4 | 5 | logd "初始化完成!" 6 | 7 | { 8 | [[ -f $crondFile ]] && { 9 | crond -c $crondPath 10 | } 11 | } || { 12 | echo "*/10 7-23 * * * $MODDIR/data/clear.sh" >$crondFile 13 | echo -n "*/10 7-23 * * *" >$MODDIR/data/crond_data 14 | crond -c $crondPath 15 | } 16 | 17 | { 18 | [[ $(pgrep -f 'regularly.d' | grep -v $$) != "" ]] && { 19 | device 20 | logd "开始运行了!" 21 | logd "------------------------------------------------------------" 22 | } 23 | } || { 24 | device 25 | logd "运行失败!" 26 | exit 1 27 | } 28 | -------------------------------------------------------------------------------- /module.prop: -------------------------------------------------------------------------------- 1 | id=RegularlyClean 2 | name=定时清理 3 | version=v6.0.0 4 | versionCode=2024051901 5 | author=焕晨HChen 6 | description=CROND: [ 等待刷新.. ] 7 | updateJson=https://raw.githubusercontent.com/HChenX/RegularlyClean/master/update.json -------------------------------------------------------------------------------- /service.sh: -------------------------------------------------------------------------------- 1 | MODDIR=${0%/*} 2 | 3 | wait_login() { 4 | while [ "$(getprop sys.boot_completed)" != "1" ]; do 5 | sleep 1 6 | done 7 | 8 | while [ ! -d "/sdcard/Android" ]; do 9 | sleep 1 10 | done 11 | } 12 | wait_login 13 | 14 | . "$MODDIR"/utils.sh 15 | chmod -R 0777 "$MODDIR" 16 | chmod -R 0777 "$path" 17 | echo -n "$MODDIR" >"$path"/module_path 18 | logClear "开机启动成功!" 19 | killAll 20 | sh "$MODDIR"/init.sh 21 | "$MODDIR"/RegularlyClean & -------------------------------------------------------------------------------- /state.sh: -------------------------------------------------------------------------------- 1 | #全局变量 2 | MODDIR=${0%/*} 3 | 4 | . "$MODDIR"/utils.sh 5 | 6 | killCrond 7 | { 8 | [[ $(du -k "$MODDIR"/data/crond_data | cut -f1) -ne 0 ]] && { 9 | time=$(cat "$MODDIR"/data/crond_data) 10 | echo -n "$time $MODDIR/clear.sh" >"$crondFile" 11 | crond -c "$crondPath" 12 | sed -i "/^description=/c description=CROND: [定时进程已恢复运行,请等待开始清理···]" "$MODDIR/module.prop" 13 | } 14 | } || { 15 | su -c "sh $path/scheduled_tasks/create_crond.sh &>/dev/null" 16 | } 17 | -------------------------------------------------------------------------------- /uninstall.sh: -------------------------------------------------------------------------------- 1 | rm -rf /data/media/0/Android/RegularlyClean 2 | rm -rf /data/media/0/Android/RegularlyClean_old -------------------------------------------------------------------------------- /update.json: -------------------------------------------------------------------------------- 1 | { 2 | "versionCode": 2024051901, 3 | "version": "v6.0.0", 4 | "zipUrl": "https://github.com/HChenX/RegularlyClean/releases/download/v.6.0.0/RegularlyClean.zip", 5 | "changelog": "https://raw.githubusercontent.com/HChenX/RegularlyClean/master/update.md" 6 | } -------------------------------------------------------------------------------- /update.md: -------------------------------------------------------------------------------- 1 | ## 更新日志: 2 | 3 | ### 版本号:定时清理 v.6.0.0 4 | 5 | - 修复备份文件无法删除的问题。 6 | - 修复安全模式存在保护漏洞的问题。 7 | - 完善注释讲解,辅助填写正确的规则。 8 | - 优化代码逻辑,修复代码漏洞。 9 | 10 | ## Update: 11 | 12 | ### Version: RegularlyClean v.6.0.0 13 | 14 | - Fix the issue of backup files being unable to be deleted. 15 | - Fix the issue of security mode with protection vulnerabilities. 16 | - Improve annotation explanations and assist in filling out correct rules. 17 | - Optimize code logic and fix code vulnerabilities. 18 | 19 | ### Author by @焕晨HChen 20 | -------------------------------------------------------------------------------- /utils.sh: -------------------------------------------------------------------------------- 1 | path="/data/media/0/Android/RegularlyClean" 2 | logFile="$path"/log.txt 3 | config="$path"/config.ini 4 | crondPath="$MODDIR"/data/regularly.d 5 | crondFile="$MODDIR"/data/regularly.d/root 6 | 7 | { 8 | [[ -f "/data/adb/ksu/bin/busybox" ]] && { 9 | alias crond="/data/adb/ksu/bin/busybox crond" 10 | } 11 | } || { 12 | { 13 | [[ -f "/data/adb/ap/bin/busybox" ]] && { 14 | alias crond="/data/adb/ap/bin/busybox crond" 15 | } 16 | } || { 17 | alias crond="\$( magisk --path )/.magisk/busybox/crond" 18 | } 19 | } 20 | 21 | logd() { 22 | echo "[$(date '+%g/%m/%d %H:%M')] | $1" >>$logFile 23 | } 24 | 25 | logClear() { 26 | echo "[$(date '+%g/%m/%d %H:%M')] | $1" >$logFile 27 | } 28 | 29 | logNewDay() { 30 | logClear "是新的一天!: [$(date +'%m/%d') 重置记录]" 31 | } 32 | 33 | killCrond() { 34 | pid="$(pgrep -f 'regularly.d' | grep -v $$)" 35 | [[ -n $pid ]] && { 36 | for kill_pid in $pid; do 37 | kill -9 "$kill_pid" 38 | done 39 | } 40 | } 41 | 42 | killAll() { 43 | pid="$(pgrep -f 'RegularlyClean' | grep -v $$)" 44 | [[ -n $pid ]] && { 45 | for kill_pid in $pid; do 46 | kill -9 "$kill_pid" 47 | done 48 | } 49 | } 50 | 51 | device() { 52 | logd "品牌: $(getprop ro.product.brand)" 53 | logd "型号: $(getprop ro.product.model)" 54 | logd "代号: $(getprop ro.product.device)" 55 | logd "安卓: $(getprop ro.build.version.release)" 56 | } 57 | --------------------------------------------------------------------------------