记一次Android接环信添加圆形头像昵称以及遇到的一些坑

先上图吧就两张静止图片吧:


image.png

image.png

接三方SDK官方文档先看(http://docs-im.easemob.com/im/android/sdk/import

按照官方文档一步一步来,注册并创建应用,到环信官网下载环信 SDK。然后根据自己的需要导入自己想要的功能。我这里主要是单聊,以及圆形头像与昵称的保存。保存数据用的是ormlite。主要记录一下坑。这里就不具体讲登录注册了。

问题:public class MyChatFragment extends EaseChatFragment implements EaseChatFragment.EaseChatFragmentHelper 如果报错的话需要依赖
implementation 'android.arch.lifecycle:extensions:1.1.1'
问题:设置圆形头像找到EaseUserUtils
image.png
public static void setUserAvatar(Context context, String username, ImageView imageView){
        EaseUser user = getUserInfo(username);

        RequestOptions optionsCircle = new RequestOptions();
        DrawableTransitionOptions transitionOptions = new DrawableTransitionOptions();
        optionsCircle.placeholder(R.drawable.icon_head);
        optionsCircle.transform(new GlideCircleTransform());
        optionsCircle.diskCacheStrategy(DiskCacheStrategy.ALL);

        if(user != null && user.getAvatar() != null){
            try {
                int avatarResId = Integer.parseInt(user.getAvatar());
                Glide.with(context)
                        .load(avatarResId)
                        .apply(optionsCircle)
//                        .transition(transitionOptions.crossFade())
                        .into(imageView);

            } catch (Exception e) {

                Glide.with(context)
                        .load(user.getAvatar())
                        .apply(optionsCircle)
//                        .transition(transitionOptions.crossFade())
                        .into(imageView);
            }
        }else Glide.with(context)
                    .load(R.drawable.icon_head)
                    .apply(optionsCircle)
//                    .transition(transitionOptions.crossFade())
                    .into(imageView);

    }
问题:发送的缩略图大小修改在EaseChatRowImage类里面 ,接收 登录环信后台修改大小
new AsyncTask<Object, Void, Bitmap>() {

                @Override
                protected Bitmap doInBackground(Object... args) {
                    File file = new File(thumbernailPath);
                    if (file.exists()) {
                        return EaseImageUtils.decodeScaleImage(thumbernailPath, 480, 480);
                    } else if (new File(imgBody.thumbnailLocalPath()).exists()) {
                        return EaseImageUtils.decodeScaleImage(imgBody.thumbnailLocalPath(), 480, 480);
                    } else {
                        if (message.direct() == EMMessage.Direct.SEND) {
                            if (localFullSizePath != null && new File(localFullSizePath).exists()) {
                                return EaseImageUtils.decodeScaleImage(localFullSizePath, 480, 480);
                            } else {
                                return null;
                            }
                        } else {
                            return null;
                        }
                    }
                }

                protected void onPostExecute(Bitmap image) {
                    if (image != null) {
                        imageView.setImageBitmap(image);
                        EaseImageCache.getInstance().put(thumbernailPath, image);
                    }
                }
            }.execute();
问题:UserCacheManager 获取用户个人信息默认通过本地数据库里面查询,有则使用本地的信息,没有则调取服务器信息

代码注释的地方则是从服务器上获取

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

        UserCacheInfo info = null;

        // 如果本地缓存不存在或者过期,则从存储服务器获取
        if (notExistedOrExpired(userId)){

//            HttpHelper.getInstance().getImInfo(context,userId, new NetWorkDataProcessingCallBack() {
//                @Override
//                public void onSuccess(Object response, String urlType, String msg) {
//                    if (response == null) return;
//
//                    UserBean userBean = (UserBean) response;
//                    save(userId,userBean.getName(),userBean.getImg());
//                }
//
//                @Override
//                public void onError(String urlType, String msg) {}
//            });

        }
        // 从本地缓存中获取用户数据
        info = getFromCache(userId);
        return info;
    }
CjImHelper 这个类主要是环信的初始化之类的东西,以及消息的监听
public class CjImHelper {

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

    private Context mContext;

    private EaseUI easeUI;

    public boolean isVideoCalling;
    public boolean isVoiceCalling;

    // 记录是否已经初始化
    private boolean isInit = false;

    //监听
    private EMConversationListener convListener;

    public void setConvListener(EMConversationListener convListener) {
        this.convListener = convListener;
    }

    private static CjImHelper mInstance;

    private CjImHelper() {

    }

    public synchronized static CjImHelper getInstance() {
        if (mInstance == null) {
            mInstance = new CjImHelper();
        }
        return mInstance;
    }

    /**
     * init helper
     *
     * @param context
     *            application context
     */
    public void init(Context context) {

        this.mContext =context;
        initEasemob();
    }

