简介

yun2win即时通讯云安卓客户端主要由聊天实例和推送服务组成,其中聊天服务组件由开发者从Github获得源码,自行修改定义,保证开发者对界面功能的绝对自主。

开发准备

  • github下载yun2winSDK及demo
  • 下载源码详解

    app为主体显示Module uikit为公共服务Module

    app下libs的yun2win-0.1.jar为推送SDK

    主体Module结构图

    base文件夹:app初始相关类

    Bridge文件夹:推送连接、接收和发送

    common文件夹:公共配置等

    db文件夹:数据库管理

    entities文件夹:实体集合

    manage文件夹:模型实体管理

    model文件夹:模型集合

    service文件夹:服务管理

    ui文件夹:界面相关

  • 配置信息

    在清单文件AndroidManifest.xml里加入以下权限,以及写上你注册的appkey

    权限配置(实际开发中可能需要更多的权限,可参考demo):

       
    <?xml version="1.0" encoding="utf-8" ?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.yun2win.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.ACCESS_FINE_LOCATION" />
            <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
            <uses-permission android:name="android.permission.WRITE_SETTINGS" />
            <!-- 手机状态 -->
            <uses-permission android:name="android.permission.GET_TASKS" />
            <uses-permission android:name="android.permission.FLASHLIGHT" />
            <uses-permission android:name="android.permission.VIBRATE" />
            <uses-permission android:name="android.permission.WAKE_LOCK" />
            <uses-permission android:name="android.permission.BLUETOOTH" />
            <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
            <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
            <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
            <!-- 读写文件 -->
            <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" />
            <application android:name="y2w.base.AppContext"
            android:allowbackup="true"
            android:icon="@drawable/lyy_icon"
            android:label="@string/app_name"
            android:theme="@style/AppTheme">
                <!-- 设置yun2win应用的appkey -->
                <meta-data android:name="YUN2WIN_APP_KEY"
                android:value="CerAgk970T8MlUmz" /> 
            </application>
    </manifest>
                            

    关于YUN2WIN_APP_KEY对应的value获取,在创建应用后,申请APPKEY并进行相关配置。

  • app打包混淆

    在proguard文件中加入以下keep

    -keep class com.yun2win.** {*;}

    -dontwarn com.yun2win.**

注册

发送注册请求

   
       //account  pwd username设置账户 密码 用户名
Users.getInstance().getRemote().register(account, pwd, username,new Back.Result<user>() {
            @override
            public void onsuccess(user user) { />/注册成功 返回当前用户信息 跳转界面
                    UserInfo.setUserInfo(user.getEntity().getAccount(),"","","","","","");
                    Intent intent = new Intent(context,LoginActivity.class);
                    startActivity(intent);
                    finish();
            }
            @Override
            public void onError(int errorCode,String error) {
            //注册失败 
            }
            }
    });
                        

登录

发送登陆请求获取当前用户数据

   
Users.getInstance().getRemote().login(account, password, new Back.Result<currentuser>() 
    {
        @Override
        public void onSuccess(CurrentUser currentUser) {
            //同步会话联系人
            Users.getInstance().getCurrentUser().getRemote().sync(new Back.Callback() 
               {
                    @Override
                    public void onSuccess() {
                    startActivity(new Intent(LoginActivity.this, MainActivity.class));
                    finish();
                    }
                    @Override
                    public void onError(int errorCode, String error) {
                        //同步失败
                    }
              });
        }
        @Override
        public void onError(int errorCode, String error) {
          //注册失败
        }
    });
                        

登陆成功,在跳转页面onCreate方法里面添加如下代码(此处为MainActivity)

   
//推送服务器连接
Users.getInstance().getCurrentUser().getImBridges().connect();
                               

当前用户

用户属性

   
String id;//用户ID
String name;//用户名字
String account;//用户账号
String createdAt;//创建时间
String updatedAt;//更新时间
String avatarUrl;//用户名字
                                

