IMHuanXin环信
来源:互联网 发布:卓讯数据库 编辑:程序博客网 时间:2024/06/09 15:00
MainActivity内容
import android.content.Intent;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.text.TextUtils;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;import com.hyphenate.EMCallBack;import com.hyphenate.chat.EMClient;public class MainActivity extends AppCompatActivity { // 发起聊天 username 输入框 private EditText mChatIdEdit; // 发起聊天 private Button mStartChatBtn; // 退出登录 private Button mSignOutBtn; private TextView mTv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 判断sdk是否登录成功过,并没有退出和被踢,否则跳转到登陆界面 if (!EMClient.getInstance().isLoggedInBefore()) { Intent intent = new Intent(MainActivity.this,LoginActivity.class); startActivity(intent); finish(); return; } setContentView(R.layout.activity_main); initView(); } /** * 初始化界面 */ private void initView() { mTv = (TextView) findViewById(R.id.tv_id); mChatIdEdit = (EditText) findViewById(R.id.ec_edit_chat_id); mStartChatBtn = (Button) findViewById(R.id.ec_btn_start_chat); // 获取当前登录用户的 username final String currUsername = EMClient.getInstance().getCurrentUser(); mTv.setText(currUsername); mStartChatBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 获取我们发起聊天的者的username String chatId = mChatIdEdit.getText().toString().trim(); if (!TextUtils.isEmpty(chatId)) { // 获取当前登录用户的 username // String currUsername = EMClient.getInstance().getCurrentUser(); if (chatId.equals(currUsername)) { Toast.makeText(MainActivity.this, "不能和自己聊天", Toast.LENGTH_SHORT).show(); return; } // 跳转到聊天界面,开始聊天 Intent intent = new Intent(MainActivity.this, ChatActivity.class); intent.putExtra("ec_chat_id", chatId); startActivity(intent); } else { Toast.makeText(MainActivity.this, "Username 不能为空", Toast.LENGTH_LONG).show(); } } }); mSignOutBtn = (Button) findViewById(R.id.ec_btn_sign_out); mSignOutBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { signOut(); } }); } /** * 退出登录 */ private void signOut() { // 调用sdk的退出登录方法,第一个参数表示是否解绑推送的token,没有使用推送或者被踢都要传false EMClient.getInstance().logout(false, new EMCallBack() { @Override public void onSuccess() { Log.i("lzan13", "logout success"); // 调用退出成功,结束app finish(); } @Override public void onError(int i, String s) { Log.i("lzan13", "logout error " + i + " - " + s); } @Override public void onProgress(int i, String s) { } }); }}
App
import android.app.ActivityManager;import android.app.Application;import android.content.pm.PackageManager;import android.util.Log;import com.hyphenate.chat.EMClient;import com.hyphenate.chat.EMOptions;import java.util.Iterator;import java.util.List;/** * Created by Administrator on 2017/10/16. */public class App extends Application { @Override public void onCreate() { super.onCreate(); EMOptions options = new EMOptions(); // 默认添加好友时,是不需要验证的,改成需要验证 options.setAcceptInvitationAlways(false); 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(this.getPackageName())) { Log.e("App", "enter the service process!"); // 则此application::onCreate 是被service 调用的,直接返回 return; } //初始化 EMClient.getInstance().init(this, options); //在做打包混淆时,关闭debug模式,避免消耗不必要的资源 EMClient.getInstance().setDebugMode(true); } private String getAppName(int pID) { String processName = null; ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE); List l = am.getRunningAppProcesses(); Iterator i = l.iterator(); PackageManager pm = this.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 processName; }}
ChatActivity内容
import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.text.TextUtils;import android.text.method.ScrollingMovementMethod;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import com.hyphenate.EMCallBack;import com.hyphenate.EMMessageListener;import com.hyphenate.chat.EMClient;import com.hyphenate.chat.EMCmdMessageBody;import com.hyphenate.chat.EMConversation;import com.hyphenate.chat.EMMessage;import com.hyphenate.chat.EMTextMessageBody;import java.util.List;public class ChatActivity extends AppCompatActivity implements EMMessageListener { // 聊天信息输入框 private EditText mInputEdit; // 发送按钮 private Button mSendBtn; // 显示内容的 TextView private TextView mContentText; // 消息监听器 private EMMessageListener mMessageListener; // 当前聊天的 ID private String mChatId; // 当前会话对象 private EMConversation mConversation; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_chat); // 获取当前会话的username(如果是群聊就是群id) mChatId = getIntent().getStringExtra("ec_chat_id"); mMessageListener = this; initView(); initConversation(); } /** * 初始化界面 */ private void initView() { mInputEdit = (EditText) findViewById(R.id.ec_edit_message_input); mSendBtn = (Button) findViewById(R.id.ec_btn_send); mContentText = (TextView) findViewById(R.id.ec_text_content); // 设置textview可滚动,需配合xml布局设置 mContentText.setMovementMethod(new ScrollingMovementMethod()); // 设置发送按钮的点击事件 mSendBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String content = mInputEdit.getText().toString().trim(); if (!TextUtils.isEmpty(content)) { mInputEdit.setText(""); // 创建一条新消息,第一个参数为消息内容,第二个为接受者username EMMessage message = EMMessage.createTxtSendMessage(content, mChatId); // 将新的消息内容和时间加入到下边 mContentText.setText(mContentText.getText() + "\n发送:" + content + " - time: " + message.getMsgTime()); // 调用发送消息的方法 EMClient.getInstance().chatManager().sendMessage(message); // 为消息设置回调 message.setMessageStatusCallback(new EMCallBack() { @Override public void onSuccess() { // 消息发送成功,打印下日志,正常操作应该去刷新ui Log.i("lzan13", "send message on success"); } @Override public void onError(int i, String s) { // 消息发送失败,打印下失败的信息,正常操作应该去刷新ui Log.i("lzan13", "send message on error " + i + " - " + s); } @Override public void onProgress(int i, String s) { // 消息发送进度,一般只有在发送图片和文件等消息才会有回调,txt不回调 } }); } } }); } /** * 初始化会话对象,并且根据需要加载更多消息 */ private void initConversation() { /** * 初始化会话对象,这里有三个参数么, * 第一个表示会话的当前聊天的 useranme 或者 groupid * 第二个是绘画类型可以为空 * 第三个表示如果会话不存在是否创建 */ mConversation = EMClient.getInstance().chatManager().getConversation(mChatId, null, true); // 设置当前会话未读数为 0 mConversation.markAllMessagesAsRead(); int count = mConversation.getAllMessages().size(); if (count < mConversation.getAllMsgCount() && count < 20) { // 获取已经在列表中的最上边的一条消息id String msgId = mConversation.getAllMessages().get(0).getMsgId(); // 分页加载更多消息,需要传递已经加载的消息的最上边一条消息的id,以及需要加载的消息的条数 mConversation.loadMoreMsgFromDB(msgId, 20 - count); } // 打开聊天界面获取最后一条消息内容并显示 if (mConversation.getAllMessages().size() > 0) { EMMessage messge = mConversation.getLastMessage(); EMTextMessageBody body = (EMTextMessageBody) messge.getBody(); // 将消息内容和时间显示出来 mContentText.setText("聊天记录:" + body.getMessage() + " - time: " + mConversation.getLastMessage().getMsgTime()); } } /** * 自定义实现Handler,主要用于刷新UI操作 */ Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 0: EMMessage message = (EMMessage) msg.obj; // 这里只是简单的demo,也只是测试文字消息的收发,所以直接将body转为EMTextMessageBody去获取内容 EMTextMessageBody body = (EMTextMessageBody) message.getBody(); // 将新的消息内容和时间加入到下边 mContentText.setText(mContentText.getText() + "\n接收:" + body.getMessage() + " - time: " + message.getMsgTime()); break; } } }; @Override protected void onResume() { super.onResume(); // 添加消息监听 EMClient.getInstance().chatManager().addMessageListener(mMessageListener); } @Override protected void onStop() { super.onStop(); // 移除消息监听 EMClient.getInstance().chatManager().removeMessageListener(mMessageListener); } /** * --------------------------------- Message Listener ------------------------------------- * 环信消息监听主要方法 */ /** * 收到新消息 * * @param list 收到的新消息集合 */ @Override public void onMessageReceived(List<EMMessage> list) { // 循环遍历当前收到的消息 for (EMMessage message : list) { if (message.getFrom().equals(mChatId)) { // 设置消息为已读 mConversation.markMessageAsRead(message.getMsgId()); // 因为消息监听回调这里是非ui线程,所以要用handler去更新ui Message msg = mHandler.obtainMessage(); msg.what = 0; msg.obj = message; mHandler.sendMessage(msg); } else { // 如果消息不是当前会话的消息发送通知栏通知 } } } @Override public void onCmdMessageReceived(List<EMMessage> list) { for (int i = 0; i < list.size(); i++) { // 透传消息 EMMessage cmdMessage = list.get(i); EMCmdMessageBody body = (EMCmdMessageBody) cmdMessage.getBody(); Log.i("lzan13", body.action()); } } @Override public void onMessageRead(List<EMMessage> list) { } /** * 收到新的发送回执 * TODO 无效 暂时有bug * * @param list 收到发送回执的消息集合 */ @Override public void onMessageDelivered(List<EMMessage> list) { } /** * 收到新的已读回执 * * @param list 收到消息已读回执 */ @Override public void onMessageRecalled(List<EMMessage> list) { } /** * 消息的状态改变 * * @param emMessage 发生改变的消息 * @param o 包含改变的消息 */ @Override public void onMessageChanged(EMMessage emMessage, Object o) { }}
LoginActivity内容
import android.app.ProgressDialog;import android.content.Intent;import android.os.Bundle;import android.os.Handler;import android.support.v7.app.AppCompatActivity;import android.text.TextUtils;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;import com.hyphenate.EMCallBack;import com.hyphenate.EMError;import com.hyphenate.chat.EMClient;import com.hyphenate.exceptions.HyphenateException;public class LoginActivity extends AppCompatActivity { // 弹出框 private ProgressDialog mDialog; // username 输入框 private EditText mUsernameEdit; // 密码输入框 private EditText mPasswordEdit; // 注册按钮 private Button mSignUpBtn; // 登录按钮 private Button mSignInBtn; private Handler handler = new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); initView(); } /** * 初始化界面控件 */ private void initView() { mUsernameEdit = (EditText) findViewById(R.id.ec_edit_username); mPasswordEdit = (EditText) findViewById(R.id.ec_edit_password); mSignUpBtn = (Button) findViewById(R.id.ec_btn_sign_up); mSignUpBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { signUp(); } }); mSignInBtn = (Button) findViewById(R.id.ec_btn_sign_in); mSignInBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { signIn(); } }); } /** * 注册方法 */ private void signUp() { // 注册是耗时过程,所以要显示一个dialog来提示下用户 mDialog = new ProgressDialog(this); mDialog.setMessage("注册中,请稍后..."); mDialog.show(); new Thread(new Runnable() { @Override public void run() { try { String username = mUsernameEdit.getText().toString().trim(); String password = mPasswordEdit.getText().toString().trim(); EMClient.getInstance().createAccount(username, password); handler.post(new Runnable() { @Override public void run() { if (!LoginActivity.this.isFinishing()) { mDialog.dismiss(); } Toast.makeText(LoginActivity.this, "注册成功", Toast.LENGTH_LONG).show(); } }); } catch (final HyphenateException e) { e.printStackTrace(); handler.post(new Runnable() { @Override public void run() { if (!LoginActivity.this.isFinishing()) { mDialog.dismiss(); } /** * 关于错误码可以参考官方api详细说明 * http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1_e_m_error.html */ int errorCode = e.getErrorCode(); String message = e.getMessage(); Log.d("lzan13", String.format("sign up - errorCode:%d, errorMsg:%s", errorCode, e.getMessage())); switch (errorCode) { // 网络错误 case EMError.NETWORK_ERROR: Toast.makeText(LoginActivity.this, "网络错误 code: " + errorCode + ", message:" + message, Toast.LENGTH_LONG).show(); break; // 用户已存在 case EMError.USER_ALREADY_EXIST: Toast.makeText(LoginActivity.this, "用户已存在 code: " + errorCode + ", message:" + message, Toast.LENGTH_LONG).show(); break; // 参数不合法,一般情况是username 使用了uuid导致,不能使用uuid注册 case EMError.USER_ILLEGAL_ARGUMENT: Toast.makeText(LoginActivity.this, "参数不合法,一般情况是username 使用了uuid导致,不能使用uuid注册 code: " + errorCode + ", message:" + message, Toast.LENGTH_LONG).show(); break; // 服务器未知错误 case EMError.SERVER_UNKNOWN_ERROR: Toast.makeText(LoginActivity.this, "服务器未知错误 code: " + errorCode + ", message:" + message, Toast.LENGTH_LONG).show(); break; case EMError.USER_REG_FAILED: Toast.makeText(LoginActivity.this, "账户注册失败 code: " + errorCode + ", message:" + message, Toast.LENGTH_LONG).show(); break; default: Toast.makeText(LoginActivity.this, "ml_sign_up_failed code: " + errorCode + ", message:" + message, Toast.LENGTH_LONG).show(); break; } } }); } catch (Exception e) { e.printStackTrace(); } } }).start(); } /** * 登录方法 */ private void signIn() { mDialog = new ProgressDialog(this); mDialog.setMessage("正在登陆,请稍后..."); mDialog.show(); String username = mUsernameEdit.getText().toString().trim(); String password = mPasswordEdit.getText().toString().trim(); if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password)) { Toast.makeText(LoginActivity.this, "用户名和密码不能为空", Toast.LENGTH_LONG).show(); return; } EMClient.getInstance().login(username, password, new EMCallBack() { /** * 登陆成功的回调 */ @Override public void onSuccess() { handler.post(new Runnable() { @Override public void run() { mDialog.dismiss(); // 加载所有会话到内存 EMClient.getInstance().chatManager().loadAllConversations(); // 加载所有群组到内存,如果使用了群组的话 // EMClient.getInstance().groupManager().loadAllGroups(); // 登录成功跳转界面 Intent intent = new Intent(LoginActivity.this, MainActivity.class); startActivity(intent); finish(); } }); } /** * 登陆错误的回调 * @param i * @param s */ @Override public void onError(final int i, final String s) { runOnUiThread(new Runnable() { @Override public void run() { mDialog.dismiss(); Log.d("lzan13", "登录失败 Error code:" + i + ", message:" + s); /** * 关于错误码可以参考官方api详细说明 * http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1_e_m_error.html */ switch (i) { // 网络异常 2 case EMError.NETWORK_ERROR: Toast.makeText(LoginActivity.this, "网络错误 code: " + i + ", message:" + s, Toast.LENGTH_LONG).show(); break; // 无效的用户名 101 case EMError.INVALID_USER_NAME: Toast.makeText(LoginActivity.this, "无效的用户名 code: " + i + ", message:" + s, Toast.LENGTH_LONG).show(); break; // 无效的密码 102 case EMError.INVALID_PASSWORD: Toast.makeText(LoginActivity.this, "无效的密码 code: " + i + ", message:" + s, Toast.LENGTH_LONG).show(); break; // 用户认证失败,用户名或密码错误 202 case EMError.USER_AUTHENTICATION_FAILED: Toast.makeText(LoginActivity.this, "用户认证失败,用户名或密码错误 code: " + i + ", message:" + s, Toast.LENGTH_LONG).show(); break; // 用户不存在 204 case EMError.USER_NOT_FOUND: Toast.makeText(LoginActivity.this, "用户不存在 code: " + i + ", message:" + s, Toast.LENGTH_LONG).show(); break; // 无法访问到服务器 300 case EMError.SERVER_NOT_REACHABLE: Toast.makeText(LoginActivity.this, "无法访问到服务器 code: " + i + ", message:" + s, Toast.LENGTH_LONG).show(); break; // 等待服务器响应超时 301 case EMError.SERVER_TIMEOUT: Toast.makeText(LoginActivity.this, "等待服务器响应超时 code: " + i + ", message:" + s, Toast.LENGTH_LONG).show(); break; // 服务器繁忙 302 case EMError.SERVER_BUSY: Toast.makeText(LoginActivity.this, "服务器繁忙 code: " + i + ", message:" + s, Toast.LENGTH_LONG).show(); break; // 未知 Server 异常 303 一般断网会出现这个错误 case EMError.SERVER_UNKNOWN_ERROR: Toast.makeText(LoginActivity.this, "未知的服务器异常 code: " + i + ", message:" + s, Toast.LENGTH_LONG).show(); break; default: Toast.makeText(LoginActivity.this, "ml_sign_in_failed code: " + i + ", message:" + s, Toast.LENGTH_LONG).show(); break; } } }); } @Override public void onProgress(int i, String s) { } }); }}
activity_chat布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <!--输入框--> <RelativeLayout android:id="@+id/ec_layout_input" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true"> <Button android:id="@+id/ec_btn_send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="Send"/> <EditText android:id="@+id/ec_edit_message_input" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_toLeftOf="@id/ec_btn_send"/> </RelativeLayout> <!--展示消息内容--> <TextView android:id="@+id/ec_text_content" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/ec_layout_input" android:maxLines="15" android:scrollbars="vertical"/></RelativeLayout>
activity_login布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <EditText android:id="@+id/ec_edit_username" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="username"/> <EditText android:id="@+id/ec_edit_password" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="password"/> <Button android:id="@+id/ec_btn_sign_up" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="注册"/> <Button android:id="@+id/ec_btn_sign_in" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="登录"/> </LinearLayout></RelativeLayout>
activity_main
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="alice.bw.com.day14imhuanxin.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/tv_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="当前账号"/> <EditText android:id="@+id/ec_edit_chat_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="对方的username"/> <Button android:id="@+id/ec_btn_start_chat" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="发起聊天"/> <Button android:id="@+id/ec_btn_sign_out" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="退出登录"/> </LinearLayout></RelativeLayout>
阅读全文
0 0
- IMHuanXin环信
- 环信
- 环信
- 环信
- 环信
- 环信
- 环信
- 环信的推送
- 环信即时通讯云
- 环信im集成
- iOS-集成环信
- 环信-armeabi-v7a
- 环信架构
- 环信提示
- 环信 即时消息
- 环信客服集成
- 环信错误
- 环信web集成
- 数值计算-线性方程组求解(1)-LU分解-MATLAB实现
- E
- ubuntu14.04安装cuda8.0后,编译安装opencv2.4.13.4
- Ubuntu屏幕分辨率设置
- bzoj 5059: 前鬼后鬼的守护
- IMHuanXin环信
- 利用python进入数据分析之数据规整化:清理、转换、合并、重塑(二)
- 写爬虫时遇到的   处理
- 10月英语
- 什么是 Java 中的内部类
- Linux DRM(一)Display Server
- 自定义圆环进度条
- centos系统查看本机IP地址
- Drawerlayout