diff --git a/.winboll/bashMergeProjects-to-Projects_Keeper.sh b/.winboll/bashMergeProjects-to-Projects_Keeper.sh
new file mode 100644
index 0000000..0f1bff7
--- /dev/null
+++ b/.winboll/bashMergeProjects-to-Projects_Keeper.sh
@@ -0,0 +1,192 @@
+#!/system/bin/sh
+## 合并其他项目分支的模块源码到projects-keeper分支。
+
+# ====================== 0. 进入目标目录 ======================
+TARGET_DIR="/sdcard/AppProjects/Projects_Keeper"
+
+echo "切换工作目录到:$TARGET_DIR"
+if ! cd "$TARGET_DIR"; then
+ echo "=============================================="
+ echo "错误:无法进入目标目录 $TARGET_DIR"
+ echo "=============================================="
+ exit 1
+fi
+
+# ====================== 1. 拉取远程最新源码(失败直接退出) ======================
+echo "=============================================="
+echo "正在拉取远程最新源码..."
+echo "=============================================="
+if ! git pull; then
+ echo "=============================================="
+ echo "错误:拉取远程源码失败!"
+ echo "请检查网络、仓库冲突或手动处理 git 状态后再执行脚本。"
+ echo "=============================================="
+ exit 1
+fi
+echo "✅ 源码已拉取为最新状态"
+echo ""
+
+# ====================== 2. 目录路径检查 ======================
+CUR_DIR=$(pwd)
+if [ "$CUR_DIR" != "$TARGET_DIR" ]; then
+ echo "错误:当前目录不是项目根目录!"
+ echo "请先进入目录:$TARGET_DIR"
+ exit 1
+fi
+
+# ====================== 3. Git 分支检查 ======================
+CUR_BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null)
+TARGET_BRANCH="projects-keeper"
+
+if [ "$CUR_BRANCH" != "$TARGET_BRANCH" ]; then
+ echo "错误:当前不在 $TARGET_BRANCH 分支!"
+ echo "当前分支:$CUR_BRANCH"
+ echo "请先执行:git checkout $TARGET_BRANCH"
+ exit 1
+fi
+
+# ====================== 4. 预设标准模块列表 ======================
+MERGE_OBJECTS_LIST=(
+.git
+.gitignore
+.gitmodules
+.winboll
+GenKeyStore
+LICENSE
+LICENSE-Private-Demo
+LICENSE-Private-Demo_docs
+README.md
+aes
+appbase
+autonfc
+build.gradle
+contacts
+debugtemp
+gallery
+gpsrelaysentinel
+gradle
+gradle.properties-android-demo
+gradle.properties-androidx-demo
+gradlew
+libaes
+libappbase
+libdebugtemp
+libgpsrelaysentinel
+libwinboll
+local.properties-demo
+mymessagemanager
+positions
+powerbell
+settings.gradle-demo
+winboll
+winboll.properties-demo
+)
+
+# ====================== 5. 获取当前目录真实文件列表 ======================
+REAL_ITEMS=()
+while IFS= read -r line; do
+ if [[ "$line" != "." && "$line" != ".." ]]; then
+ REAL_ITEMS+=("$line")
+ fi
+done < <(ls -a)
+
+# ====================== 6. 差异比对函数 ======================
+check_diff() {
+ local missing=()
+ local extra=()
+
+ for item in "${MERGE_OBJECTS_LIST[@]}"; do
+ local found=0
+ for r in "${REAL_ITEMS[@]}"; do
+ if [[ "$item" == "$r" ]]; then
+ found=1
+ break
+ fi
+ done
+ if (( found == 0 )); then
+ missing+=("$item")
+ fi
+ done
+
+ for r in "${REAL_ITEMS[@]}"; do
+ local found=0
+ for item in "${MERGE_OBJECTS_LIST[@]}"; do
+ if [[ "$item" == "$r" ]]; then
+ found=1
+ break
+ fi
+ done
+ if (( found == 0 )); then
+ extra+=("$r")
+ fi
+ done
+
+ if [[ ${#missing[@]} -gt 0 || ${#extra[@]} -gt 0 ]]; then
+ echo "=============================================="
+ echo "【错误】合并环境与脚本预设列表不匹配!"
+ echo "请手动核对并修改合并脚本。"
+ echo "=============================================="
+
+ if [[ ${#missing[@]} -gt 0 ]]; then
+ echo -e "\n👉 本地缺失项目:"
+ for m in "${missing[@]}"; do echo " $m"; done
+ fi
+
+ if [[ ${#extra[@]} -gt 0 ]]; then
+ echo -e "\n👉 本地多余项目:"
+ for e in "${extra[@]}"; do echo " $e"; done
+ fi
+
+ echo -e "\n=============================================="
+ exit 1
+ fi
+}
+
+# 执行差异校验
+check_diff
+
+# ====================== 全部校验通过,继续执行合并 ======================
+echo -e "#@@@ 开始合并模块源码 @@@#
+## 目标合并对象列表:"
+
+for item in "${MERGE_OBJECTS_LIST[@]}"; do
+ echo "$item"
+done
+
+echo -e "## 对象列表结束
+"
+
+## 合并 APP 项目
+MERGE_APP_PROJECT_LIST=(
+DemoAPP
+)
+echo -e "#@@@ 开始合并应用型模块源码 @@@#
+## 目标合并对象列表:"
+
+for item in "${MERGE_APP_PROJECT_LIST[@]}"; do
+ echo "正在合并 $item 项目 ..."
+ item_lower=$(echo "$item" | tr 'A-Z' 'a-z')
+git checkout origin/$item_lower $item_lower
+ git add .
+ git commit -m "合并 $item 项目"
+done
+
+## 合并 LIB 项目
+MERGE_LIB_PROJECT_LIST=(
+WinBoLL
+APPBase
+AES
+)
+echo -e "#@@@ 开始合并类库型模块源码 @@@#
+## 目标合并对象列表:"
+
+for item in "${MERGE_LIB_PROJECT_LIST[@]}"; do
+ echo "正在合并 $item 项目 ..."
+ item_lower=$(echo "$item" | tr 'A-Z' 'a-z')
+git checkout origin/$item_lower $item_lower lib$item_lower
+ git add .
+ git commit -m "合并 $item 项目"
+done
+
+echo '正在推送 Projects_Keeper 项目'
+git push
\ No newline at end of file
diff --git a/.winboll/bashMergeProjects-to-Projects_Keeper_Tag.sh b/.winboll/bashMergeProjects-to-Projects_Keeper_Tag.sh
new file mode 100644
index 0000000..6d30f3b
--- /dev/null
+++ b/.winboll/bashMergeProjects-to-Projects_Keeper_Tag.sh
@@ -0,0 +1,145 @@
+#!/system/bin/sh
+## 逻辑:按时间取最新标签 → 拉取该标签目录合并
+
+# 按创建时间取模块最新标签(最新打的标签排最后)
+get_latest_module_tag(){
+ local mod=$1
+ git for-each-ref --sort=-creatordate --format='%(refname)' refs/tags/${mod}-* \
+ | grep -v '\^{}' \
+ | head -1 \
+ | sed 's/refs\/tags\///'
+}
+
+# 通过标签获取commit
+get_commit_from_tag(){
+ local tag=$1
+ git rev-parse --short "${tag}^{commit}"
+}
+
+# 工作目录
+TARGET_DIR="/sdcard/AppProjects/Projects_Keeper_Tag"
+echo "进入目录:${TARGET_DIR}"
+cd "${TARGET_DIR}" || exit 1
+
+# 同步远程
+echo "========================================"
+echo "同步远程分支与全部版本标签"
+echo "========================================"
+git fetch origin --prune
+git fetch origin --tags
+echo "同步完成"
+echo ""
+
+# 校验目标分支
+NOW_BRANCH=$(git symbolic-ref --short HEAD)
+TARGET_BRANCH="projects_keeper_tag"
+if [ "${NOW_BRANCH}" != "${TARGET_BRANCH}" ];then
+ echo "错误:请先切换到 ${TARGET_BRANCH} 分支"
+ exit 1
+fi
+
+# 目录结构校验
+MERGE_OBJECTS_LIST=(
+.git
+.gitignore
+.gitmodules
+.winboll
+GenKeyStore
+LICENSE
+LICENSE-Private-Demo
+LICENSE-Private-Demo_docs
+README.md
+aes
+appbase
+autonfc
+build.gradle
+contacts
+debugtemp
+gallery
+gpsrelaysentinel
+gradle
+gradle.properties-android-demo
+gradle.properties-androidx-demo
+gradlew
+libaes
+libappbase
+libdebugtemp
+libgpsrelaysentinel
+libwinboll
+local.properties-demo
+mymessagemanager
+positions
+powerbell
+settings.gradle-demo
+winboll
+winboll.properties-demo
+)
+
+REAL_ITEMS=()
+while IFS= read -r line; do
+ [[ $line != "." && $line != ".." ]] && REAL_ITEMS+=("$line")
+done < <(ls -a)
+
+check_diff(){
+ local miss=() extra=()
+ for i in "${MERGE_OBJECTS_LIST[@]}";do
+ [[ ! " ${REAL_ITEMS[@]} " =~ " ${i} " ]] && miss+=("$i")
+ done
+ for i in "${REAL_ITEMS[@]}";do
+ [[ ! " ${MERGE_OBJECTS_LIST[@]} " =~ " ${i} " ]] && extra+=("$i")
+ done
+ if [[ ${#miss[@]} -gt 0 || ${#extra[@]} -gt 0 ]];then
+ echo "本地目录结构不一致,终止运行"
+ exit 1
+ fi
+}
+check_diff
+
+echo -e "#@@@ 按时间获取最新标签合并模块源码 @@@#"
+
+# 应用型模块
+MERGE_APP_PROJECT_LIST=(DemoAPP)
+echo -e "---------- 应用型模块 ----------"
+for name in "${MERGE_APP_PROJECT_LIST[@]}";do
+ low_name=$(echo "$name" | tr 'A-Z' 'a-z')
+ tag=$(get_latest_module_tag "${low_name}")
+ if [[ -z "${tag}" ]];then
+ echo "跳过 ${low_name}:无远程标签"
+ continue
+ fi
+ commit=$(get_commit_from_tag "${tag}")
+ if [[ -z "${commit}" ]];then
+ echo "跳过 ${low_name}:标签无有效提交点"
+ continue
+ fi
+ echo "模块:${low_name} 最新时间标签:${tag} 提交ID:${commit}"
+ # 强制拉取覆盖
+ git checkout -f "${tag}" -- "${low_name}"
+ git add "${low_name}"
+ git commit -m "合并模块${name} 同步最新时间标签${tag}"
+done
+
+# 类库模块
+MERGE_LIB_PROJECT_LIST=(WinBoLL APPBase AES)
+echo -e "---------- 类库模块 ----------"
+for name in "${MERGE_LIB_PROJECT_LIST[@]}";do
+ low_name=$(echo "$name" | tr 'A-Z' 'a-z')
+ tag=$(get_latest_module_tag "${low_name}")
+ if [[ -z "${tag}" ]];then
+ echo "跳过 ${low_name}:无远程标签"
+ continue
+ fi
+ commit=$(get_commit_from_tag "${tag}")
+ if [[ -z "${commit}" ]];then
+ echo "跳过 ${low_name}:标签无有效提交点"
+ continue
+ fi
+ echo "模块:${low_name} 最新时间标签:${tag} 提交ID:${commit}"
+ git checkout -f "${tag}" -- "${low_name}" "lib${low_name}"
+ git add "${low_name}" "lib${low_name}"
+ git commit -m "合并模块${name} 同步最新时间标签${tag}"
+done
+
+echo "全部模块合并执行完毕"
+echo "执行推送:git push"
+git push
diff --git a/appbase/build.properties b/appbase/build.properties
index 68642b1..492916a 100644
--- a/appbase/build.properties
+++ b/appbase/build.properties
@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
-#Tue May 12 09:17:15 HKT 2026
-stageCount=10
+#Sun May 17 16:16:36 HKT 2026
+stageCount=16
libraryProject=libappbase
baseVersion=15.20
-publishVersion=15.20.9
+publishVersion=15.20.15
buildCount=0
-baseBetaVersion=15.20.10
+baseBetaVersion=15.20.16
diff --git a/libappbase/build.gradle b/libappbase/build.gradle
index 2e7654e..876e8b7 100644
--- a/libappbase/build.gradle
+++ b/libappbase/build.gradle
@@ -25,14 +25,5 @@ android {
}
dependencies {
- // 网络连接类库
- api 'com.squareup.okhttp3:okhttp:4.4.1'
- // Gson
- api 'com.google.code.gson:gson:2.8.9'
- // Html 解析
- api 'org.jsoup:jsoup:1.13.1'
- // 添加JSch依赖(SFTP核心,com.jcraft:jsch:0.1.54)
- api 'com.jcraft:jsch:0.1.54'
-
api fileTree(dir: 'libs', include: ['*.jar'])
}
diff --git a/libappbase/build.properties b/libappbase/build.properties
index 8d3d61f..492916a 100644
--- a/libappbase/build.properties
+++ b/libappbase/build.properties
@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
-#Tue May 12 09:16:45 HKT 2026
-stageCount=10
+#Sun May 17 16:16:36 HKT 2026
+stageCount=16
libraryProject=libappbase
baseVersion=15.20
-publishVersion=15.20.9
+publishVersion=15.20.15
buildCount=0
-baseBetaVersion=15.20.10
+baseBetaVersion=15.20.16
diff --git a/libappbase/src/main/AndroidManifest.xml b/libappbase/src/main/AndroidManifest.xml
index bbfd3f3..da1cde4 100644
--- a/libappbase/src/main/AndroidManifest.xml
+++ b/libappbase/src/main/AndroidManifest.xml
@@ -3,18 +3,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
package="cc.winboll.studio.libappbase">
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/libappbase/src/main/java/cc/winboll/studio/libappbase/LogUtils.java b/libappbase/src/main/java/cc/winboll/studio/libappbase/LogUtils.java
index 8ac2fe9..a0e4f2a 100644
--- a/libappbase/src/main/java/cc/winboll/studio/libappbase/LogUtils.java
+++ b/libappbase/src/main/java/cc/winboll/studio/libappbase/LogUtils.java
@@ -135,8 +135,8 @@ public class LogUtils {
return;
}
- final long MAX_FILE_SIZE = 6291456L;
- final long KEEP_FILE_SIZE = 3145728L;
+ final long KEEP_FILE_SIZE = 25000L; // ~25KB 确保剪贴板可完整复制
+ final long MAX_FILE_SIZE = 2*KEEP_FILE_SIZE;
final long fileSize = _mfLogCatchFile.length();
if (fileSize <= MAX_FILE_SIZE) {
diff --git a/libappbase/src/main/java/cc/winboll/studio/libappbase/views/AboutView.java b/libappbase/src/main/java/cc/winboll/studio/libappbase/views/AboutView.java
index 8d94b53..050a8b6 100644
--- a/libappbase/src/main/java/cc/winboll/studio/libappbase/views/AboutView.java
+++ b/libappbase/src/main/java/cc/winboll/studio/libappbase/views/AboutView.java
@@ -12,13 +12,11 @@ import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
-
import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.R;
import cc.winboll.studio.libappbase.ToastUtils;
import cc.winboll.studio.libappbase.dialogs.DebugHostDialog;
-import cc.winboll.studio.libappbase.dialogs.APPValidationDialog;
import cc.winboll.studio.libappbase.models.APPInfo;
/**
@@ -328,14 +326,7 @@ public class AboutView extends LinearLayout {
ToastUtils.show("已取消调试状态,重启应用可生效。");
}
});
- // 正版校验弹窗
- ibSigngetDialog.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- LogUtils.d(TAG, "ibSigngetDialog onClick:唤起应用正版校验弹窗");
- new APPValidationDialog(mContext, mszAppName, mszAppVersionName).show();
- }
- });
+
// 调试地址配置弹窗
ibWinBoLLHostDialog.setOnClickListener(new OnClickListener() {
@Override