272 lines
8.3 KiB
Bash
Executable File
272 lines
8.3 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
set -eu
|
|
|
|
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
|
|
REPO_ROOT=$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)
|
|
|
|
SOURCE_ICON="$REPO_ROOT/src-tauri/icons/icon.png"
|
|
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_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"
|
|
sips -z "$size" "$size" "$SOURCE_ICON" --out "$output" >/dev/null
|
|
}
|
|
|
|
for spec in \
|
|
"48 mipmap-mdpi" \
|
|
"72 mipmap-hdpi" \
|
|
"96 mipmap-xhdpi" \
|
|
"144 mipmap-xxhdpi" \
|
|
"192 mipmap-xxxhdpi"
|
|
do
|
|
set -- $spec
|
|
resize_icon "$1" "$ANDROID_RES_DIR/$2/ic_launcher.png"
|
|
resize_icon "$1" "$ANDROID_RES_DIR/$2/ic_launcher_round.png"
|
|
done
|
|
|
|
for spec in \
|
|
"108 mipmap-mdpi" \
|
|
"162 mipmap-hdpi" \
|
|
"216 mipmap-xhdpi" \
|
|
"324 mipmap-xxhdpi" \
|
|
"432 mipmap-xxxhdpi"
|
|
do
|
|
set -- $spec
|
|
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
|