注册

环信即时通讯单聊集成,添加好友,实现单聊

前段时间由于项目需要,了解一下环信即时通讯,然后自己通过查资料写了一个基于环信的单聊demo,一下是源码,希望可以帮助到需要的小伙伴。 
 
先上一下效果图吧



20160510104925517.png




20160510105128098.png




20160510105400382.png




20160510105511478.png




20160510105614263.png




首先,我们要去环信官网注册账号,这个我就不多说了,注册完登录,创建应用,新建两个测试IM用户,

20160510100622399.png


这里主要用到的是应用标示(Appkey) 

20160510100635834.png




D870.tmp_.jpg


好了,在环信官网下载对应的sdk,这个不多说了,最好下载一个文档,里面讲的很详细的。 
好了,一下是源码 

20160510101347448.png


AppManager.Java
public class AppManager {
private static Stack<Activity> mActivityStack;
private static AppManager mAppManager;

private AppManager() {
}

/**
* 单一实例
*/
public static AppManager getInstance() {
if (mAppManager == null) {
mAppManager = new AppManager();
}
return mAppManager;
}

/**
* 添加Activity
*/
public void addActivity(Activity activity) {
if (mActivityStack == null) {
mActivityStack = new Stack<Activity>();
}
mActivityStack.add(activity);
}

/**
* 获取栈顶Activity
*/
public Activity getTopActivity() {
Activity activity = mActivityStack.lastElement();
return activity;
}

/**
* 结束栈顶Activity
*/
public void killTopActivity() {
Activity activity = mActivityStack.lastElement();
killActivity(activity);
}

/**
* 结束指定的Activity
*/
public void killActivity(Activity activity) {
if (activity != null) {
mActivityStack.remove(activity);
activity.finish();
activity = null;
}
}

/**
* 结束指定类名的Activity
*/
public void killActivity(Class<?> cls) {
for (Activity activity : mActivityStack) {
if (activity.getClass().equals(cls)) {
killActivity(activity);
}
}
}

/**
* 结束所有Activity
*/
public void killAllActivity() {
for (int i = 0, size = mActivityStack.size(); i < size; i++) {
if (null != mActivityStack.get(i)) {
mActivityStack.get(i).finish();
}
}
mActivityStack.clear();
}

/**
* 退出应用程序
*/
public void AppExit(Context context) {
try {
killAllActivity();
ActivityManager activityMgr = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
activityMgr.restartPackage(context.getPackageName());
System.exit(0);
} catch (Exception e) {}
}
}
BaseActivity.java​
public abstract class BaseActivity extends Activity {

protected Context context = null;
protected BaseApplication mApplication;
protected Handler mHandler;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mApplication = (BaseApplication) getApplication();
AppManager.getInstance().addActivity(this);
// check netwotk
context = this;
}

@Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
}

@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}

@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
}

@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
}

}
BaseApplication.java​
public class BaseApplication extends Application {

private static final String TAG = BaseApplication.class.getSimpleName();

private static BaseApplication mInstance = null;

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}

/*
* (non-Javadoc)
*
* @see android.app.Application#onCreate()
*/
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
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("com.xmliu.imsample")) {
Log.e(TAG, "enter the service process!");
// "com.easemob.chatuidemo"为demo的包名,换到自己项目中要改成自己包名

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

// EMChat.getInstance().setAutoLogin(false);
EMChat.getInstance().init(getApplicationContext());
// 在做代码混淆的时候需要设置成false
EMChat.getInstance().setDebugMode(true);
initHXOptions();
mInstance = this;

}

protected void initHXOptions() {
Log.d(TAG, "init HuanXin Options");

// 获取到EMChatOptions对象
EMChatOptions options = EMChatManager.getInstance().getChatOptions();
// 默认添加好友时,是不需要验证的true,改成需要验证false
options.setAcceptInvitationAlways(false);
// 默认环信是不维护好友关系列表的,如果app依赖环信的好友关系,把这个属性设置为true
options.setUseRoster(true);
options.setNumberOfMessagesLoaded(1);
}

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) {
CharSequence c = pm.getApplicationLabel(pm
.getApplicationInfo(info.processName,
PackageManager.GET_META_DATA));
// Log.d("Process", "Id: "+ info.pid +" ProcessName: "+
// info.processName +" Label: "+c.toString());
// processName = c.toString();
processName = info.processName;
return processName;
}
} catch (Exception e) {
// Log.d("Process", "Error>> :"+ e.toString());
}
}
return processName;
}

