feat(sdk): 新增 autoInitialize(),放入 license 文件即可完成全量 SDK 初始化
- LicenseFile 新增 serverUrl 字段(私有化部署时由后端写入) - LicenseSDK 新增 readLicenseFileData() 供 sdk-core 反射调用 - XuqmSDK.autoInitialize(context) 从 assets/xuqm/license.xuqm 读取 appKey 和 serverUrl,一行完成公/私有化 SDK 初始化 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
父节点
02407dfe16
当前提交
84eeecb4cc
@ -27,6 +27,24 @@ object XuqmSDK {
|
|||||||
@Volatile
|
@Volatile
|
||||||
private var loginSession: XuqmLoginSession? = null
|
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(
|
fun initialize(
|
||||||
context: Context,
|
context: Context,
|
||||||
appKey: String,
|
appKey: String,
|
||||||
@ -52,6 +70,14 @@ object XuqmSDK {
|
|||||||
serverUrl?.takeIf { it.isNotBlank() }?.let { configurePrivateServer(context, appKey, it) }
|
serverUrl?.takeIf { it.isNotBlank() }?.let { configurePrivateServer(context, appKey, it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
private fun readLicenseFileData(context: Context): Pair<String, String?>? = 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<String, String?>
|
||||||
|
}.getOrNull()
|
||||||
|
|
||||||
private fun configurePrivateServer(context: Context, appKey: String, serverUrl: String) {
|
private fun configurePrivateServer(context: Context, appKey: String, serverUrl: String) {
|
||||||
val base = serverUrl.trimEnd('/') + "/"
|
val base = serverUrl.trimEnd('/') + "/"
|
||||||
val wsBase = serverUrl.trimEnd('/')
|
val wsBase = serverUrl.trimEnd('/')
|
||||||
|
|||||||
@ -186,6 +186,16 @@ object LicenseSDK {
|
|||||||
return store.deviceId
|
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<String, String?>? {
|
||||||
|
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).
|
* Clear all license data (token, device ID, status).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -11,6 +11,8 @@ data class LicenseFile(
|
|||||||
@SerializedName(value = "appName", alternate = ["app_name"]) val appName: String? = null,
|
@SerializedName(value = "appName", alternate = ["app_name"]) val appName: String? = null,
|
||||||
@SerializedName(value = "companyName", alternate = ["company_name"]) val companyName: String? = null,
|
@SerializedName(value = "companyName", alternate = ["company_name"]) val companyName: String? = null,
|
||||||
@SerializedName(value = "baseUrl", alternate = ["base_url"]) val baseUrl: 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 = "issuedAt", alternate = ["issued_at"]) val issuedAt: String? = null,
|
||||||
@SerializedName(value = "expiresAt", alternate = ["expires_at"]) val expiresAt: String? = null,
|
@SerializedName(value = "expiresAt", alternate = ["expires_at"]) val expiresAt: String? = null,
|
||||||
)
|
)
|
||||||
|
|||||||
正在加载...
在新工单中引用
屏蔽一个用户