diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index f8474ae..42b52e2 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -170,8 +170,6 @@ jobs: download_base_url="https://github.com/${GITHUB_REPOSITORY}/releases/download/${GITHUB_REF_NAME}" { - echo "建议优先下载具有稳定签名的 **release** 构建" - echo echo "| 架构 | 构建类型 | 文件 | SHA256 | 大小 |" echo "| --- | --- | --- | --- | --- |" diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3025a4f..af66105 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,3 +1,5 @@ +import java.util.Properties + plugins { alias(libs.plugins.android.application) alias(libs.plugins.compose.compiler) @@ -18,16 +20,28 @@ android { signingConfigs { create("release") { - val releaseStoreFile = System.getenv("RELEASE_STORE_FILE") - val releaseStorePassword = System.getenv("RELEASE_STORE_PASSWORD") - val releaseKeyAlias = System.getenv("RELEASE_KEY_ALIAS") - val releaseKeyPassword = System.getenv("RELEASE_KEY_PASSWORD") + val envFile = rootProject.file(".env") + val envProps = Properties() + if (envFile.exists()) + envFile.inputStream().use { envProps.load(it) } + fun getValue(key: String): String? { + var value = ( + envProps.getProperty(key)?.trim()?.takeIf { it.isNotEmpty() } + ?: System.getenv(key)?.trim()?.takeIf { it.isNotEmpty() } + ) + ?.trim('"', '\'') + if (value != null && value.startsWith("~")) + value = System.getProperty("user.home") + value.substring(1) + return value + } + + val releaseStoreFile = getValue("RELEASE_STORE_FILE") if (!releaseStoreFile.isNullOrBlank()) { storeFile = file(releaseStoreFile) - storePassword = releaseStorePassword - keyAlias = releaseKeyAlias - keyPassword = releaseKeyPassword + storePassword = getValue("RELEASE_STORE_PASSWORD") + keyAlias = getValue("RELEASE_KEY_ALIAS") + keyPassword = getValue("RELEASE_KEY_PASSWORD") enableV1Signing = true enableV2Signing = true enableV3Signing = true @@ -39,7 +53,7 @@ android { defaultConfig { applicationId = "io.github.miuzarte.scrcpyforandroid" minSdk = 26 - targetSdk = 36 + targetSdk = 37 versionCode = 13 versionName = "0.1.7" @@ -93,8 +107,8 @@ android { } } - buildToolsVersion = "36.0.0" - ndkVersion = "28.2.13676358" + buildToolsVersion = "37.0.0" + ndkVersion = "29.0.14206865" } dependencies { @@ -115,12 +129,12 @@ dependencies { implementation(libs.miuix.icons) implementation(libs.miuix.navigation3.ui) implementation(libs.backdrop) - implementation("io.github.vvb2060.ndk:boringssl:20250114") - implementation("org.lsposed.libcxx:libcxx:27.0.12077973") - implementation("org.bouncycastle:bcpkix-jdk18on:1.80") - implementation("org.conscrypt:conscrypt-android:2.5.2") - implementation("sh.calvin.reorderable:reorderable:3.0.0") - implementation("androidx.datastore:datastore-preferences:1.2.1") + implementation(libs.boringssl) + implementation(libs.libcxx) + implementation(libs.bcpkix.jdk18on) + implementation(libs.conscrypt.android) + implementation(libs.reorderable) + implementation(libs.androidx.datastore.preferences) implementation(libs.androidx.compose.runtime) implementation(libs.androidx.biometric) implementation(libs.androidx.security.crypto) diff --git a/app/src/androidTest/java/io/github/miuzarte/scrcpyforandroid/ExampleInstrumentedTest.kt b/app/src/androidTest/java/io/github/miuzarte/scrcpyforandroid/ExampleInstrumentedTest.kt index 1be3e1b..e09ac94 100644 --- a/app/src/androidTest/java/io/github/miuzarte/scrcpyforandroid/ExampleInstrumentedTest.kt +++ b/app/src/androidTest/java/io/github/miuzarte/scrcpyforandroid/ExampleInstrumentedTest.kt @@ -19,6 +19,6 @@ class ExampleInstrumentedTest { fun useAppContext() { // Context of the app under test. val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("io.github.miuzarte.scrcpyforandroid", appContext.packageName) + assertEquals(BuildConfig.APPLICATION_ID, appContext.packageName) } } \ No newline at end of file diff --git a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/nativecore/AdbMdnsDiscoverer.kt b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/nativecore/AdbMdnsDiscoverer.kt index 1a8b9e2..087f41c 100644 --- a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/nativecore/AdbMdnsDiscoverer.kt +++ b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/nativecore/AdbMdnsDiscoverer.kt @@ -1,5 +1,6 @@ package io.github.miuzarte.scrcpyforandroid.nativecore +import android.annotation.SuppressLint import android.content.Context import android.net.nsd.NsdManager import android.net.nsd.NsdServiceInfo @@ -72,6 +73,8 @@ internal object AdbMdnsDiscoverer { Log.w(TAG, "stop discovery failed: $serviceType, error=$errorCode") } + @Suppress("DEPRECATION") + @SuppressLint("NewApi") override fun onServiceFound(serviceInfo: NsdServiceInfo) { if (discoveryFinished.get()) return Log.v(TAG, "service found: ${serviceInfo.serviceName}") @@ -82,7 +85,7 @@ internal object AdbMdnsDiscoverer { override fun onServiceResolved(serviceInfo: NsdServiceInfo) { if (discoveryFinished.get()) return - val hostAddress = serviceInfo.host?.hostAddress ?: return + val hostAddress = serviceInfo.hostAddresses[0].hostAddress ?: return if (hostAddress.isBlank()) return if (!includeLanDevices) { diff --git a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/AboutScreen.kt b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/AboutScreen.kt index e352d7b..0e637c8 100644 --- a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/AboutScreen.kt +++ b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/AboutScreen.kt @@ -73,6 +73,7 @@ import top.yukonga.miuix.kmp.preference.ArrowPreference import top.yukonga.miuix.kmp.shapes.SmoothRoundedCornerShape import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme import top.yukonga.miuix.kmp.theme.MiuixTheme.textStyles +import java.util.Locale.getDefault @Composable internal fun AboutScreen() { @@ -269,7 +270,8 @@ private fun AboutContent( ) } Text( - text = "v${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})", + text = "v${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})" + + " · ${BuildConfig.BUILD_TYPE.uppercase(getDefault())} BUILD", modifier = Modifier .fillMaxWidth() .graphicsLayer { diff --git a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/password/PasswordRepository.kt b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/password/PasswordRepository.kt index 30a7bd4..f610d33 100644 --- a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/password/PasswordRepository.kt +++ b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/password/PasswordRepository.kt @@ -13,6 +13,7 @@ import java.security.GeneralSecurityException import java.security.KeyStoreException import java.util.UUID +@Suppress("DEPRECATION") object PasswordRepository { private const val PREFS_NAME = "LockscreenPasswords" private const val KEY_ORDER = "__order" diff --git a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/services/PictureInPictureActionReceiver.kt b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/services/PictureInPictureActionReceiver.kt index ff38b73..c2ddbef 100644 --- a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/services/PictureInPictureActionReceiver.kt +++ b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/services/PictureInPictureActionReceiver.kt @@ -5,6 +5,7 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter +import io.github.miuzarte.scrcpyforandroid.BuildConfig import kotlinx.coroutines.runBlocking // not working in MIUI @@ -28,7 +29,7 @@ class PictureInPictureActionReceiver : BroadcastReceiver() { companion object { const val ACTION_STOP_SCRCPY = - "io.github.miuzarte.scrcpyforandroid.action.STOP_SCRCPY_FROM_PIP" + "${BuildConfig.APPLICATION_ID}.action.STOP_SCRCPY_FROM_PIP" private const val REQUEST_CODE_STOP_SCRCPY = 1 fun createIntentFilter(): IntentFilter = IntentFilter(ACTION_STOP_SCRCPY) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3356b72..5ef68b8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,24 +1,31 @@ [versions] -agp = "9.1.0" +agp = "9.1.1" +bcpkixJdk18on = "1.83" +boringssl = "20251124" +conscryptAndroid = "2.5.3" +datastorePreferences = "1.2.1" kotlin = "2.3.20" coreKtx = "1.18.0" +libcxx = "29.0.14206865" lifecycleRuntimeKtx = "2.10.0" activityCompose = "1.13.0" -composeBom = "2026.03.00" -androidxNavigation3 = "1.1.0-beta01" +composeBom = "2026.03.01" +androidxNavigation3 = "1.1.0" junit = "4.13.2" androidxJunit = "1.3.0" espressoCore = "3.7.0" miuix = "0.9.0" backdrop = "1.0.6" material = "1.13.0" -runtime = "1.10.5" +reorderable = "3.0.0" +runtime = "1.10.6" androidxCorePip = "1.0.0-alpha02" -androidxBiometric = "1.4.0-alpha04" +androidxBiometric = "1.4.0-alpha06" androidxSecurityCrypto = "1.1.0" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastorePreferences" } androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" } androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } @@ -30,9 +37,13 @@ androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-te androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" } androidx-compose-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" } androidx-navigation3-runtime = { group = "androidx.navigation3", name = "navigation3-runtime-android", version.ref = "androidxNavigation3" } +bcpkix-jdk18on = { module = "org.bouncycastle:bcpkix-jdk18on", version.ref = "bcpkixJdk18on" } +boringssl = { module = "io.github.vvb2060.ndk:boringssl", version.ref = "boringssl" } +conscrypt-android = { module = "org.conscrypt:conscrypt-android", version.ref = "conscryptAndroid" } junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidxJunit" } androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } +libcxx = { module = "org.lsposed.libcxx:libcxx", version.ref = "libcxx" } material = { group = "com.google.android.material", name = "material", version.ref = "material" } miuix-ui = { group = "top.yukonga.miuix.kmp", name = "miuix-ui", version.ref = "miuix" } miuix-blur = { group = "top.yukonga.miuix.kmp", name = "miuix-blur", version.ref = "miuix" } @@ -44,6 +55,7 @@ androidx-compose-runtime = { group = "androidx.compose.runtime", name = "runtime androidx-core-pip = { group = "androidx.core", name = "core-pip", version.ref = "androidxCorePip" } androidx-biometric = { group = "androidx.biometric", name = "biometric", version.ref = "androidxBiometric" } androidx-security-crypto = { group = "androidx.security", name = "security-crypto-ktx", version.ref = "androidxSecurityCrypto" } +reorderable = { module = "sh.calvin.reorderable:reorderable", version.ref = "reorderable" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" }