环信称自己市场占有第一,这次试着集成环信
不过一开始就被坑了,环信的UI组件库叫做 EaseUI ,这玩意居然只有eclipse的版本,官方文档说Android Studio导入有问题,要手动改,这一点不如融云
不过找到了一篇博客,直接新建module复制关键文件,终于搞定了
若出现UnsatisfiedLinkError 创建armeabi-v7a,把armeabi里的复制一份放进去
聊天3个基本页面 会话列表页面,联系人页面,聊天页面 都是Fragment
会话列表 ConversationListFragment
initView里面是没网的时候,显示在item上面的布局 , 监听连接是否成功和断开的方法没写
17行 隐藏 标题栏
20行设置了 点击会话item的事件,拿到EMConversation对象,通过它可以获取对方的username,会话的类型,把必要的参数交给intent,进入聊天页面
19行 给列表绑定 onCreateContextMenu 事件,长按就会弹出菜单,onContextItemSelected执行点击的结果, 类似actionbar的菜单事件
1 public class ConversationListFragment extends EaseConversationListFragment { 2 3 private TextView errorText; 4 5 @Override 6 protected void initView() { 7 super.initView(); 8 View errorView = View.inflate(getActivity(), R.layout.em_chat_neterror_item, null); 9 errorItemContainer.addView(errorView); 10 errorText = (TextView) errorView.findViewById(R.id.tv_connect_errormsg); 11 } 12 13 14 @Override 15 protected void setUpView() { 16 super.setUpView(); 17 titleBar.setVisibility(View.GONE); 18 // 注册上下文菜单 19 registerForContextMenu(conversationListView); 20 conversationListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 21 @Override 22 public void onItemClick(AdapterView<?> adapterView, View view, int pos, long id) { 23 EMConversation conversation = conversationListView.getItem(pos); 24 String name = conversation.getUserName(); 25 if (name.equals(EMClient.getInstance().getCurrentUser())) { 26 Logger.e("不能自己聊"); 27 } else { 28 Intent intent = new Intent(getActivity(), ChatActivity.class); 29 if (conversation.isGroup()) { 30 if (conversation.getType() == EMConversation.EMConversationType.ChatRoom) { 31 intent.putExtra("type", EaseConstant.CHATTYPE_CHATROOM); 32 } else { 33 intent.putExtra("type", EaseConstant.CHATTYPE_GROUP); 34 } 35 } 36 intent.putExtra("id", name); 37 startActivity(intent); 38 } 39 40 } 41 }); 42 43 } 44 45 @Override 46 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { 47 getActivity().getMenuInflater().inflate(R.menu.conversationlist, menu); 48 } 49 50 @Override 51 public boolean onContextItemSelected(MenuItem item) { 52 if (item.getItemId() == R.id.delete) { 53 EMConversation tobeDeleteCons = conversationListView.getItem(((AdapterView.AdapterContextMenuInfo) item 54 .getMenuInfo()).position); 55 String username = tobeDeleteCons.getUserName(); 56 //删除和某个user会话,如果需要保留聊天记录,传false 57 EMClient.getInstance().chatManager().deleteConversation(username, true); 58 } else if (item.getItemId() == R.id.test) { 59 Logger.e("test"); 60 } 61 return true; 62 } 63 }
聊天页面是activity
10 11 获取传入的参数,用然后启动 EaseChatFragment,直接整个布局容纳fragment
主要只要传如联系人的id或者群组的id就够了
1 public class ChatActivity extends AppCompatActivity { 2 3 private EaseChatFragment chatFragment; 4 5 @Override 6 protected void onCreate(Bundle savedInstanceState) { 7 super.onCreate(savedInstanceState); 8 setContentView(R.layout.activity_chat); 9 ButterKnife.bind(this); 10 String name=getIntent().getExtras().getString("username"); 11 int type=getIntent().getExtras().getInt("type"); 12 13 chatFragment = new EaseChatFragment(); 14 15 Bundle bundle=new Bundle(); 16 bundle.putString(EaseConstant.EXTRA_USER_ID,name); 17 bundle.putInt(EaseConstant.EXTRA_CHAT_TYPE,type); 18 chatFragment.setArguments(bundle); 19 getSupportFragmentManager().beginTransaction().add(R.id.container, chatFragment).commit(); 20 21 } 22 @Override 23 public void onBackPressed() { 24 chatFragment.onBackPressed(); 25 } 26 }
发送位置这块,sdk已经做好,但是没有在AndroidManifest 配置就要报错了
在module的AndroidManifest 直接写上
<activity android:name=".ui.EaseBaiduMapActivity"></activity> <!-- 百度地图所需的service --> <service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" /> <meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="3ecea51f560650b1ed8a4b99808f52e8" />
如果想要实现 点击头像,点击消息框的事件 就要新建一个 fragment 继承EaseChatFragment
重写方法

messageList = (EaseChatMessageList) getView().findViewById(R.id.message_list); //初始化messagelist messageList.init(toChatUsername, chatType, null); //设置item里的控件的点击事件 messageList.setItemClickListener(new EaseChatMessageList.MessageListItemClickListener() { @Override public void onUserAvatarClick(String username) { //头像点击事件 } @Override public void onResendClick(final EMMessage message) { //重发消息按钮点击事件 } @Override public void onBubbleLongClick(EMMessage message) { //气泡框长按事件 } @Override public boolean onBubbleClick(EMMessage message) { //气泡框点击事件,EaseUI有默认实现这个事件,如果需要覆盖,return值要返回true return false; } }); //获取下拉刷新控件 swipeRefreshLayout = messageList.getSwipeRefreshLayout(); //刷新消息列表 messageList.refresh(); messageList.refreshSeekTo(position); messageList.refreshSelectLast();
联系人页面
值得注意的是 联系人界面有一些 固定到顶部的item,这里也都封装好了,在initView里定义好headerview ,找到控件设置点击事件,再用listview 的addHeaderView
其次要注意的是 联系人的数据 这个在setUpView中用setContactsMap设置,一般来说都是从服务器获取,自然就需要加载时间了,可以设置loadingView,再加载数据时显示,完毕隐藏
1 public class ContactListFragment extends EaseContactListFragment { 2 3 private View loadingView; 4 private ContactItemView applicationItem; 5 6 7 @Override 8 protected void initView() { 9 super.initView(); 10 View headerView = LayoutInflater.from(getActivity()).inflate(R.layout.em_contacts_header, null); 11 HeaderItemClickListener listener = new HeaderItemClickListener(); 12 applicationItem = (ContactItemView) headerView.findViewById(R.id.application_item); 13 applicationItem.setOnClickListener(listener); 14 headerView.findViewById(R.id.group_item).setOnClickListener(listener); 15 listView.addHeaderView(headerView); 16 17 //添加正在加载数据提示的loading view 18 loadingView = LayoutInflater.from(getActivity()).inflate(R.layout.em_layout_loading_data, null); 19 contentContainer.addView(loadingView); 20 21 //注册上下文菜单 22 registerForContextMenu(listView); 23 24 } 25 26 @Override 27 protected void setUpView() { 28 super.setUpView(); 29 Map<String, EaseUser> userMap = new HashMap<>(); 30 for (int i = 1; i < 20; i++) { 31 EaseUser easeUser = new EaseUser("User " + i); 32 userMap.put(" " + i, easeUser); 33 } 34 setContactsMap(userMap); 35 super.setUpView(); 36 } 37 38 39 class HeaderItemClickListener implements View.OnClickListener { 40 @Override 41 public void onClick(View view) { 42 switch (view.getId()) { 43 case R.id.application_item: 44 Toast.makeText(getActivity(), "application_item", 0).show(); 45 break; 46 case R.id.group_item: 47 Toast.makeText(getActivity(), "group_item", 0).show(); 48 break; 49 } 50 } 51 } 52 53 }