diff --git a/.github/patch_android.py b/.github/patch_android.py index d533efa..ff9093f 100644 --- a/.github/patch_android.py +++ b/.github/patch_android.py @@ -4,38 +4,33 @@ import sys import shutil import argparse -# 根据命令行参数决定打包中文版还是英文版 -# 用法: python patch_android.py --lang zh 或 --lang en +# 根据命令行参数决定打包语言版本 parser = argparse.ArgumentParser() parser.add_argument("--lang", choices=["zh", "en"], default="zh", help="打包语言版本") args = parser.parse_args() LANG = args.lang PKG_NAME = "juneix.embyx" -PKG_PATH = PKG_NAME.replace(".", "/") # juneix/embyx +PKG_PATH = PKG_NAME.replace(".", "/") APP_NAME = "EmbyX" -ICON_SRC = f"{LANG}/icon.png" # zh/icon.png 或 en/icon.png +ICON_SRC = f"{LANG}/icon.png" # ── 0. 从 HTML 徽章提取版本号 ───────────────────────────────────────────────── -# HTML 中的版本徽章格式为 ">v1.1<",两个版本的徽章内容保持一致,统一读 zh/index.html -# 修改规格:如需从其他文件读取版本,修改下方 VERSION_SRC 路径即可 VERSION_SRC = "zh/index.html" -version_name = "1.0" # 默认回退值 -version_code = 100 # 对应 v1.0 +version_name = "1.0" +version_code = 100 if os.path.exists(VERSION_SRC): with open(VERSION_SRC, "r", encoding="utf-8") as f: html = f.read() - # 匹配徽章文本,例如 ">v1.1<" 或 ">v2.0<"(非贪婪,只取第一个) + # 匹配徽章文本,例如 ">v1.1<" 或 ">v2.0<" m = re.search(r">v(\d+)\.(\d+)(?:\.(\d+))?<", html) if m: major = int(m.group(1)) minor = int(m.group(2)) patch = int(m.group(3)) if m.group(3) else 0 version_name = f"{major}.{minor}" if patch == 0 else f"{major}.{minor}.{patch}" - # versionCode 规则:major×10000 + minor×100 + patch - # 示例:v1.0→10000, v1.1→10100, v1.9→10900, v2.0→20000, v1.1.2→10102 - # 这样三段版本号也能正确递增,且不会与两段版本号冲突 + # versionCode 规则:major×10000 + minor×100 + patch 保证覆盖安装递增 version_code = major * 10000 + minor * 100 + patch print(f" Detected version: v{version_name} → versionCode={version_code}") else: @@ -46,7 +41,6 @@ else: print(f"Patching Android Project for lang={LANG}, pkg={PKG_NAME}, version={version_name}...") # ── 1. 图标文件 ────────────────────────────────────────────────────────────── -# 将对应语言版本的 icon.png 复制到 Android drawable 资源目录 os.makedirs("android/app/src/main/res/drawable", exist_ok=True) if os.path.exists(ICON_SRC): shutil.copy(ICON_SRC, "android/app/src/main/res/drawable/icon.png") @@ -59,20 +53,19 @@ manifest_path = "android/app/src/main/AndroidManifest.xml" with open(manifest_path, "r", encoding="utf-8") as f: manifest = f.read() -# 替换默认图标引用为我们的 drawable/icon +# 替换默认图标引用 manifest = manifest.replace("@mipmap/ic_launcher_round", "@drawable/icon") manifest = manifest.replace("@mipmap/ic_launcher", "@drawable/icon") manifest = manifest.replace("@drawable/icon_round", "@drawable/icon") -# 添加 WAKE_LOCK 权限(屏保/常亮需要) +# 添加 WAKE_LOCK 权限(屏保与视频常亮需要) if "android.permission.WAKE_LOCK" not in manifest: manifest = manifest.replace( "", ' \n' ) -# 注册 EmbyXDreamService(Android 系统屏保服务) -# 修改规格:如需换 label 或 icon,修改下方 android:label / android:permission 即可 +# 注册系统屏保服务 EmbyXDreamService service_block = """ @@ -247,7 +224,6 @@ with open(colors_path, "w", encoding="utf-8") as f: print(" Created/Updated colors.xml") # ── 8. 修改主题 (Themes/Styles) 适配 Google SplashScreen API ───────────────── -# 增强鲁棒性:同时查找 themes.xml 和 styles.xml,处理多种可能的生成路径 target_files = [ "values/themes.xml", "values-night/themes.xml", @@ -262,25 +238,28 @@ for rel_path in target_files: with open(full_path, "r", encoding="utf-8") as f: content = f.read() - # 使用更灵活的正则匹配 style 标签及其 parent - # 兼容单引号/双引号/空格 - style_pattern = r'()' - if re.search(style_pattern, content): - content = re.sub(style_pattern, r'\1Theme.SplashScreen\3', content) + # 定位启动主题节点,替换 parent 并注入规范属性 + style_block_pattern = r'(]*>)(.*?)()' + m = re.search(style_block_pattern, content, flags=re.DOTALL) + if m: + start_tag = m.group(1) + inner_items = m.group(2) - # 注入官方规范属性 - # 移除可能存在的旧 background 属性 - content = re.sub(r'.*?', '', content) - content = re.sub(r'.*?', '', content) - content = re.sub(r'.*?', '', content) - content = re.sub(r'.*?', '', content) + start_tag = re.sub(r'parent="[^"]*"', 'parent="Theme.SplashScreen"', start_tag) + + # 清理历史兼容属性,避免冲突 + inner_items = re.sub(r'.*?', '', inner_items) + inner_items = re.sub(r'.*?', '', inner_items) + inner_items = re.sub(r'.*?', '', inner_items) + inner_items = re.sub(r'.*?', '', inner_items) splash_items = """ @color/black @drawable/icon @style/AppTheme.NoActionBar """ - content = content.replace('', f'{splash_items} ', 1) + new_block = f"{start_tag}{inner_items}{splash_items} " + content = content[:m.start()] + new_block + content[m.end():] with open(full_path, "w", encoding="utf-8") as f: f.write(content) @@ -290,20 +269,17 @@ for rel_path in target_files: if not splash_style_found: print(" WARNING: AppTheme.NoActionBarLaunch style not found in any res files!") -# ── 9. MainActivity 注入官方启动入口 ────────────────────────────────────────── -# 确保在 super.onCreate 之前注入,且不重复注入 +# ── 9. MainActivity 注入启动页入口 ────────────────────────────────────────── with open(main_activity_path, "r", encoding="utf-8") as f: ma = f.read() -# 确保导入语句存在 if "import androidx.core.splashscreen.SplashScreen;" not in ma: ma = ma.replace("import android.os.Bundle;", "import android.os.Bundle;\nimport androidx.core.splashscreen.SplashScreen;") if "SplashScreen.installSplashScreen(this)" not in ma: - # 精准查找 super.onCreate 并在其上方插入 ma = ma.replace( "super.onCreate(savedInstanceState);", - "SplashScreen.installSplashScreen(this);\n super.onCreate(savedInstanceState);\n // 设置透明背景防止闪烁\n this.bridge.getWebView().setBackgroundColor(android.graphics.Color.BLACK);" + "SplashScreen.installSplashScreen(this);\n super.onCreate(savedInstanceState);\n // 设置透明底色防止切换回白屏闪烁\n this.bridge.getWebView().setBackgroundColor(android.graphics.Color.BLACK);" ) with open(main_activity_path, "w", encoding="utf-8") as f: