diff --git a/sdk-core/src/main/java/com/xuqm/sdk/XuqmSDK.kt b/sdk-core/src/main/java/com/xuqm/sdk/XuqmSDK.kt index 51f4c2a..01fd8ef 100644 --- a/sdk-core/src/main/java/com/xuqm/sdk/XuqmSDK.kt +++ b/sdk-core/src/main/java/com/xuqm/sdk/XuqmSDK.kt @@ -27,6 +27,24 @@ object XuqmSDK { @Volatile private var loginSession: XuqmLoginSession? = null + /** + * Initializes the SDK automatically from the license file embedded in assets/xuqm/. + * Place the license.xuqm file downloaded from the tenant platform into your app's + * src/main/assets/xuqm/ directory — no hardcoded appKey or serverUrl needed. + * + * For private deployments the license file contains the server URL and all service + * endpoints are configured automatically. For public deployments the default endpoints + * (dev.xuqinmin.com) are used. + */ + fun autoInitialize(context: Context, logLevel: LogLevel = LogLevel.WARN) { + val (appKey, serverUrl) = readLicenseFileData(context) + ?: throw IllegalStateException( + "No license file found in assets/xuqm/. " + + "Download license.xuqm from the tenant platform and place it in src/main/assets/xuqm/." + ) + initialize(context, appKey, serverUrl, logLevel) + } + fun initialize( context: Context, appKey: String, @@ -52,6 +70,14 @@ object XuqmSDK { serverUrl?.takeIf { it.isNotBlank() }?.let { configurePrivateServer(context, appKey, it) } } + @Suppress("UNCHECKED_CAST") + private fun readLicenseFileData(context: Context): Pair? = runCatching { + val clazz = Class.forName("com.xuqm.sdk.license.LicenseSDK") + val instance = clazz.getField("INSTANCE").get(null) + val method = clazz.getMethod("readLicenseFileData", Context::class.java) + method.invoke(instance, context.applicationContext) as? Pair + }.getOrNull() + private fun configurePrivateServer(context: Context, appKey: String, serverUrl: String) { val base = serverUrl.trimEnd('/') + "/" val wsBase = serverUrl.trimEnd('/') diff --git a/sdk-license/src/main/java/com/xuqm/sdk/license/LicenseSDK.kt b/sdk-license/src/main/java/com/xuqm/sdk/license/LicenseSDK.kt index 1873378..2635886 100644 --- a/sdk-license/src/main/java/com/xuqm/sdk/license/LicenseSDK.kt +++ b/sdk-license/src/main/java/com/xuqm/sdk/license/LicenseSDK.kt @@ -186,6 +186,16 @@ object LicenseSDK { return store.deviceId } + /** + * Returns (appKey, serverUrl) from the embedded license file, or null if no file is present. + * Called by XuqmSDK.autoInitialize() via reflection — sdk-core cannot depend on sdk-license directly. + */ + fun readLicenseFileData(context: Context): Pair? { + val licenseFile = LicenseFileReader.read(context) ?: return null + val appKey = licenseFile.appKey.takeIf { it.isNotBlank() } ?: return null + return appKey to licenseFile.serverUrl?.takeIf { it.isNotBlank() } + } + /** * Clear all license data (token, device ID, status). */ diff --git a/sdk-license/src/main/java/com/xuqm/sdk/license/model/LicenseFile.kt b/sdk-license/src/main/java/com/xuqm/sdk/license/model/LicenseFile.kt index da04d0e..c4ae8e1 100644 --- a/sdk-license/src/main/java/com/xuqm/sdk/license/model/LicenseFile.kt +++ b/sdk-license/src/main/java/com/xuqm/sdk/license/model/LicenseFile.kt @@ -11,6 +11,8 @@ data class LicenseFile( @SerializedName(value = "appName", alternate = ["app_name"]) val appName: String? = null, @SerializedName(value = "companyName", alternate = ["company_name"]) val companyName: String? = null, @SerializedName(value = "baseUrl", alternate = ["base_url"]) val baseUrl: String? = null, + // Set only for private deployments; used by XuqmSDK.autoInitialize() to configure all service endpoints. + @SerializedName(value = "serverUrl", alternate = ["server_url"]) val serverUrl: String? = null, @SerializedName(value = "issuedAt", alternate = ["issued_at"]) val issuedAt: String? = null, @SerializedName(value = "expiresAt", alternate = ["expires_at"]) val expiresAt: String? = null, )