    private void initEasemob(){
        int pid = android.os.Process.myPid();
        String processAppName = getAppName(pid);
        // 如果APP启用了远程的service,此application:onCreate会被调用2次
        // 为了防止环信SDK被初始化2次,加此判断会保证SDK被初始化1次
        // 默认的APP会在以包名为默认的process name下运行,如果查到的process name不是APP的process name就立即返回

        if (processAppName == null ||!processAppName.equalsIgnoreCase(mContext.getPackageName())) {
            Log.e(LOG_TAG, "enter the service process!");

            // 则此application::onCreate 是被service 调用的,直接返回
            return;
        }

        if(isInit){
            return ;
        }

        /**
         * SDK初始化的一些配置
         * 关于 EMOptions 可以参考官方的 API 文档
         * http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_options.html
         */
        EMOptions options = new EMOptions();

        // 设置Appkey,如果配置文件已经配置,这里可以不用设置
        // options.setAppKey("lzan13#hxsdkdemo");
        // 设置自动登录
        options.setAutoLogin(true);
        // 设置是否需要发送已读回执
        options.setRequireAck(true);
        // 设置是否需要发送回执,TODO 这个暂时有bug,上层收不到发送回执
        options.setRequireDeliveryAck(true);
        // 设置是否需要服务器收到消息确认
        options.setAutoTransferMessageAttachments(true);
        // 收到好友申请是否自动同意,如果是自动同意就不会收到好友请求的回调,因为sdk会自动处理,默认为true
        options.setAcceptInvitationAlways(false);
        // 设置是否自动接收加群邀请,如果设置了当收到群邀请会自动同意加入
        options.setAutoAcceptGroupInvitation(false);
        // 设置(主动或被动)退出群组时,是否删除群聊聊天记录
        options.setDeleteMessagesAsExitGroup(false);
        // 设置是否允许聊天室的Owner 离开并删除聊天室的会话
        options.allowChatroomOwnerLeave(true);
        // 设置google GCM推送id,国内可以不用设置
        // options.setGCMNumber(MLConstants.ML_GCM_NUMBER);
        // 设置集成小米推送的appid和appkey
        // options.setMipushConfig(MLConstants.ML_MI_APP_ID, MLConstants.ML_MI_APP_KEY);

        // 调用初始化方法初始化sdk
        EaseUI.getInstance().init(mContext, options);

        easeUI = EaseUI.getInstance();

        setEaseUIProviders();
        // 设置开启debug模式
        EMClient.getInstance().setDebugMode(true);

        registerMessageListener();
        // 设置初始化已经完成
        isInit = true;
    }

