环信简单实现

jar

依赖

compile 'com.android.support:appcompat-v7:26.1.0'
compile 'com.android.support:cardview-v7:26.1.0'
compile 'com.android.support:recyclerview-v7:26.1.0'

环信开发账号的注册

Android Studio可以直接添加依赖

将以下代码放到项目根目录的build.gradle文件里

repositories { maven { url "https://raw.githubusercontent.com/HyphenateInc/Hyphenate-SDK-Android/master/repository" } }

在你的module的build.gradle里加入以下代码

android { //use legacy for android 6.0 useLibrary 'org.apache.http.legacy' } dependencies { compile 'com.android.support:appcompat-v7:23.4.0' //Optional compile for GCM (Google Cloud Messaging). compile 'com.google.android.gms:play-services-gcm:9.4.0' compile 'com.hyphenate:hyphenate-sdk:3.2.3' }

如果想使用不包含音视频通话的sdk,用compile 'com.hyphenate:hyphenate-sdk-lite:3.2.3'

权限

<!-- 环信 -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

application标签内

android:name=".MyApplication"
<!-- 设置环信应用的AppKey -->
<meta-data
    android:name="EASEMOB_APPKEY"
    android:value="1101170121178296#qqchat"/>
<!-- 声明SDK所需的service SDK核心功能 -->
<service
    android:name="com.hyphenate.chat.EMChatService"
    android:exported="true" />
<service
    android:name="com.hyphenate.chat.EMJobService"
    android:exported="true"
    android:permission="android.permission.BIND_JOB_SERVICE" />
<!-- 声明SDK所需的receiver -->
<receiver android:name="com.hyphenate.chat.EMMonitorReceiver">
    <intent-filter>
        <action android:name="android.intent.action.PACKAGE_REMOVED" />

        <data android:scheme="package" />
    </intent-filter>
    <!-- 可选filter -->
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.intent.action.USER_PRESENT" />
    </intent-filter>
</receiver>

APP打包混淆

-keep class com.hyphenate.** {*;}
-dontwarn  com.hyphenate.**

消息类的封装

public class MSG {
    public static final int TYPE_RECEIVED = 0;//消息的类型:接收
    public static final int TYPE_SEND = 1;    //消息的类型:发送

    private String content;

    private int type;

    public MSG(String content, int type) {
        this.content = content;
        this.type = type;
    }

    public String getContent() {
        return content;
    }

    public int getType() {
        return type;
    }
}

RecyclerView子项的布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:cardview="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/ll_msg_left"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?android:attr/selectableItemBackground"
        android:clickable="true"
        android:focusable="true"
        android:orientation="horizontal"
        android:padding="2dp">

        <android.support.v7.widget.CardView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:cardCornerRadius="20dp"
            app:cardPreventCornerOverlap="false"
            app:cardUseCompatPadding="true">

            <ImageView
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:scaleType="centerCrop"
                 />
        </android.support.v7.widget.CardView>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/chating_left_01_on"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/tv_msg_left"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_margin="10dp"
                android:textColor="#fff" />
        </LinearLayout>

    </LinearLayout>

    <LinearLayout
        android:id="@+id/ll_msg_right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:background="?android:attr/selectableItemBackground"
        android:clickable="true"
        android:focusable="true"
        android:orientation="horizontal"
        android:padding="2dp">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/chating_right_02"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/tv_msg_right"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_margin="10dp" />
        </LinearLayout>

        <android.support.v7.widget.CardView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:cardCornerRadius="20dp"
            app:cardPreventCornerOverlap="false"
            app:cardUseCompatPadding="true">

            <ImageView
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:scaleType="centerCrop" />

        </android.support.v7.widget.CardView>
    </LinearLayout>
</RelativeLayout>

RecyclerView适配器

public class MsgAdapter extends RecyclerView.Adapter<MsgAdapter.MyViewHolder> {

    private List<MSG> mMsgList;

    public MsgAdapter(List<MSG> mMsgList) {
        this.mMsgList = mMsgList;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = View.inflate(parent.getContext(), R.layout.item_msg, null);
        MyViewHolder holder = new MyViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        MSG msg = mMsgList.get(position);
        if (msg.getType() == MSG.TYPE_RECEIVED){
            holder.llLeft.setVisibility(View.VISIBLE);
            holder.llRight.setVisibility(View.GONE);
            holder.tv_Left.setText(msg.getContent());
        } else if (msg.getType() == MSG.TYPE_SEND){
            holder.llLeft.setVisibility(View.GONE);
            holder.llRight.setVisibility(View.VISIBLE);
            holder.tv_Right.setText(msg.getContent());
        }
    }

    @Override
    public int getItemCount() {
        return mMsgList.size();
    }

    static class MyViewHolder extends RecyclerView.ViewHolder{

        LinearLayout llLeft;
        LinearLayout llRight;
        TextView tv_Left;
        TextView tv_Right;
        public MyViewHolder(View itemView) {
            super(itemView);

            llLeft = (LinearLayout) itemView.findViewById(R.id.ll_msg_left);
            llRight = (LinearLayout) itemView.findViewById(R.id.ll_msg_right);

            tv_Left = (TextView) itemView.findViewById(R.id.tv_msg_left);
            tv_Right = (TextView) itemView.findViewById(R.id.tv_msg_right);

        }
    }
}

初始化SDK

在自定义Application的onCreate中初始化

public class MyApplication extends Application {

    private Context appContext;

    @Override
    public void onCreate() {
        super.onCreate();

        EMOptions options = new EMOptions();
        options.setAcceptInvitationAlways(false);

        appContext = this;
        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(appContext.getPackageName())) {
            Log.e("--->", "enter the service process!");

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

        //初始化
        EMClient.getInstance().init(getApplicationContext(), 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;
    }
}

第一个注册页面

package xiaweizi.com.qqchat;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
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.chat.EMClient;
import com.hyphenate.exceptions.HyphenateException;

public class RegistActivity extends AppCompatActivity {

    private static final String TAG = "--->";

    private EditText etName;
    private EditText etPassword;
    private Button btRegister;
    private Button btLogin;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_regist);

        etName = (EditText) findViewById(R.id.et_register_name);
        etPassword = (EditText) findViewById(R.id.et_register_password);

        btLogin = (Button) findViewById(R.id.bt_login);
        btRegister = (Button) findViewById(R.id.bt_register);

        btRegister.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {

                            String name = etName.getText().toString().trim();
                            String password = etPassword.getText().toString().trim();

                            if (TextUtils.isEmpty(name) || TextUtils.isEmpty(password)){
                                return;
                            }

                            EMClient.getInstance().createAccount(name, password);
                            toast("注册成功");

                        } catch (HyphenateException e) {
                            e.printStackTrace();
                            Log.i(TAG, "run: " + e);
                            toast("注册失败" + e.getDescription());
                        }
                    }
                }).start();
            }
        });

        btLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String name = etName.getText().toString().trim();
                String password = etPassword.getText().toString().trim();

                if (TextUtils.isEmpty(name) || TextUtils.isEmpty(password)){
                    return;
                }

                EMClient.getInstance().login(name,password,new EMCallBack() {//回调
                    @Override
                    public void onSuccess() {
                        EMClient.getInstance().groupManager().loadAllGroups();
                        EMClient.getInstance().chatManager().loadAllConversations();
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(RegistActivity.this, "登陆成功!", Toast.LENGTH_SHORT).show();
                                //进入聊天界面
                                startActivity(new Intent(RegistActivity.this, StartActivity.class));
                                finish();
                            }
                        });
                    }  

                    @Override
                    public void onProgress(int progress, String status) {

                    }

                    @Override
                    public void onError(int code, String message) {
                        startActivity(new Intent(RegistActivity.this, StartActivity.class));
                        toast("登陆失败" + message);
                    }
                });

            }
        });


    }

    private void toast(final String msg){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(RegistActivity.this, msg, Toast.LENGTH_SHORT).show();
            }
        });
    }
}

