安卓開發中使用環信進行IM及時通訊

搞了兩天,實現了最基本的兩臺手機之間的文字通訊,寫下經驗給後學者,免得踩坑;
在這裏插入圖片描述

參考視頻:

從騰訊課堂上的環信IM公開課,Android_SDK集成參考視頻

步驟:

首先下載sdk,解壓後把libs.lite中的jar包放在項目app下的libs包中,點右鍵Add as library
在src下的main下新建一個jniLibs的directory,把libs.lite剩下幾個放進去

menifest中權限

<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.ACCESS_MOCK_LOCATION" />
    <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:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:name=".MyApplication"
        android:usesCleartextTraffic="true"
        android:theme="@style/AppTheme">
<activity android:name=".ChatActivity"></activity>
        <uses-library android:name="org.apache.http.legacy" android:required="false" />

        <meta-data
            android:name="EASEMOB_APPKEY"
            android:value="這裏填入你自己的appkey" /> <!-- 聲明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>

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

在build.gradle的android{}中加入

compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

啓動類MyApplication


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;

public class MyApplication extends Application {
    private static final String TAG = "MyApplication";

    @Override
    public void onCreate() {
        super.onCreate();
        //配置信息
        EMOptions options = new EMOptions();
// 默認添加好友時,是不需要驗證的,改成需要驗證
        options.setAcceptInvitationAlways(false);
// 是否自動將消息附件上傳到環信服務器,默認爲True是使用環信服務器上傳下載,如果設爲 false,需要開發者自己處理附件消息的上傳和下載
        options.setAutoTransferMessageAttachments(true);
// 是否自動下載附件類消息的縮略圖等,默認爲 true 這裏和上邊這個參數相關聯
        options.setAutoDownloadThumbnail(true);
        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(TAG, "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;
    }
}

activity_main(註冊登錄的那個界面)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/username"
        android:hint="用戶名"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <EditText
        android:id="@+id/password"
        android:hint="密碼"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <Button
        android:id="@+id/logup"
        android:layout_gravity="center"
        android:text="註冊"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <Button
        android:id="@+id/login"
        android:text="登錄"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>


</LinearLayout>

MainActivity(登錄註冊界面)


import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.hyphenate.EMCallBack;
import com.hyphenate.chat.EMClient;
import com.hyphenate.exceptions.HyphenateException;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    EditText username;
    EditText password;
    Button login;
    Button logup;
    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        username = findViewById(R.id.username);
        password = findViewById(R.id.password);
        login = findViewById(R.id.login);
        logup = findViewById(R.id.logup);
        logup.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                signup();
            }
        });
        login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                signin();
            }
        });

    }

    public String gettext(EditText editText){
        return editText.getText().toString();
    }

    private void signup(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    EMClient.getInstance().createAccount(gettext(username),gettext(password));
                    Log.i(TAG, "註冊成功");
                } catch (HyphenateException e) {
                    e.printStackTrace();
                    Log.e(TAG, "註冊失敗"+e.getErrorCode()+","+e.getDescription() );
                }
            }
        }).start();
    }

    private void signin(){
        EMClient.getInstance().login(gettext(username), gettext(password), new EMCallBack() {
            @Override
            public void onSuccess() {
                startActivity(new Intent(MainActivity.this,ChatActivity.class));
                finish();
            }

            @Override
            public void onError(int i, String s) {
                Log.e(TAG, "登陸失敗"+i+","+s );
            }

            @Override
            public void onProgress(int i, String s) {

            }
        });
    }
}

activity_chat(聊天界面)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".ChatActivity">

    <TextView
        android:id="@+id/tv_info"
        android:text=""
        android:layout_width="match_parent"
        android:background="#fff000"
        android:textSize="17sp"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <EditText
        android:id="@+id/ed_id"
        android:hint="對方的id"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <EditText
        android:id="@+id/ed_send"
        android:hint="要發送的消息"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <Button
        android:id="@+id/bt_send"
        android:text="發送消息"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <Button
        android:id="@+id/bt_quit"
        android:text="退出登錄"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

ChatActivity(聊天界面)


import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
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.EMMessage;
import com.hyphenate.chat.EMTextMessageBody;

import java.util.List;

import androidx.appcompat.app.AppCompatActivity;

public class ChatActivity extends AppCompatActivity implements EMMessageListener {
    TextView tv_info;
    EditText ed_id, ed_send;
    Button bt_send;
    Button bt_quit;
    private static final String TAG = "ChatActivity";
    Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);
        tv_info = findViewById(R.id.tv_info);
        ed_id = findViewById(R.id.ed_id);
        ed_send = findViewById(R.id.ed_send);
        bt_send = findViewById(R.id.bt_send);
        bt_quit = findViewById(R.id.bt_quit);
        bt_send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //String content = ed_send.getText().toString();
                EMMessage message = EMMessage.createTxtSendMessage(gettext(ed_send), gettext(ed_id));
//如果是羣聊,設置chattype,默認是單聊
                message.setChatType(EMMessage.ChatType.Chat);
//發送消息
                EMClient.getInstance().chatManager().sendMessage(message);
                tv_info.setText(tv_info.getText() + "\n" + gettext(ed_id) + ":" + gettext(ed_send));
                message.setMessageStatusCallback(new EMCallBack() {
                    @Override
                    public void onSuccess() {
                        Log.i(TAG, "消息發送成功");
                    }

                    @Override
                    public void onError(int i, String s) {
                        Log.e(TAG, "消息發送失敗 " + i + "," + s);
                    }

                    @Override
                    public void onProgress(int i, String s) {

                    }
                });
            }
        });
        bt_quit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                signout();
            }
        });
    }

    private String gettext(EditText editText) {
        return editText.getText().toString();
    }


    @Override
    public void onMessageReceived(List<EMMessage> list) {
        for (EMMessage message : list) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tv_info.setText(tv_info.getText() + "\n" + ((EMTextMessageBody) message.getBody()).getMessage());
                }
            });
        }
    }

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

    }

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

    }

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

    }

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

    }

    @Override
    public void onMessageChanged(EMMessage emMessage, Object o) {

    }

    @Override
    protected void onResume() {
        super.onResume();
        EMClient.getInstance().chatManager().addMessageListener(this);
    }


    //在destroy中註冊,如果在onStop中就是隻要看其他應用就會收不到消息
    @Override
    protected void onDestroy() {
        super.onDestroy();
        EMClient.getInstance().chatManager().removeMessageListener(this);
        //signout();
    }

    private void signout() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                EMClient.getInstance().logout(true);
            }
        }).start();
        EMClient.getInstance().chatManager().removeMessageListener(this);
        startActivity(new Intent(ChatActivity.this, MainActivity.class));
        finish();
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章