@Override
public void onLowMemory() {
// TODO Auto-generated method stub
super.onLowMemory();
Log.i(TAG, "onLowMemory");
}

@Override
public void onTerminate() {
// TODO Auto-generated method stub
Log.i(TAG, "onTerminate");
super.onTerminate();
}

public static BaseApplication getInstance() {
return mInstance;
}

}
ChatListAdapter.java​
public class ChatListAdapter extends BaseAdapter {

Context mContext;
List<ChatListData> mListData;

public ChatListAdapter(Context mContext, List<ChatListData> mListData) {
super();
this.mContext = mContext;
this.mListData = mListData;
}

@Override
public int getCount() {
// TODO Auto-generated method stub
return mListData.size();
}

@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}

@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}

@Override
public View getView(int index, View cView, ViewGroup arg2) {
// TODO Auto-generated method stub

Holder holder;
if (cView == null) {
holder = new Holder();
cView = LayoutInflater.from(mContext).inflate(
R.layout.chat_listview_item, null);
holder.rAvatar = (Button) cView
.findViewById(R.id.listview_item_receive_avatar);
holder.rContent = (TextView) cView
.findViewById(R.id.listview_item_receive_content);
holder.chatTime = (TextView) cView
.findViewById(R.id.listview_item_time);
holder.sContent = (TextView) cView
.findViewById(R.id.listview_item_send_content);
holder.sAvatar = (Button) cView
.findViewById(R.id.listview_item_send_avatar);
holder.sName = (TextView) cView.findViewById(R.id.name1);
holder.sName1 = (TextView) cView.findViewById(R.id.name2);
cView.setTag(holder);

} else {
holder = (Holder) cView.getTag();
}

holder.chatTime.setVisibility(View.GONE);

if (mListData.get(index).getType() == 2) {
holder.rAvatar.setVisibility(View.VISIBLE);
holder.rContent.setVisibility(View.VISIBLE);
holder.sName.setVisibility(View.VISIBLE);
holder.sName.setText("您的朋友说:");
holder.sContent.setVisibility(View.GONE);
holder.sAvatar.setVisibility(View.GONE);
holder.sName1.setVisibility(View.GONE);

} else if (mListData.get(index).getType() == 1) {
holder.rAvatar.setVisibility(View.GONE);
holder.sName.setVisibility(View.GONE);
holder.rContent.setVisibility(View.GONE);
holder.sContent.setVisibility(View.VISIBLE);
holder.sAvatar.setVisibility(View.VISIBLE);
holder.sName1.setVisibility(View.VISIBLE);
holder.sName1.setText("我");
}
holder.chatTime.setText(mListData.get(index).getChatTime());
holder.rContent.setText(mListData.get(index).getReceiveContent());
holder.sContent.setText(mListData.get(index).getSendContent());

return cView;
}

class Holder {
Button rAvatar;
TextView rContent;
TextView chatTime;
TextView sContent;
TextView sName;
TextView sName1;
Button sAvatar;
}
}
FriendListAdapter.java​
public class FriendListAdapter extends BaseAdapter {

Context mContext;
List<String> mListData;

public FriendListAdapter(Context mContext, List<String> mListData) {
super();
this.mContext = mContext;
this.mListData = mListData;
}

@Override
public int getCount() {
// TODO Auto-generated method stub
return mListData.size();
}

@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}

@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}

@Override
public View getView(int index, View cView, ViewGroup arg2) {
// TODO Auto-generated method stub
FHolder holder;
if (cView == null) {
holder = new FHolder();
cView = LayoutInflater.from(mContext).inflate(
R.layout.friend_listview_item, null);
holder.name = (TextView) cView
.findViewById(R.id.friend_listview_name);
cView.setTag(holder);

} else {
holder = (FHolder) cView.getTag();
}

holder.name.setText(mListData.get(index));

return cView;
}

