[Android][IM Instant Messaging] Android development integration quick start

Reference connection

https://blog.csdn.net/qq_32090185/article/details/89307710

 

SDK integration

Yunxin instant messaging Android-SDK supports two integration methods:

  • Automatic integration via Gradle (recommended)

  • By downloading the SDK , then manually integrate it into your project.

In addition, in order to allow developers to easily and quickly integrate IM functions in the App, we also provide open source UI components , which can realize the chat function through simple configuration.

Gradle integration

First, in the build.gradle file of the entire project, configure repositories, use jcenter or maven, choose one of the two, as follows:

allprojects {
    repositories {
        jcenter() // 或者 mavenCentral()
    }
}

Then, in the build.gradle file of the main project, add dependencies.

android {
   defaultConfig {
       ndk {
           //设置支持的SO库架构
           abiFilters "armeabi-v7a", "x86","arm64-v8a","x86_64"
        }
   }
}

Then add different dependencies according to the needs of your own project. Note: The component version numbers of Yunxin must be consistent. You can check the current latest version on the SDK download page. Take the xxx version as an example:

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'

    // 数据库加密
    implementation 'net.zetetic:android-database-sqlcipher:3.5.9'
}

Manual integration

First enter the SDK download page to complete the download, and then copy the corresponding SDK files to the libs directory of your project as needed to complete the configuration.

The SDK file description is as follows:

libs
├── arm64-v8a
│   ├── libne_audio.so          //语音消息录制功能,必需
│   ├── traceroute.so          //网络探测功能,必需
├── armeabi-v7a
│   ├── libne_audio.so
│   ├── traceroute.so
├── x86
│   ├── libne_audio.so
│   ├── traceroute.so
├── x86_64
│   ├── libne_audio.so
│   ├── traceroute.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          //通过云信来集成小米等厂商推送时需要

Note :

  1. To use the database encryption function, you also need to import the dependent library'net.zetetic:android-database-sqlcipher:3.5.9' through gradle.
  2. traceroute.so needs to be downloaded separately, download address

Permissions and components

In AndroidManifest.xmladding the following configuration ( please com.netease.nim.demo replace with your own package name ) :

<?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"/>
    <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.intent.action.BOOT_COMPLETED"/>
                <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>

Obfuscated configuration

If your apk will eventually be obfuscated, please add the following code to the proguard configuration file:

-dontwarn com.netease.**
-keep class com.netease.** {*;}

#如果你使用全文检索插件,需要加入
-dontwarn org.apache.lucene.**
-keep class org.apache.lucene.** {*;}

#如果你开启数据库功能,需要加入
-keep class net.sqlcipher.** {*;}

Instructions for use

Interface introduction

The SDK provides two types of interfaces for developers to use:

The first type is to initiate a request actively,

The second category is to monitor events and changes as observers.

The first interface names are Serviceending, for example AuthService,

The second type interface names are ServiceObserverending, for example AuthServiceObserver, individual long class names may direct to Observerthe end, for example SystemMessageObserver.

SDK interface calls must, call the main process in the main process SDK XXXServicemethods provided,

In the process of registering the main XXXServiceObserverobserver (an event change, calls back to the main thread of the main process).

If your module is running in a non-main process, please implement the communication between the main process and the non-main process by yourself ( AIDL/Messenger/ContentProvider/BroadcastReceiver等IPC渠道) pass the data returned by the main process callback or monitoring to the non-main process.

The SDK provides three interface return values:

Basic data type (synchronous interface),

InvocationFuture (asynchronous interface)

AbortableFuture (asynchronous interface).

Asynchronous interfaces are basically called from the main process, and then executed in the background process, and finally the result is returned to the main process.

SDK interface return value Description
Basic data type Synchronous interface
InvocationFuture Asynchronous interface
AbortableFuture Asynchronous interface, used when it takes a long time or when transferring a large amount of data, you can use the abort() method to interrupt the request. For example, upload and download, login, etc.

Asynchronous interface can set callback function, providing two methods: RequestCallback and RequestCallbackWrapper.

Asynchronous interface callback function Description
RequestCallback Need to implement 3 interfaces:
success onSuccess, failure onFailed, exception onException
RequestCallbackWrapper Need to implement onResult. Three interfaces of success, failure and exception are encapsulated, and the parameters are distinguished
  • SDK 4.4.0 API call framework enhancement:
    • Support asynchronous API calls initiated by non-UI threads with Looper, and directly call back to the caller thread. The old version will call back to the UI thread by default.
    • Provide an interface for forced conversion from asynchronous to synchronous: NIMClient#syncRequest, which allows you to set the maximum synchronization waiting time, and supports scenarios that require synchronous calls to Yunxin API in non-UI threads.
    • Add the automatically generated NIMSDK class, developers can directly use the NIMSDK#getXXXService method to obtain the service interface, no longer need to pass XXXService.class, simplify the API call method. The call entry classes automatically generated by other plug-ins are: NIMChatRoomSDK, NIMLuceneSDK. Example, using NIMSDK.getAuthService().login()replacement NIMClient.getService(AuthService.class).login().

Data cache directory

When a multimedia message is received, the SDK will download some related files by default.

At the same time, the SDK also records some key log files, so the SDK needs a data cache directory.

The directory can be initialized when the SDK SDKOptions#sdkStorageRootPathset.

