快速开始
更新时间: 2023/01/30 18:58:36
网易作为国内最大最早的即时通信开发商之一,从最早的网易泡泡到后来的易信,已经有了超过十五年的通讯技术积累。现在我们整合了这些产品高稳定、高可靠即时通信能力,开发者能以很小的成本将即时通信功能集成到自己的 APP 中。
网易云信即时通讯Android-SDK为Android移动应用提供完善的即时通信功能开发框架,屏蔽其内部复杂细节,对外提供较为简洁的 API 接口,方便第三方应用快速集成即时通信功能。SDK 兼容 Android 4.4+。
SDK集成
云信即时通讯 Android-SDK 支持两种集成方式:
-
通过 Gradle 自动集成 (推荐)
-
通过下载SDK,然后手动集成到您的工程项目中。
此外,为了让开发者可以轻松快速的在 App 中集成 IM 功能,我们还提供了开源的 UI组件,通过简单的配置就可以实现聊天功能。
Gradle集成
- 在整个工程的 build.gradle 文件中,配置 repositories(使用maven)。示例代码如下:
allprojects {
repositories {
mavenCentral()
}
}
- 在主工程的 build.gradle 文件中,设置支持的 SO 库架构。
android {
defaultConfig {
ndk {
//设置支持的SO库架构
abiFilters "armeabi-v7a", "x86","arm64-v8a","x86_64"
}
}
}
- 根据自己项目的需求,添加不同的依赖。
云信的组件版本号必须一致。可在SDK下载页面查看当前最新版本。如下示例代码中的 x.x.x 指最新版本。
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
// 添加依赖。注意,版本号必须一致。
// 基础功能 (必需)
implementation 'com.netease.nimlib:basesdk:x.x.x'
// 聊天室需要
implementation 'com.netease.nimlib:chatroom:x.x.x'
// 通过云信来集成小米等厂商推送需要
implementation 'com.netease.nimlib:push:x.x.x'
// 超大群需要
implementation 'com.netease.nimlib:superteam:x.x.x'
// 全文检索插件
implementation 'com.netease.nimlib:lucene:x.x.x'
}
手动集成
- 前往SDK下载页面完成 SDK 下载。
- 按需将对应的 SDK 文件拷贝到您的工程的 libs 目录下,即可完成配置。
SDK 文件说明如下:
libs
├── arm64-v8a
│ ├── libne_audio.so //语音消息录制功能,必需
│ ├── traceroute.so //网络探测功能,必需
| ├── libc++_shared.so //C++动态库,必需
| ├── libhigh-available.so //高可用功能库,必需
├── armeabi-v7a
│ ├── libne_audio.so
│ ├── traceroute.so
| ├── libc++_shared.so
| ├── libhigh-available.so
├── x86
│ ├── libne_audio.so
│ ├── traceroute.so
| ├── libc++_shared.so
| ├── libhigh-available.so
├── x86_64
│ ├── libne_audio.so
│ ├── traceroute.so
| ├── libc++_shared.so
| ├── libhigh-available.so
│
├── nim-basesdk-x.x.x.jar //IM基础功能,必需
├── nim-chatroom-x.x.x.jar //聊天室功能
├── nim-lucene-x.x.x.jar //全文检索插件
├── nim-push-x.x.x.jar //通过云信来集成小米等厂商推送时需要
权限与组件
在 AndroidManifest.xml
中加入以下配置(请将 com.netease.nim.demo 替换为自己的包名):
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.netease.nim.demo">
<!-- 权限声明 -->
<!-- 访问网络状态-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!-- 外置存储存取权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 多媒体相关 -->
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!-- Android11:V8.6.1及之后的版本不需要;其他:V4.4.0及之后的版本不需要 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!-- 控制呼吸灯,振动器等,用于新消息提醒 -->
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.VIBRATE" />
<!-- 8.0+系统需要-->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- 下面的 uses-permission 一起加入到你的 AndroidManifest 文件中。 -->
<permission
android:name="com.netease.nim.demo.permission.RECEIVE_MSG"
android:protectionLevel="signature"/>
<uses-permission android:name="com.netease.nim.demo.permission.RECEIVE_MSG"/>
<application
...>
<!-- APP key, 可以在这里设置,也可以在 SDKOptions 中提供。
如果 SDKOptions 中提供了,则取 SDKOptions 中的值。 -->
<meta-data
android:name="com.netease.nim.appKey"
android:value="key_of_your_app" />
<!-- 云信后台服务,请使用独立进程。 -->
<service
android:name="com.netease.nimlib.service.NimService"
android:process=":core"/>
<!-- 云信后台辅助服务 -->
<service
android:name="com.netease.nimlib.service.NimService$Aux"
android:process=":core"/>
<!-- 云信后台辅助服务 -->
<service
android:name="com.netease.nimlib.job.NIMJobService"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE"
android:process=":core"/>
<!-- 云信监视系统启动和网络变化的广播接收器,保持和 NimService 同一进程 -->
<receiver android:name="com.netease.nimlib.service.NimReceiver"
android:process=":core"
android:exported="false">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
<!-- 云信进程间通信 Receiver -->
<receiver android:name="com.netease.nimlib.service.ResponseReceiver"/>
<!-- 云信进程间通信service -->
<service android:name="com.netease.nimlib.service.ResponseService"/>
<!-- 云信进程间通信provider -->
<provider
android:name="com.netease.nimlib.ipc.NIMContentProvider"
android:authorities="com.netease.nim.demo.ipc.provider"
android:exported="false"
android:process=":core" />
<!-- 云信内部使用的进程间通信provider -->
<!-- SDK启动时会强制检测该组件的声明是否配置正确,如果检测到该声明不正确,SDK会主动抛出异常引发崩溃 -->
<provider
android:name="com.netease.nimlib.ipc.cp.provider.PreferenceContentProvider"
android:authorities="com.netease.nim.demo.ipc.provider.preference"
android:exported="false" />
</application>
</manifest>
防混淆配置
如果你的 apk 最终会经过代码混淆,请在 proguard 配置文件中加入以下代码防止混淆:
-dontwarn com.netease.nim.**
-keep class com.netease.nim.** {*;}
-dontwarn com.netease.nimlib.**
-keep class com.netease.nimlib.** {*;}
-dontwarn com.netease.share.**
-keep class com.netease.share.** {*;}
-dontwarn com.netease.mobsec.**
-keep class com.netease.mobsec.** {*;}
#如果你使用全文检索插件,需要加入
-dontwarn org.apache.lucene.**
-keep class org.apache.lucene.** {*;}
#如果你开启数据库功能,需要加入
-keep class net.sqlcipher.** {*;}
使用说明
接口介绍
SDK 提供了两类接口供开发者使用:第一类是主动发起请求,第二类是作为观察者监听事件和变化。第一类接口名均以 Service
结尾,例如 AuthService
,第二类接口名均以 ServiceObserver
结尾,例如 AuthServiceObserver
,个别太长的类名则可能直接以 Observer
结尾,比如 SystemMessageObserver
。
SDK 接口调用必须在主进程中,请在主进程中调用 SDK XXXService
提供的方法,在主进程中注册 XXXServiceObserver
的观察者(有事件变更,会回调给主进程的主线程)。如果你的模块运行在非主进程,请自行实现主进程与非主进程的通信(AIDL/Messenger/ContentProvider/BroadcastReceiver等IPC渠道
)将主进程回调或监听返回的数据传递给非主进程。
SDK 提供三种接口返回值:基本数据类型(同步接口),InvocationFuture(异步接口) 和 AbortableFuture(异步接口)。异步接口基本上都是从主进程发起调用,然后在后台进程执行,最后再将结果返回给主进程。
SDK 接口返回值 | 说明 |
---|---|
基本数据类型 | 同步接口 |
InvocationFuture | 异步接口 |
AbortableFuture | 异步接口,耗时很长或者传输大量数据时使用,可用 abort() 方法,中断请求。例如上传下载、登录等 |
异步接口可设置回调函数,提供两种方式:RequestCallback 和 RequestCallbackWrapper。
异步接口回调函数 | 说明 |
---|---|
RequestCallback | 需要实现3个接口: 成功 onSuccess, 失败 onFailed, 异常 onException |
RequestCallbackWrapper | 需要实现 onResult。封装了成功,失败和异常的3个接口,在参数上进行区分 |
- SDK 4.4.0 API调用框架增强:
- 支持带 Looper 的非UI线程发起的异步API调用,直接回调到调用者线程。老版本会默认回调到 UI 线程。
- 提供异步强制转成同步的接口:NIMClient#syncRequest,允许设置最大同步等待时间,支持非 UI 线程里需要同步调用云信 API的场景。
- 添加自动生成的 NIMSDK类,开发者可以直接采用 NIMSDK#getXXXService 方法获取服务接口,不再需要传递 XXXService.class,简化 API 调用方式。其他插件自动生成的调用入口类为:NIMChatRoomSDK、NIMLuceneSDK。例如采用
NIMSDK.getAuthService().login()
替换NIMClient.getService(AuthService.class).login()
。
数据缓存目录
当收到多媒体消息后,SDK 默认会下载一些相关的文件,同时 SDK 还要记录一些关键的日志文件,因此 SDK 需要一个数据缓存目录。
该目录可以在 SDK 初始化时通过 SDKOptions#sdkStorageRootPath
进行设置。在 SDK 4.4.0版本起,如果开发者配置在 Context#getExternalCacheDir
及 Context#getExternalFilesDir
等应用扩展存储缓存目录下(即/sdcard/Android/data/{package}
),SDK 内部将不再检查写权限。值得注意的是,该缓存目录下的文件会随着App卸载而被删除,也可以由用户手动在设置界面里面清除。
如果不设置,则默认为/{外卡根目录}/{应用包名}/nim/
,其中外卡根目录获取方式为 Environment.getExternalStorageDirectory().getPath()
。
如果你的 APP 需要清除缓存功能,可扫描该目录下的文件,按照规则清理即可。 在 SDK 初始化完成后可以通过 NimClient#getSdkStorageDirPath
获取 SDK 数据缓存目录。
SDK数据缓存目录下面包含:
子目录 | 内容 |
---|---|
log | SDK日志文件:如nim_sdk.log,大小一般不超过 8M。 |
image | 图片消息中的原图 |
audio | 语音消息中的音频 |
video | 视频消息中的原视频 |
thumb | 图片/视频消息中的缩略图 |
file | 文件消息中的文件 |
初始化
初始化
将SDK集成到客户端后,使用SDK前需要先完成初始化工作。此外请注意:v6.9.0起,改用AndroidX支持库,Target API 改为28,不再支持support库。
推荐在应用的 Application#onCreate
中,加入 SDK 的初始化代码:
/**
* 在Application#onCreate()中初始化SDK
*
* @param context 调用上下文
* @param info 登录用户信息。如果提供,将同时进行自动登录。如果当前还没有登录用户,请传入null。详见自动登录章节。
* @param options 初始化配置参数
*/
public static void init(Context context, LoginInfo info, SDKOptions options);
示例:
public class NimApplication extends Application {
/**
* 注意:每个进程都会创建自己的Application 然后调用onCreate()方法,
* 如果用户有自己的逻辑需要写在Application#onCreate()(还有Application的其他方法)中,一定要注意判断进程,不能把业务逻辑写在core进程,
* 理论上,core进程的Application#onCreate()(还有Application的其他方法)只能做与im sdk 相关的工作
*/
public void onCreate() {
// ... your codes
// SDK初始化(启动后台服务,若已经存在用户登录信息, SDK 将进行自动登录)。不能对初始化语句添加进程判断逻辑。
NIMClient.init(this, loginInfo(), options());
// ... your codes
// 使用 `NIMUtil` 类可以进行主进程判断。
// boolean mainProcess = NIMUtil.isMainProcess(context)
if (NIMUtil.isMainProcess(this)) {
// 注意:以下操作必须在主进程中进行
// 1、UI相关初始化操作
// 2、相关Service调用
}
}
// 如果提供,将同时进行自动登录。如果当前还没有登录用户,请传入null。详见自动登录章节。
private LoginInfo loginInfo() {
return null;
}
// 设置初始化配置参数,如果返回值为 null,则全部使用默认参数。
private SDKOptions options() {
SDKOptions options = new SDKOptions();
...
// 配置是否需要预下载附件缩略图,默认为 true
options.preloadAttach = true;
...
return options;
}
}
初始化配置参数
初始化时,支持通过SDKOptions
设置部分属性来满足不同的业务需求。
SDKOptions 参数说明:
参数 | 说明 |
---|---|
appKey | 设置云信SDK的appKey。appKey还可以在AndroidManifest文件中,通过meta-data的方式设置。 |
statusBarNotificationConfig | 云信封装的消息提醒配置 |
userInfoProvider | 用户信息提供者,目前主要用于通知栏显示用户昵称和头像 |
messageNotifierCustomization | 通知栏提醒文案定制 |
sdkStorageRootPath | 外置存储根目录,用于存放多媒体消息,日志等文件 如果使用data/user/0/的子目录,在没有存储权限的情况下会导致部分文件操作失败,可以使用data/data/的子目录 |
preloadAttach | 是否需要SDK自动预加载多媒体消息的附件 |
thumbnailSize | 消息缩略图的尺寸 |
sessionReadAck | 是否开启会话已读多端同步 |
improveSDKProcessPriority | 是否提高SDK进程优先级(默认提高,可以降低SDK核心进程被系统回收的概率) |
serverConfig | 配置私有化的服务器地址 |
preLoadServers | 预加载服务,默认true,不建议设置为false,预加载连接可以优化登陆流程 |
teamNotificationMessageMarkUnread | 群通知消息是否计入未读数,默认不计入未读 |
useXLog | 使用性能更好的SDK日志模式。默认使用普通日志模式。 |
animatedImageThumbnailEnabled | 开启对动图缩略图的支持,默认为 false,截取第一帧 |
asyncInitSDK | 是否异步初始化SDK,默认为 false。开启可降低 Application#onCreate 中 SDK 初始化函数的同步响应时间 |
reducedIM | 是否是弱IM场景,默认为 false。如果您的APP 仅在部分场景按需使用 IM 能力(不需要在应用启动时就做自动登录),并不需要保证消息通知、数据的实时性,那么这里可以填 true。弱 IM 场景下,push 进程采用懒启动策略(延迟到用户登录阶段),启动后其生命周期将跟随 UI 进程,降低弱 IM 场景的APP的后台功耗开销。 |
checkManifestConfig | 是否在 SDK 初始化时检查清单文件配置是否完全,默认为 false,建议开发者在调试阶段打开,上线时关掉 |
mixPushConfig | 配置第三方推送appid、appkey、证书 |
enableBackOffReconnectStrategy | 是否使用随机退避重连策略,默认true,强烈建议打开。如需关闭,请咨询云信技术支持。 |
enableLBSOptimize | 是否启用网络连接优化策略,默认开启。 |
enableTeamMsgAck | 是否启用群消息已读功能,默认关闭 |
shouldConsiderRevokedMessageUnreadCount | 撤回消息时未读数减一 |
mNosTokenSceneConfig | nos token 场景配置 |
loginCustomTag | 登录时的自定义字段 , 登陆成功后会同步给其他端 ,获取可参考 AuthServiceObserver#observeOtherClients() |
disableAwake | 禁止后台进程唤醒ui进程 |
fetchServerTimeInterval | 获取服务器时间连续请求间隔时间, 最小1000ms, 默认2000ms |
customPushContentType | 离线推送不显示详情时,要显示的文案对应的类型名称 |
notifyStickTopSession | 置顶会话是否同步 |
enableForegroundService | 启动NimService失败时,是否尝试以前台服务方式启动 |
cdnRequestDataInterval | Cdn信息上报的回调间隔 |
rollbackSQLCipher | 是否回滚SQLCipher加密的数据库 |
coreProcessStartTimeout | core进程启动的超时时间(单位:毫秒) |
clearTimeTagAtBeginning | 是否重置同步时间戳,启动时重置,只重置一次(不建议开启,如需开启请联系技术支持) |
enableDatabaseBackup | 是否开启数据库备份功能 |
captureDeviceInfoConfig | 设备信息获取配置 null代表都可以获取 不获取设备信息可能影响功能,使用请联系技术支持 |
secondTimeoutForSendMessage | 发消息的第二超时时间,非常规功能,开启请联系技术支持 |
enableRecentContactsTimeIndex | 是否开启最近联系人会话时间索引,默认不开启,开启最近联系人会话时间索引后会明显减少查询最近联系人会话耗时,但是同时也会增加最新联系人会话写入操作耗时。 |
notificationChannelProvider | 可配置通知要走的通道,如果不配置,根据响铃振动等配置走对应默认通道 |
enableFcs | 是否支持aws s3存储,默认开启 |
fcsDownloadAuthStrategy | aws s3存储下载鉴权策略,如需开启,请咨询云信技术支持 |
enabledQChatMessageCache | 是否开启圈组消息缓存支持,默认不开启 |
特别提醒:SDK 的初始化方法必须在主进程中调用,在非主进程中初始化无效。请在主进程中调用 SDK XXXService 提供的方法,在主进程中注册 XXXServiceObserver的观察者(有事件变更,会回调给主进程的主线程)。
任意位置初始化SDK
v5.0.0版本开始支持在任意位置初始化SDK,一方面能够降低在Application.onCreate中初始化的耗时,另一方面为了更充分的支持按需使用的弱IM场景。采用此方式初始化SDK,将采用以下两个接口:
- NIMClient#config, 在Application#onCreate()中配置SDK(仅仅是配置,不影响性能)
- NIMClient#initSDK, 在UI进程主线程上按需使用的初始化SDK,但不要放在Application#onCreate中。
还可以通过以下配置,
- 通过SDKOptions#asyncInitSDK 支持SDK的异步初始化(NIMClient#initSDK)
- 通过SDKOptions#reducedIM 支持延迟加载push进程服务
与在Application#onCreate中初始化SDK相比,新的方式不再需要做进程判断,SDKOptions的应用方式相同。
初始化状态监听
可以通过以下接口来监听当前登录状态:
/**
* 监听主进程初始化状态<br>
* 注册时,如果主进程以及处于初始化完成状态,Observer的onEvent方法会被立即调用一次,告知观察者当前状态。
*
* @param observer 观察者, 参数为当前状态
* @param register true为注册,false为注销
*/
void observeMainProcessInitCompleteResult(Observer<Boolean> observer, boolean register);
- 示例
NIMClient.getService(SdkLifecycleObserver.class).observeMainProcessInitCompleteResult(new Observer<Boolean>() {
@Override
public void onEvent(Boolean aBoolean) {
if (aBoolean != null && aBoolean) {
// 主进程初始化完毕,可以开始访问数据库
...
}
}
}, true);
登录
在调用SDK登录接口之前,需要先完成IM账号的注册(注册一次即可),为应用下的每一位IM用户注册一个唯一的账号(account,又称accid)。推荐开发者首先阅读这里来加深对云信账号体系流程的认知。 目前,云信提供两种注册方式:
- 方式1:调用服务端API注册接口完成注册,目前推荐使用该方式。
- 方式2:网易云信控制台页面手动注册。进入相应的
云信应用->功能管理->IM免费版->账号管理
。注意:此方法仅为调试阶段使用。IM专业版暂不支持此功能。
手动登录
在新设备上初次登录,以及被踢、切换账号与注销登录后下一次登录,需要使用手动登录。对应用户手动输入登录账号密码的场景。
/**
* 登录接口。sdk会自动连接服务器,传递用户信息,返回登录结果。
* 该操作中途可取消。如果因为网络比较差,或其他原因导致服务器迟迟没有返回,用户也没有主动取消,
* 在45秒后AbortableFuture的onFailed会被调用到。
*
* @param info 登录的用户信息
* @return AbortableFuture
*/
public AbortableFuture<LoginInfo> login(LoginInfo info);
- 参数说明
LoginInfo 参数 | 说明 |
---|---|
account | 用户帐号 |
token | 登录 token |
authType(可选) | SDK认证类型 0:最初的loginToken的校验方式(默认) 1:基于appSecret计算的token鉴权方式 2:基于第三方回调的token鉴权方式 |
loginExt(可选) | 登陆自定义字段 authType为2时使用该字段内容去第三方服务器鉴权 |
appKey(可选) | 当前应用的 appKey,一个 appKey 对应一个账号体系。 如果不填,则优先使用 SDKOptions 中配置的 appKey, 如果没有则使用 AndroidManifest 中配置的appKey |
customClientType(可选) | 自定义客户端类型 |
- 示例
public class LoginActivity extends Activity {
public void doLogin() {
LoginInfo info = new LoginInfo();
RequestCallback<LoginInfo> callback =
new RequestCallback<LoginInfo>() {
@Override
public void onSuccess(LoginInfo param) {
LogUtil.i(TAG, "login success");
// your code
}
@Override
public void onFailed(int code) {
if (code == 302) {
LogUtil.i(TAG, "账号密码错误");
// your code
} else {
// your code
}
}
@Override
public void onException(Throwable exception) {
// your code
}
};
//执行手动登录
NIMClient.getService(AuthService.class).login(info).setCallback(callback);
}
}
针对 onFailed 中的错误码说明如下:
错误码 | 说明 |
---|---|
302 | appKey/account/token 三者不对应导致 |
408 | 连接超时 |
415 | 网络断开或者与云信服务器建立连接失败 |
416 | 调用频次过高 |
1000 | 登录成功之前,调用本地数据库相关接口(手动登录的情况下数据库未打开) |
自动登录
手动登录成功后,保存至本地的用户账号和密码,可用作自动登录时使用。自动登录主要针对应用被清理掉后,如再次点击图标等启动时,无需输入用户名密码即可完成登录的场景。此时可以在无网络,未登录成功的状态下直接访问用户本地SDK数据。
// 在初始化SDK的时候,将本地所存的account与token传入loginInfo(),用以自动登录
NIMClient.init(this, loginInfo(), options());
- 示例
public class NimApplication extends Application {
public void onCreate() {
// ... your codes
NIMClient.init(this, loginInfo(), options());
// ... your codes
}
private LoginInfo loginInfo() {
// 从本地读取上次登录成功时保存的用户登录信息
String account = Preferences.getUserAccount();
String token = Preferences.getUserToken();
if (!TextUtils.isEmpty(account) && !TextUtils.isEmpty(token)) {
DemoCache.setAccount(account.toLowerCase());
return new LoginInfo(account, token);
} else {
return null;
}
}
}
动态登录
8.3.0 之前的版本用户登录的凭据为accid
和token
,该token
为静态token
,一经生成不会随时间变更,除非开发者主动变更。一旦泄露,用户隐私会持续遭遇风险。8.3.0 版本新增动态登录策略,token
具备时效性,可有效提升token
破解难度,有效降低密码泄露影响。
8.3.0 通过LogInfo
新增authType
支持动态登录。
authType
设为1
,需同时设置SDKOption.AuthProvider
用于提供动态token
。该token
通过约定算法由appsecret
、时间戳等信息生成。
登录状态监听
可以通过以下接口来监听当前登录状态:
/**
* 注册/注销在线状态变化观察者。
* 注册后,Observer的onEvent方法会被立即调用一次,告知观察者当前状态。
*
* @param observer 观察者, 参数为当前状态
* @param register true为注册,false为注销
*/
public void observeOnlineStatus(Observer<StatusCode> observer, boolean register);
- 参数说明
StatusCode为一个包含多个属性的枚举类型,每个属性包含一个int类型的value和一个String类型的desc。服务端踢人时如果配置描述字段,在此回调中会表现在desc变量中。
StatusCode属性 | 说明 |
---|---|
INVALID | 未定义 |
UNLOGIN | 未登录/登录失败 |
NET_BROKEN | 网络连接已断开 |
CONNECTING | 正在连接服务器 |
LOGINING | 正在登录中 |
SYNCING | 正在同步数据 |
LOGINED | 已成功登录 |
KICKOUT | 被其他端的登录踢掉,此时应该跳转至手动登录界面 |
KICK_BY_OTHER_CLIENT | 被同时在线的其他端主动踢掉,此时应该跳转至手动登录界面 |
FORBIDDEN | 被服务器禁止登录 |
VER_ERROR | 客户端版本错误 |
PWD_ERROR | 用户名或密码错误 |
DATA_UPGRADE | 数据库需要迁移到加密状态(类似被踢出、账号被禁用、密码错误等情况,自动登录失败,需要返回到登录界面进行重新登录操作) |
- 示例
NIMClient.getService(AuthServiceObserver.class).observeOnlineStatus(
new Observer<StatusCode> () {
public void onEvent(StatusCode status) {
//获取状态的描述
String desc = status.getDesc();
if (status.wontAutoLogin()) {
// 被踢出、账号被禁用、密码错误等情况,自动登录失败,需要返回到登录界面进行重新登录操作
}
}
}, true);
主动查询登录状态
SDK支持主动查询当前账号是否处于在线状态:
/**
* 获取当前用户状态
*
* @return 当前状态
*/
public static StatusCode getStatus();
数据同步
SDK 在登录成功后,会自动同步群信息,离线消息,漫游消息,系统通知等数据。数据同步过程可以通过以下接口监听:
/**
* 注册/注销登录后同步数据过程通知
*
* @param observer 观察者,参数为同步数据的过程状态(开始/结束)
* @param register true为注册,false为注销
*/
public void observeLoginSyncDataStatus(Observer<LoginSyncStatus> observer, boolean register);
- 参数说明
LoginSyncStatus属性 | 说明 |
---|---|
NO_BEGIN | 未开始 |
BEGIN_SYNC | 开始同步(正在同步)。 同步开始时,SDK 数据库中的数据可能还是旧数据。 (如果是首次登录,那么 SDK 数据库中还没有数据, 重新登录时 SDK 数据库中还是上一次退出时保存的数据) 在同步过程中,SDK 数据的更新会通过相应的监听接口发出数据变更通知。 |
SYNC_COMPLETED | 同步完成 。SDK 数据库已完成更新 |
- 示例
NIMClient.getService(AuthServiceObserver.class).observeLoginSyncDataStatus(new Observer<LoginSyncStatus>() {
@Override
public void onEvent(LoginSyncStatus status) {
if (status == LoginSyncStatus.BEGIN_SYNC) {
LogUtil.i(TAG, "login sync data begin");
} else if (status == LoginSyncStatus.SYNC_COMPLETED) {
LogUtil.i(TAG, "login sync data completed");
}
}
}, register);
在数据同步完成后,整个登录过程才算真正完成。
断网重连
SDK 提供了自动重连机制(自动重新建立与云信服务器的连接并重新登录),所有重连的登录状态变更都会在 observeOnlineStatus
方法中回调。
SDK 在两种场景下会自动进行重连:
- 手动/自动登录成功后,网络不佳导致链接断开的情况。
- 网络不佳时,账号密码本身正常(未被封禁,且账号密码均正确),启动App时调用自动登录接口的情况。
满足上述中一个条件,当用户遇到普通网络问题如连接超时等,会自动进行重连登录,不需要上层开发者去做额外的重登逻辑。
多端登录与互踢
云信SDK支持配置多种多端登录策略:
- 只允许一端登录
- 桌面PC与Web端互踢、移动Android和iOS端互踢、桌面与移动端同时登录。
- 如果SDK相同,互踢;
- Windows SDK和Web SDK为一类,Android SDK和iOS SDK为另一类,这两类之间,同类互踢,不同类不互踢。
- 各端均可以同时登录在线(最多10个设备同时在线)
多端登录监听
登录成功后,可以注册多端登录状态观察者。
/**
* 注册/注销多端登录状态观察者。
*
* @param observer 观察者,参数为同时登录的其他端信息。
* 如果有其他端注销,参数为剩余的在线端。如果没有剩余在线端了,参数为null。
* @param register true为注册,false为注销
*/
public void observeOtherClients(Observer<List<OnlineClient>> observer, boolean register);
- 参数说明
参数 | 说明 |
---|---|
observer | 观察者,参数为同时登录的其他端信息。 如果有其他端注销,参数为剩余的在线端。 如果没有剩余在线端了,参数为 null。 |
register | 是否注册观察者,注册为 true, 注销为 false |
OnlineClient 接口说明:
返回值 | 方法 | 说明 |
---|---|---|
String | getOs() | 客户端的操作系统信息 |
int | getClientType() | 客户端类型 |
long | getLoginTime() | 登录时间 |
String | getClientIp() | 客户端 IP |
String | getCustomTag() | 登录自定义属性 |
- 示例
Observer<List<OnlineClient>> clientsObserver = new Observer<List<OnlineClient>>() {
@Override
public void onEvent(List<OnlineClient> onlineClients) {
if (onlineClients == null || onlineClients.size() == 0) {
return;
}
OnlineClient client = onlineClients.get(0);
switch (client.getClientType()) {
case ClientType.Windows:
// PC端
break;
case ClientType.MAC:
// MAC端
break;
case ClientType.Web:
// Web端
break;
case ClientType.iOS:
// IOS端
break;
case ClientType.Android:
// Android端
break;
default:
break;
}
}
};
NIMClient.getService(AuthServiceObserver.class).observeOtherClients(clientsObserver, true);
互踢
SDK支持本端主动踢掉其他登录端:
/**
* 踢掉多端同时在线的其他端
* @param client 被踢端信息
* @return InvocationFuture 可设置回调函数,监听操作结果。
*/
public InvocationFuture<Void> kickOtherClient(OnlineClient client);
- 示例
NIMClient.getService(AuthService.class).kickOtherClient(client).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
// 踢出其他端成功
}
@Override
public void onFailed(int code) {
// 踢出其他端失败,返回失败code
}
@Override
public void onException(Throwable exception) {
// 踢出其他端错误
}
});
当被其他端踢掉,可以通过observeOnlineStatus
来监听。收到被踢回调后,建议进行注销并切换到登录界面。
此外,还可以通过 AuthService 的getKickedClientType() 方法来获取发起踢掉登录的客户端类型;通过getKickedCustomClientType()方法来获取发起踢掉登录的自定义客户端类型。
注销登录
应用登出/注销自己的账号时需要调用 SDK 的登出操作,该方法没有回调。注意: 登出操作,不要放在 Activity(Fragment) 的 onDestroy 方法中。
/**
* 注销接口
*/
public void logout();
- 示例
NIMClient.getService(AuthService.class).logout();
其他辅助方法
- 离线查看数据
对于一些弱 IM 场景,需要在登录成功前或者未登录状态下访问指定账号的数据(聊天记录、好友资料等)。 SDK 提供两种方案:
-
使用自动登录。在登录成功前,可以访问 SDK 服务来读取本地数据(但不能发送数据)。
-
使用
AuthService#openLocalCache
接口打开本地数据,这是一个同步方法,打开后即可读取 SDK 数据库中的记录。可以通过注销来切换账号查看本地数据。
/**
* 离线时打开本地数据
* 适用场景:在手动登录没有成功前(可能由于网络问题,登录时间较长),可以访问SDK本地数据。
* 此外,不调用本接口,采用自动登录也能达到同样的效果。
*
* @return 是否成功打开SDK本地数据
*/
public boolean openLocalCache(String account);
- 获取SDK版本号
NIMClient
中提供获取版本号的方法:
/**
* 运行时获取当前 SDK 版本号
*
*/
public static java.lang.String getSDKVersion();
- 查询云信服务器当前时间
MiscService
中提供查询云信服务器当前时间的方法:
/**
* 获取服务器时间 当前服务器时间戳,有频控限制。如果处于频控限制内,返回的时间为上一次获取时间+两次时间的偏移量。接口频控限制为1秒/次。
*
*/
InvocationFuture<java.lang.Long> getServerTime();