class FHolder {
TextView name;
}
}
ChatListData.java​
public class ChatListData {

String receiveAvatar;
String receiveContent;
String chatTime;
String sendAvatar;
String sendContent;
/**
* 1 发送; 2接收
*/
int type;
/**
* 1 发送; 2接收
*/
public int getType() {
return type;
}
/**
* 1 发送; 2接收
*/
public void setType(int type) {
this.type = type;
}

public String getReceiveAvatar() {
return receiveAvatar;
}

public void setReceiveAvatar(String receiveAvatar) {
this.receiveAvatar = receiveAvatar;
}

public String getReceiveContent() {
return receiveContent;
}

public void setReceiveContent(String receiveContent) {
this.receiveContent = receiveContent;
}

public String getChatTime() {
return chatTime;
}

public void setChatTime(String chatTime) {
this.chatTime = chatTime;
}

public String getSendAvatar() {
return sendAvatar;
}

public void setSendAvatar(String sendAvatar) {
this.sendAvatar = sendAvatar;
}

public String getSendContent() {
return sendContent;
}

public void setSendContent(String sendContent) {
this.sendContent = sendContent;
}

}
ChatListActivity.java​
public class ChatListActivity extends BaseActivity {

private EditText contentET;
private TextView topNameTV;
private Button sendBtn;
private NewMessageBroadcastReceiver msgReceiver;

private ListView mListView;
private List<ChatListData> mListData = new ArrayList<ChatListData>();
private ChatListAdapter mAdapter;
private InputMethodManager imm;

private String receiveName = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_main);

mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case 0x00001:
imm.hideSoftInputFromWindow(
contentET.getApplicationWindowToken(), 0); // 隐藏键盘
mAdapter.notifyDataSetChanged(); // 刷新聊天列表
mListView.setSelection(mListData.size()); // 跳转到listview最底部
contentET.setText(""); // 清空发送内容
break;
default:
break;
}
}

};

receiveName = this.getIntent().getStringExtra("userid");

initView();

topNameTV.setText(receiveName);
// 只有注册了广播才能接收到新消息,目前离线消息,在线消息都是走接收消息的广播(离线消息目前无法监听,在登录以后,接收消息广播会执行一次拿到所有的离线消息)
msgReceiver = new NewMessageBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter(EMChatManager
.getInstance().getNewMessageBroadcastAction());
intentFilter.setPriority(3);
registerReceiver(msgReceiver, intentFilter);

imm = (InputMethodManager) contentET.getContext().getSystemService(
Context.INPUT_METHOD_SERVICE);

mAdapter = new ChatListAdapter(ChatListActivity.this, mListData);
mListView.setAdapter(mAdapter);

initEvent();
}

private void initView() {
contentET = (EditText) findViewById(R.id.chat_content);
topNameTV = (TextView) findViewById(R.id.chat_list_name);
sendBtn = (Button) findViewById(R.id.chat_send_btn);
mListView = (ListView) findViewById(R.id.chat_listview);
}

private void initEvent() {
// TODO Auto-generated method stub
sendBtn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
sendMsg();
}
});

contentET.setOnKeyListener(new OnKeyListener() {

@Override
public boolean onKey(View arg0, int keycode, KeyEvent arg2) {
// TODO Auto-generated method stub
if (keycode == KeyEvent.KEYCODE_ENTER
&& arg2.getAction() == KeyEvent.ACTION_DOWN) {
sendMsg();
return true;
}
return false;
}
});
}

void sendMessageHX(String username, final String content) {
// 获取到与聊天人的会话对象。参数username为聊天人的userid或者groupid,后文中的username皆是如此
EMConversation conversation = EMChatManager.getInstance()
.getConversation(username);
// 创建一条文本消息
EMMessage message = EMMessage.createSendMessage(EMMessage.Type.TXT);
// // 如果是群聊,设置chattype,默认是单聊
// message.setChatType(ChatType.GroupChat);
// 设置消息body
TextMessageBody txtBody = new TextMessageBody(content);
message.addBody(txtBody);
// 设置接收人
message.setReceipt(username);
// 把消息加入到此会话对象中
conversation.addMessage(message);
// 发送消息
EMChatManager.getInstance().sendMessage(message, new EMCallBack() {

@Override
public void onError(int arg0, String arg1) {
// TODO Auto-generated method stub
Log.i("TAG", "消息发送失败");
}

@Override
public void onProgress(int arg0, String arg1) {
// TODO Auto-generated method stub
Log.i("TAG", "正在发送消息");
}

@Override
public void onSuccess() {
// TODO Auto-generated method stub
Log.i("TAG", "消息发送成功");
ChatListData data = new ChatListData();
data.setSendContent(content);
data.setType(1);
mListData.add(data);
mHandler.sendEmptyMessage(0x00001);
}
});
}

private class NewMessageBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 注销广播
abortBroadcast();