    private String getAppName(int pID) {
        String processName = null;
        ActivityManager am = (ActivityManager) mContext.getSystemService(ACTIVITY_SERVICE);
        List l = am.getRunningAppProcesses();
        Iterator i = l.iterator();
        PackageManager pm = mContext.getPackageManager();
        while (i.hasNext()) {
            ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo) (i.next());
            try {
                if (info.pid == pID) {
                    processName = info.processName;
                    return processName;
                }
            } catch (Exception e) {
                // Log.d("Process", "Error>> :"+ e.toString());
            }
        }
        return null;
    }

    protected void setEaseUIProviders() {
        // set profile provider if you want easeUI to handle avatar and nickname
        easeUI.setUserProfileProvider(UserCacheManager::getEaseUser);

        //set notification options, will use default if you don't set it
        easeUI.getNotifier().setNotificationInfoProvider(new EaseNotifier.EaseNotificationInfoProvider() {

            @Override
            public String getTitle(EMMessage message) {
                //you can update title here
                return null;
            }

            @Override
            public int getSmallIcon(EMMessage message) {
                //you can update icon here
                return 0;
            }

            @Override
            public String getDisplayedText(EMMessage message) {
                // be used on notification bar, different text according the message type.
                String ticker = EaseCommonUtils.getMessageDigest(message, mContext.getApplicationContext());
                if(message.getType() == EMMessage.Type.TXT){
                    ticker = ticker.replaceAll("\\[.{2,3}\\]", "[表情]");
                }
                EaseUser user = getUserInfo(message.getFrom());
                if(user != null){
                    if(EaseAtMessageHelper.get().isAtMeMsg(message)){
                        return String.format("%s在群聊中@了你", user.getNickname());
                    }
                    return user.getNickname() + ": " + ticker;
                }else{
                    if(EaseAtMessageHelper.get().isAtMeMsg(message)){
                        return String.format("%s在群聊中@了你", message.getFrom());
                    }
                    return message.getFrom() + ": " + ticker;
                }
            }

            @Override
            public String getLatestText(EMMessage message, int fromUsersNum, int messageNum) {
                // here you can customize the text.
                // return fromUsersNum + "contacts send " + messageNum + "messages to you";
                return null;
            }

            @Override
            public Intent getLaunchIntent(EMMessage message) {
                // you can set what activity you want display when user click the notification
                Intent intent = new Intent(mContext,ChatActivity.class);

                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP );
                // open calling activity if there is call
                if(isVideoCalling){
//                    intent = new Intent(appContext, VideoCallActivity.class);
                }else if(isVoiceCalling){
//                    intent = new Intent(appContext, VoiceCallActivity.class);
                }else{
                    EMMessage.ChatType chatType = message.getChatType();
                    if (chatType == EMMessage.ChatType.Chat) { // single chat message
                        intent.putExtra("userId", message.getFrom());
                        intent.putExtra("chatType", EaseConstant.CHATTYPE_SINGLE);
                    } else { // group chat message
                        // message.getTo() is the group id
                        intent.putExtra("userId", message.getTo());
                        if(chatType == EMMessage.ChatType.GroupChat){
                            intent.putExtra("chatType", EaseConstant.CHATTYPE_GROUP);
                        }else{
                            intent.putExtra("chatType", EaseConstant.CHATTYPE_CHATROOM);
                        }

                    }
                }
                return intent;
            }
        });


    }

    EMMessageListener messageListener;
    protected void registerMessageListener() {
        messageListener = new EMMessageListener() {
            private BroadcastReceiver broadCastReceiver = null;

            @Override
            public void onMessageReceived(List<EMMessage> messages) {
                for (EMMessage message : messages) {
                    EMLog.d(LOG_TAG, "onMessageReceived id : " + message.getMsgId());
                    //接收并处理扩展消息
                    String userName = message.getStringAttribute(UserCacheManager.kChatUserNick, "");
                    String userId = message.getStringAttribute(UserCacheManager.kChatUserId, "");
                    String userPic = message.getStringAttribute(UserCacheManager.kChatUserPic, "");

                    String hxIdFrom = message.getFrom();
                    EaseUser easeUser = new EaseUser(hxIdFrom);
                    easeUser.setAvatar(userPic);
                    easeUser.setNickname(userName);

                    UserCacheManager.save(hxIdFrom,userName,userPic);
                    easeUI.getNotifier().notify(message);

                }

                if (convListener!=null)
                    convListener.onCoversationUpdate();

            }

            @Override
            public void onCmdMessageReceived(List<EMMessage> messages) {
                for (EMMessage message : messages) {
                    EMLog.d(LOG_TAG, "receive command message");
                }
            }

            @Override
            public void onMessageRead(List<EMMessage> messages) {
            }

            @Override
            public void onMessageDelivered(List<EMMessage> message) {
            }

            @Override
            public void onMessageRecalled(List<EMMessage> list) {

            }

            @Override
            public void onMessageChanged(EMMessage message, Object change) {
            }
        };

        EMClient.getInstance().chatManager().addMessageListener(messageListener);
    }

}
问题:混淆崩溃问题附上自己的百度地图,环信,Ormlite的混淆代码。。。最开始用demo里面的easeui混淆之后百度地图老是崩溃,最后发现替换里面的百度地图架包和so文件用最新的就好了,这是个大坑。。。。附上demo地址:https://github.com/lcjiang1993/CjEaseUiDemo 。 希望对出现问题的朋友有所帮助吧。
#****************baiduMap****************************
-keep class com.baidu.** {*;}
-keep class vi.com.** {*;}
-dontwarn com.baidu.**
#****************baiduMap****************************

#环信
-keep class org.xmlpull.** {*;}
-keep class com.hyphenate.** {*;}
-keep class com.hyphenate.chat.** {*;}
-dontwarn  com.hyphenate.**
-keep class org.jivesoftware.** {*;}
-keep class org.apache.** {*;}
#2.0.9后加入语音通话功能,如需使用此功能的api,加入以下keep
-keep class net.java.sip.** {*;}
-keep class org.webrtc.voiceengine.** {*;}
-keep class org.bitlet.** {*;}
-keep class org.slf4j.** {*;}
-keep class ch.imvs.** {*;}
-keep class com.superrtc.** { *; }

#华为混淆
-keep class com.huawei.hms.update.** {
*;
}
-dontwarn com.huawei.hms.update.**

# OrmLite uses reflection
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }

-keepattributes *Annotation*
-keepclassmembers class com.package.bo.** { *; }
-keepclassmembers class * {
@com.j256.ormlite.field.DatabaseField *;
}
-keepattributes Signature
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • 扯淡下: 好久没有更新文章了,连续工作了9个小时,拖着疲惫的身体,对环信接入中遇到的一些坑以及经验做一个总结。 说...
    若无初见阅读 5,312评论 6 7
  • 1)项目里面不需要环信SDK的太多功能,只是想要聊天和好友功能,其他都不用,那SDK一定要总是跟着更新么? a.环...
    DefaultYuan阅读 26,539评论 17 59
  • 在离职之际,也没有啥事可以做,就自己捣腾下代码混淆,言归正传。 为了防止自己的劳动成果被别人窃取,混淆代码能有效防...
    Orz013阅读 1,002评论 0 0
  • 打卡营第10天 近几天在忙月度的各类报表数据、总结和述职,周六有一天的会需要准备,下周补齐
    彩霞2018阅读 150评论 0 0
  • 时间,是一个奇妙的东西。它可以变得很长,也可以变得很短。人,是一个矛盾的动物。它可以喜欢你,也可以讨厌你。人和时间...
    Hanranxqp阅读 156评论 0 0