diff --git a/Jenkinsfile b/Jenkinsfile
index 4ecb971..2d58dc0 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -50,12 +50,10 @@ pipeline {
stage('Resolve Versions') {
steps {
script {
- // Read version using cmd.exe findstr
- def verRaw = bat(
- script: '@findstr /B "PUBLISH_VERSION=" gradle.properties',
- returnStdout: true
- ).trim()
- def currentVer = verRaw.contains('=') ? verRaw.split('=', 2)[1].trim() : '0.1.0'
+ // Read version using pure Groovy (no Windows external commands)
+ def props = readFile('gradle.properties')
+ def verLine = props.readLines().find { it.trim().startsWith('PUBLISH_VERSION=') }
+ def currentVer = verLine ? verLine.split('=', 2)[1].trim() : '0.1.0'
echo "Current PUBLISH_VERSION: ${currentVer}"
def parts = currentVer.tokenize('.')
@@ -72,8 +70,9 @@ pipeline {
echo "Auto-bumped PUBLISH_VERSION: ${currentVer} → ${newVer}"
env.NEW_VERSION = newVer
- // Write back using powershell
- bat "powershell -Command \"(Get-Content gradle.properties) -replace '^PUBLISH_VERSION=.*', 'PUBLISH_VERSION=${newVer}' | Set-Content -NoNewline gradle.properties\""
+ // Write back using pure Groovy
+ def newProps = props.replaceAll(/(?m)^PUBLISH_VERSION=.*/, "PUBLISH_VERSION=${newVer}")
+ writeFile(file: 'gradle.properties', text: newProps)
def modules = env.PUBLISH_MODULES.split(',').toList()
def versionMap = [:]
diff --git a/sdk-core/src/main/AndroidManifest.xml b/sdk-core/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..f8741b0
--- /dev/null
+++ b/sdk-core/src/main/AndroidManifest.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/sdk-core/src/main/java/com/xuqm/sdk/internal/XuqmInitializerProvider.kt b/sdk-core/src/main/java/com/xuqm/sdk/internal/XuqmInitializerProvider.kt
new file mode 100644
index 0000000..62e7d1e
--- /dev/null
+++ b/sdk-core/src/main/java/com/xuqm/sdk/internal/XuqmInitializerProvider.kt
@@ -0,0 +1,30 @@
+package com.xuqm.sdk.internal
+
+import android.content.ContentProvider
+import android.content.ContentValues
+import android.database.Cursor
+import android.net.Uri
+import com.xuqm.sdk.XuqmSDK
+
+/**
+ * Auto-initializes XuqmSDK at app startup when a license file is present.
+ * Registered in sdk-core AndroidManifest so any module (im/update/push/license)
+ * triggers one-shot initialization without explicit init calls from the app.
+ */
+class XuqmInitializerProvider : ContentProvider() {
+ override fun onCreate(): Boolean {
+ val ctx = context?.applicationContext ?: return true
+ runCatching {
+ if (!XuqmSDK.isInitialized()) {
+ XuqmSDK.autoInitialize(ctx)
+ }
+ }
+ return true
+ }
+
+ override fun query(uri: Uri, projection: Array?, selection: String?, selectionArgs: Array?, sortOrder: String?): Cursor? = null
+ override fun getType(uri: Uri): String? = null
+ override fun insert(uri: Uri, values: ContentValues?): Uri? = null
+ override fun delete(uri: Uri, selection: String?, selectionArgs: Array?): Int = 0
+ override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array?): Int = 0
+}
diff --git a/sdk-license/src/main/java/com/xuqm/sdk/license/internal/LicenseInitializerProvider.kt b/sdk-license/src/main/java/com/xuqm/sdk/license/internal/LicenseInitializerProvider.kt
index e65964b..ba99ef4 100644
--- a/sdk-license/src/main/java/com/xuqm/sdk/license/internal/LicenseInitializerProvider.kt
+++ b/sdk-license/src/main/java/com/xuqm/sdk/license/internal/LicenseInitializerProvider.kt
@@ -10,14 +10,8 @@ class LicenseInitializerProvider : ContentProvider() {
override fun onCreate(): Boolean {
val ctx = context ?: return true
LicenseContextHolder.init(ctx)
- // Auto-initialize the full SDK if a license file is present in assets/xuqm/.
- // Runs before Application.onCreate(), so no app-level init code is needed.
- runCatching {
- val licenseFile = LicenseFileReader.read(ctx) ?: return@runCatching
- val appKey = licenseFile.appKey.takeIf { it.isNotBlank() } ?: return@runCatching
- val serverUrl = licenseFile.serverUrl?.takeIf { it.isNotBlank() }
- XuqmSDK.initialize(ctx, appKey, serverUrl)
- }
+ // SDK initialization is handled by sdk-core XuqmInitializerProvider.
+ // This provider only ensures LicenseContextHolder has the application context.
return true
}
diff --git a/sdk-update/src/main/java/com/xuqm/sdk/update/UpdateSDK.kt b/sdk-update/src/main/java/com/xuqm/sdk/update/UpdateSDK.kt
index 2e464c6..3cced93 100644
--- a/sdk-update/src/main/java/com/xuqm/sdk/update/UpdateSDK.kt
+++ b/sdk-update/src/main/java/com/xuqm/sdk/update/UpdateSDK.kt
@@ -49,19 +49,7 @@ object UpdateSDK {
}.getOrNull()
}
- private suspend fun awaitInitialization() {
- val xuqmClazz = runCatching { Class.forName("com.xuqm.sdk.XuqmSDK") }.getOrNull()
- if (xuqmClazz != null) {
- val isInitMethod = xuqmClazz.getMethod("isInitialized")
- val maxWaitMs = 30000L
- val start = System.currentTimeMillis()
- while (!(isInitMethod.invoke(null) as Boolean)) {
- if (System.currentTimeMillis() - start > maxWaitMs) {
- throw IllegalStateException("UpdateSDK initialization timed out waiting for XuqmSDK")
- }
- kotlinx.coroutines.delay(100)
- }
- }
+ private fun awaitInitialization() {
XuqmSDK.requireInit()
}