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>
原创粉丝点击