Files
opendance-android/app/build.gradle.kts
T

175 lines
6.2 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import java.util.Properties
// OpenDance Studio —— Android 辅助 App(应用模块)
//
// 契约:contracts/websocket-keypoints.md v0.1.0(本端为**发送方**)
// contracts/skeleton-topology.md v0.1.0(MediaPipe 33 点)
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("org.jetbrains.kotlin.plugin.compose")
}
android {
namespace = "com.opendance.studio"
compileSdk = 34
defaultConfig {
applicationId = "com.opendance.studio"
minSdk = 29 // Android 10(文档 T-AND-009 验收要求 Android 10+)
targetSdk = 34
versionCode = 1
versionName = "0.1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
// 契约版本,供关于页与日志显示
buildConfigField("String", "CONTRACT_VERSION", "\"0.1.0\"")
buildConfigField("String", "WS_SUBPROTOCOL", "\"opendance.pose.v1\"")
}
/**
* 签名配置:优先读取 keystore.properties(已被 .gitignore 忽略),
* 否则读取环境变量;两者都没有时回退到 debug 签名。
*
* 这样 `./gradlew assembleRelease` 在没有任何私密文件的情况下也能产出**已签名**的
* APK(用 debug key),便于 CI 与验收;正式发布必须提供自己的 keystore
* (见 build/gen-keystore.sh 与 README.txt)。
*/
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = Properties()
if (keystorePropertiesFile.exists()) {
keystorePropertiesFile.inputStream().use { keystoreProperties.load(it) }
}
fun signingValue(key: String, env: String): String? =
keystoreProperties.getProperty(key) ?: System.getenv(env)
val releaseStoreFile = signingValue("storeFile", "KEYSTORE_PATH")
val hasReleaseKeystore = releaseStoreFile != null && file(releaseStoreFile).exists()
signingConfigs {
if (hasReleaseKeystore) {
create("release") {
storeFile = file(releaseStoreFile!!)
storePassword = signingValue("storePassword", "KEYSTORE_PASSWORD")
keyAlias = signingValue("keyAlias", "KEY_ALIAS")
keyPassword = signingValue("keyPassword", "KEY_PASSWORD")
}
}
}
buildTypes {
debug {
applicationIdSuffix = ".debug"
isMinifyEnabled = false
// debug 保留全部 ABI,方便在模拟器(x86_64)上调试
ndk {
abiFilters.clear()
abiFilters.addAll(listOf("arm64-v8a", "armeabi-v7a", "x86", "x86_64"))
}
}
release {
// 发布包只打包真实手机用得到的 ABI。
// x86/x86_64 仅供模拟器使用,却占掉约 27 MB(几乎是发布包的一半),
// 对真机用户纯属浪费。
ndk {
abiFilters.clear()
abiFilters.addAll(listOf("arm64-v8a", "armeabi-v7a"))
}
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
)
signingConfig = if (hasReleaseKeystore) {
signingConfigs.getByName("release")
} else {
// 回退:用 debug 签名,保证 CI 上 assembleRelease 也能产出已签名 APK
signingConfigs.getByName("debug")
}
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
buildFeatures {
compose = true
buildConfig = true
}
packaging {
resources {
excludes += setOf(
"/META-INF/{AL2.0,LGPL2.1}",
"/META-INF/DEPENDENCIES",
"/META-INF/LICENSE*",
"/META-INF/NOTICE*",
)
}
// MediaPipe 的 .task 模型必须保持不压缩,否则运行时按文件路径读取会失败
androidResources {
noCompress += "task"
}
}
testOptions {
unitTests.isReturnDefaultValues = true
}
lint {
abortOnError = false
}
}
dependencies {
// ---- Android 基础 ----
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.6")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.6")
implementation("androidx.activity:activity-compose:1.9.2")
// ---- Compose ----
val composeBom = platform("androidx.compose:compose-bom:2024.10.01")
implementation(composeBom)
androidTestImplementation(composeBom)
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.material:material-icons-extended")
debugImplementation("androidx.compose.ui:ui-tooling")
// ---- CameraX(T-AND-002)----
val cameraX = "1.4.0"
implementation("androidx.camera:camera-core:$cameraX")
implementation("androidx.camera:camera-camera2:$cameraX")
implementation("androidx.camera:camera-lifecycle:$cameraX")
implementation("androidx.camera:camera-view:$cameraX")
// ---- MediaPipe Pose 端侧推理(T-AND-003)----
implementation("com.google.mediapipe:tasks-vision:0.10.35")
// ---- WebSocket 推流(T-AND-005)----
implementation("com.squareup.okhttp3:okhttp:4.12.0")
// ---- 权限 ----
implementation("com.google.accompanist:accompanist-permissions:0.34.0")
// ---- 单元测试(T-AND-004 等纯逻辑,跑在 JVM 上,无需设备)----
testImplementation("junit:junit:4.13.2")
testImplementation("org.jetbrains.kotlin:kotlin-test:2.0.21")
androidTestImplementation("androidx.test.ext:junit:1.2.1")
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
}