云信im在Android中的使用2

昨天写的是云信IM版本的V10以上的,但是我目前项目使用的是V9也就是V10以下的版本,两者在使用方式上还是有所区别的,所以今天想了想,还是写一篇V10以下的,也贴上自己的一些代码,比较有参考性

一、首先我们先贴出云信IM官网的首页(https://doc.yunxin.163.com/messaging/guide?platform=android)

官网是有给出demo,第一次使用的可以先下载demo,先跑看看,体验一下

我使用的是IM Demo

主要是项目只需要用到消息模块,单聊,群聊,通讯录等,语聊方面我们项目使用的是ZEGO即构,不是云信

二、根据以上需要的功能,我们就在项目来集成并使用
1.我们的集成方式是通过 Gradle 自动集成,也是推荐的集成方式
复制代码
allprojects {
    repositories {
        mavenCentral()
    }
}

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

dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')
    // 添加依赖。注意,版本号必须一致。

    // 基础功能 (必需)
    implementation "com.netease.nimlib:basesdk:${LATEST_VERSION}"

    // 聊天室需要
    implementation "com.netease.nimlib:chatroom:${LATEST_VERSION}"

    // 通过网易云信来集成小米等厂商推送需要
    implementation "com.netease.nimlib:push:${LATEST_VERSION}"

    // 超大群需要
    implementation "com.netease.nimlib:superteam:${LATEST_VERSION}"

    // 全文检索插件
    implementation "com.netease.nimlib:lucene:${LATEST_VERSION}"

    // 海外融合存储需要
    // 该功能仅支持 Gradle 集成,不提供手动集成方式
    implementation "com.netease.nimlib:fusionstorage:${LATEST_VERSION}"
    implementation "com.google.code.gson:gson:${GSON_VERSION}" // Gson 推荐版本 2.8.9
}
2.添加权限

使用云信IM的相关功能是需要一定的权限

复制代码
<?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" />


    <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.push.net.HeartbeatService"
				android:process=":core"
				/>
		
		<!-- 声明云信后台辅助服务 -->
		<service
				android:name="com.netease.nimlib.job.NIMJobService"
				android:exported="false"
				android:permission="android.permission.BIND_JOB_SERVICE"
				android:process=":core"
				/>
		
		<!-- 云信SDK的监视系统启动和网络变化的广播接收器,用户开机自启动以及网络变化时候重新登录 -->
		<receiver
				android:name="com.netease.nimlib.service.NimReceiver"
				android:exported="false"
				android:process=":core"
				>
			<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.cp.provider.PreferenceContentProvider"
				android:authorities="${applicationId}.ipc.provider.preference"
				android:exported="false"
				/>
		<provider
				android:name="com.netease.nimlib.ipc.NIMContentProvider"
				android:authorities="${applicationId}.ipc.provider"
				android:exported="false"
				android:process=":core"
				/>
    </application>
</manifest>
3.添加混淆

不然在项目打包时会被混淆,所以需要防止被混淆

复制代码
-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.** {*;}

三、云信IM初始化

以上通过集成完后,我们就需要在项目进行相关的初始化

复制代码
public class NimApplication extends Application {

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

以上是官网给出的初始化方式和建议

以下是我们项目的初始化方式:

复制代码
object HaTioNimConfig {

    private var isInitNimConfig = false

    /**
     * 云信im SDK/NimClient 配置 初始化
     */
    fun initNimSDKConfig(context: Context) {
        if (!isInitNimConfig) {
            isInitNimConfig = true
            //云信im 初始化
            NIMClient.init(context, getLoginSuccessInfo(), initNimSDKOptionsSettings(context))
            //通知栏消息提醒开关
            NIMClient.toggleNotification(true)
            //注册云信im 的 相关事件注册
            registerNimIM(context)
        }
    }

    /**
     * 获取登录成功的信息
     */
    private fun getLoginSuccessInfo(): LoginInfo? {
        val account: String = HaTioModuleManager.getUserProvider()?.getLoginInfo()?.id ?: ""
        val token: String = HaTioModuleManager.getUserProvider()?.getLoginInfo()?.imToken ?: ""
        HaTioLog.d("getTopImLogin 云信登录  --> account=$account")
        HaTioLog.d("getTopImLogin 云信登录  --> token=$token")
        return if (!TextUtils.isEmpty(account) && !TextUtils.isEmpty(token)) {
            LoginInfo(account, token)
        } else {
            null
        }
    }

    /**
     * 云信sdk 相关数据 配置
     */
    private fun initNimSDKOptionsSettings(context: Context): SDKOptions {
        val options = SDKOptions()
        options.appKey = AppConfigManager.appKey
        options.notifyStickTopSession = false //客户端会话置顶
        options.disableAwake = true
        options.sessionReadAck = true
        options.serverConfig = initServerConfig()
        options.sdkStorageRootPath = initSdkStorageRootPath(context)
        options.messageNotifierCustomization = initMessageNotifierCustomization()
        val notificationConfig = initStatusBarNotificationConfig()
        notificationConfig.titleOnlyShowAppName = true
        options.statusBarNotificationConfig = notificationConfig
        return options
    }

}

class HaTioMessageInit : IHaTioInit {

    //todo 初始化消息相关sdk
    override fun onInitModuleSdk(application: Application?) {
        application?.let {
            HaTioNimConfig.initNimSDKConfig(it)
        }
    }
}

class HaTioInitConfig {

    companion object {
        val instance: HaTioInitConfig by lazy { HaTioInitConfig() }

        val LoginInit = "com.nim.imchat.HaTioLoginInit"
        val MsgInit = "com.nim.imchat.HaTioMessageInit"
        val UserInit = "com.nim.imchat.HaTioUserInit"
        val initModuleNames = arrayOf(LoginInit, MsgInit,UserInit)
    }

