大概早就想写一篇博客,每次动手,最后的结果便是存了草稿。要么懒得组织语言,要么觉得铺天盖地都是写的很好的。恰逢公司需要集成环信聊天,便在朋友的监督下,终于写下这篇博客,记录下自己的学习。
大概对于任何第三方,sdk的导入以及在官方创建自己的应用获取appkey都是必不可少的。基本步骤不再赘余。
导入第三方sdk,以及获取到appkey之后,便是对于清单文件的配置:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="Your Package"
android:versionCode="100"
android:versionName="1.0.0">
<!-- Required -->
<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:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:name="Your Application">
<!-- 设置环信应用的AppKey -->
<meta-data android:name="EASEMOB_APPKEY" android:value="Your AppKey" />
<!-- 声明SDK所需的service SDK核心功能-->
<service android:name="com.hyphenate.chat.EMChatService" android:exported="true"/>
<service android:name="com.hyphenate.chat.EMJobService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="true"
/>
<!-- 声明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>
</application>
</manifest>
清单文件配置好,便可以开始初始化,创建自己的Application,在这里说一句,不要忘记在清单文件的application中加入android:name="Your Application"
这一项内容,哦,因为这个错误,最终觉得自己可以把自己蠢哭。初始化的代码配置如下:
public class ECApplication 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("TAG", "enter the service process!");
// 则此application::onCreate 是被service 调用的,直接返回
return;
}
EMClient.getInstance().init(this, options);
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;
}
}
初始化之后就可以编写环信账号的注册以及登录:
注册需要自己新开一个线程,注册的代码:
private void signup() {
new Thread(new Runnable() {
@Override
public void run() {
try { EMClient.getInstance().createAccount(mUserNameView.getText().toString().trim(), mPasswordView.getText().toString().trim());
Log.e("tag", "注册成功");
} catch (HyphenateException e) {
e.printStackTrace();
Log.e("tag", "注册失败"+e.getErrorCode()+e.getMessage());
}
}
}).start();
}
登录的代码:
private void signin() {
EMClient.getInstance().login(mUserNameView.getText().toString(), mPasswordView.getText().toString(), new EMCallBack() {
@Override
public void onSuccess() {
Intent intent=new Intent(ECLoginActiviy.this,MainActivity.class);
startActivity(intent);
Log.e("tag", "登录成功");
finish();
}
@Override
public void onProgress(int arg0, String arg1) {
// TODO Auto-generated method stub
}
@Override
public void onError(int arg0, String arg1) {
Log.i("TAG", "登录失败"+arg0+" "+arg1);
}
});
}
注册完成之后,便可以开始收发消息的处理,我把所有的消息都简单粗暴的显示在一个TextView里面。布局很简单,通过控件的注册便能看出,一个TextView,输入框及发送按钮。
另外需要注意的是,接收消息时的方法是onMessageReceived(),而不是onCmdMessageReceived(),至于我为什么知道,恩……
在最后,不要忘记在onResume()以及onStop()里对于广播的处理。
好啦,这样就可以完成环信文本消息的接收以及发送了。
public class ECChatActivity extends ActionBarActivity implements EMMessageListener {
private TextView mContextView;
private EditText mInputView;
private Button btnSend;
private String chatId="Your ChatId";
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chet);
mContextView=(TextView) findViewById(R.id.tv_text_context);
mInputView=(EditText) findViewById(R.id.et_message_input);
btnSend=(Button) findViewById(R.id.btn_send);
btnSend.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String content=mInputView.getText().toString().trim();
EMMessage message = EMMessage.createTxtSendMessage(content, chatId);
message.setChatType(ChatType.GroupChat);
EMClient.getInstance().chatManager().sendMessage(message);
mContextView.setText(mContextView.getText()+"/n"+content);
message.setMessageStatusCallback(new EMCallBack() {
@Override
public void onSuccess() {
Log.i("TAG", "发送成功");
}
@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
Log.i("TAG", "消息发送失败"+arg0+"-----"+arg1);
}
});
}
});
}
@Override
public void onCmdMessageReceived(List<EMMessage> list) {
}
@Override
public void onMessageChanged(EMMessage arg0, Object arg1) {
}
@Override
public void onMessageDelivered(List<EMMessage> arg0) {
}
@Override
public void onMessageRead(List<EMMessage> arg0) {
}
@Override
public void onMessageReceived(List<EMMessage> arg0) {
for (final EMMessage emMessage : list) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mContextView.setText(mContextView.getText()+"/n"+
((EMTextMessageBody)emMessage.getBody()).getMessage());
}
});
}
}
@Override
protected void onResume() {
super.onResume();
EMClient.getInstance().chatManager().addMessageListener(this);
}
@Override
protected void onStop() {
super.onStop();
EMClient.getInstance().chatManager().removeMessageListener(this);
}
}
江南啊,又开始了夜晚润物细无声的春雨了,总算这篇博客逃出了被存草稿的命运,发表完,该睡了。