// 消息id(每条消息都会生成唯一的一个id,目前是SDK生成)
String msgId = intent.getStringExtra("msgid");
// 发送方
String username = intent.getStringExtra("from");
// 收到这个广播的时候,message已经在db和内存里了,可以通过id获取mesage对象
EMMessage message = EMChatManager.getInstance().getMessage(msgId);
EMConversation conversation = EMChatManager.getInstance()
.getConversation(username);

MessageBody tmBody = message.getBody();

ChatListData data = new ChatListData();
data.setReceiveContent(((TextMessageBody) tmBody).getMessage());
data.setType(2);
mListData.add(data);
mHandler.sendEmptyMessage(0x00001);

Log.i("TAG", "收到消息:" + ((TextMessageBody) tmBody).getMessage());
// 如果是群聊消息,获取到group id
if (message.getChatType() == ChatType.GroupChat) {
username = message.getTo();
}

if (!username.equals(username)) {
// 消息不是发给当前会话,return
return;
}
}
}

@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unregisterReceiver(msgReceiver);

}

private void sendMsg() {
String content = contentET.getText().toString().trim();
if (TextUtils.isEmpty(content)) {
Toast.makeText(getApplicationContext(), "请输入发送的内容",
Toast.LENGTH_SHORT).show();
} else {
sendMessageHX(receiveName, content);
}
}

}
ChatLoginActivity.java​
public class ChatLoginActivity extends BaseActivity {

private EditText mUsernameET;
private EditText mPasswordET;
private TextView mPasswordForgetTV;
private Button mSigninBtn;
private TextView mSignupTV;
private CheckBox mPasswordCB;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_login);

mUsernameET = (EditText) findViewById(R.id.chat_login_username);
mPasswordET = (EditText) findViewById(R.id.chat_login_password);
mPasswordForgetTV = (TextView) findViewById(R.id.chat_login_forget_password);
mSigninBtn = (Button) findViewById(R.id.chat_login_signin_btn);
mSignupTV = (TextView) findViewById(R.id.chat_login_signup);
mPasswordCB = (CheckBox) findViewById(R.id.chat_login_password_checkbox);

if (EMChat.getInstance().isLoggedIn()) {
Log.d("TAG", "已经登陆过");
EMGroupManager.getInstance().loadAllGroups();
EMChatManager.getInstance().loadAllConversations();
startActivity(new Intent(ChatLoginActivity.this,
MainActivity.class));
}

mPasswordCB.setOnCheckedChangeListener(new OnCheckedChangeListener() {

@Override
public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
// TODO Auto-generated method stub
if (arg1) {
mPasswordCB.setChecked(true);
//动态设置密码是否可见
mPasswordET
.setTransformationMethod(HideReturnsTransformationMethod
.getInstance());
} else {
mPasswordCB.setChecked(false);
mPasswordET
.setTransformationMethod(PasswordTransformationMethod
.getInstance());
}
}
});

mSigninBtn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
final String userName = mUsernameET.getText().toString().trim();
final String password = mPasswordET.getText().toString().trim();

if (TextUtils.isEmpty(userName)) {
Toast.makeText(getApplicationContext(), "请输入用户名",
Toast.LENGTH_SHORT).show();
} else if (TextUtils.isEmpty(password)) {
Toast.makeText(getApplicationContext(), "请输入密码",
Toast.LENGTH_SHORT).show();
} else {
EMChatManager.getInstance().login(userName, password,
new EMCallBack() {// 回调
@Override
public void onSuccess() {
runOnUiThread(new Runnable() {
public void run() {
EMGroupManager.getInstance()
.loadAllGroups();
EMChatManager.getInstance()
.loadAllConversations();
Log.d("main", "登陆聊天服务器成功!");
Toast.makeText(
getApplicationContext(),
"登陆成功", Toast.LENGTH_SHORT)
.show();
startActivity(new Intent(
ChatLoginActivity.this,
MainActivity.class));
// mApplication.mSharedPreferences
// .edit()
// .putString("loginName",
// userName).commit();
}
});
}

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

}

@Override
public void onError(int code, String message) {
if (code == -1005) {
message = "用户名或密码错误";
}
final String msg = message;
runOnUiThread(new Runnable() {
public void run() {
Log.d("main", "登陆聊天服务器失败!");
Toast.makeText(
getApplicationContext(),
msg, Toast.LENGTH_SHORT)
.show();
}
});
}
});
}
}
});

mSignupTV.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
startActivity(new Intent(ChatLoginActivity.this,
ChatRegisterActivity.class));
}
});
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {

new AlertDialog.Builder(ChatLoginActivity.this)
.setTitle("应用提示")
.setMessage(
"确定要退出"
+ getResources().getString(
R.string.app_name) + "客户端吗?")
.setPositiveButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
AppManager.getInstance().AppExit(
ChatLoginActivity.this);
ChatLoginActivity.this.finish();
}
})
.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
}
}).show();
}

return super.onKeyDown(keyCode, event);
}
}
ChatRegisterActivity.java​
public class ChatRegisterActivity extends BaseActivity {

private EditText mUsernameET;
private EditText mPasswordET;
private EditText mCodeET;
private Button mSignupBtn;
private Handler mHandler;
private CheckBox mPasswordCB;
private TextView mBackTV;
private ImageView mCodeIV;
private String currCode;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_register);

mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 1000:
Toast.makeText(getApplicationContext(), "注册成功",
Toast.LENGTH_SHORT).show();
break;
case 1001:
Toast.makeText(getApplicationContext(), "网络异常,请检查网络!",
Toast.LENGTH_SHORT).show();
break;
case 1002:
Toast.makeText(getApplicationContext(), "用户已存在!",
Toast.LENGTH_SHORT).show();
break;
case 1003:
Toast.makeText(getApplicationContext(), "注册失败,无权限",
Toast.LENGTH_SHORT).show();
break;
case 1004:
Toast.makeText(getApplicationContext(),
"注册失败: " + (String) msg.obj, Toast.LENGTH_SHORT)
.show();
break;

default:
break;
}
};
};

mUsernameET = (EditText) findViewById(R.id.chat_register_username);
mPasswordET = (EditText) findViewById(R.id.chat_register_password);
mCodeET = (EditText) findViewById(R.id.chat_register_code);
mSignupBtn = (Button) findViewById(R.id.chat_register_signup_btn);
mPasswordCB = (CheckBox) findViewById(R.id.chat_register_password_checkbox);
mBackTV = (TextView) findViewById(R.id.chat_register_back);
mCodeIV = (ImageView) findViewById(R.id.chat_register_password_code);

mCodeIV.setImageBitmap(IdentifyCode.getInstance().createBitmap());
currCode = IdentifyCode.getInstance().getCode();

mCodeIV.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
mCodeIV.setImageBitmap(IdentifyCode.getInstance()
.createBitmap());
currCode = IdentifyCode.getInstance().getCode();
Log.i("TAG", "currentCode==>" + currCode);
}
});

mBackTV.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
finish();
}
});
mPasswordCB.setOnCheckedChangeListener(new OnCheckedChangeListener() {

@Override
public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
// TODO Auto-generated method stub
if (arg1) {
mPasswordCB.setChecked(true);
mPasswordET
.setTransformationMethod(HideReturnsTransformationMethod
.getInstance());
} else {
mPasswordCB.setChecked(false);
mPasswordET
.setTransformationMethod(PasswordTransformationMethod
.getInstance());
}
}
});
mSignupBtn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
final String userName = mUsernameET.getText().toString().trim();
final String password = mPasswordET.getText().toString().trim();
final String code = mCodeET.getText().toString().trim();

if (TextUtils.isEmpty(userName)) {
Toast.makeText(getApplicationContext(), "请输入用户名",
Toast.LENGTH_SHORT).show();
} else if (TextUtils.isEmpty(password)) {
Toast.makeText(getApplicationContext(), "请输入密码",
Toast.LENGTH_SHORT).show();
} else if (TextUtils.isEmpty(code)) {
Toast.makeText(getApplicationContext(), "请输入验证码",
Toast.LENGTH_SHORT).show();
} else if (!code.equals(currCode.toLowerCase())) {
Toast.makeText(getApplicationContext(), "验证码输入不正确",
Toast.LENGTH_SHORT).show();
} else {
new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
try {
// 调用sdk注册方法
EMChatManager.getInstance()
.createAccountOnServer(userName,
password);
mHandler.sendEmptyMessage(1000);
} catch (final EaseMobException e) {
// 注册失败
Log.i("TAG", "getErrorCode:" + e.getErrorCode());
int errorCode = e.getErrorCode();
if (errorCode == EMError.NONETWORK_ERROR) {
mHandler.sendEmptyMessage(1001);
} else if (errorCode == EMError.USER_ALREADY_EXISTS) {
mHandler.sendEmptyMessage(1002);
} else if (errorCode == EMError.UNAUTHORIZED) {
mHandler.sendEmptyMessage(1003);
} else {
Message msg = Message.obtain();
msg.what = 1004;
msg.obj = e.getMessage();
mHandler.sendMessage(msg);
}
}
}
}).start();
}
}
});
}
}
MainActivity.java​
public class MainActivity extends BaseActivity {

private ListView mListView;
private Button mAddBtn;
private Button logoutBtn;
private View addView;
private EditText mIdET;
private EditText mReasonET;
private TextView mUserTV;
private TextView mGoTV;
private FriendListAdapter mAdapter;
private List<String> userList = new ArrayList<String>();

/* 常量 */
private final int CODE_ADD_FRIEND = 0x00001;

@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_friends);

mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case CODE_ADD_FRIEND:
Toast.makeText(getApplicationContext(), "请求发送成功,等待对方验证",
Toast.LENGTH_SHORT).show();
break;

default:
break;
}
}

};

EMContactManager.getInstance().setContactListener(
new MyContactListener());
EMChat.getInstance().setAppInited();

mListView = (ListView) findViewById(R.id.chat_listview);
mAddBtn = (Button) findViewById(R.id.chat_add_btn);
mUserTV = (TextView) findViewById(R.id.current_user);
mGoTV = (TextView) findViewById(R.id.friend_list_go);
logoutBtn = (Button) findViewById(R.id.chat_logout_btn);

mUserTV.setText(EMChatManager.getInstance().getCurrentUser());

initList();

mAddBtn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
addView = LayoutInflater.from(MainActivity.this).inflate(
R.layout.chat_add_friends, null);
mIdET = (EditText) addView
.findViewById(R.id.chat_add_friend_id);
mReasonET = (EditText) addView
.findViewById(R.id.chat_add_friend_reason);
new AlertDialog.Builder(MainActivity.this)
.setTitle("添加好友")
.setView(addView)
.setPositiveButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
String idStr = mIdET.getText()
.toString().trim();
String reasonStr = mReasonET.getText()
.toString().trim();
try {
EMContactManager.getInstance()
.addContact(idStr,
reasonStr);
mHandler.sendEmptyMessage(CODE_ADD_FRIEND);
} catch (EaseMobException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.i("TAG", "addContacterrcode==>"
+ e.getErrorCode());
}// 需异步处理
}
})
.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
dialog.dismiss();
}
}).create().show();

}
});
logoutBtn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub

showLogoutDialog();

}
});

mListView.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
startActivity(new Intent(MainActivity.this,
ChatListActivity.class).putExtra("userid",
userList.get(arg2)));
}
});

mListView.setOnItemLongClickListener(new OnItemLongClickListener() {

@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
showDeleteDialog(userList.get(arg2));
return true;
}
});
}

private void initList() {
try {
userList.clear();
userList = EMContactManager.getInstance().getContactUserNames();
mAdapter = new FriendListAdapter(MainActivity.this, userList);
mListView.setAdapter(mAdapter);
} catch (EaseMobException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
Log.i("TAG", "usernames errcode==>" + e1.getErrorCode());
Log.i("TAG", "usernames errcode==>" + e1.getMessage());
}// 需异步执行
}

private class MyContactListener implements EMContactListener {

@Override
public void onContactAgreed(String username) {
// 好友请求被同意
Log.i("TAG", "onContactAgreed==>" + username);
// 提示有新消息
EMNotifier.getInstance(getApplicationContext()).notifyOnNewMsg();
Toast.makeText(getApplicationContext(), username + "同意了你的好友请求",
Toast.LENGTH_SHORT).show();
}

@Override
public void onContactRefused(String username) {
// 好友请求被拒绝
Log.i("TAG", "onContactRefused==>" + username);
}

@Override
public void onContactInvited(String username, String reason) {
// 收到好友添加请求
Log.i("TAG", username + "onContactInvited==>" + reason);
showAgreedDialog(username, reason);
EMNotifier.getInstance(getApplicationContext()).notifyOnNewMsg();
}

@Override
public void onContactDeleted(List<String> usernameList) {
// 好友被删除时回调此方法
Log.i("TAG", "usernameListDeleted==>" + usernameList.size());
}

@Override
public void onContactAdded(List<String> usernameList) {
// 添加了新的好友时回调此方法
for (String str : usernameList) {
Log.i("TAG", "usernameListAdded==>" + str);
}
}
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {

showExitDialog();
}

return super.onKeyDown(keyCode, event);
}

private void showLogoutDialog() {
new AlertDialog.Builder(MainActivity.this)
.setTitle("应用提示")
.setMessage(
"确定要注销" + EMChatManager.getInstance().getCurrentUser()
+ "用户吗?")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// EMChatManager.getInstance().logout();
logout(new EMCallBack() {

@Override
public void onSuccess() {
// TODO Auto-generated method stub
startActivity(new Intent(MainActivity.this,
ChatLoginActivity.class));
}

@Override
public void onProgress(int arg0, String arg1) {
// TODO Auto-generated method stub

}

@Override
public void onError(int arg0, String arg1) {
// TODO Auto-generated method stub

}
});

}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
}).show();
}

public void logout(final EMCallBack callback) {
// setPassword(null);
EMChatManager.getInstance().logout(new EMCallBack() {

@Override
public void onSuccess() {
// TODO Auto-generated method stub
if (callback != null) {
callback.onSuccess();
}
}

@Override
public void onError(int code, String message) {
// TODO Auto-generated method stub

}

@Override
public void onProgress(int progress, String status) {
// TODO Auto-generated method stub
if (callback != null) {
callback.onProgress(progress, status);
}
}

});
}

private void showAgreedDialog(final String user, String reason) {
new AlertDialog.Builder(MainActivity.this)
.setTitle("应用提示")
.setMessage(
"用户 " + user + " 想要添加您为好友,是否同意?\n" + "验证信息:" + reason)
.setPositiveButton("同意", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
EMChatManager.getInstance().acceptInvitation(user);
initList();
} catch (EaseMobException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.i("TAG",
"showAgreedDialog1==>" + e.getErrorCode());
}
}
})
.setNegativeButton("拒绝", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
try {
EMChatManager.getInstance().refuseInvitation(user);
} catch (EaseMobException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.i("TAG",
"showAgreedDialog2==>" + e.getErrorCode());
}
}
})
.setNeutralButton("忽略", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
}).show();
}

private void showDeleteDialog(final String user) {
new AlertDialog.Builder(MainActivity.this)
.setTitle("应用提示")
.setMessage("确定删除好友 " + user + " 吗?\n")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
EMContactManager.getInstance().deleteContact(user);
initList();
} catch (EaseMobException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.i("TAG",
"showAgreedDialog1==>" + e.getErrorCode());
}
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
}).show();
}

private void showExitDialog() {
new AlertDialog.Builder(MainActivity.this)
.setTitle("应用提示")
.setMessage(
"确定要退出" + getResources().getString(R.string.app_name)
+ "客户端吗?")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
AppManager.getInstance().AppExit(MainActivity.this);
MainActivity.this.finish();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
}).show();
}

}
IdentifyCode.java​
public class IdentifyCode {

private static final char CHARS = { '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'l', 'm',
'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A',
'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };

private static IdentifyCode bmpCode;

public static IdentifyCode getInstance() {
if (bmpCode == null)
bmpCode = new IdentifyCode();
return bmpCode;
}

// default settings
private static final int DEFAULT_CODE_LENGTH = 3;
private static final int DEFAULT_FONT_SIZE = 25;
private static final int DEFAULT_LINE_NUMBER = 2;
private static final int BASE_PADDING_LEFT = 5, RANGE_PADDING_LEFT = 15,
BASE_PADDING_TOP = 15, RANGE_PADDING_TOP = 20;
private static final int DEFAULT_WIDTH = 60, DEFAULT_HEIGHT = 40;

// settings decided by the layout xml
// canvas width and height
private int width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT;

// random word space and pading_top
private int base_padding_left = BASE_PADDING_LEFT,
range_padding_left = RANGE_PADDING_LEFT,
base_padding_top = BASE_PADDING_TOP,
range_padding_top = RANGE_PADDING_TOP;

// number of chars, lines; font size
private int codeLength = DEFAULT_CODE_LENGTH,
line_number = DEFAULT_LINE_NUMBER, font_size = DEFAULT_FONT_SIZE;

// variables
private String code;
private int padding_left, padding_top;
private Random random = new Random();

// 验证码图�?
public Bitmap createBitmap() {
padding_left = 0;

Bitmap bp = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas c = new Canvas(bp);

code = createCode();

c.drawColor(Color.WHITE);
Paint paint = new Paint();
paint.setTextSize(font_size);

for (int i = 0; i < code.length(); i++) {
randomTextStyle(paint);
randomPadding();
c.drawText(code.charAt(i) + "", padding_left, padding_top, paint);
}

for (int i = 0; i < line_number; i++) {
drawLine(c, paint);
}

c.save(Canvas.ALL_SAVE_FLAG);// 保存
c.restore();//
return bp;
}

public String getCode() {
return code;
}

// 验证�?
private String createCode() {
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < codeLength; i++) {
buffer.append(CHARS[random.nextInt(CHARS.length)]);
}
return buffer.toString();
}

private void drawLine(Canvas canvas, Paint paint) {
int color = randomColor();
int startX = random.nextInt(width);
int startY = random.nextInt(height);
int stopX = random.nextInt(width);
int stopY = random.nextInt(height);
paint.setStrokeWidth(1);
paint.setColor(color);
canvas.drawLine(startX, startY, stopX, stopY, paint);
}

private int randomColor() {
return randomColor(1);
}

private int randomColor(int rate) {
int red = random.nextInt(256) / rate;
int green = random.nextInt(256) / rate;
int blue = random.nextInt(256) / rate;
return Color.rgb(red, green, blue);
}

private void randomTextStyle(Paint paint) {
int color = randomColor();
paint.setColor(color);
paint.setFakeBoldText(random.nextBoolean()); // true为粗体,false为非粗体
float skewX = random.nextInt(11) / 10;
skewX = random.nextBoolean() ? skewX : -skewX;
paint.setTextSkewX(skewX); // float类型参数,负数表示右斜,整数左斜
// paint.setUnderlineText(true); //true为下划线,false为非下划线?
// paint.setStrikeThruText(true); //true为删除线,false为非删除线?
}

private void randomPadding() {
padding_left += base_padding_left + random.nextInt(range_padding_left);
padding_top = base_padding_top + random.nextInt(range_padding_top);
}
}
布局文件就相对简单很多了,登录页面很简单,还是贴出来吧。 
activity_chat_login.xml​
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:id="@+id/chat_login_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#131313"
android:gravity="center"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:text="登录"
android:textColor="#fff" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#CAFFFF"
android:orientation="vertical"
android:paddingBottom="30dp"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:paddingTop="60dp" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#131313"
android:orientation="vertical" >

<EditText
android:id="@+id/chat_login_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#00000000"
android:drawableLeft="@drawable/login_user"
android:drawablePadding="5dp"
android:ems="10"
android:hint="用户名"
android:inputType="textPersonName"
android:textColor="#fff"
android:textSize="12sp" />

<View
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000000" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<EditText
android:id="@+id/chat_login_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="1"
android:background="#00000000"
android:drawableLeft="@drawable/login_password"
android:drawablePadding="5dp"
android:ems="10"
android:hint="密码"
android:inputType="textPassword"
android:textColor="#fff"
android:textSize="12sp" />

<CheckBox
android:id="@+id/chat_login_password_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="5dp"
android:button="@drawable/password_checkbox" />
</LinearLayout>
</LinearLayout>

<Button
android:id="@+id/chat_login_signin_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="#359D90"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:text="登录"
android:textColor="#fff" />

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal" >

<TextView
android:id="@+id/chat_login_signup0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="#5D5D5D"
android:textSize="12sp" />

<TextView
android:id="@+id/chat_login_signup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/chat_login_signup0"
android:text="注册用户"
android:textColor="#6F6F6F"
android:textSize="12sp"
android:textStyle="bold" />

<TextView
android:id="@+id/chat_login_forget_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="忘记密码"
android:textColor="#5D5D5D"
android:textSize="12sp" />
</RelativeLayout>
</LinearLayout>

</LinearLayout>
好友列表页 
activity_chat_friends.xml​
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#359D90"
android:orientation="horizontal"
android:paddingBottom="5dp"
android:paddingTop="5dp" >

<TextView
android:id="@+id/current_user"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="我的好友"
android:textColor="#fff" />

<Button
android:id="@+id/chat_logout_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="5dp"
android:background="@drawable/chat_logout_icon" />
</RelativeLayout>

<TextView
android:id="@+id/friend_list_go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:textStyle="bold|italic"
android:textColor="#000fff"
android:text="好友列表" />

<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginTop="5dp"
android:background="#DDDDDD" />

<ListView
android:id="@+id/chat_listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:scrollbars="none" />

<Button
android:id="@+id/chat_add_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@drawable/send_btn_bg"
android:paddingBottom="12dp"
android:paddingLeft="10
本文由环信热心用户SeanMis小七发表,个人博客地址SeanMis小七

1 个评论

要回复文章请先登录注册