feat: update AndroidManifest and capacitor.config for cleartext traffic and HTTP scheme

This commit is contained in:
2026-06-06 19:50:18 +08:00
parent e0ca242e3b
commit 350e736d0b
5 changed files with 60 additions and 4 deletions
+1
View File
@@ -7,6 +7,7 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="@style/AppTheme">
<activity
+6 -1
View File
@@ -4,6 +4,11 @@
"webDir": "build",
"bundledWebRuntime": false,
"server": {
"androidScheme": "https"
"androidScheme": "http"
},
"plugins": {
"CapacitorHttp": {
"enabled": true
}
}
}
+3 -1
View File
@@ -13,7 +13,9 @@
"cap:sync": "cap sync",
"cap:open:android": "cap open android",
"cap:open:ios": "cap open ios",
"mobile:build": "bun run build && cap sync"
"mobile:build": "bun run build && cap sync",
"android:dev": "node scripts/cap-config.mjs dev && vite build --mode development && cap sync",
"android:prod": "node scripts/cap-config.mjs prod && vite build --mode production && cap sync"
},
"devDependencies": {
"@capacitor/cli": "^8.3.4",
+30
View File
@@ -0,0 +1,30 @@
/**
* Writes capacitor.config.json with the correct androidScheme for the given mode.
* node scripts/cap-config.mjs dev -> http (emulator, no mixed-content issues)
* node scripts/cap-config.mjs prod -> https (production, secure)
*/
import { writeFileSync } from "fs";
const mode = process.argv[2];
if (mode !== "dev" && mode !== "prod") {
console.error("Usage: node scripts/cap-config.mjs <dev|prod>");
process.exit(1);
}
const config = {
appId: "com.bussg.app",
appName: "Bus SG App",
webDir: "build",
bundledWebRuntime: false,
server: {
androidScheme: mode === "dev" ? "http" : "https"
},
plugins: {
CapacitorHttp: {
enabled: true
}
}
};
writeFileSync("capacitor.config.json", JSON.stringify(config, null, 2) + "\n");
console.log(`capacitor.config.json written for ${mode} (androidScheme: ${config.server.androidScheme})`);
+20 -2
View File
@@ -1,6 +1,24 @@
<script>
import { onDestroy, onMount } from "svelte";
const RAW_API_BASE = import.meta.env.VITE_API_BASE ?? "";
function resolveApiBase() {
const base = RAW_API_BASE.trim().replace(/\/+$/, "");
if (!base) {
return "";
}
const platform = globalThis.Capacitor?.getPlatform?.();
if (platform === "android") {
return base.replace(/^http:\/\/(localhost|127\.0\.0\.1)(?=[:/]|$)/, "http://10.0.2.2");
}
return base;
}
const API_BASE = resolveApiBase();
let statusText = "Idle";
let statusState = "";
let responseText = "No request yet.";
@@ -121,7 +139,7 @@
while (true) {
const query = new URLSearchParams({ $top: String(pageSize), $skip: String(skip) });
const response = await fetch(`/api/v1/bus-stops?${query.toString()}`);
const response = await fetch(`${API_BASE}/api/v1/bus-stops?${query.toString()}`);
if (!response.ok) {
throw new Error(`Unable to load bus stops (${response.status})`);
}
@@ -340,7 +358,7 @@
setStatus("Loading", "");
responseText = "Loading...";
const url = `/api/v1/bus-arrival?${query.toString()}`;
const url = `${API_BASE}/api/v1/bus-arrival?${query.toString()}`;
const response = await fetch(url);
const text = await response.text();