当前用户属性

   
String appKey;
String secret;
String token;
MToken imToken;//用于连接y2wIM消息推送服务器
Contacts contacts;//联系人对象
Sessions sessions;//会话对象
UserConversations userConversations;//用户会话对象
UserSessions userSessions;//群组对象
IMBridges imBridges;//消息推送代理对象
Remote remote;//远程方法封装对象
CurrentUser user;//当前会话对象
                         

获取当前登陆的用户信息(yun2win支持多用户登陆)

   
//获取当前用户的名字
Users.getInstance().getCurrentUser().getEntity().getName();
//获取当前用户的头像
Users.getInstance().getCurrentUser().getEntity().getAvatarUrl();
//获取当前用户其它信息亦然
                           

用户会话

用户会话实体UserConversation属性

  
String id;//会话ID
String targetId;//如果是群卫会话ID 个人对个人是对方用户ID
String name;//会话名称
String type;//会话类型
boolean top;//是否置顶
boolean visiable;//是否可见
int unread;//未读消息
//最后一条消息发送者 唯一标识码
String lastSender;
String lastType;
//最后一条消息展示类容
String lastContent;
boolean isDelete;//是否被删除
String createdAt;
String updatedAt;
String avatarUrl;//头像地址
                

为了保证消息的完整性,我们采取同步服务端数据到本地数据库,同时通过查询本地数据库更新界面,同步时拿本地最后一条更新数据的时间同步后面的数据(默认时间1990-01-01 00:00:00),联系人和聊天消息亦然

同步处理机制

通过CallBackUpdate管理界面和更新消息通知,当创建一个当前界面时添加CallBackUpdate实例,销毁当前界面时,移除当前CallBackUpdate实例

接收消息通知

   
Handler updatesessionHandler= new Handler()
 {
    @Override
    public void handleMessage(Message msg) {
           super.handleMessage(msg);
            if(msg.what ==0){//更新界面
            conversationAdapter.updateListView();
            }else if(msg.what==1){//接收更新,本地服务器获取新的内容
                    conversations = Users.getInstance().
                    getCurrentUser().getUserConversations().getUserConversations();
                    conversationAdapter.setCOnversations(conversations);
                    updatesessionHandler.sendEmptyMessage(0);
            }
    }
};
                           

添加CallBackUpdate

 
//CallBackUpdate.updateType.userConversation.toString() 当前页面标识 
AppData.getInstance().getUpdateHashMap().
put(CallBackUpdate.updateType.userConversation.toString(),callBackUpdate);
                           

移除CallBackUpdate

 
//CallBackUpdate.updateType.userConversation.toString() 当前页面标识 
 AppData.getInstance().getUpdateHashMap().remove(CallBackUpdate.updateType.userConversation.toString());
                           

同步会话

 
Users.getInstance().getCurrentUser().getUserConversations().getRemote().sync(new Back.Result<list<userconversation>>() {
        @Override
        public void onSuccess(List<userconversation>userConversationList) {
                //同步到的消息添加到本地数据库
                Users.getInstance().getCurrentUser().getUserConversations().add(userConversationList);
                //返回更新成功,通知界面更新
                //AppData.getInstance().getUpdateHashMap().
                get(CallBackUpdate.updateType.userConversation.toString()).updateUI();
                callback.onSuccess();
        }
        @Override
        public void onError(int errorCode,String error) {
                callback.onError(errorCode,error);
        }
});
                           

联系人

联系人Contacts属性

 
//联系人唯一标识码
String id;
//用户唯一标识码
String userId;
String name;//名字
String email;//邮箱
String createdAt;//创建时间
String updatedAt;//更新时间
String avatarUrl;//头像地址
String role;//角色
String status;//状态
String jobTitle;//工作
boolean isDelete;//是否删除
String phone;//电话
String address;//地址
                

同步参考用户会话

