175 lines
6.2 KiB
Kotlin
175 lines
6.2 KiB
Kotlin
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")
|
||
}
|