diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 1d032b92..c17d9b09 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -177,6 +177,11 @@ jobs:
pnpm tauri icon ../../data/icons/readest-book.png
git checkout .
+ MANIFEST="src-tauri/gen/android/app/src/main/AndroidManifest.xml"
+ PERMISSION_LINE=''
+ grep -q 'REQUEST_INSTALL_PACKAGES' "$MANIFEST" || \
+ sed -i "/android.permission.INTERNET/a \ $PERMISSION_LINE" "$MANIFEST"
+
pushd src-tauri/gen/android
echo "keyAlias=${{ secrets.ANDROID_KEY_ALIAS }}" > keystore.properties
echo "password=${{ secrets.ANDROID_KEY_PASSWORD }}" >> keystore.properties
diff --git a/apps/readest-app/package.json b/apps/readest-app/package.json
index f45c4af1..7fc00faa 100644
--- a/apps/readest-app/package.json
+++ b/apps/readest-app/package.json
@@ -30,6 +30,7 @@
"build-ios-appstore": "dotenv -e .env.ios-appstore.local -- tauri ios build --export-method app-store-connect",
"release-macos-universial-appstore": "dotenv -e .env.tauri.local -e .env.apple-appstore.local -- bash scripts/release-mac-appstore.sh",
"release-ios-appstore": "dotenv -e .env.ios-appstore.local -- bash scripts/release-ios-appstore.sh",
+ "release-google-play": "dotenv -e .env.google-play.local -- bash scripts/release-google-play.sh",
"config-wrangler": "sed -i \"s/\\${TRANSLATIONS_KV_ID}/$TRANSLATIONS_KV_ID/g\" wrangler.toml",
"preview": "NEXT_PUBLIC_APP_PLATFORM=web opennextjs-cloudflare build && opennextjs-cloudflare preview",
"deploy": "NEXT_PUBLIC_APP_PLATFORM=web opennextjs-cloudflare build && opennextjs-cloudflare deploy",
diff --git a/apps/readest-app/scripts/release-google-play.sh b/apps/readest-app/scripts/release-google-play.sh
new file mode 100755
index 00000000..18a03bd8
--- /dev/null
+++ b/apps/readest-app/scripts/release-google-play.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+set -e
+
+VERSION=$(jq -r '.version' package.json)
+
+if [[ -z "$VERSION" ]]; then
+ echo "❌ Failed to extract version from package.json"
+ exit 1
+fi
+
+echo "📦 Found version: $VERSION"
+
+IFS='.' read -r MAJOR MINOR PATCH <<< "$VERSION"
+
+if [[ -z "$MAJOR" || -z "$MINOR" || -z "$PATCH" ]]; then
+ echo "❌ Invalid version format: $VERSION"
+ exit 1
+fi
+
+# Convert x.y.z => x * 10000 + y * 1000 + z
+VERSION_CODE=$((10#$MAJOR * 10000 + 10#$MINOR * 1000 + 10#$PATCH))
+echo "🔢 Computed versionCode: $VERSION_CODE"
+
+PROPERTIES_FILE="./src-tauri/gen/android/app/tauri.properties"
+
+if [[ ! -f "$PROPERTIES_FILE" ]]; then
+ echo "❌ File not found: $PROPERTIES_FILE"
+ exit 1
+fi
+
+HEADER_LINE=$(head -n 1 "$PROPERTIES_FILE")
+{
+ echo "$HEADER_LINE"
+ echo "tauri.android.versionName=$VERSION"
+ echo "tauri.android.versionCode=$VERSION_CODE"
+} > "$PROPERTIES_FILE"
+
+echo "✅ Updated $PROPERTIES_FILE"
+
+echo "🚀 Running: pnpm tauri android build"
+pnpm tauri android build
diff --git a/apps/readest-app/src-tauri/gen/android/app/src/main/AndroidManifest.xml b/apps/readest-app/src-tauri/gen/android/app/src/main/AndroidManifest.xml
index 75a31949..e4743bda 100644
--- a/apps/readest-app/src-tauri/gen/android/app/src/main/AndroidManifest.xml
+++ b/apps/readest-app/src-tauri/gen/android/app/src/main/AndroidManifest.xml
@@ -1,7 +1,6 @@
-