第二个匹配页面

package xiaweizi.com.qqchat;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class StartActivity extends AppCompatActivity {

    private EditText etChatFriend;
    private Button btStartChat;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start);
        etChatFriend = (EditText) findViewById(R.id.et_chat_friend);
        btStartChat = (Button) findViewById(R.id.bt_start_chat);

        btStartChat.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String friend = etChatFriend.getText().toString().trim();
                if (TextUtils.isEmpty(friend))
                    return;

                Intent intent = new Intent(StartActivity.this, ChatActivity.class);
                intent.putExtra("friend", friend);
                startActivity(intent);
                finish();


            }
        });
    }
}

第三个聊天页面

package xiaweizi.com.qqchat;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;

import com.hyphenate.EMMessageListener;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMMessage;

import java.util.ArrayList;
import java.util.List;

public class ChatActivity extends AppCompatActivity {

    private static final String TAG = "ChatActivity--->";

    private MsgAdapter mAdapter;

    private RecyclerView mRecyclerView;
    private EditText etInput;
    private Button btSend;

    private List<MSG> mList;

    private String friend;
    private EMMessageListener msgListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
        setContentView(R.layout.activity_main);

        friend = getIntent().getStringExtra("friend");
        Log.i(TAG, "onCreate: " + friend);

        mRecyclerView = (RecyclerView) findViewById(R.id.rv_chat);
        etInput = (EditText) findViewById(R.id.et_input);
        btSend = (Button) findViewById(R.id.bt_send);

