- 集成依赖管理配置文件 libs.versions.toml,统一管理项目依赖版本 - 实现演示 API 接口定义,包含登录、注册、用户管理等 RESTful 端点 - 创建认证仓库 AuthRepository,处理用户会话管理和加密存储 - 开发登录和注册界面,实现用户身份验证流程 - 构建聊天界面 ChatScreen,支持消息收发和历史记录显示 - 实现联系人管理功能,包含好友搜索和添加删除操作 - 添加会话列表界面,展示最近聊天记录和未读消息提示
232 行
5.4 KiB
Markdown
232 行
5.4 KiB
Markdown
# XuqmGroup Android SDK 文档
|
||
|
||
> Kotlin 2.3.10 · AGP 9.1.0 · minSdk 24 · compileSdk 36
|
||
|
||
## 模块结构
|
||
|
||
```
|
||
XuqmGroup-AndroidSDK/
|
||
├── sdk-core/ # 核心:初始化、HTTP、Token 存储、通用工具/组件
|
||
├── sdk-im/ # IM:WebSocket 实时通信
|
||
├── sdk-push/ # 推送:设备 Token 注册
|
||
├── sdk-update/ # 版本管理:检查更新、下载安装、RN 热更新
|
||
└── sample-app/ # 示例 App(Jetpack Compose)
|
||
```
|
||
|
||
## 集成
|
||
|
||
### Gradle(Maven 私有仓库)
|
||
|
||
在项目根 `settings.gradle.kts` 添加仓库:
|
||
```kotlin
|
||
dependencyResolutionManagement {
|
||
repositories {
|
||
maven {
|
||
url = uri("https://nexus.xuqinmin.com/repository/android-hosted/")
|
||
credentials {
|
||
username = providers.gradleProperty("NEXUS_USER").orNull ?: ""
|
||
password = providers.gradleProperty("NEXUS_PASSWORD").orNull ?: ""
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
在 `gradle.properties` 或环境变量中配置:
|
||
```properties
|
||
NEXUS_USER=your_username
|
||
NEXUS_PASSWORD=your_password
|
||
```
|
||
|
||
引入依赖:
|
||
```kotlin
|
||
dependencies {
|
||
implementation("com.xuqm:sdk-core:0.1.0")
|
||
implementation("com.xuqm:sdk-im:0.1.0") // 可选
|
||
implementation("com.xuqm:sdk-push:0.1.0") // 可选
|
||
implementation("com.xuqm:sdk-update:0.1.0") // 可选
|
||
}
|
||
```
|
||
|
||
## 快速开始
|
||
|
||
### 1. 初始化(Application.onCreate)
|
||
|
||
```kotlin
|
||
XuqmSDK.initialize(
|
||
context = this,
|
||
appId = "ak_your_app_id",
|
||
debug = BuildConfig.DEBUG
|
||
)
|
||
```
|
||
|
||
### 2. 用户登录后初始化 IM
|
||
|
||
```kotlin
|
||
// 调用业务登录接口,拿到 userSig 后再登录 IM
|
||
val userSig = api.getUserSig(userId)
|
||
ImSDK.login(userId = userId, userSig = userSig)
|
||
|
||
// Push 设备注册在 PushSDK.initialize() 内部自动完成
|
||
```
|
||
|
||
---
|
||
|
||
## sdk-core
|
||
|
||
### SDKConfig
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `appId` | String | 应用标识(租户平台获取) |
|
||
| `debug` | Boolean | 开启日志 |
|
||
|
||
### TokenStore
|
||
|
||
基于 `DataStore<Preferences>` 持久化存储。
|
||
|
||
```kotlin
|
||
// 存储
|
||
XuqmSDK.tokenStore.save("eyJ...")
|
||
|
||
// 读取(协程)
|
||
val token = XuqmSDK.tokenStore.get()
|
||
|
||
// 清除(登出)
|
||
XuqmSDK.tokenStore.clear()
|
||
```
|
||
|
||
### ApiClient
|
||
|
||
基于 OkHttp 5 + Retrofit 3,自动附加 Bearer Token,统一解析 `ApiResponse<T>`。
|
||
|
||
```kotlin
|
||
// 通过 RetrofitFactory 获取接口实例
|
||
val service = RetrofitFactory.create(MyApiService::class.java)
|
||
```
|
||
|
||
---
|
||
|
||
## sdk-im
|
||
|
||
### ImClient
|
||
|
||
```kotlin
|
||
val imClient = ImClient()
|
||
|
||
// 注册事件监听
|
||
imClient.listener = object : ImEventListener {
|
||
override fun onConnected() { /* WebSocket 连接成功 */ }
|
||
override fun onDisconnected(code: Int, reason: String) { /* 断开 */ }
|
||
override fun onMessage(msg: ImMessage) { /* 收到新消息 */ }
|
||
override fun onRevoke(msgId: String, operatorId: String) { /* 消息被撤回 */ }
|
||
override fun onError(t: Throwable) { /* 连接错误 */ }
|
||
}
|
||
|
||
// 连接
|
||
imClient.connect()
|
||
|
||
// 发送消息
|
||
imClient.send(SendMessageParams(
|
||
toId = "user_002",
|
||
chatType = ChatType.SINGLE,
|
||
msgType = MsgType.TEXT,
|
||
content = "Hello!"
|
||
))
|
||
|
||
// 撤回消息
|
||
imClient.revoke(msgId = "uuid")
|
||
|
||
// 断开连接(Activity/Fragment 销毁时调用)
|
||
imClient.disconnect()
|
||
```
|
||
|
||
### 消息类型(MsgType)
|
||
|
||
`TEXT` / `IMAGE` / `VIDEO` / `AUDIO` / `FILE` / `CUSTOM` / `LOCATION` / `NOTIFY` / `RICH_TEXT` / `CALL_AUDIO` / `CALL_VIDEO` / `FORWARD`
|
||
|
||
### ImMessage 结构
|
||
|
||
```kotlin
|
||
data class ImMessage(
|
||
val id: String,
|
||
val fromId: String,
|
||
val toId: String,
|
||
val chatType: ChatType, // SINGLE / GROUP
|
||
val msgType: MsgType,
|
||
val content: String,
|
||
val extra: String?,
|
||
val revoked: Boolean,
|
||
val createdAt: String
|
||
)
|
||
```
|
||
|
||
### 自动重连
|
||
|
||
断线后指数退避重连,初始间隔 3 秒,最大间隔 30 秒。调用 `disconnect()` 后停止重连。
|
||
|
||
---
|
||
|
||
## sdk-push
|
||
|
||
### 推送接入
|
||
|
||
在 `PushSDK.initialize()` 后由 SDK 自动完成厂商初始化、设备注册与 token 上传,不再要求业务侧单独调用注册接口。
|
||
|
||
### 与 IM 联动
|
||
|
||
当 IM 和推送服务均已开启时,IM 服务在目标用户离线时会自动调用推送服务发送离线推送通知。
|
||
业务方只需分别注册推送 Token 和 IM 登录,无需额外配置。
|
||
|
||
---
|
||
|
||
## sdk-update
|
||
|
||
### 检查原生 App 更新
|
||
|
||
```kotlin
|
||
val result: UpdateResult = UpdateSDK.checkUpdate(
|
||
appId = "ak_xxx",
|
||
platform = Platform.ANDROID
|
||
)
|
||
|
||
if (result.needsUpdate) {
|
||
// result.versionName, result.downloadUrl, result.forceUpdate
|
||
UpdateSDK.downloadAndInstall(context, result.downloadUrl)
|
||
}
|
||
```
|
||
|
||
`downloadAndInstall` 会将 APK 下载到 `getExternalFilesDir(null)`,通过 `FileProvider` 触发系统安装。
|
||
AndroidManifest 中已配置 `@xml/file_paths`(`external-files-path`)。
|
||
|
||
### 检查 RN Bundle 更新
|
||
|
||
```kotlin
|
||
val rnResult = UpdateSDK.checkRnUpdate(
|
||
appId = "ak_xxx",
|
||
moduleId = "main",
|
||
platform = "android",
|
||
currentVersion = "1.0.0"
|
||
)
|
||
|
||
if (rnResult.needsUpdate) {
|
||
val filePath = UpdateSDK.downloadBundle(context, rnResult.downloadUrl, "main.android.bundle")
|
||
// 校验 MD5
|
||
// 通知 RN 引擎加载新 bundle
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 发版
|
||
|
||
```bash
|
||
# 在 gradle.properties 中配置 NEXUS_USER / NEXUS_PASSWORD
|
||
./gradlew :sdk-core:publish
|
||
./gradlew :sdk-im:publish
|
||
./gradlew :sdk-push:publish
|
||
./gradlew :sdk-update:publish
|
||
```
|
||
|
||
发布至 `https://nexus.xuqinmin.com/repository/android-hosted/`,groupId `com.xuqm`,版本号在各模块 `build.gradle.kts` 中维护。
|