    fun initModuleSdk(application: Application?){
        for (moduleInitName in initModuleNames) {
            try {
                val clazz = Class.forName(moduleInitName)
                val init = clazz.getDeclaredConstructor().newInstance() as IHaTioInit
                // 调用初始化方法
                init.onInitModuleSdk(application)
            } catch (e: ClassNotFoundException) {
                e.printStackTrace()
            } catch (e: InstantiationException) {
                e.printStackTrace()
            } catch (e: IllegalAccessException) {
                e.printStackTrace()
            }
        }
    }
}

然后在Application中调用

复制代码
HaTioInitConfig.instance.initModuleSdk(this)

四、登录IM

初始化以后,就可以登录IM,只有登录成功后才可以获取IM的相关信息

我们项目的逻辑是,先登录自己的接口,成功后再通过登录成功返回的信息去登录云信IM

复制代码
fun loginApp(
        username: String = "",
        captcha: String
    ) {
        val map = hashMapOf<String, Any>()
        map["username"] = username
        map["captcha"] = captcha

        launchReqCall(
            block = { HaTioLoginRepository.loginApp(map) },
            onSuccess = { userInfo ->
                HaTioModuleManager.getMessageProvider()
                    ?.tioImLogin(account = userInfo?.id ?: "", token = userInfo?.imToken ?: "") {
                        if (it) {
                            //云信登录成功
                        }else{
                            //云信登录失败
                        }
                    }
            },
            onFail = { code, msg, status ->
                _userLoginInfo.tryEmit(null)
            },
            loadVisible = true,  
            errorToast = true,   
            successToast = false 
        )
    }

class HaTioMsgImpl : IHaTioMessageProvider {

    override fun init(context: Context?) {

    }

    override fun tioImLogin(
        account: String,
        token: String,
        callback: ((Boolean) -> Unit)?
    ) {
        HaTioLog.d("云信登录 account $account token $token")
        val loginInfo = LoginInfo(account, token)
        NIMClient.getService(AuthService::class.java).login(loginInfo)
            .setCallback(object : RequestCallback<LoginInfo> {
                override fun onSuccess(result: LoginInfo) {
                    HaTioLog.d("云信登录 onSuccess ${result.toJson()}")
                    callback?.invoke(true)
                }

                override fun onFailed(code: Int) {
                    HaTioLog.d("云信登录 onFailed $code")
                    callback?.invoke(false)
                }

                override fun onException(exception: Throwable) {
                    HaTioLog.d("云信登录 onException ${exception.message}")
                    callback?.invoke(false)
                }
            })
    }

    override fun timImLogout(callback: ((Boolean) -> Unit)?) {
        NIMClient.getService(AuthService::class.java).logout(3 * 1000L)
            .setCallback(object : RequestCallback<Void> {
                override fun onSuccess(param: Void?) {
                    HaTioLog.d("云信登出 onSuccess")
                    callback?.invoke(true)
                }

                override fun onFailed(code: Int) {
                    HaTioLog.d("云信登出 onFailed $code")
                    callback?.invoke(false)
                }

                override fun onException(exception: Throwable) {
                    HaTioLog.d("云信登出 onException ${exception.message}")
                    callback?.invoke(false)
                }
            })
    }
}
五、登录成功后,就可以获取消息列表、聊天列表等

比如:

我们来获取消息列表

复制代码
NIMSDK.getMsgService().queryRecentContacts(
            queryAnchor,
            QueryDirectionEnum.QUERY_OLD,
            pageSize
        ).setCallback(object : RequestCallbackWrapper<List<RecentContact>>() {
            override fun onResult(code: Int, result: List<RecentContact>?, exception: Throwable?) {
                HaTioLog.d("queryRecentContacts code=$code; size=${result?.size} data=${result?.toJson()}}")

               
                    }
                }
            }
        })

我们来获取会话列表(聊天列表)

复制代码
NIMClient.getService(MsgService::class.java)
            .queryMessageListEx(
                iMMessage ?: haTioCreateDefaultNimMsg(chatImId, chatType),
                QueryDirectionEnum.QUERY_OLD,
                limit,
                true
            ).setCallback(object : RequestCallback<List<IMMessage>> {
                override fun onSuccess(result: List<IMMessage>) {
                    
                }

                override fun onFailed(code: Int) {}

                override fun onException(exception: Throwable?) {}

            })

其他的功能,根据官网给出的API来操作就好了

客户端的API:https://doc.yunxin.163.com/messaging/client-apis?platform=android

服务端的API:https://doc.yunxin.163.com/messaging/server-apis?platform=server

相关推荐
2501_915918414 小时前
iOS 混淆与 IPA 加固一页式行动手册(多工具组合实战 源码成品运维闭环)
android·运维·ios·小程序·uni-app·iphone·webview
不吃凉粉11 小时前
Android Studio USB串口通信
android·ide·android studio
zhangphil11 小时前
android studio设置大内存,提升编译速度
android·android studio
编程乐学13 小时前
安卓非原创--基于Android Studio 实现的天气预报App
android·ide·android studio·课程设计·大作业·天气预报·安卓大作业
大熊的瓜地14 小时前
Android automotive 框架
android·android car
私人珍藏库15 小时前
[Android] Alarm Clock Pro 11.1.0一款经典简约个性的时钟
android·时钟
消失的旧时光-194317 小时前
ScheduledExecutorService
android·java·开发语言
小糖学代码17 小时前
MySQL:14.mysql connect
android·数据库·mysql·adb
怪兽201419 小时前
请谈谈什么是同步屏障?
android·面试
帅锅锅00720 小时前
SeLinux 全面详解
android·linux