        initData();
        mAdapter = new MsgAdapter(mList);

        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mRecyclerView.setAdapter(mAdapter);

        btSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String content = etInput.getText().toString().trim();
                if (!TextUtils.isEmpty(content)){

                    //创建一条文本消息,content为消息文字内容,toChatUsername为对方用户或者群聊的id,后文皆是如此
                    EMMessage message = EMMessage.createTxtSendMessage(content, friend);
                    //发送消息
                    EMClient.getInstance().chatManager().sendMessage(message);
                    Log.i(TAG, "发送成功!");

                    MSG msg = new MSG(content, MSG.TYPE_SEND);
                    mList.add(msg);
                    mAdapter.notifyItemInserted(mList.size() - 1);
                    mRecyclerView.scrollToPosition(mList.size() - 1);
                    etInput.setText("");
                }
            }
        });

        //收到消息
        //收到透传消息
        //消息状态变动
        msgListener = new EMMessageListener() {

            @Override
            public void onMessageReceived(List<EMMessage> messages) {
                //收到消息
                String result = messages.get(0).getBody().toString();
                String msgReceived = result.substring(5, result.length() - 1);

                Log.i(TAG, "onMessageReceived: " + msgReceived);
                final MSG msg = new MSG(msgReceived, MSG.TYPE_RECEIVED);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mList.add(msg);
                        mAdapter.notifyDataSetChanged();
                        mRecyclerView.scrollToPosition(mList.size() - 1);
                    }
                });

            }

            @Override
            public void onCmdMessageReceived(List<EMMessage> messages) {
                //收到透传消息
            }

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

            }

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

            }

            @Override
            public void onMessageChanged(EMMessage message, Object change) {
                //消息状态变动
            }
        };
        EMClient.getInstance().chatManager().addMessageListener(msgListener);
    }

    @Override
    protected void onResume() {
        super.onResume();


    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EMClient.getInstance().chatManager().removeMessageListener(msgListener);
    }

    private void initData() {
        mList = new ArrayList<>();
        mList.add(new MSG("日照香炉生紫烟,你与何人在聊天" , MSG.TYPE_SEND));
        mList.add(new MSG("黄河之水天上来,就是普通一女孩" , MSG.TYPE_RECEIVED));
        mList.add(new MSG("万水千山只等闲,微信闲扯这么甜" , MSG.TYPE_SEND));
        mList.add(new MSG("日出江花红胜火,我俩只是谈工作" , MSG.TYPE_RECEIVED));
        mList.add(new MSG("曾经沧海难为水,你俩肯定有一腿" , MSG.TYPE_SEND));
        mList.add(new MSG("除却巫山不是云,谁要骗你不是人" , MSG.TYPE_RECEIVED));
    }
}

猜你喜欢

转载自my.oschina.net/u/3737161/blog/1631925
今日推荐