diff --git a/.github/scripts/patch-android-system-bars.mjs b/.github/scripts/patch-android-system-bars.mjs
new file mode 100644
index 0000000..795c9bd
--- /dev/null
+++ b/.github/scripts/patch-android-system-bars.mjs
@@ -0,0 +1,103 @@
+import fs from "node:fs";
+import path from "node:path";
+import { fileURLToPath } from "node:url";
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+const root = path.resolve(__dirname, "../..");
+const androidRoot = path.join(root, "template", "src-tauri", "gen", "android");
+
+function walk(dir, matcher) {
+ const hits = [];
+ if (!fs.existsSync(dir)) return hits;
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
+ const full = path.join(dir, entry.name);
+ if (entry.isDirectory()) {
+ hits.push(...walk(full, matcher));
+ } else if (matcher(full)) {
+ hits.push(full);
+ }
+ }
+ return hits;
+}
+
+function patchMainActivity(filePath) {
+ const original = fs.readFileSync(filePath, "utf8");
+ const packageMatch = original.match(/^package\s+([^\s]+)/m);
+ if (!packageMatch) {
+ console.warn(`Skip MainActivity (no package): ${filePath}`);
+ return;
+ }
+
+ const pkg = packageMatch[1];
+ const content = `package ${pkg}
+
+import android.os.Bundle
+import androidx.core.view.WindowCompat
+
+class MainActivity : TauriActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ // 内容不延伸到状态栏 / 导航栏区域
+ WindowCompat.setDecorFitsSystemWindows(window, true)
+ }
+}
+`;
+
+ fs.writeFileSync(filePath, content);
+ console.log(`Patched MainActivity: ${path.relative(root, filePath)}`);
+}
+
+function ensureThemeItems(xml) {
+ let next = xml;
+ const items = [
+ `- true
`,
+ `- ?android:colorBackground
`,
+ `- ?android:colorBackground
`,
+ ];
+
+ for (const item of items) {
+ const name = item.match(/name="([^"]+)"/)?.[1];
+ if (!name) continue;
+ if (next.includes(`name="${name}"`)) {
+ next = next.replace(
+ new RegExp(`- [^<]*
`, "g"),
+ item,
+ );
+ } else {
+ next = next.replace(/<\/style>/, ` ${item}\n `);
+ }
+ }
+
+ return next;
+}
+
+function patchThemes(filePath) {
+ const original = fs.readFileSync(filePath, "utf8");
+ const patched = ensureThemeItems(original);
+ if (patched !== original) {
+ fs.writeFileSync(filePath, patched);
+ console.log(`Patched theme: ${path.relative(root, filePath)}`);
+ }
+}
+
+if (!fs.existsSync(androidRoot)) {
+ console.error(`Android project not found: ${androidRoot}`);
+ console.error("Run tauri android init before patch-android-system-bars.mjs");
+ process.exit(1);
+}
+
+for (const file of walk(androidRoot, (p) => p.endsWith("MainActivity.kt"))) {
+ patchMainActivity(file);
+}
+
+for (const file of walk(androidRoot, (p) => {
+ const normalized = p.replace(/\\/g, "/");
+ return (
+ normalized.endsWith("values/themes.xml") ||
+ normalized.endsWith("values-night/themes.xml")
+ );
+})) {
+ patchThemes(file);
+}
+
+console.log("Android system bar patch applied");
diff --git a/.github/workflows/build-app.yml b/.github/workflows/build-app.yml
index 5a33275..6a11d79 100644
--- a/.github/workflows/build-app.yml
+++ b/.github/workflows/build-app.yml
@@ -145,6 +145,9 @@ jobs:
env:
NDK_HOME: ${{ env.ANDROID_HOME }}/ndk/${{ env.NDK_VERSION }}
+ - name: Disable edge-to-edge system bars on Android
+ run: node .github/scripts/patch-android-system-bars.mjs
+
- name: Regenerate app icons for Android
run: node .github/scripts/generate-app-icons.mjs
env: