_359package io.agora.chatuikitquickstart;
_359import android.Manifest;
_359import android.os.Bundle;
_359import android.text.TextUtils;
_359import android.text.method.ScrollingMovementMethod;
_359import android.view.MotionEvent;
_359import android.view.View;
_359import android.widget.EditText;
_359import android.widget.TextView;
_359import android.widget.Toast;
_359import androidx.appcompat.app.AppCompatActivity;
_359import androidx.core.content.ContextCompat;
_359import org.json.JSONObject;
_359import java.util.HashMap;
_359import java.util.Map;
_359import io.agora.CallBack;
_359import io.agora.ConnectionListener;
_359import io.agora.Error;
_359import io.agora.chat.ChatClient;
_359import io.agora.chat.ChatMessage;
_359import io.agora.chat.ChatOptions;
_359import io.agora.chat.uikit.EaseUIKit;
_359import io.agora.chat.uikit.chat.EaseChatFragment;
_359import io.agora.chat.uikit.chat.interfaces.OnChatExtendMenuItemClickListener;
_359import io.agora.chat.uikit.chat.interfaces.OnChatInputChangeListener;
_359import io.agora.chat.uikit.chat.interfaces.OnChatRecordTouchListener;
_359import io.agora.chat.uikit.chat.interfaces.OnMessageSendCallBack;
_359import io.agora.chatuikitquickstart.utils.LogUtils;
_359import io.agora.chatuikitquickstart.utils.PermissionsManager;
_359import io.agora.cloud.HttpClientManager;
_359import io.agora.cloud.HttpResponse;
_359import io.agora.util.EMLog;
_359import static io.agora.cloud.HttpClientManager.Method_POST;
_359public class MainActivity extends AppCompatActivity {
_359 private static final String NEW_LOGIN = "NEW_LOGIN";
_359 private static final String RENEW_TOKEN = "RENEW_TOKEN";
_359 private static final String LOGIN_URL = "https://a41.chat.agora.io/app/chat/user/login";
_359 private static final String REGISTER_URL = "https://a41.chat.agora.io/app/chat/user/register";
_359 private EditText et_username;
_359 private TextView tv_log;
_359 private ConnectionListener connectionListener;
_359 protected void onCreate(Bundle savedInstanceState) {
_359 super.onCreate(savedInstanceState);
_359 setContentView(R.layout.activity_main);
_359 requestPermissions();
_359 addConnectionListener();
_359 private void initView() {
_359 et_username = findViewById(R.id.et_username);
_359 tv_log = findViewById(R.id.tv_log);
_359 tv_log.setMovementMethod(new ScrollingMovementMethod());
_359 private void requestPermissions() {
_359 checkPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE, 110);
_359//=================== init SDK start ========================
_359 private void initSDK() {
_359 ChatOptions options = new ChatOptions();
_359 // Set your appkey applied from Agora Console
_359 String sdkAppkey = getString(R.string.app_key);
_359 if(TextUtils.isEmpty(sdkAppkey)) {
_359 Toast.makeText(MainActivity.this, "You should set your AppKey first!", Toast.LENGTH_SHORT).show();
_359 // Set your appkey to options
_359 options.setAppKey(sdkAppkey);
_359 // Set whether confirmation of delivery is required by the recipient. Default: false
_359 options.setRequireDeliveryAck(true);
_359 // Set not to log in automatically
_359 options.setAutoLogin(false);
_359 // Use uikit to initialize Chat SDK
_359 EaseUIKit.getInstance().init(this, options);
_359 // Make Chat SDK debuggable
_359 ChatClient.getInstance().setDebugMode(true);
_359//=================== init SDK end ========================
_359//================= SDK listener start ====================
_359 private void addConnectionListener() {
_359 connectionListener = new ConnectionListener() {
_359 public void onConnected() {
_359 public void onDisconnected(int error) {
_359 if (error == Error.USER_REMOVED) {
_359 onUserException("account_removed");
_359 } else if (error == Error.USER_LOGIN_ANOTHER_DEVICE) {
_359 onUserException("account_conflict");
_359 } else if (error == Error.SERVER_SERVICE_RESTRICTED) {
_359 onUserException("account_forbidden");
_359 } else if (error == Error.USER_KICKED_BY_CHANGE_PASSWORD) {
_359 onUserException("account_kicked_by_change_password");
_359 } else if (error == Error.USER_KICKED_BY_OTHER_DEVICE) {
_359 onUserException("account_kicked_by_other_device");
_359 } else if(error == Error.USER_BIND_ANOTHER_DEVICE) {
_359 onUserException("user_bind_another_device");
_359 } else if(error == Error.USER_DEVICE_CHANGED) {
_359 onUserException("user_device_changed");
_359 } else if(error == Error.USER_LOGIN_TOO_MANY_DEVICES) {
_359 onUserException("user_login_too_many_devices");
_359 public void onTokenExpired() {
_359 signInWithToken(null);
_359 LogUtils.showLog(tv_log,"ConnectionListener onTokenExpired");
_359 public void onTokenWillExpire() {
_359 getTokenFromAppServer(RENEW_TOKEN);
_359 LogUtils.showLog(tv_log, "ConnectionListener onTokenWillExpire");
_359 // Call removeConnectionListener(connectionListener) when the activity is destroyed
_359 ChatClient.getInstance().addConnectionListener(connectionListener);
_359//================= SDK listener end ====================
_359//=================== click event start ========================
_359 * Sign up with username and password.
_359 public void signUp(View view) {
_359 String username = et_username.getText().toString().trim();
_359 String pwd = ((EditText) findViewById(R.id.et_pwd)).getText().toString().trim();
_359 if(TextUtils.isEmpty(username) || TextUtils.isEmpty(pwd)) {
_359 LogUtils.showErrorToast(this, tv_log, getString(R.string.username_or_pwd_miss));
_359 Map<String, String> headers = new HashMap<>();
_359 headers.put("Content-Type", "application/json");
_359 JSONObject request = new JSONObject();
_359 request.putOpt("userAccount", username);
_359 request.putOpt("userPassword", pwd);
_359 LogUtils.showErrorLog(tv_log,"begin to signUp...");
_359 HttpResponse response = HttpClientManager.httpExecute(REGISTER_URL, headers, request.toString(), Method_POST);
_359 int code= response.code;
_359 String responseInfo = response.content;
_359 if (responseInfo != null && responseInfo.length() > 0) {
_359 JSONObject object = new JSONObject(responseInfo);
_359 String resultCode = object.getString("code");
_359 if(resultCode.equals("RES_OK")) {
_359 LogUtils.showToast(MainActivity.this, tv_log, getString(R.string.sign_up_success));
_359 String errorInfo = object.getString("errorInfo");
_359 LogUtils.showErrorLog(tv_log,errorInfo);
_359 LogUtils.showErrorLog(tv_log,responseInfo);
_359 LogUtils.showErrorLog(tv_log,responseInfo);
_359 } catch (Exception e) {
_359 e.printStackTrace();
_359 LogUtils.showErrorLog(tv_log, e.getMessage());
_359 * Log in with token.
_359 public void signInWithToken(View view) {
_359 getTokenFromAppServer(NEW_LOGIN);
_359 public void signOut(View view) {
_359 if(ChatClient.getInstance().isLoggedInBefore()) {
_359 ChatClient.getInstance().logout(true, new CallBack() {
_359 public void onSuccess() {
_359 LogUtils.showToast(MainActivity.this, tv_log, getString(R.string.sign_out_success));
_359 public void onError(int code, String error) {
_359 LogUtils.showErrorToast(MainActivity.this, tv_log, "Sign out failed! code: "+code + " error: "+error);
_359 public void onProgress(int progress, String status) {
_359 public void startChat(View view) {
_359 EditText et_to_username = findViewById(R.id.et_to_username);
_359 String toChatUsername = et_to_username.getText().toString().trim();
_359 if(TextUtils.isEmpty(toChatUsername)) {
_359 LogUtils.showErrorToast(this, tv_log, getString(R.string.not_find_send_name));
_359 // 1: single chat; 2: group chat; 3: chat room
_359 EaseChatFragment fragment = new EaseChatFragment.Builder(toChatUsername, 1)
_359 .setOnChatExtendMenuItemClickListener(new OnChatExtendMenuItemClickListener() {
_359 public boolean onChatExtendMenuItemClick(View view, int itemId) {
_359 if(itemId == io.agora.chat.uikit.R.id.extend_item_take_picture) {
_359 return !checkPermissions(Manifest.permission.CAMERA, 111);
_359 }else if(itemId == io.agora.chat.uikit.R.id.extend_item_picture || itemId == io.agora.chat.uikit.R.id.extend_item_file || itemId == io.agora.chat.uikit.R.id.extend_item_video) {
_359 return !checkPermissions(Manifest.permission.READ_EXTERNAL_STORAGE, 112);
_359 .setOnChatRecordTouchListener(new OnChatRecordTouchListener() {
_359 public boolean onRecordTouch(View v, MotionEvent event) {
_359 return !checkPermissions(Manifest.permission.RECORD_AUDIO, 113);
_359 .setOnMessageSendCallBack(new OnMessageSendCallBack() {
_359 public void onSuccess(ChatMessage message) {
_359 LogUtils.showLog(tv_log, "Send success: message type: " + message.getType().name());
_359 public void onError(int code, String errorMsg) {
_359 LogUtils.showErrorLog(tv_log, "Send failed: error code: "+code + " errorMsg: "+errorMsg);
_359 getSupportFragmentManager().beginTransaction().replace(R.id.fl_fragment, fragment).commit();
_359//=================== click event end ========================
_359//=================== get token from server start ========================
_359 private void getTokenFromAppServer(String requestType) {
_359 if(ChatClient.getInstance().getOptions().getAutoLogin() && ChatClient.getInstance().isLoggedInBefore()) {
_359 LogUtils.showErrorLog(tv_log, getString(R.string.has_login_before));
_359 String username = et_username.getText().toString().trim();
_359 String pwd = ((EditText) findViewById(R.id.et_pwd)).getText().toString().trim();
_359 if(TextUtils.isEmpty(username) || TextUtils.isEmpty(pwd)) {
_359 LogUtils.showErrorToast(MainActivity.this, tv_log, getString(R.string.username_or_pwd_miss));
_359 Map<String, String> headers = new HashMap<>();
_359 headers.put("Content-Type", "application/json");
_359 JSONObject request = new JSONObject();
_359 request.putOpt("userAccount", username);
_359 request.putOpt("userPassword", pwd);
_359 LogUtils.showErrorLog(tv_log,"begin to getTokenFromAppServer ...");
_359 HttpResponse response = HttpClientManager.httpExecute(LOGIN_URL, headers, request.toString(), Method_POST);
_359 int code = response.code;
_359 String responseInfo = response.content;
_359 if (responseInfo != null && responseInfo.length() > 0) {
_359 JSONObject object = new JSONObject(responseInfo);
_359 String token = object.getString("accessToken");
_359 if(TextUtils.equals(requestType, NEW_LOGIN)) {
_359 ChatClient.getInstance().loginWithAgoraToken(username, token, new CallBack() {
_359 public void onSuccess() {
_359 LogUtils.showToast(MainActivity.this, tv_log, getString(R.string.sign_in_success));
_359 public void onError(int code, String error) {
_359 LogUtils.showErrorToast(MainActivity.this, tv_log, "Login failed! code: " + code + " error: " + error);
_359 public void onProgress(int progress, String status) {
_359 }else if(TextUtils.equals(requestType, RENEW_TOKEN)) {
_359 ChatClient.getInstance().renewToken(token);
_359 LogUtils.showErrorToast(MainActivity.this, tv_log, "getTokenFromAppServer failed! code: " + code + " error: " + responseInfo);
_359 LogUtils.showErrorToast(MainActivity.this, tv_log, "getTokenFromAppServer failed! code: " + code + " error: " + responseInfo);
_359 } catch (Exception e) {
_359 e.printStackTrace();
_359 LogUtils.showErrorToast(MainActivity.this, tv_log, "getTokenFromAppServer failed! code: " + 0 + " error: " + e.getMessage());
_359//=================== get token from server end ========================
_359 * Check and request permission
_359 * @param requestCode
_359 private boolean checkPermissions(String permission, int requestCode) {
_359 if(!PermissionsManager.getInstance().hasPermission(this, permission)) {
_359 PermissionsManager.getInstance().requestPermissions(this, new String[]{permission}, requestCode);
_359 * user met some exception: conflict, removed or forbidden, goto login activity
_359 protected void onUserException(String exception) {
_359 LogUtils.showLog(tv_log, "onUserException: " + exception);
_359 ChatClient.getInstance().logout(false, null);
_359 public void execute(Runnable runnable) {
_359 new Thread(runnable).start();
_359 protected void onDestroy() {
_359 if(connectionListener != null) {
_359 ChatClient.getInstance().removeConnectionListener(connectionListener);