联系人排序

 
contacts =  Users.getInstance().getCurrentUser().getContacts().getContacts();
for (Contact data : contacts) {
SortModel sm = new SortModel();
sm.setId(data.getEntity().getId());
sm.setUserId(data.getEntity().getUserId());
sm.setName(data.getEntity().getName());
sm.setPinyin(data.getEntity().getName());
sm.setEmail(data.getEntity().getEmail());
sm.setAvatarUrl(data.getEntity().getAvatarUrl());
sm.setStatus(data.getEntity().getStatus());
sm.setRole(data.getEntity().getRole());
sm.setSortLetters(StringUtil.getPinYinSortLetters(characterParser,sm.getPinyin()));
SourceDataList.add(sm);
}
// 根据a-z进行排序源数据
Collections.sort(SourceDataList, pinyinComparator);
contactAdapter.setListViewdate(SourceDataList);
                           

同步联系人

 
//同步会话联系人
Users.getInstance().getCurrentUser().getRemote().sync(new Back.Callback() {
        @Override
        public void onSuccess() {
                Users.getInstance().getCurrentUser().getContacts().add(contacts);
                //返回更新成功,通知界面更新
                //AppData.getInstance().getUpdateHashMap().
                get(CallBackUpdate.updateType.contact.toString()).updateUI();
        }
        @Override
        public void onError(int errorCode, String error) {
        }
});
                           

查找用户

 
Users.getInstance().getRemote().search(keyword, new Back.Result<list<contactentity>>() {
        @Override
        public void onSuccess(List<contactentity> entities) {
                if (entities==null||entities.size()<=0) {
                ToastUtil.ToastMessage(AddContactActivity.this, "抱歉,没有查询到任何用户");
                return;
                }
                //更新界面
                Message msg = new Message();
                msg.what = 1;
                msg.obj = entities;
                updatelistHandler.sendMessage(msg);
        }
        @Override
        public void onError(int errorCode, String error) {
                ToastUtil.ToastMessage(AddContactActivity.this, "抱歉,没有查询到任何用户");
        }
});
                           

获得个人用户信息

 
  //_otheruserid 查找人的用户ID
Users.getInstance().getRemote().userGet(_otheruserid, new Back.Result<user>() {
        @Override
        public void onSuccess(User user) {
                account = user.getEntity().getAccount();
                username = user.getEntity().getName();
                avatarUrl =user.getEntity().getAvatarUrl();
                updatefriendHandler.sendEmptyMessage(0);
        }
        @Override
        public void onError(int Code, String error) {
        }
});
                         

添加用户到联系人

添加好友,是把某人添加到自己联系人,不需要对方确认,也不会出现在对方联系人,除非对方也添加

 
//_otherId 联系人ID
Users.getInstance().getCurrentUser().getContacts().getRemote().contactDelete(_otherId, new Back.Callback() {
        @Override
        public void onSuccess() {
                ToastUtil.ToastMessage(context, "删除联系人成功");
                //通知更新联系人界面
                AppData.getInstance().getUpdateHashMap().
                get(CallBackUpdate.updateType.contact.toString()).syncDate();
                finish();
        }
        @Override
        public void onError(int errorCode,String error) {
              ToastUtil.ToastMessage(context, "删除失败");
        }
});
                

提醒

请记下联系人ID不是用户ID,添加一个用户到我的联系人,就会生成一个相对这个用户的联系人ID

从联系人删除用户

 
//_otheruserid 对方用户ID 对方账户 名字 头像
Users.getInstance().getCurrentUser().getContacts().getRemote().contactAdd(_otheruserid, account, username, avatarUrl, new Back.Result<contact>() {
        @Override
        public void onSuccess(Contact contact) {
                ToastUtil.ToastMessage(context, "添加联系人成功");
                //得到联系人ID
                _otherId = contact.getEntity().getId();
                //通知更新联系人界面
                AppData.getInstance().getUpdateHashMap().
                get(CallBackUpdate.updateType.contact.toString()).syncDate();
                isfriend = true;
                updatefriendHandler.sendEmptyMessage(2);
        }
        @Override
        public void onError(int errorCode, String error) {
               ToastUtil.ToastMessage(context, "添加失败");
        }
});
                        

