Android环信官方集成文档:http://docs.easemob.com/im/200androidclientintegration/10androidsdkimport

我在项目里集成环信时是根据环信官方EaseUI进行集成的,EaseUI环信说明文档:http://docs.easemob.com/im/200androidclientintegration/135easeuiuseguide

这里只介绍怎么通过扩展消息显示头像和昵称,参考文章:在android中5分钟实现环信昵称头像的显示,感谢作者!

一、将以下三个java文件复制到自己的项目里:

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;

/**
 * sqlite数据库辅助类
 * Created by lkj
 */

public class SqliteHelper extends OrmLiteSqliteOpenHelper {

    private final String LOG_TAG = getClass().getSimpleName();

    // 数据库名字
    private static final String DATABASE_NAME = "im_user_cache.db";

    // 版本号
    private static final int DATABASE_VERSION = 1;

    private static SqliteHelper mInstance;

    private Dao<UserCacheInfo, Integer> mUserInfoDao = null;

    public SqliteHelper(Context context){
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    public synchronized static SqliteHelper getInstance(){
        if (mInstance == null) {
            ///TODO:: 把这里的 DemoApplication.getInstance() 换成自己的Application类实例对象。例如:new MainApplication()
            mInstance = new SqliteHelper(MyApplication.getInstance());
        }

        return mInstance;
    }

    /**
     * 创建SQLite数据库
     */
    @Override
    public void onCreate(SQLiteDatabase sqliteDatabase, ConnectionSource connectionSource) {
        try {
            TableUtils.createTable(connectionSource, UserCacheInfo.class);
        } catch (SQLException e) {
            Log.e(LOG_TAG, "Unable to create datbases", e);
        } catch (java.sql.SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 更新SQLite数据库
     */
    @Override
    public void onUpgrade(
            SQLiteDatabase sqliteDatabase,
            ConnectionSource connectionSource,
            int oldVer,
            int newVer) {
        try {
            TableUtils.dropTable(connectionSource, UserCacheInfo.class, true);

            onCreate(sqliteDatabase, connectionSource);
        } catch (SQLException e) {
            Log.e(LOG_TAG,
                    "Unable to upgrade database from version " + oldVer + " to new "
                            + newVer, e);
        } catch (java.sql.SQLException e) {
            e.printStackTrace();
        }
    }

    public Dao<UserCacheInfo,Integer> getUserDao() throws SQLException{
        if(mUserInfoDao == null){
            try {
                mUserInfoDao = getDao(UserCacheInfo.class);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return mUserInfoDao;
    }

}
import com.google.gson.Gson;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;

/**
 * 用户缓存信息类
 * 需要ormlite库支持
 * Created by Martin on 2017/4/24.
 */
@DatabaseTable(tableName="UserCacheInfo")
public class UserCacheInfo{

    @DatabaseField(generatedId=true)
    private int id;

    /*环信ID*/
    @DatabaseField(index = true)
    private String userId;

    /*昵称*/
    @DatabaseField
    private String nickName;

    /*头像*/
    @DatabaseField
    private String avatarUrl;

    /*数据过期时间*/
    @DatabaseField(canBeNull = false)
    private long expiredDate;

    // 必须顶一个无参数的构造函数,否则会报【virtual method】异常
    UserCacheInfo(){}

    /*json字符串转换成model*/
    public static UserCacheInfo parse(String jsonStr) {
        return (new Gson()).fromJson(jsonStr, UserCacheInfo.class);
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public String getAvatarUrl() {
        return avatarUrl;
    }

    public void setAvatarUrl(String avatarUrl) {
        this.avatarUrl = avatarUrl;
    }

    public long getExpiredDate() {
        return expiredDate;
    }

    public void setExpiredDate(long expiredDate) {
        this.expiredDate = expiredDate;
    }

}
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMMessage;
import com.hyphenate.easeui.domain.EaseUser;
import com.j256.ormlite.dao.Dao;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户缓存管理类
 * Created by Martin on 2017/4/24.
 */
public class UserCacheManager {

    private static Context context;
    private static SPUtils spUtils;

    public UserCacheManager(Context context){
        this.context=context;
        spUtils=SPUtils.getInstance(UserConstants.USER_INFO);
    }

    /**
     * 消息扩展属性
     */
    private static final String kChatUserId = "ChatUserId";// 环信ID
    private static final String kChatUserNick = "ChatUserNick";// 昵称
    private static final String kChatUserPic = "ChatUserPic";// 头像Url

    /**
     * 获取所有用户信息
     * @return*/
    public static List<UserCacheInfo> getAll(){
        Dao<UserCacheInfo, Integer> dao = SqliteHelper.getInstance().getUserDao();
        try {
            List<UserCacheInfo> list = dao.queryForAll();
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 获取用户信息
     * @param userId 用户环信ID
     * @return*/
    public static UserCacheInfo get(final String userId){
        UserCacheInfo info = null;

        // 如果本地缓存不存在或者过期,则从存储服务器获取
        if (notExistedOrExpired(userId)){
            MyHttpUtils.get(context, MyApiHelper.URL_USER_INFO + userId,
                    new MyHttpUtils.HttpCallback() {
                        @Override
                        public void success(String success) {                            if (TextUtils.isEmpty(success)) return;
                            UserInfoBean infoModel = JSON.parseObject(success, UserInfoBean.class);
                            if (infoModel.getResult()==0){
                                UserInfoBean.DataBean dataBean=infoModel.getData();
                                if (ObjectUtils.isNotEmpty(dataBean)){
                                    //生成头像的绝对路径,保存在本地
                                        save(userId,dataBean.getNickName(),dataBean.getAppImage());
                                }
                            }
                        }

                        @Override
                        public void fail(String fail) {                        }
                    });
        }
        // 从本地缓存中获取用户数据
        info = getFromCache(userId);
       return info;
    }

    /**
     * 获取用户信息
     * @param userId 用户环信ID
     * @return*/
    public static UserCacheInfo getFromCache(String userId){

        try {
            Dao<UserCacheInfo, Integer> dao = SqliteHelper.getInstance().getUserDao();
            UserCacheInfo model = dao.queryBuilder().where().eq("userId", userId).queryForFirst();
            return model;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 获取用户信息
     * @param userId
     * @return*/
    public static EaseUser getEaseUser(String userId){

        UserCacheInfo user = get(userId);
        if (user == null) return null;

        EaseUser easeUser = new EaseUser(userId);
        easeUser.setAvatar(user.getAvatarUrl());
        easeUser.setNickname(user.getNickName());

        return easeUser;
    }

    /**
     * 用户是否存在
     * @param userId 用户环信ID
     * @return*/
    public static boolean isExisted(String userId){
        Dao<UserCacheInfo, Integer> dao = SqliteHelper.getInstance().getUserDao();
        try {
            long count = dao.queryBuilder().where().eq("userId", userId).countOf();
            return count > 0;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    /**
     * 用户不存在或已过期
     * @param userId 用户环信ID
     * @return*/
    public static boolean notExistedOrExpired(String userId){
        Dao<UserCacheInfo, Integer> dao = SqliteHelper.getInstance().getUserDao();
        try {
            long count = dao.queryBuilder().where()
                    .eq("userId", userId).and()
                    .gt("expiredDate",new Date().getTime())
                    .countOf();
            return count <= 0;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return true;
    }

    /**
     * 缓存用户信息
     * @param userId 用户环信ID
     * @param avatarUrl 头像Url
     * @param nickName 昵称
     * @return*/
    public static boolean save(String userId, String nickName, String avatarUrl){
        try {
            Dao<UserCacheInfo, Integer> dao = SqliteHelper.getInstance().getUserDao();

            UserCacheInfo user = getFromCache(userId);

            // 新增
            if (user == null){
                user = new UserCacheInfo();
            }

            user.setUserId(userId);
            user.setAvatarUrl(avatarUrl);
            user.setNickName(nickName);
            user.setExpiredDate(new Date().getTime() + 24*60*60*1000);// 一天过期,单位:毫秒

            Dao.CreateOrUpdateStatus status = dao.createOrUpdate(user);

            if(status.getNumLinesChanged() > 0){
                Log.i("UserCacheManager", "操作成功~");
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("UserCacheManager", "操作异常~");
        }

        return false;
    }

    /**
     * 更新当前用户的昵称
     * @param nickName 昵称
     */
    public static void updateMyNick(String nickName){
        UserCacheInfo user = getMyInfo();
        if (user == null)  return;

        save(user.getUserId(), nickName, user.getAvatarUrl());
    }

    /**
     * 更新当前用户的头像
     * @param avatarUrl 头像Url(完成路径)
     */
    public static void updateMyAvatar(String avatarUrl){
        UserCacheInfo user = getMyInfo();
        if (user == null)  return;

        save(user.getUserId(), user.getNickName(), avatarUrl);
    }

    /**
     * 缓存用户信息
     * @param model 用户信息
     * @return*/
    public static boolean save(UserCacheInfo model){

        if(model == null) return false;

        return save(model.getUserId(),model.getNickName(),model.getAvatarUrl());
    }

    /**
     * 缓存用户信息
     * @param ext 用户信息
     * @return*/
    public static boolean save(String ext){
        if(ext == null) return false;

        UserCacheInfo user = UserCacheInfo.parse(ext);
        return save(user);
    }

    /**
     * 缓存用户信息
     * @param ext 消息的扩展属性
     * @return*/
    public static void save(Map<String,Object> ext){

        if(ext == null) return;

        try {
            String userId = ext.get(kChatUserId).toString();
            String avatarUrl = ext.get(kChatUserPic).toString();
            String nickName = ext.get(kChatUserNick).toString();

            save(userId,nickName,avatarUrl);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取当前环信用户信息
     * @return*/
    public static UserCacheInfo getMyInfo(){
        return get(EMClient.getInstance().getCurrentUser());
    }

    /**
     * 获取用户昵称
     * @return*/
    public static String getMyNickName(){
        UserCacheInfo user = getMyInfo();
        if(user == null) return EMClient.getInstance().getCurrentUser();

        return user.getNickName();
    }

    /**
     * 设置消息的扩展属性
     * @param msg 发送的消息
     */
    public static void setMsgExt(EMMessage msg){
        if(msg == null) return;
        UserCacheInfo user = getMyInfo();
        msg.setAttribute(kChatUserId, user.getUserId());
        msg.setAttribute(kChatUserNick, user.getNickName());
        msg.setAttribute(kChatUserPic, user.getAvatarUrl());
    }

    /**
     * 获取登录用户的昵称头像
     * @return*/
    public static String getMyInfoStr(){

        Map<String,Object> map = new HashMap<>();

        UserCacheInfo user = getMyInfo();
        map.put(kChatUserId, user.getUserId());
        map.put(kChatUserNick, user.getNickName());
        map.put(kChatUserPic, user.getAvatarUrl());

        return new Gson().toJson(map);
    }
}

二、从消息扩展中获取头像昵称:

1.首先,要注释从APP服务器获取昵称头像的方法。
删除类文件:UserWebInfo.java和UserWebManager.java。
UserCacheManager.java中注释第57-68行,不从APP服务器中获取昵称头像:

// 如果本地缓存不存在或者过期,则从存储服务器获取
if (notExistedOrExpired(userId)){UserWebManager.getUserInfoAync(userId, new UserWebManager.UserCallback() {//从自己服务器获取用户信息@Overridepublic void onCompleted(UserWebInfo info) {if(info == null) return;// 缓存到本地save(userId, info.getNickName(),info.getAvatarUrl());}});
}

2.登录(或注册)成功后,需要缓存当前用户的昵称头像。
在登录(或注册)服务端回调(不是环信IM登录回调)里,增加如下代码:

// 登录成功,将用户的环信ID、昵称和头像缓存在本地
UserCacheManager.save(userId, nickName, avatarUrl);

3.发送消息时携带昵称头像。
ChatFragment.java里的 onSetMessageAttributes函数。第231行增加代码:

// 设置消息的扩展属性,携带昵称头像
UserCacheManager.setMsgExt(message);

4.接收消息时携带昵称头像。
DemoHelper.java里的 onMessageReceived函数。第856行增加代码:

// 从消息的扩展属性里获取昵称头像
UserCacheManager.save(message.ext());

5.另外。音视频通话里,昵称头像也要进行处理。 (不需要音视频通话功能的开发者可以省略后面所有步骤)
发送音视频通话请求时携带昵称头像。
CallActivity.java里第162行代码更改为:

// 通过扩展属性将昵称头像传给对方
String ext = UserCacheManager.getMyInfoStr();
if (msg.what == MSG_CALL_MAKE_VIDEO) {EMClient.getInstance().callManager().makeVideoCall(username,ext);
} else { EMClient.getInstance().callManager().makeVoiceCall(username,ext);
}

6.接收音视频通话时保存昵称头像。
CallReceiver.java第33行增加代码:

// 缓存用户昵称头像
String ext = EMClient.getInstance().callManager().getCurrentCallSession().getExt();
UserCacheManager.save(ext);

7.音频通话里显示昵称头像。
VoiceCallActivity.java第114行代码改为:

// 显示昵称头像
UserCacheInfo user = UserCacheManager.get(username);
if (user != null){nickTextView.setText(user.getNickName());//Glide.with(VoiceCallActivity.this).load(user.getAvatarUrl()).placeholder(R.drawable.em_default_avatar).into(avatarImage);}else {nickTextView.setText(username);}

8.视频通话里显示昵称头像。
VideoCallActivity.java第171行代码改为:

// 显示昵称头像
UserCacheInfo user = UserCacheManager.get(username);
if (user != null){nickTextView.setText(user.getNickName());
}else {nickTextView.setText(username);
}

通过以上步骤相信大家应该就能实现使用扩展消息显示昵称头像了。

Android接入环信扩展消息显示头像、昵称相关推荐

  1. 环信php修改头像,环信第二波 更改聊天头像,昵称等问题

    基于上次那篇有关环信的个人集成方法被环信周刊官方收录以后,一直没有再写环信相关知识. 今天我将在这继续写一下关于环信获取用户头像和昵称的方法.环信官方文档里面有两种方法, 1:通过自己后台根据用户ID ...

  2. IM实战:Android接入环信 IM SDK

    本次学习目标: 注册环信: Android端集成环信 IM SDK: 实现注册-登录-发送消息-会话列表等: 一.环信IM        什么是环信IM 环信IM是一款即时通讯产品,为开发者提供基于移 ...

  3. android环信群聊显名称,Android环信群聊插入头像和昵称

    最近在用环信开发项目中,发现环信的后台并不支持录入头像和昵称. 群聊的list列表中用户的头像是默认图,昵称是用户的id. 这显然很不友好,环信给出的方案如下: 方法一:从APP服务器获取昵称和头像 ...

  4. Android基于环信自定义消息实现转账红包(一)

    最近做了一个项目,需要实现转账红包功能.我这里接入的是环信,我自己做的过程中也比较坎坷,所以想把实现的方法整理了一下分享给大家(如果大家有更好的实现方法,欢迎评论区留言,废话不多说了开始上货,东西有点 ...

  5. Android基于环信SDK开发IM即时聊天(一)

    2016-09-02更新:可以看一下最新的这篇文章和源码,Android基于环信SDK开发IM即时聊天(二) 目前市面上我了解的做第三方即时聊天SDK的有两家:环信.融云,这里我使用环信SDK来完成即 ...

  6. Android基于环信开发的即时通讯APP

    Android基于环信开发的即时通讯APP,源代码在Github上,GitHub地址为:https://github.com/PowerDos/BLChat ,希望能够帮到你们,下面是系统简介. 简介 ...

  7. Android基于环信SDK开发IM即时聊天(二)

    声明1:北京时间现在是2019/6/10,评论里的问题我看到了,这几天我找时间看看源代码问题出在哪,在此感谢大家的监督 声明2:此Demo我是在5.1测试机上测试通过,感谢WTQ_DOMIAN的评论, ...

  8. 解决Android设置环信显示头像和昵称问题

    1.问题 在使用环信进行及时聊天时或者群聊时,显示用户名称的往往是其环信username(例如165983547),但我们真正希望显示的是用户的昵称(例如 张三),而聊天时候的头像默认是环信默认头像而 ...

  9. Android 集成环信IM,实现头像和昵称的显示

    环信中要设置昵称和头像有两种方法,一种是通过请求服务器获得,一种是通过发送扩展消息获得.本人推荐通过发送扩展消息获得,简单又方便.所以下面我就只讲通过发送扩展消息获取的方法. 具体的实现步骤如下: 1 ...

最新文章

  1. Netscaler 认证,访问报http 5000 内部错误
  2. Word2013、2016中页码总页数设置为当前节总页数
  3. YUV420转YUV444 , YUV420转RGB
  4. Acwing第 9 场周赛【未完结】
  5. pytorch几种损失函数CrossEntropyLoss、NLLLoss、BCELoss、BCEWithLogitsLoss、focal_loss、heatmap_loss
  6. Python数据分析·读取CSV文件转为字典
  7. 【设计模式 05】工厂方法模式
  8. html做在线预览pdf文件,html中在线预览pdf文件之pdf在线预览插件
  9. 这次要说不明白 immutable 类,我就怎么地!
  10. idea 报错improperly specified vm option. to fix the problem,edit your jvm option and remove the option
  11. 关于最近很火的Python圣诞树
  12. CDH启用kerberos认证问题导致GSS initiate failed
  13. 微信小程序 非webview分享给好友及生成分享海报
  14. systemd、upstart和system V
  15. MSK的CPM调制和I-Q调制
  16. leetcode_977
  17. 华为鸿蒙os手机计划表,华为为什么还没有推出鸿蒙OS智能手机的计划
  18. python 通登录银行_带你了解Python|自动化实现学习通登录
  19. RESTful HTTP中对POST,PUT,PATCH的区别
  20. 68页智慧管廊项目建设解决方案

热门文章

  1. 分享个仙剑奇侠传九野挂机脚本,自动对战过关刷奖励
  2. 地势坤,君子以厚德载物
  3. tizen操作系统将支持android,三星Tizen操作系统将支持Android应用
  4. 计算机鼠标不动了,鼠标不动了怎么办,教您鼠标不动了怎么办
  5. bacnet (收集)
  6. 登录系统时的手机验证码如何获取的
  7. php字符串转数组重命名键,【PHP】字符串转数组、数组转字符串
  8. 刷脸支付优化用户体验赋能商家运营
  9. MM32F3273G8P火龙果开发板MindSDK开发教程12 -获取msa311加速器的敲击事件
  10. VeryCD挥别影视做游戏 月入亿元转型成功