This commit is contained in:
2026-05-13 08:50:19 +02:00
parent d0aa15a5a8
commit 04c0cdc1eb
9 changed files with 212 additions and 220 deletions

View File

@@ -6,27 +6,26 @@ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
REPO_ROOT=$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)
SOURCE_ICON="$REPO_ROOT/src-tauri/icons/icon.png"
ANDROID_OVERLAY_DIR="$REPO_ROOT/src-tauri/android-overlay"
ANDROID_APP_DIR="$REPO_ROOT/src-tauri/gen/android/app"
ANDROID_RES_DIR="$ANDROID_APP_DIR/src/main/res"
ANDROID_VALUES_DIR="$ANDROID_RES_DIR/values"
ANDROID_VALUES_NIGHT_DIR="$ANDROID_RES_DIR/values-night"
ANDROID_GRADLE_FILE="$ANDROID_APP_DIR/build.gradle.kts"
ANDROID_MAIN_ACTIVITY="$ANDROID_APP_DIR/src/main/java/in/cinny/app/MainActivity.kt"
ANDROID_BUILDTASK_FILE="$REPO_ROOT/src-tauri/gen/android/buildSrc/src/main/java/in/cinny/app/kotlin/BuildTask.kt"
if [ ! -f "$SOURCE_ICON" ]; then
echo "Missing source icon: $SOURCE_ICON" >&2
exit 1
fi
if [ ! -d "$ANDROID_OVERLAY_DIR" ]; then
echo "Missing Android overlay directory: $ANDROID_OVERLAY_DIR" >&2
exit 1
fi
if [ ! -d "$ANDROID_RES_DIR" ]; then
echo "Missing Android resources directory: $ANDROID_RES_DIR" >&2
echo "Run android init first." >&2
exit 1
fi
mkdir -p "$ANDROID_VALUES_DIR" "$ANDROID_VALUES_NIGHT_DIR"
resize_icon() {
size="$1"
output="$2"
@@ -56,216 +55,9 @@ do
resize_icon "$1" "$ANDROID_RES_DIR/$2/ic_launcher_foreground.png"
done
cat > "$ANDROID_GRADLE_FILE" <<'EOF'
import java.io.FileInputStream
import java.util.Properties
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("rust")
}
val tauriProperties = Properties().apply {
val propFile = file("tauri.properties")
if (propFile.exists()) {
propFile.inputStream().use { load(it) }
}
}
android {
compileSdk = 36
namespace = "in.cinny.app"
defaultConfig {
manifestPlaceholders["usesCleartextTraffic"] = "true"
applicationId = "in.cinny.app"
minSdk = 24
targetSdk = 36
versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt()
versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0")
}
signingConfigs {
create("release") {
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = Properties()
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["password"] as String
storeFile = file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["password"] as String
}
}
buildTypes {
getByName("debug") {
manifestPlaceholders["usesCleartextTraffic"] = "true"
isDebuggable = true
isJniDebuggable = true
isMinifyEnabled = false
packaging {
jniLibs.keepDebugSymbols.add("*/arm64-v8a/*.so")
jniLibs.keepDebugSymbols.add("*/armeabi-v7a/*.so")
jniLibs.keepDebugSymbols.add("*/x86/*.so")
jniLibs.keepDebugSymbols.add("*/x86_64/*.so")
}
}
getByName("release") {
signingConfig = signingConfigs.getByName("release")
isMinifyEnabled = true
proguardFiles(
*fileTree(".") { include("**/*.pro") }
.plus(getDefaultProguardFile("proguard-android-optimize.txt"))
.toList().toTypedArray()
)
}
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
buildConfig = true
}
}
rust {
rootDirRel = "../../../"
}
dependencies {
implementation("androidx.webkit:webkit:1.14.0")
implementation("androidx.appcompat:appcompat:1.7.1")
implementation("androidx.activity:activity-ktx:1.10.1")
implementation("com.google.android.material:material:1.12.0")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.4")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.0")
}
apply(from = "tauri.build.gradle.kts")
EOF
cat > "$ANDROID_MAIN_ACTIVITY" <<'EOF'
package `in`.cinny.app
import android.os.Bundle
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
class MainActivity : TauriActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val content = findViewById<android.view.View>(android.R.id.content)
ViewCompat.setOnApplyWindowInsetsListener(content) { view, windowInsets ->
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
view.updatePadding(
left = insets.left,
top = insets.top,
right = insets.right,
bottom = insets.bottom,
)
windowInsets
}
}
}
EOF
cat > "$ANDROID_BUILDTASK_FILE" <<'EOF'
import java.io.File
import org.apache.tools.ant.taskdefs.condition.Os
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.logging.LogLevel
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
open class BuildTask : DefaultTask() {
@Input
var rootDirRel: String? = null
@Input
var target: String? = null
@Input
var release: Boolean? = null
@TaskAction
fun assemble() {
val executable = """node"""
try {
runTauriCli(executable)
} catch (e: Exception) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
runTauriCli("$executable.cmd")
} else {
throw e
}
}
}
fun runTauriCli(executable: String) {
val rootDirRel = rootDirRel ?: throw GradleException("rootDirRel cannot be null")
val target = target ?: throw GradleException("target cannot be null")
val release = release ?: throw GradleException("release cannot be null")
val tauriCli = File(
project.projectDir,
"${rootDirRel}/../node_modules/@tauri-apps/cli/tauri.js"
).canonicalPath
val args = listOf(tauriCli, "android", "android-studio-script")
project.exec {
workingDir(File(project.projectDir, rootDirRel))
executable(executable)
args(args)
if (project.logger.isEnabled(LogLevel.DEBUG)) {
args("-vv")
} else if (project.logger.isEnabled(LogLevel.INFO)) {
args("-v")
}
if (release) {
args("--release")
}
args(listOf("--target", target))
}.assertNormalExitValue()
}
}
EOF
cat > "$ANDROID_VALUES_DIR/colors.xml" <<'EOF'
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="cinny_system_bar_background">#1A1A1A</color>
</resources>
EOF
cat > "$ANDROID_VALUES_NIGHT_DIR/colors.xml" <<'EOF'
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="cinny_system_bar_background">#1A1A1A</color>
</resources>
EOF
cat > "$ANDROID_VALUES_DIR/themes.xml" <<'EOF'
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.cinny" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="android:statusBarColor">@color/cinny_system_bar_background</item>
<item name="android:navigationBarColor">@color/cinny_system_bar_background</item>
<item name="android:windowLightStatusBar">false</item>
<item name="android:windowLightNavigationBar">false</item>
</style>
</resources>
EOF
cat > "$ANDROID_VALUES_NIGHT_DIR/themes.xml" <<'EOF'
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.cinny" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="android:statusBarColor">@color/cinny_system_bar_background</item>
<item name="android:navigationBarColor">@color/cinny_system_bar_background</item>
<item name="android:windowLightStatusBar">false</item>
<item name="android:windowLightNavigationBar">false</item>
</style>
</resources>
EOF
find "$ANDROID_OVERLAY_DIR" -type f | while IFS= read -r overlay_file; do
relative_path=${overlay_file#"$ANDROID_OVERLAY_DIR/"}
destination="$REPO_ROOT/src-tauri/gen/android/$relative_path"
mkdir -p "$(dirname "$destination")"
cp "$overlay_file" "$destination"
done