最近正在集成融云即时通信功能,因为公司先开发的iOS平台,再开发的安卓,而iOS更喜欢用融云,而不是环信,所以我也不得不学习使用融云。这次其实也是被iOS坑的比较惨的一次,以前在别的公司是因为UI要和iOS统一,那才叫一步一个坑呢,在这里要感谢下现在明智的UI,真的不必什么都追随iOS。
首先要说明的是在融云平台不必申请两个app,因为本来就是一个软件,申请两个app,得到的两个appid之间怎么能互相发消息呢,对于没有项目经理的我们,这个一定要知道的。
其次是融云生产环境和开发环境用的不是一对app key和secret,开发的时候可以区分使用,防止测试消息跑到正式上线环境中。
第一步:集成
1,module的gradle文件中加入:
compile 'cn.rongcloud.android:IMLib:2.8.6' compile 'cn.rongcloud.android:IMKit:2.8.6' compile 'cn.rongcloud.android:CallLib:2.8.6' compile 'cn.rongcloud.android:CallKit:2.8.6'这是我目前的版本。
2,manifest文件中加入:
官方在provider中没有tools:replace="authorities",meta-data中也没有tools:replace="android:resource",
这是因为我集成了一个第三方的拍照和从相册选取照片的框架,他们都使用了文件系统导致的,所以才加了这两句,你 没有集成的话不需要。
3, Application中初始化:
RongIM.init(this);
好了,切入正题,发消息,在这之前呢用户登录成功以后要先拿到本用户在融云的唯一标识token,这个工作本来融云说是app server的工作,可是他不干,非要我们自己拿,那就自己拿咯,代码如下:
//获取融云token
OkHttpClient mOkHttpClient = new OkHttpClient();
RequestBody formBody = new FormBody.Builder()
.add("userId", userID)//当前登录的用户的id
.add("name", userName)//当前登录的用户的名字
.add("portraitUri", userPhoto)//当前登录的用户的头像地址
.build();
String num = new Random(100).nextInt() + "";//一个随机数
String time = System.currentTimeMillis() + "";//一个时间戳
Request request = new Request.Builder()
.url("https://api.cn.ronghub.com/user/getToken.json")
.addHeader("App-Key", "你申请的key")
.addHeader("Nonce", num)
.addHeader("Timestamp", time)
.addHeader("Signature", StringUtil.sha1("你申请的secret" + num + time))
.post(formBody)
.build();
Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String str = response.body().string();
try {
JSONObject object = new JSONObject(str);
if (object.getInt("code") == 200) {
connect(context, object.getString("token"));//连接融云
PreferencesUtils.putString(ConstantUtil.RONGYUN_USER_TOKEN, object.getString("token"));//存入sp
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
参数说明(来自融云官网):消息头说明:只要是请求融云api,都要加一个消息头,如上面那个消息头,各参数如下:
名称 | 类型 | 说明 |
---|---|---|
App-Key 或 RC-App-Key |
String | 开发者平台分配的 App Key。 |
Nonce 或 RC-Nonce |
String | 随机数,无长度限制。 |
Timestamp 或 RC-Timestamp |
String | 时间戳,从 1970 年 1 月 1 日 0 点 0 分 0 秒开始到现在的秒数。 |
Signature 或 RC-Signature |
String | 数据签名。 |
Signature (数据签名)计算方法:将系统分配的 App Secret、Nonce (随机数)、Timestamp (时间戳)三个字符串按先后顺序拼接成一个字符串并进行 SHA1 哈希计算。
RC-
前缀的 HTTP Header 是为了适应某些 PaaS 平台(如 SAE)过滤特定 HTTP Header 的机制而考虑的,如果您使用这些平台时遇到问题,可以使用 RC-
前缀,一般情况下使用默认的 HTTP Header 即可。
上面代码里我的sha1哈希计算方法如下(百度的):
public static String sha1(String data) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA1");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
md.update(data.getBytes());
StringBuffer buf = new StringBuffer();
byte[] bits = md.digest();
for(int i=0;i
上面在onResponse方法里面的connect(Context, String)就是连接融云的方法了。
public static void connect(Context context, String token) {
LogUtils.e(token);
if (context.getApplicationInfo().packageName.equals(AppContext.getCurProcessName(context.getApplicationContext()))) {
/**
* IMKit SDK调用第二步,建立与服务器的连接
*/
RongIM.connect(token, new RongIMClient.ConnectCallback() {
/**
* Token 错误,在线上环境下主要是因为 Token 已经过期,您需要向 App Server 重新请求一个新的 Token
*/
@Override
public void onTokenIncorrect() {
}
/**
* 连接融云成功
* @param userid 当前 token
*/
@Override
public void onSuccess(String userid) {
//连接融云成功以后要调用setCurrentUserInfo方法在融云需要的地方显示当前用户的头像。
RongIM.getInstance().setCurrentUserInfo(new UserInfo(userid,username,userphoto));
//为了显示陌生人的头像,携带到消息中
RongIM.getInstance().setMessageAttachedUserInfo(true);
RongIM.getInstance().enableNewComingMessageIcon(true);//显示新消息提醒
RongIM.getInstance().enableUnreadMessageIcon(true);//显示未读消息数目
}
/**
* 连接融云失败
* @param errorCode 错误码,可到官网 查看错误码对应的注释
* http://www.rongcloud.cn/docs/android.html#常见错误码
*/
@Override
public void onError(RongIMClient.ErrorCode errorCode) {
}
});
}
}
这样就连接融云成功了,只要集成聊天页面就可以正常聊天了,再送个彩蛋吧,如果要在聊天时显示对方和自己的头像和名字,要Application实现接口RongIM.UserInfoProvider并实现方法getUserInfo
@Override
public UserInfo getUserInfo(final String s)
具体方法我就不写了,方法的思路是如果参数s是当前登录用户的userid就返回一个new UserInfo(当前用户的id,名字,头像),如果不是根据s从你的app server获取跟你聊天的那个人的名字和头像地址,然后做参数返回一个new UserInfo,而且返回前不要忘了调用
RongIM.getInstance().refreshUserInfoCache(userInfo);
这样用户聊天时,无论谁发消息,只要一有消息发出融云都会调用这个方法去显示刚才说话的那个人的头像和名字。
有什么不懂的地方欢迎提问哦