XuqmGroup-Web/docs-site/docs/android/license.md
XuqmGroup 038d862838 License改造:ops平台管理最大设备数、审批有效期、License SDK文档
- ops平台AppDetailView添加License授权管理卡片(内联编辑最大设备数)
- 服务开通审批对话框LICENSE类型支持选择有效期
- ops API新增getAppLicense/updateMaxDevices方法
- 文档站新增Android License SDK集成文档
- setup.md添加sdk-license依赖和ProGuard规则

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 22:39:43 +08:00

4.2 KiB

Android 授权管理License SDK

模块com.xuqm:sdk-license · 最低 Android 版本API 24 (Android 7.0)

License SDK 用于设备授权注册与验证,所有平台Android / iOS / 鸿蒙)共用同一个 License Key。


快速接入

1. 添加依赖

// app/build.gradle.kts
dependencies {
    implementation("com.xuqm:sdk-license:0.4.2")
}

2. 放置 License 文件

从租户平台下载 .xuqmlicense 加密文件,放入 app 的 assets 目录:

app/src/main/assets/xuqm/license.xuqm

SDK 会按以下顺序查找文件:

  1. assets/xuqm/license.xuqm
  2. assets/xuqm/ 目录下第一个 .xuqmlicense 文件

3. 检查授权

SDK 无需手动初始化,首次调用 checkLicense() 时自动读取并解密 License 文件。

LicenseSDK.checkLicense { isValid ->
    if (isValid) {
        // 授权通过,允许使用
    } else {
        // 授权失败,提示用户
    }
}

API 说明

checkLicense

检查设备授权状态。首次调用时自动完成:读取 License 文件 → 解密 → 注册/验证设备 → 缓存结果。

// 回调方式
LicenseSDK.checkLicense { isValid ->
    // true: 授权通过  false: 授权失败
}

// 协程方式
lifecycleScope.launch {
    val isValid = LicenseSDK.checkLicense()
}

内部逻辑

  1. 检查本地缓存(默认 10 分钟有效期)
  2. 缓存有效 → 直接返回 true
  3. 缓存过期或无缓存:
    • 有 Token → 调用验证接口
    • 无 Token 或验证失败 → 调用注册接口
  4. 网络异常且缓存曾成功 → 返回 true(离线模式)
  5. 网络异常且无缓存 → 返回 false

设备唯一码

SDK 自动选择设备唯一码,优先级如下:

优先级 来源 稳定性
1 ANDROID_ID 同一签名 + 设备 + 用户不变,重装不变
2 持久化 UUID 首次生成后持久化存储

保持不变的场景App 重启、App 重装(同一签名)、系统升级

会变化的场景:恢复出厂设置、更换签名重新安装


离线模式

SDK 支持离线使用:

  • 首次激活需要网络连接
  • 激活成功后,缓存有效期内(默认 10 分钟)可离线使用
  • 网络异常时,若缓存曾经成功验证,继续返回授权通过

数据存储

数据 存储方式 说明
deviceId EncryptedSharedPreferences AES-256 加密
token EncryptedSharedPreferences AES-256 加密
授权状态 EncryptedSharedPreferences AES-256 加密
fallback UUID SharedPreferences ANDROID_ID 不可用时使用

AppKey 变更

当 License 文件中的 AppKey 与已存储的不一致时,SDK 会自动:

  1. 清除所有旧数据Token、deviceId、状态
  2. 使用新 AppKey 重新注册

完整示例

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        // 无需初始化代码,SDK 自动读取 License 文件
    }
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        LicenseSDK.checkLicense { isValid ->
            runOnUiThread {
                if (isValid) {
                    // 进入主界面
                } else {
                    Toast.makeText(this, "授权验证失败", Toast.LENGTH_LONG).show()
                    finish()
                }
            }
        }
    }
}

常见问题

Q: checkLicense 返回 false 怎么办? A: 检查以下几点:

  • License 文件是否放在 assets/xuqm/ 目录
  • 文件名是否为 license.xuqm 或以 .xuqmlicense 结尾
  • 设备是否有网络连接(首次激活需要网络)
  • License 是否已过期或被管理员禁用

Q: 不同平台可以用同一个 License 吗? A: 可以。所有平台共用同一个 AppKey,设备数量统一计算。

Q: 设备被禁用后如何恢复? A: 由租户管理员在租户平台的授权管理页面重新激活该设备,App 端无需额外操作,下次 checkLicense 会自动恢复正常。