# Android 授权管理(License SDK) **模块**:`com.xuqm:sdk-license` · **最低 Android 版本**:API 24 (Android 7.0) License SDK 用于设备授权注册与验证,所有平台(Android / iOS / 鸿蒙)共用同一个 License Key。 --- ## 快速接入 ### 1. 添加依赖 ```kotlin // 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 文件。 ```kotlin LicenseSDK.checkLicense { isValid -> if (isValid) { // 授权通过,允许使用 } else { // 授权失败,提示用户 } } ``` --- ## API 说明 ### checkLicense 检查设备授权状态。首次调用时自动完成:读取 License 文件 → 解密 → 注册/验证设备 → 缓存结果。 ```kotlin // 回调方式 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 重新注册 --- ## 完整示例 ```kotlin 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` 会自动恢复正常。