外观
Android 接入
需要查某个方法的参数、返回值或回调时,查看 Android 方法参考。
Android SDK 通过会话和通讯录两个 AndroidX Fragment 接入宿主主导航。聊天、搜索、资料、群管理与媒体页面由 SDK 自行导航;Java 与 Kotlin 宿主使用同一套公开 API。
环境
| 项目 | 要求 |
|---|---|
| 系统 | Android 5.0 / API 21+ |
| 源码编译 | compileSdk 35、JDK 17 |
| SDK 工程工具 | AGP 8.7.3、Gradle 8.9 |
| 字节码 | Java 8 |
| UI 容器 | AndroidX FragmentActivity / AppCompatActivity |
源码模块使用 compileSdk 35;这与最低运行系统 API 21 是不同概念。宿主可继续使用自身的 targetSdk,并按目标 Android 版本完成权限和安全区适配。
加入本地模块
保留 android/core 和 android/uikit,在宿主的 settings.gradle.kts 中声明:
kotlin
include(":popo-core", ":popo-uikit")
project(":popo-core").projectDir = file("../android/core")
project(":popo-uikit").projectDir = file("../android/uikit")宿主应用模块添加:
kotlin
dependencies {
implementation(project(":popo-uikit"))
}UIKit 已依赖 Core,无需再重复添加。宿主需提供 google() 与 mavenCentral() 仓库、Android library 插件,以及 android.useAndroidX=true;具体版本以 SDK 工程配置为准。媒体和扫码等第三方依赖由模块的 Gradle 文件管理。
初始化与 AuthProvider
在宿主 Application 的启动流程中初始化,避免系统直接重建 SDK 聊天页时找不到配置。初始化放在用户同意应用隐私政策之后,每个进程执行一次。
kotlin
import com.popoim.sdk.PopoAuthProvider
import com.popoim.sdk.PopoConfig
import com.popoim.sdk.PopoIM
val provider = PopoAuthProvider { callback ->
// 宿主自己的异步后端适配;只访问宿主取票接口。
hostAuth.fetchImAuth(
onSuccess = { auth -> callback.onSuccess(auth) },
onFailure = { error -> callback.onError(error) }
)
}
PopoIM.init(
application,
PopoConfig("https://example.com", "wss://example.com/ws", provider)
)hostAuth 是宿主实现的网络层,成功结果需映射为真实模型:
kotlin
import com.popoim.sdk.PopoAuthInfo
import com.popoim.sdk.PopoUser
val auth = PopoAuthInfo(
PopoUser(userId, username, nickname, avatar, signature),
token,
expireAt // Long,Unix 秒
)Provider 是回调接口,不能写成返回字符串或 suspend () -> String。网络失败调用 onError;成功只调用一次 onSuccess。webSocketUrl 可以省略,默认由服务地址派生 /ws。
两个 UI 入口
在宿主的两个 Tab 内容区域中分别承载:
kotlin
import com.popoim.sdk.ui.PopoConversationFragment
import com.popoim.sdk.ui.PopoContactFragment
import com.popoim.sdk.ui.PopoUIKit
supportFragmentManager.beginTransaction()
.replace(R.id.message_container, PopoConversationFragment())
.replace(R.id.contact_container, PopoContactFragment())
.commit()message_container、contact_container 是宿主自己的容器。首次创建时添加 Fragment,系统恢复后使用原实例;不要在每次标签切换时重新创建。宿主切换可见根页,SDK 处理根页以内的页面栈。
为从 SDK 内部流程返回后选中消息标签,宿主实现 PopoConversationNavigationHost.showConversationListOnReturn(),并在主 Activity 创建时注册:
kotlin
PopoUIKit.setConversationNavigationHost(this)此处 this 为已实现该接口的宿主 Activity。接口只要求宿主展示自己的消息标签,不传递 SDK 内部路由。
登录、退出与账号切换
kotlin
// 可选:verifiedUser 来自宿主确认的本机登录态。
PopoIM.restoreCachedSession(verifiedUser) { error ->
if (error != null) showError(error.message)
PopoIM.login { loginError ->
if (loginError != null) showError(loginError.message)
}
}
// Provider 已切到新的宿主账号,再显式登录。
PopoIM.login { error ->
if (error != null) showError(error.message)
}
// 宿主退出时清理当前会话及本地账号数据。
PopoIM.logout(true)PopoCallback 的 error == null 表示成功,回调位于主线程。restoreCachedSession 不请求 Token 或网络,只提前载入缓存;正常登录同样直接调用 login。isReady() 表示本进程认证与首次同步完成,不代表当前网络一定连通;currentUserId() 可查询当前外部用户 ID。
常用公开操作
kotlin
import com.popoim.sdk.PopoConversationTarget
import com.popoim.sdk.PopoUnreadListener
import com.popoim.sdk.ui.PopoUIKit
PopoUIKit.openConversation(
this,
PopoConversationTarget.friend("linzhou")
) { error ->
if (error != null) showError(error.message)
}
val unreadListener = PopoUnreadListener { count ->
renderUnread(count.conversation, count.contact)
}
PopoIM.addUnreadListener(unreadListener)
// 在对应宿主生命周期结束时移除同一个实例。
PopoIM.removeUnreadListener(unreadListener)
PopoIM.updateCurrentUser(updatedUser) { error ->
if (error != null) showError(error.message)
}
PopoUIKit.cacheSize(this) { bytes -> renderCacheSize(bytes) }
PopoUIKit.clearCache(this) { remainingBytes -> renderCacheSize(remainingBytes) }打开群聊使用 PopoConversationTarget.group(groupId);定位消息使用 openConversation(activity, target, messageId, callback)。完成回调表示已启动聊天页,不表示用户已读或已关闭页面。showError、renderUnread 与 renderCacheSize 均由宿主实现。
权限与平台接线
SDK 模块 Manifest 会参与合并,发布前检查最终 Manifest 的网络、相机、麦克风等声明和宿主权限文案。相册及文件优先使用系统选择器,不应为 SDK 补一组无关的广泛存储权限。
SDK 自动观察 Application 的前后台变化,宿主无需自行重建长连接。两个根 Fragment 跟随宿主 Activity 方向;内部页面继承下层宿主 Activity 的方向策略。主题使用 Android 的 values / values-night 资源与宿主模式。
普通通知授权、推送平台与桌面角标由宿主负责。SDK 回调给出当前未读总数,宿主替换相应角标后再与其他业务未读汇总,不能每次回调累加。缓存清理只删除可重新下载的媒体,不删除聊天记录、草稿或待发送内容。
接入检查
验证两个根页切换、从业务页打开林舟单聊、系统返回、切换账号和进程被回收后的页面恢复。另在目标 Android 版本真机检查手势区、软键盘、录音权限及竖屏视频;深浅色模式都应操作一遍。