群组

群组UserSession属性

 
//会话id
String id;
//会话类型为p2p时,对方Id
String sessionId;
//会话名称
String name;
//会话类型
boolean isDelete;
//会话创建时间
String createdAt;
//会话更新时间
String updatedAt;
//会话头像
String avatarUrl;
                        

添加群组

 
Users.getInstance().getCurrentUser().getUserSessions().getRemote().sessionStore( session.getEntity().getId(),  session.getEntity().getName(),  session.getEntity().getAvatarUrl(),  new Back.Result<usersession>(){
        @Override
        public void onSuccess(UserSession userSession) {
        }
        @Override
        public void onError(int Code, String error) {
        }
});
                    

删除群组

 
Users.getInstance().getCurrentUser().getUserSessions().getRemote().userSessionDelete( session.getEntity().getId(),new Back.Callback(){
        @Override
        public void onSuccess() {
        }
        @Override
        public void onError(int Code, String error) {
        }
});
                    

同步群组

 
Users.getInstance().getCurrentUser().getUserSessions().getRemote().sync( new Back.Result<list<usersession>>(){
        @Override
        public void onSuccess(List<usersessionentity> entities) {
        }
        @Override
        public void onError(int Code, String error) {
        }
});
                    

提醒

我的群会话只有收藏才能加入到我的群,发起群聊人默认把群会话加入我的群收藏

Session

Session属性

 
SessionEntity entity;//session实体
SessionMembers members;//session成员
Messages messages;//session消息
                        

SessionEntity属性

 
//会话id
String id;
//会话类型为p2p时,对方Id
String otherSideId;
//会话名称
String name;
//会话类型
String type;
//安全类型
String secureType;
//会话简介
String description;
//成员变更时间戳
String createMTS;
//成员信息变更时间戳
String updateMTS;
//会话创建时间
String createdAt;
//会话更新时间
String updatedAt;
//会话头像
String avatarUrl;
                         

发起群聊,创建Session

 
  /**
* 创建会话
* @param names session名字
* @param secureType 安全类型级别 public private
* @param SessionType 会话类型   p2p,group,single
* @param Urls.User_Avatar_Def 头像
*/
Users.getInstance().getCurrentUser().getSessions().getRemote().sessionCreate(names, secureType, EnumManage.sessionType, Urls.User_Avatar_Def, new Back.Result<session>() {
        @Override
        public void onSuccess(Session session) {
                addMytoGroupMembers(session);
        }
        @Override
        public void onError(int errorCode, String error) {
                ToastUtil.ToastMessage(SessionStartActivity.this, "创建失败");
                pd.dismiss();
        }
});
                             

获得Session详情

 
String targetId = EnumManage.SessionType.p2p.toString().equals(sessionType) ? otheruserID:sessionId;
/**
* 创建会话
* @param targetId 如何使一对一的聊天为对方用户ID否则为sessionID
* @param SessionType 会话类型   p2p,group,single
* @param Urls.User_Avatar_Def 头像
*/
Users.getInstance().getCurrentUser().getSessions().getSessionByTargetId(targetId, sessionType, new Back.Result<session>() {
            @Override
            public void onSuccess(Session session) {
                      _session = session;
            }
            @Override
            public void onError(int errorCode,String error) {
            }
            });
}
                    

提醒

会话类型分为p2p个人对个人group群聊group其它

SessionMember

