From 87ec0b8fcbb6fa571a9e92671732fda6856fd9bf Mon Sep 17 00:00:00 2001 From: Android Adapt Date: Thu, 7 May 2026 20:38:38 +0800 Subject: [PATCH 1/4] =?UTF-8?q?Android=2012=20=E9=80=82=E9=85=8D=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ProfileReceiver: 修复 AlarmManager 触发自定义广播在 Android 12+ 无法启动前台服务的问题,添加后台降级处理 - SplashScreen: 添加 values-v31 主题适配 Android 12 强制 SplashScreen - 日志权限: 在 manifest 中添加 READ_LOGS 权限以支持崩溃日志收集 --- app/src/main/AndroidManifest.xml | 1 + design/src/main/res/drawable/ic_logo.xml | 11 ++++++++ design/src/main/res/values-v31/themes.xml | 15 ++++++++++ .../kr328/clash/service/ProfileReceiver.kt | 28 +++++++++++++++++-- 4 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 design/src/main/res/drawable/ic_logo.xml create mode 100644 design/src/main/res/values-v31/themes.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 691af6a039..eda5aaf102 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,6 +16,7 @@ tools:ignore="QueryAllPackagesPermission" /> + + + diff --git a/design/src/main/res/values-v31/themes.xml b/design/src/main/res/values-v31/themes.xml new file mode 100644 index 0000000000..efff8bc938 --- /dev/null +++ b/design/src/main/res/values-v31/themes.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/service/src/main/java/com/github/kr328/clash/service/ProfileReceiver.kt b/service/src/main/java/com/github/kr328/clash/service/ProfileReceiver.kt index 8488a23435..88fa92d9dc 100644 --- a/service/src/main/java/com/github/kr328/clash/service/ProfileReceiver.kt +++ b/service/src/main/java/com/github/kr328/clash/service/ProfileReceiver.kt @@ -37,9 +37,31 @@ class ProfileReceiver : BroadcastReceiver() { } } Intents.ACTION_PROFILE_REQUEST_UPDATE -> { - val redirect = intent.setComponent(ProfileWorker::class.componentName) - - context.startForegroundServiceCompat(redirect) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + try { + val redirect = intent.setComponent(ProfileWorker::class.componentName) + context.startForegroundServiceCompat(redirect) + } catch (e: IllegalStateException) { + // Android 12+ forbids starting foreground service from background via AlarmManager + Global.launch { + intent.uuid?.also { uuid -> + try { + ProfileProcessor.update(context, uuid, null) + val imported = ImportedDao().queryByUUID(uuid) + if (imported != null) { + scheduleNext(context, imported) + } + Log.i("ProfileReceiver: background update completed for $uuid") + } catch (e: Exception) { + Log.e("ProfileReceiver: fallback background update failed", e) + } + } + } + } + } else { + val redirect = intent.setComponent(ProfileWorker::class.componentName) + context.startForegroundServiceCompat(redirect) + } } } } From e833d87ef721d96ee984ec1effc9073a52dff4fd Mon Sep 17 00:00:00 2001 From: Android Adapt Date: Sat, 9 May 2026 00:46:50 +0800 Subject: [PATCH 2/4] fix: compilation errors and complete Android 12+ adaptation - Add missing Build import in ProfileReceiver.kt - Refactor redundant update logic in ProfileReceiver.kt - Add androidx.core:core-splashscreen dependency - Implement installSplashScreen() in MainActivity.kt - Define SplashScreenTheme and apply to MainActivity in Manifest --- app/build.gradle.kts | 1 + app/src/main/AndroidManifest.xml | 3 ++- app/src/main/java/com/github/kr328/clash/MainActivity.kt | 3 +++ design/src/main/res/values-night/themes.xml | 8 ++++++++ design/src/main/res/values/themes.xml | 6 ++++++ gradle/libs.versions.toml | 2 ++ .../com/github/kr328/clash/service/ProfileReceiver.kt | 5 +++-- 7 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 design/src/main/res/values-night/themes.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 5272b86afb..baf2c4e4f9 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -18,6 +18,7 @@ dependencies { implementation(libs.kotlin.coroutine) implementation(libs.androidx.core) + implementation(libs.androidx.splashscreen) implementation(libs.androidx.activity) implementation(libs.androidx.fragment) implementation(libs.androidx.appcompat) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index eda5aaf102..c3cbeecb73 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,7 +43,8 @@ android:configChanges="uiMode" android:exported="true" android:label="@string/launch_name" - android:launchMode="singleTask"> + android:launchMode="singleTask" + android:theme="@style/SplashScreenTheme"> diff --git a/app/src/main/java/com/github/kr328/clash/MainActivity.kt b/app/src/main/java/com/github/kr328/clash/MainActivity.kt index 62f2a1aa7c..99525c8de4 100644 --- a/app/src/main/java/com/github/kr328/clash/MainActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/MainActivity.kt @@ -8,6 +8,7 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts.RequestPermission import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat +import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import com.github.kr328.clash.common.util.intent import com.github.kr328.clash.common.util.ticker import com.github.kr328.clash.design.MainDesign @@ -144,6 +145,8 @@ class MainActivity : BaseActivity() { } override fun onCreate(savedInstanceState: Bundle?) { + installSplashScreen() + super.onCreate(savedInstanceState) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { val requestPermissionLauncher = diff --git a/design/src/main/res/values-night/themes.xml b/design/src/main/res/values-night/themes.xml new file mode 100644 index 0000000000..d1b7214dd0 --- /dev/null +++ b/design/src/main/res/values-night/themes.xml @@ -0,0 +1,8 @@ + + + + diff --git a/design/src/main/res/values/themes.xml b/design/src/main/res/values/themes.xml index 82d685f22c..d79a9e011e 100644 --- a/design/src/main/res/values/themes.xml +++ b/design/src/main/res/values/themes.xml @@ -166,4 +166,10 @@ @android:color/transparent @android:color/transparent + + \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3190850eff..4de6691e6f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -18,6 +18,7 @@ room = "2.4.2" multiprocess = "1.0.0" quickie = "1.11.0" androidx-activity-ktx = "1.9.0" +androidx-splashscreen = "1.0.1" [libraries] build-android = { module = "com.android.tools.build:gradle", version.ref = "agp" } @@ -28,6 +29,7 @@ build-golang = { module = "com.github.kr328.golang:gradle-plugin", version.ref = kotlin-coroutine = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutine" } kotlin-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" } androidx-core = { module = "androidx.core:core-ktx", version.ref = "coreKtx" } +androidx-splashscreen = { module = "androidx.core:core-splashscreen", version.ref = "androidx-splashscreen" } androidx-activity = { module = "androidx.activity:activity", version.ref = "activity" } androidx-fragment = { module = "androidx.fragment:fragment", version.ref = "fragment" } androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" } diff --git a/service/src/main/java/com/github/kr328/clash/service/ProfileReceiver.kt b/service/src/main/java/com/github/kr328/clash/service/ProfileReceiver.kt index 88fa92d9dc..ef7111c475 100644 --- a/service/src/main/java/com/github/kr328/clash/service/ProfileReceiver.kt +++ b/service/src/main/java/com/github/kr328/clash/service/ProfileReceiver.kt @@ -5,6 +5,7 @@ import android.app.PendingIntent import android.content.BroadcastReceiver import android.content.Context import android.content.Intent +import android.os.Build import androidx.core.content.getSystemService import com.github.kr328.clash.common.Global import com.github.kr328.clash.common.compat.pendingIntentFlags @@ -37,9 +38,10 @@ class ProfileReceiver : BroadcastReceiver() { } } Intents.ACTION_PROFILE_REQUEST_UPDATE -> { + val redirect = intent.setComponent(ProfileWorker::class.componentName) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { try { - val redirect = intent.setComponent(ProfileWorker::class.componentName) context.startForegroundServiceCompat(redirect) } catch (e: IllegalStateException) { // Android 12+ forbids starting foreground service from background via AlarmManager @@ -59,7 +61,6 @@ class ProfileReceiver : BroadcastReceiver() { } } } else { - val redirect = intent.setComponent(ProfileWorker::class.componentName) context.startForegroundServiceCompat(redirect) } } From 2d1015b8dfbaac12a16784fd40598bbe50e49eeb Mon Sep 17 00:00:00 2001 From: Android Adapt Date: Sat, 9 May 2026 11:41:32 +0800 Subject: [PATCH 3/4] fix(ci): update remove_64bits_syscall_on_32bit_linux.patch to match Go 1.26 --- ...remove_64bits_syscall_on_32bit_linux.patch | 59 ++++++------------- 1 file changed, 18 insertions(+), 41 deletions(-) diff --git a/.github/patch/remove_64bits_syscall_on_32bit_linux.patch b/.github/patch/remove_64bits_syscall_on_32bit_linux.patch index bc0b9a0275..7c9c7c84b9 100644 --- a/.github/patch/remove_64bits_syscall_on_32bit_linux.patch +++ b/.github/patch/remove_64bits_syscall_on_32bit_linux.patch @@ -1,56 +1,33 @@ -Subject: [PATCH] remove 64bits syscall on 32bit linux +From bef1938b64a444911de119db613e60b9078ddd81 Mon Sep 17 00:00:00 2001 +From: wwqgtxx +Date: Sat, 9 May 2026 00:05:48 +0800 +Subject: [PATCH] Disable futex_time64 again + --- -Index: src/runtime/os_linux32.go -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== + src/runtime/os_linux32.go | 6 ------ + 1 file changed, 6 deletions(-) + diff --git a/src/runtime/os_linux32.go b/src/runtime/os_linux32.go ---- a/src/runtime/os_linux32.go (revision 030384681641464bf71ed16500075c458363510f) -+++ b/src/runtime/os_linux32.go (date 1771666707318) -@@ -21,14 +21,14 @@ +index 1ee1cdcaf90051..4aa42132d73739 100644 +--- a/src/runtime/os_linux32.go ++++ b/src/runtime/os_linux32.go +@@ -24,9 +24,6 @@ var use64bitsTimeOn32bits bool //go:nosplit func futex(addr unsafe.Pointer, op int32, val uint32, ts *timespec, addr2 unsafe.Pointer, val3 uint32) int32 { -- if !isFutexTime32bitOnly.Load() { -- ret := futex_time64(addr, op, val, ts, addr2, val3) -- // futex_time64 is only supported on Linux 5.0+ -- if ret != -_ENOSYS { -- return ret -- } -- isFutexTime32bitOnly.Store(true) +- if use64bitsTimeOn32bits { +- return futex_time64(addr, op, val, ts, addr2, val3) - } -+ //if !isFutexTime32bitOnly.Load() { -+ // ret := futex_time64(addr, op, val, ts, addr2, val3) -+ // // futex_time64 is only supported on Linux 5.0+ -+ // if ret != -_ENOSYS { -+ // return ret -+ // } -+ // isFutexTime32bitOnly.Store(true) -+ //} // Downgrade ts. var ts32 timespec32 var pts32 *timespec32 -@@ -49,14 +49,14 @@ +@@ -45,9 +42,6 @@ func timer_settime64(timerid int32, flags int32, new, old *itimerspec) int32 //go:nosplit func timer_settime(timerid int32, flags int32, new, old *itimerspec) int32 { -- if !isSetTime32bitOnly.Load() { -- ret := timer_settime64(timerid, flags, new, old) -- // timer_settime64 is only supported on Linux 5.0+ -- if ret != -_ENOSYS { -- return ret -- } -- isSetTime32bitOnly.Store(true) +- if use64bitsTimeOn32bits { +- return timer_settime64(timerid, flags, new, old) - } -+ //if !isSetTime32bitOnly.Load() { -+ // ret := timer_settime64(timerid, flags, new, old) -+ // // timer_settime64 is only supported on Linux 5.0+ -+ // if ret != -_ENOSYS { -+ // return ret -+ // } -+ // isSetTime32bitOnly.Store(true) -+ //} var newts, oldts itimerspec32 - var new32, old32 *itimerspec32 + var new32, old32 *itimerspec32 \ No newline at end of file From 17416e988dafb41b5fc24fbb53f55614fe82bca6 Mon Sep 17 00:00:00 2001 From: Android Adapt Date: Sat, 9 May 2026 14:03:30 +0800 Subject: [PATCH 4/4] fix(service): import missing uuid extension in ProfileReceiver --- .../main/java/com/github/kr328/clash/service/ProfileReceiver.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/service/src/main/java/com/github/kr328/clash/service/ProfileReceiver.kt b/service/src/main/java/com/github/kr328/clash/service/ProfileReceiver.kt index ef7111c475..791750b43e 100644 --- a/service/src/main/java/com/github/kr328/clash/service/ProfileReceiver.kt +++ b/service/src/main/java/com/github/kr328/clash/service/ProfileReceiver.kt @@ -14,6 +14,7 @@ import com.github.kr328.clash.common.constants.Intents import com.github.kr328.clash.common.log.Log import com.github.kr328.clash.common.util.componentName import com.github.kr328.clash.common.util.setUUID +import com.github.kr328.clash.common.util.uuid import com.github.kr328.clash.service.data.Imported import com.github.kr328.clash.service.data.ImportedDao import com.github.kr328.clash.service.model.Profile