In the starting SDK 4.4.0 version, if a developer configuration Context#getExternalCacheDirand Context#getExternalFilesDirunder applications such as extended stored cache directory (ie /sdcard/Android/data/{package}),

The write permission will no longer be checked inside the SDK. It is worth noting that the files in the cache directory will be deleted as the App is uninstalled, and can also be manually cleared by the user in the setting interface.

If not set, the default is /{外卡根目录}/{应用包名}/nim/, where the root directory of the wild card is obtained Environment.getExternalStorageDirectory().getPath().

If your APP needs to clear the cache function, you can scan the files in this directory and clean up according to the rules. By SDK initialization is complete after NimClient#getSdkStorageDirPathobtaining SDK data cache directory.

The SDK data cache directory contains:

Subdirectory content
log SDK log file: such as nim_sdk.log, the size generally does not exceed 8M.
image Original image in picture message
audio Audio in voice messages
video Original video in video message
thumb Thumbnails in picture/video messages
file File in file message

initialization

initialization

After integrating the SDK into the client, you need to complete the initialization work before using the SDK.

In addition, please note: Starting from v6.9.0, the AndroidX support library is used, the Target API is changed to 28, and the support library is no longer supported .

Recommended in applications Application#onCreatein the SDK initialization code:

/**
 * 在Application#onCreate()中初始化SDK
 *
 * @param context 调用上下文
 * @param info 登录用户信息。如果提供,将同时进行自动登录。如果当前还没有登录用户,请传入null。详见自动登录章节。
 * @param options 初始化配置参数
 */
public static void init(Context context, LoginInfo info, SDKOptions options);

Example:

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;
    }
}

Initialize configuration parameters

During initialization, it supports SDKOptionssetting some attributes to meet different business requirements.

SDKOptions parameter description:

parameter Description
appKey Set the appKey of Yunxin SDK. The appKey can also be set in the AndroidManifest file through meta-data.
statusBarNotificationConfig Yunxin encapsulated message reminder configuration
userInfoProvider User information provider, currently mainly used to display user nicknames and avatars in the notification bar
messageNotifierCustomization Notification bar reminder copywriting customization
sdkStorageRootPath External storage root directory for storing multimedia message files
preloadAttach Do you need the SDK to automatically preload the attachments of multimedia messages?
thumbnailSize The size of the message thumbnail
sessionReadAck Whether to open the multi-terminal synchronization of the read session
improveSDKProcessPriority Whether to increase the SDK process priority (increased by default, can reduce the probability of SDK core process being recycled by the system)
serverConfig Configure the privatized server address
preLoadServers Preload service, the default is true, it is not recommended to set to false, preload connection can optimize the login process
teamNotificationMessageMarkUnread Whether group notification messages are counted as unread, the default is not counted as unread
useXLog Use the SDK log mode with better performance. The normal log mode is used by default.
animatedImageThumbnailEnabled Enable support for GIF thumbnails, the default is false, and the first frame is captured
asyncInitSDK Whether to initialize the SDK asynchronously, the default is false. Turn it on to reduce the synchronization response time of the SDK initialization function in Application#onCreate
reducedIM Whether it is a weak IM scene, the default is false. If your APP only uses IM capabilities on-demand in some scenarios (you do not need to log in automatically when the application starts), and you do not need to ensure the real-time performance of message notifications and data, you can fill in true here. In the weak IM scenario, the push process adopts a lazy startup strategy (delayed to the user login stage), and its life cycle will follow the UI process after startup, reducing the background power consumption of the APP in the weak IM scenario.
checkMainifestConfig Whether to check whether the manifest file configuration is complete when the SDK is initialized, the default is false, it is recommended that developers turn it on during the debugging phase and turn it off when online
mixPushConfig Configure third-party push appid, appkey, certificate
enableBackOffReconnectStrategy Whether to use the random backoff reconnection strategy, the default is true, it is strongly recommended to enable it. If you need to close it, please consult Yunxin technical support.
enableLBSOptimize Whether to enable the network connection optimization strategy, it is enabled by default.
enableTeamMsgAck Whether to enable the group message read function, it is disabled by default
shouldConsiderRevokedMessageUnreadCount Unread reading minus one when the message is withdrawn
mNosTokenSceneConfig nos token scenario configuration
loginCustomTag 登录时的自定义字段 , 登陆成功后会同步给其他端 ,获取可参考 AuthServiceObserver#observeOtherClients()
disableAwake 禁止后台进程唤醒ui进程
fetchServerTimeInterval 获取服务器时间连续请求间隔时间, 最小1000ms, 默认2000ms
customPushContentType 离线推送不显示详情时,要显示的文案对应的类型名称
notifyStickTopSession 置顶会话是否同步
databaseEncryptKey 数据库加密秘钥,用于消息数据库加密。
如果不设置,数据库不开启加密存储。设置后,数据库开启加密存储;如果开启时有旧数据,旧数据自动迁移为加密数据。一旦开启加密,无法退回到不加密状态。
如果开启数据库加密,需要手动拷贝相应so和jar文件,并需要增加相应'混淆配置'。'StatusCode'增加一个新状态值'DATA_UPGRADE',标明当前数据库需要迁移到加密。

任意位置初始化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
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;
        }
    }
}

登录状态监听

可以通过以下接口来监听当前登录状态:

/**
 * 注册/注销在线状态变化观察者。
 * 注册后,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();

本篇文档内容是否对您有帮助?

 

 

Guess you like

Origin blog.csdn.net/xfb1989/article/details/111637535