添加会话成员

 
/**
* 创建会话
* @param userid 用户ID
* @param userName 用户名字
* @param groupRole 成员在群里的角色  master admin user
* @param userAvatarUrl 用户头像
* @param UserStatus 用户状态 active inactive
*/
session.getMembers().getRemote().sessionMemberAdd(userid,
userName,groupRole, userAvatarUrl, UserStatus, new Back.Result<sessionmember>(){
        @Override
        public void onSuccess(SessionMember sessionMember) {
                membersCount--;
                if(membersCount==0 && !iscreate){
                    pd.dismiss();
                    finish();
                }
        }
        @Override
        public void onError(int errorCode,String error) {
        }
});
                         

提醒

发起群聊,先把自己添加进去,groupRole设置为master

删除会话成员

 
session.getMembers().getRemote().sessionMemberDelete(sessionMember,new Back.Callback(){
        @Override
        public void onSuccess() {
        }
        @Override
        public void onError(int errorCode, String error) {
        }
});
                

同步会话成员

 
session.getMembers().getRemote().sync(new Back.Result<list<sessionmember>>(){
@Override
public void onSuccess(List<sessionmember>
sessionMembers) {
}
@Override
public void onError(int Code, String error) {
}
})
                

消息

消息同步

MessageEntity属性

 
String id;//消息ID
String sender;//发送者账号
String content;//消息内容
String createdAt;//创建时间
String updatedAt;//更新时间
String type;//消息类型
String status;//发送状态
String sessionId;//会话ID
                        

初次进入消息聊天界面

1.获得最后一条同步消息的更新时间

2.如果消息时间为默认时间,为了防止历史消息太多,加载时间长,加载最近20条直接显示(此数据不存储至数据库), 同时进行消息同步存到数据库,标记正在同步,如果正在同步中,接收到的新消息和发消息都不存到本地数据库,直接界面显示

 
int cout =Config.LOAD_MESSAGE_COUNT;//默认加载20条
//获得最近历史消息
_session.getMessages().getRemote().getLastMessages(cout, new Back.Result<list<messagemodel>>() {
        @Override
        public void onSuccess(List<messagemodel>
        messageModels) {
                //更新界面    
                messageList.clear();
                messageList.addAll(messageModels);
                refreshMessageList();
                scrollToBottom();
        }
        @Override
        public void onError(int errorCode,String error) {
        }
});
//开始同步
synMessagedate =new synMessagedate();
synMessagedate.start();
                            
 
boolean issyndate =false;//是否正在同步
class synMessagedate extends Thread{//同步消息
        @Override
        public void run() {
                super.run();
                //标记正在同步
                issyndate =true;
                boolean isstore= true;//是否存储到本地数据库
                String updateAt =_session.getMessages().getMessageUpdateAt();获取本地数据最后一个消息的更新时间
                _session.getMessages().getRemote().sync(isstore,updateAt, Config.LOAD_MESSAGE_COUNT, 
                        new Back.Result<list<messagemodel>>() {
                        @Override
                        public void onSuccess(List<messagemodel> models) {
                                if (models.size() < Config.LOAD_MESSAGE_COUNT) {//同步完成
                                    //每次取20条数据,如果取到的数据小于20条表示更新完成
                                    issyndate=false;
                                    messageDisplay();
                                } else {
                                   //没有更新完成,继续更新
                                    run();
                                }
                                //标记消息已读
                                setMessagenum(models.size());
                        }
                        @Override
                        public void onError(int errorCode,String error) {
                        }
                });
        }
}
   

如果消息时间不为默认时间,但是未读消息大于20条执行上面第2条操作,如果未读消息小于或者等于20条,直接同步更新

 
_session.getMessages().getRemote().sync(true,_session.getMessages().getMessageUpdateAt(), unread, new Back.Result<list<messagemodel>
>() {
@Override
public void onSuccess(List<messagemodel>
models) {
    setMessagenum(models.size());
    //初始化listview加载本地消息更新
    messageDisplay();
}
@Override
public void onError(int errorCode,String error) {
      messageDisplay();
}
});
                           

有新的消息,同步新消息

为了防止频繁同步消息,如果接收到消息通知,先判断messageLoading是否正在同步消息,如果正在同步, 标记hasNewMessage,表示有新的消息过来,等上次同步完成判断hasNewMessage是否有新消息,如果有,继续同步

 
if(messageLoading){
      hasNewMessage = true;
}else{
      loadNewMessage();
}
                        
                        
 
private void loadNewMessage(){
            final int unread = 50;//默认一次加载消息条数
            messageLoading = true;//标记正在同步消息
            hasNewMessage = false;//标记没有新消息
            //issyndate判断是否有初始同步消息如果有就不存储到数据库
            _session.getMessages().getRemote().sync(!issyndate,_session.getMessages().getMessageUpdateAt(), 
                        unread, new Back.Result<list <messagemodel>>() {
                        @Override
                        public void onSuccess(List<messagemodel>
                        models) {
                                boolean istobottom =false;
                                int lastnum =lv_message.getLastVisiblePosition();
                                if(lastnum >=(messageList.size()-1))
                                istobottom =true;
                                if(models!=null&&models.size()>0){
                                boolean find =false;
                                List<messagemodel>
                                tempmodels = new ArrayList<messagemodel>();
                                //去掉重复的
                                for(int i =0;i<messagelist.size();i++){ if(!find) {
                                    if (models.get(0).getentity().getid().equals
                                     (messagelist.get(i).getentity().getid())) {
                                        find=true;
                                        tempmodels.add(messagelist.get(i));
                                    }
                                    }else{
                                         tempmodels.add(messagelist.get(i));
                                    }
                                }
                                if(find){
                                    messagelist.removeall(tempmodels);
                                }
                                messagelist.addall(models);
                                refreshmessagelist();
                                if(istobottom)
                                scrolltobottom();
                                }
                                if(!issyndate){
                                     setmessagenum(models.size());
                                }
                                if(models= =null||models.size()<unread){ //判断是否同步完成
                                     messageloading=false;
                                     if(hasnewmessage){//同步完成,发现有新的消息,继续同步
                                          loadnewmessage();
                                      }
                                }else{//没有完成继续同步
                                     loadnewmessage();
                                }
                        }
                        @override
                        public void onerror(int errorcode,string error) {
                                messageloading=false;
                                if(hasnewmessage){
                                loadnewmessage();
                          }
                        }
            });
            return;
}
                            

发送文字消息

 
//创建消息Model
final MessageModel temp = _session.getMessages().createMessage(MessageCrypto.getInstance().encryText(sendtext), MessageType.Text);
//消息添加到界面更新
messageList.add(temp);
scrollToBottom();
adapter.updateListView(messageList);
et_input.setText("");
//存储 发送推送
_session.getMessages().getRemote().store(temp, new Back.Result<messagemodel>() {
        @Override
        public void onSuccess(MessageModel model) {
            //同步消息
            temp.getEntity().setId(model.getEntity().getId());
            updatechatHandler.sendEmptyMessage(2);
        }
        @Override
        public void onError(int errorCode,String error) {
           //model.getEntity().setStatus(MessageEntity.MessageState.storeFailed.toString());
        }
});
                          

自定义消息

一、添加类型

找到包名:package y2w.model.messages下的MessageType.class修改如下:


public final static int MessageTypeCount = 16;//每增加一个消息此处数字加2
public static String Location = "location";
public static String Task = "task";
public static String Av = "av";
//添加一个自定义类型

public final static int LocationRight = 10 ;
public final static int AVRight = 12 ;
public final static int TaskRight = 14 ;

public final static int LocationLeft = 11 ;
public final static int AVLeft = 13 ;
public final static int TaskLeft = 15 ;
//添加自己和对方消息类型
                            

二、初始界面

找到包名:package y2w.ui.adapter下的MessageAdapter.class修改如下:


//确定消息是来自自己的还是别人的
 private int getMessageViewType(int position) {
String type = models.get(position).getEntity().getType();
if(MessageType.System.equals(type)){
    return MessageType.TextSystem;
}
else if (MessageType.Text.equals(type)) {
    return isMySide(position) ? MessageType.TextRight
            : MessageType.TextLeft;
}  else if (MessageType.Task.equals(type)) {
    return isMySide(position) ? MessageType.TaskRight
            : MessageType.TaskLeft;
}

//界面初始化
 public View getView(int position, View view, ViewGroup parent) {
int type = getItemViewType(position);
MessageModel model = this.models.get(position);
try {
    if (view == null) {
        viewHolder = new MViewHolder();
        switch (type) {
            /*********** 系统 ***********/
            case MessageType.TextSystem:
                view = messageView.systemTextInit(viewHolder);
                break;
            /*********** 文本 ***********/
            case MessageType.TextRight:
                view = messageView.mySideTextInit(viewHolder);
                break;
            case MessageType.TextLeft:
                view = messageView.otherSideTextInit(viewHolder);
                break;
                            

三、显示处理消息


public void messagedisplay(MessageModel model,MViewHolder viewHolder,int position){
try{
    int type = getItemViewType(position);
    switch (type) {
        /*********** 系统 ***********/
        case MessageType.TextSystem:
            messageDisplay.systemTextDisplay(model,viewHolder, position);
            break;
        /*********** 文本 ***********/
        case MessageType.TextRight:
            messageDisplay.setMySideTextDisplay(model,viewHolder, position);
            break;
        case MessageType.TextLeft:
            messageDisplay.setOtherSideTextDisplay(model, viewHolder, position);
            break;                                         
    

推送服务

SDK初始化

applicationonCreate方法加入如下:


IMClient.init(this);
                            

连接服务器

连接服务器前,确认已通过yun2win Server API 接口获取 Token ,将获得的 Token 传入 connect 方法,开始连接服务器。在整个应用程序全局,只需要调用一次 connect 方法,SDK 会负责自动重连。 执行:


Users.getInstance().getCurrentUser().getImBridges().connect();
public void connect(){
        final Handler handler = new Handler(){
                        @Override
                        public void handleMessage(Message msg) {
                                if(msg.what == 1){
                                    MToken mToken = (MToken) msg.obj;
                                    user.setImToken(mToken);
                                    imBridge = new IMBridge(user);
                                    imBridge.connect(new IMClient.onConnectionStatusChanged() {
                                            @Override
                                            public void onChanged(int status, int error) {				//服务器连接状态
                                            }
                                            }, new IMClient.OnMessageReceiveListener() {
                                            @Override
                                            public void onMessage(String message, IMSession imSession, String sendMsg, String data) {
                                                 //接收服务器推送消息
                                            }
                                    });
                                }else{
                                    LogUtil.getInstance().log(TAG,"get imToken failure",null);
                                }
                        }
                };
                //获取IMToken
                user.getImToken(new Back.Result<mtoken>() {
                    @Override
                    public void onSuccess(MToken mToken) {
                        Message msg = new Message();
                        msg.what = 1;
                        msg.obj = mToken;
                        handler.sendMessage(msg);
                    }
                    @Override
                    public void onError(int errorCode,String error) {
                        Message msg = new Message();
                        msg.what = -1;
                        handler.sendMessage(msg);
                    }
        });
}
                            

发送推送消息


public void sendMessage(Session session,String message,IMClient.SendCallback callback){
        IMSession imSession = new IMSession();
        String sessionId = session.getEntity().getType() + "_" + session.getEntity().getId();
        imSession.setId(sessionId);
        imSession.setMts(session.getMessages().getTimeStamp());
        imClient.sendMessage(imSession, CmdBuilder.buildMessage(sessionId), callback);
}                                                   
    

更新会话


public void updateSession(IMSession imSession,String members,IMClient.SendCallback callback){
     imClient.updateSession(imSession, members, callback);
}

用户手册

Demo手册     SDK手册