環信聊天,可發圖片和語音2
阿新 • • 發佈:2019-01-27
1、錄音的程式碼實現,先寫一個按鈕了,當點選時執行的事件
2、實現聊天佈局,先新增一個chatAdapter繼承BaseAdapter,這裡需要用到兩個佈局檔案,一個是傳送的,一個是接收的,通過判斷使用者名稱來實現用哪個佈局顯示,顯示的時候還要判斷是文字圖片還是語音,是對方發的還是自己發的,/** * 錄音 */ recording.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (MotionEvent.ACTION_DOWN == event.getAction()) { if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { Toast.makeText(getApplication(), "記憶體卡不存在", Toast.LENGTH_SHORT).show(); return false; } v.setPressed(true); try { voiceRecorder.startRecording(null, userName, getApplicationContext()); } catch (Exception e) { e.printStackTrace(); v.setPressed(false); Toast.makeText(getApplication(), "錄音失敗,請重試", Toast.LENGTH_SHORT).show(); if (voiceRecorder != null) { voiceRecorder.discardRecording(); } } } else if (MotionEvent.ACTION_MOVE == event.getAction()) { if (event.getY() < 0) { Toast.makeText(getApplication(), "鬆開手指,取消傳送", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getApplication(), "手指上滑,取消傳送", Toast.LENGTH_SHORT).show(); } return true; } else if (MotionEvent.ACTION_UP == event.getAction()) { v.setPressed(false); if (event.getY() < 0) {//如果已經上滑後 voiceRecorder.discardRecording(); return true; } try { int length = voiceRecorder.stopRecoding(); // 停止錄音 if (length > 0) { EMMessage message = EMMessage.createVoiceSendMessage(voiceRecorder.getVoiceFilePath(), length, userName); EMClient.getInstance().chatManager().sendMessage(message); recording.setBackgroundResource(R.drawable.record_animate_01); Message msg3 = mHandler.obtainMessage(); msg3.what = 0; mHandler.sendMessage(msg3); } else if (length == EMError.FILE_INVALID) { Toast.makeText(getApplication(), "無錄音許可權", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getApplication(), "錄音時間太短", Toast.LENGTH_SHORT).show(); } } catch (Exception e) { } } return false; } }); }
兩個佈局的程式碼,chat_item1.xmlclass ChatAdapter extends BaseAdapter { List<EMMessage> emMessages; ChatAdapter(List<EMMessage> emMessages) { this.emMessages = emMessages; } @Override public int getCount() { return emMessages.size(); } @Override public Object getItem(int i) { return emMessages.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int i, View view, ViewGroup viewGroup) { final EMMessage message = emMessages.get(i);//每條訊息 if (message.getFrom().equals(userName)) { view = getLayoutInflater().inflate(R.layout.chat_item1, null); } else { view = getLayoutInflater().inflate(R.layout.chat_item2, null); } final TextView time = (TextView) view.findViewById(R.id.time); ImageView head = (ImageView) view.findViewById(R.id.head); // Bitmap b = message.getBody() // head.setImageBitmap(); TextView tv = (TextView) view.findViewById(R.id.tv); final DraweeView image = (DraweeView) view.findViewById(R.id.image); long msgTime = message.getMsgTime(); // 資訊時間 if (i == 0 || msgTime - emMessages.get(i - 1).getMsgTime() > 120000) { time.setVisibility(View.VISIBLE); long dateTaken = System.currentTimeMillis(); // 當前系統時間 String currentDate = (String) DateFormat.format("yyyy/MM/dd", dateTaken); // 當前系統日期 String messageDate = (String) DateFormat.format("yyyy/MM/dd", msgTime); // 資訊的日期 if (currentDate.equals(messageDate)) { // 如果是當天 time.setText(DateFormat.format("kk:mm:ss", msgTime));// 只顯示時間 } else { time.setText(DateFormat.format("yyyy/MM/dd kk:mm:ss",// 顯示日期加時間 msgTime)); } } if (message.getType() == EMMessage.Type.TXT) {//文字顯示 String mess = ((EMTextMessageBody) message.getBody()).getMessage(); tv.setText(mess); } else if (message.getType() == EMMessage.Type.IMAGE) {//圖片顯示 tv.setVisibility(View.GONE); image.setVisibility(View.VISIBLE); if (message.getFrom().equals(userName)) { // 對方發的訊息 String ThumbnailUrl = ((EMImageMessageBody) message.getBody()).getThumbnailUrl(); // 獲取縮圖片地址 String thumbnailPath = ImageUtils.getScaledImage(getApplication(), ThumbnailUrl); String imageRemoteUrl = ((EMImageMessageBody) message.getBody()).getRemoteUrl();// 獲取遠端原圖片地址 fb.display(image, thumbnailPath);//顯示圖片 imageClick(image, imageRemoteUrl);//圖片新增監聽 } else { // 自己發的訊息 String LocalUrl = ((EMImageMessageBody) message.getBody()).getLocalUrl(); // 獲取本地圖片地址 Bitmap bm = ImageUtils.decodeScaleImage(LocalUrl, 160, 160);//獲取縮圖 image.setImageBitmap(bm);//顯示圖片 Log.e(TAG, "bm=" + bm + "==LocalUrl=" + LocalUrl); imageClick(image, LocalUrl);//圖片新增監聽 } } else if (message.getType() == EMMessage.Type.VOICE) {//語音 tv.setVisibility(View.GONE); tv.setGravity(Gravity.TOP); image.setVisibility(View.VISIBLE); tv.setText(((EMVoiceMessageBody) message.getBody()).getLength() + "”"); // 設定語音的時長 // 設定為語音的圖片 if (message.direct() == EMMessage.Direct.RECEIVE) { image.setImageResource(R.drawable.chatfrom_voice_playing); } else { image.setImageResource(R.drawable.chatto_voice_playing); } image.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { // 開始播放錄音 startPlay(message, image); } }); } return view; } // 圖片點選監聽 private void imageClick(ImageView image, final String imageUrl) { image.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { //new PopWindow_Image(Chat.this, imageUrl).showAtLocation(arg0, 0, 0, 0); new PopWindow_image(fb, Chat.this, imageUrl).showAtLocation(arg0, 0, 0, 0); } }); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:orientation="vertical" android:padding="10dip" android:layout_height="match_parent"> <TextView android:gravity="center_horizontal" android:id="@+id/time" android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="gone" android:text="2015.16"/> <LinearLayout android:layout_width="match_parent" android:layout_marginRight="50dp" android:layout_height="wrap_content" android:orientation="horizontal" > <ImageView android:id="@+id/head" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginRight="5dp" android:background="@drawable/ic_launcher" /> <com.facebook.drawee.view.DraweeView android:id="@+id/image" android:layout_width="100dip" android:layout_height="100dip" android:maxWidth="150dp" android:visibility="gone" /> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_vertical" android:maxWidth="220dp" android:text="5555" android:textSize="16dp" /> </LinearLayout> </LinearLayout>
chat_item2.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:padding="10dip"
android:layout_height="match_parent">
<TextView
android:gravity="center_horizontal"
android:id="@+id/time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:text="2015.16"/>
<LinearLayout
android:layout_marginTop="30dip"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:maxWidth="220dp"
android:text="5555"
android:textSize="16dp" />
<com.facebook.drawee.view.DraweeView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="220dp"
android:visibility="gone"
/>
<ImageView
android:id="@+id/head"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginRight="5dp"
android:background="@drawable/ic_launcher" />
</LinearLayout>
</RelativeLayout>
3、播放語音的方法
// 開始播放
private void startPlay(final EMMessage message, ImageView image) {
EMVoiceMessageBody voiceBody = (EMVoiceMessageBody) message.getBody();
if (message.direct() == EMMessage.Direct.SEND) {
// for sent msg, we will try to play the voice file directly
playVoice(voiceBody.getLocalUrl(), message, image);
} else {
if (message.status() == EMMessage.Status.SUCCESS) {
playVoice(voiceBody.getLocalUrl(), message, image);
} else if (message.status() == EMMessage.Status.INPROGRESS) {
//toast("資訊還在傳送中");
Toast.makeText(getApplication(), "資訊還在傳送中", Toast.LENGTH_SHORT).show();
} else if (message.status() == EMMessage.Status.FAIL) {
// toast("接收失敗");
Toast.makeText(getApplication(), "接收失敗", Toast.LENGTH_SHORT).show();
}
}
}
// 播放錄音
public void playVoice(String filePath, final EMMessage message, final ImageView image) {
File file = new File(filePath);
if (!file.exists() || !file.isFile()) {
System.err.println("file not exist");
// toast("語音檔案不存在");
return;
}
playMsgId = message.getMsgId();
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(filePath);
mPlayer.prepare();
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
if (mPlayer == null) // 表示因為要播放其他語音時已經被停止了,所以不需要再次呼叫停止
return;
stopPlayVoice(message); // stop animation
}
});
isPlaying = true;
mPlayer.start();
playIv = image;
showAnimation(message);
} catch (Exception e) {
}
}
4、停止語音方法
/**
* 停止語音
*
* @param message
*/
public void stopPlayVoice(final EMMessage message) {
voiceAnimation.stop();
if (message.direct() == EMMessage.Direct.RECEIVE) {
playIv.setImageResource(R.drawable.chatfrom_voice_playing);
} else {
playIv.setImageResource(R.drawable.chatto_voice_playing);
}
// stop play voice
if (mPlayer != null) {
mPlayer.stop();
mPlayer.release();
}
isPlaying = false;
playMsgId = null;
adapter.notifyDataSetChanged();
}
5、顯示語音時的動畫
// show the voice playing animation
private void showAnimation(final EMMessage message) {
// play voice, and start animation
if (message.direct() == EMMessage.Direct.RECEIVE) {
playIv.setImageResource(R.drawable.voice_from_icon);
} else {
playIv.setImageResource(R.drawable.voice_to_icon);
}
voiceAnimation = (AnimationDrawable) playIv.getDrawable();
voiceAnimation.start();
}
6、傳送圖片實現方法
/**
* 選擇本地圖片
*/
protected void selectPicFromLocal() {
Intent intent;
if (Build.VERSION.SDK_INT < 19) {
intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
} else {
intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
startActivityForResult(intent, REQUEST_CODE_LOCAL);
}
返回的data資料處理/**
* 選取圖片
*
* @param requestCode
* @param resultCode
* @param data
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == REQUEST_CODE_LOCAL) {//傳送圖片
if (data != null) {
Uri selectedImage = data.getData();
if (selectedImage != null) {
sendPicByUri(selectedImage);//傳送圖片
}
}
}
}
}
/**
* send image
*
* @param selectedImage
*/
protected void sendPicByUri(Uri selectedImage) {
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getApplication().getContentResolver().query(selectedImage, filePathColumn, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
cursor = null;
if (picturePath == null || picturePath.equals("null")) {
Toast toast = Toast.makeText(getApplication(), R.string.cant_find_pictures, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
return;
}
sendImageMessage(picturePath);
} else {
File file = new File(selectedImage.getPath());
if (!file.exists()) {
Toast toast = Toast.makeText(getApplication(), R.string.cant_find_pictures, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
return;
}
sendImageMessage(file.getAbsolutePath());
}
}
/**
* 傳送圖片
*
* @param imagePath
*/
protected void sendImageMessage(String imagePath) {
EMMessage message = EMMessage.createImageSendMessage(imagePath, false, userName);
if (message == null) {
return;
}
EMClient.getInstance().chatManager().sendMessage(message);
Message msg2 = mHandler.obtainMessage();
msg2.what = 0;
mHandler.sendMessage(msg2);
}
最後完整程式碼
package com.example.apple.huanxin.ui;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.drawable.AnimationDrawable;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.apple.huanxin.R;
import com.example.apple.huanxin.presenter.ChatPresenter;
import com.example.apple.huanxin.presenter.IChatPresenter;
import com.example.apple.huanxin.utils.MyListView;
import com.example.apple.huanxin.utils.PopWindow_image;
import com.facebook.drawee.view.DraweeView;
import com.hyphenate.EMError;
import com.hyphenate.EMMessageListener;
import com.hyphenate.chat.EMChatManager;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMCmdMessageBody;
import com.hyphenate.chat.EMConversation;
import com.hyphenate.chat.EMImageMessageBody;
import com.hyphenate.chat.EMMessage;
import com.hyphenate.chat.EMTextMessageBody;
import com.hyphenate.chat.EMVoiceMessageBody;
import com.hyphenate.util.ImageUtils;
import com.hyphenate.util.VoiceRecorder;
import net.tsz.afinal.FinalBitmap;
import java.io.File;
import java.util.List;
public class Chat extends AppCompatActivity implements View.OnClickListener, EMMessageListener, IChatPresenter {
private EditText input_text;
private Button send;
private TextView text_content;
private Button sendImage;
private Button recording;
private MyListView listView;
private VoiceRecorder voiceRecorder;// 環信封裝的錄音功能類
private String userName;// 當前聊天的 ID
// 當前會話物件
private EMConversation mConversation;
// 訊息監聽器
private EMMessageListener mMessageListener;
private final String TAG = "Chat";
private ChatAdapter adapter;
private boolean message_more = true;// 聊天記錄是否還有更多
private String startMsgId;// 獲取聊天記錄時的第一條資訊id
private ChatPresenter chatPresenter;
protected static final int REQUEST_CODE_LOCAL = 3;
private FinalBitmap fb;//顯示圖片
public static boolean isPlaying = false;
private MediaPlayer mPlayer = null;// 播放語音的物件(播放器)
private String playMsgId = null;// 正在播放的語音資訊id,用於判斷播放的是哪一個語音資訊
private AnimationDrawable voiceAnimation = null;
private ImageView playIv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
Intent intent = getIntent();
userName = intent.getStringExtra("userName");
mMessageListener = this;
listView = (MyListView) findViewById(R.id.listview);
chatPresenter = new ChatPresenter(this, this);
initView();
initConversation();//獲取歷史記錄資料
}
private void initView() {
fb = FinalBitmap.create(Chat.this);
fb.configLoadfailImage(R.drawable.ic_launcher);
fb.configLoadingImage(R.drawable.ic_launcher);
input_text = (EditText) findViewById(R.id.input_text);
send = (Button) findViewById(R.id.send);
send.setOnClickListener(this);
sendImage = (Button) findViewById(R.id.sendImage);
sendImage.setOnClickListener(this);
recording = (Button) findViewById(R.id.recording);
//錄音時的動畫
voiceRecorder = new VoiceRecorder(new Handler() {
@Override
public void handleMessage(android.os.Message msg) {
// 切換msg切換圖片
recording.setBackgroundResource(R.drawable.record_animate_01);
}
});
text_content = (TextView) findViewById(R.id.text_content);
// 設定textview可滾動,需配合xml佈局設定
text_content.setMovementMethod(new ScrollingMovementMethod());
listView.setonRefreshListener(new MyListView.OnRefreshListener() {
@Override
public void onRefresh() {
// new Thread(new LoadMoreMsgRun()).start();// 載入聊天記錄
}
});
/**
* 錄音
*/
recording.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (MotionEvent.ACTION_DOWN == event.getAction()) {
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
Toast.makeText(getApplication(), "記憶體卡不存在", Toast.LENGTH_SHORT).show();
return false;
}
v.setPressed(true);
try {
voiceRecorder.startRecording(null, userName, getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
v.setPressed(false);
Toast.makeText(getApplication(), "錄音失敗,請重試", Toast.LENGTH_SHORT).show();
if (voiceRecorder != null) {
voiceRecorder.discardRecording();
}
}
} else if (MotionEvent.ACTION_MOVE == event.getAction()) {
if (event.getY() < 0) {
Toast.makeText(getApplication(), "鬆開手指,取消傳送", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplication(), "手指上滑,取消傳送", Toast.LENGTH_SHORT).show();
}
return true;
} else if (MotionEvent.ACTION_UP == event.getAction()) {
v.setPressed(false);
if (event.getY() < 0) {//如果已經上滑後
voiceRecorder.discardRecording();
return true;
}
try {
int length = voiceRecorder.stopRecoding(); // 停止錄音
if (length > 0) {
EMMessage message = EMMessage.createVoiceSendMessage(voiceRecorder.getVoiceFilePath(), length, userName);
EMClient.getInstance().chatManager().sendMessage(message);
recording.setBackgroundResource(R.drawable.record_animate_01);
Message msg3 = mHandler.obtainMessage();
msg3.what = 0;
mHandler.sendMessage(msg3);
} else if (length == EMError.FILE_INVALID) {
Toast.makeText(getApplication(), "無錄音許可權", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplication(), "錄音時間太短", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
}
}
return false;
}
});
}
/**
* @param msg
*/
@Override
public void setMessage(String msg) {
Message msg1 = mHandler.obtainMessage();
msg1.what = 0;
msg1.obj = msg;
mHandler.sendMessage(msg1);
}
/**
* 下拉更多
*/
// class LoadMoreMsgRun implements Runnable {
// public void run() {
// // 判斷是否還有更多
// if (message_more == true) {
// // 獲取startMsgId之前的pagesize條訊息,此方法獲取的messages
// // sdk會自動存入到此會話中,app中無需再次把獲取到的messages新增到會話中
//
// mConversation.loadMoreMsgFromDB(mConversation.getAllMessages().get(0).getMsgId(), 10);// 載入更多記錄
//
// if (mConversation.getUnreadMsgCount() > mConversation.getAllMsgCount()) {// 表示獲取到更多資訊了
//
//// loadFinish(1, mConversation.get - messageCount);// 重新設定介面卡
//// messageCount = conversation.getMsgCount();
// startMsgId = mConversation.getAllMessages().get(0).getMsgId();// 設定第一條資訊的id
//
// } else { // 沒有獲取到
// loadFinish(2, 0); // 提示沒有更多
// message_more = false;// 設定沒有更多標記
// }
// } else if (message_more == false) {
// loadFinish(2, 0); // 提示沒有更多
// }
//
// loadFinish(3, 0);// lisetview下拉重新整理完成
// }
// }
// 載入完成後的ui處理
// private void loadFinish(final int tag, final int index) {
// runOnUiThread(new Runnable() {
// public void run() {
// if (tag == 1) {
// // 重新設定介面卡
// listView.setAdapter(adapter);
// listView.setSelection(index);
// } else if (tag == 2) {
// // toast("沒有更多記錄了");
// } else if (tag == 3)
// listView.onRefreshComplete(); // 重新整理完成
// }
// });
// }
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.send:
String content = input_text.getText().toString();
chatPresenter.sendMessage(content, userName);
break;
case R.id.sendImage:
selectPicFromLocal();
break;
default:
break;
}
}
/**
* 選擇本地圖片
*/
protected void selectPicFromLocal() {
Intent intent;
if (Build.VERSION.SDK_INT < 19) {
intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
} else {
intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
startActivityForResult(intent, REQUEST_CODE_LOCAL);
}
/**
* 初始化會話物件,並且根據需要載入更多訊息
*/
private void initConversation() {
/**
* 初始化會話物件,這裡有三個引數麼,
* 第一個表示會話的當前聊天的 useranme 或者 groupid
* 第二個是繪畫型別可以為空
* 第三個表示如果會話不存在是否建立
*/
mConversation = EMClient.getInstance().chatManager().getConversation(userName, null, true);
// 設定當前會話未讀數為 0
mConversation.markAllMessagesAsRead();
// startMsgId = mConversation.getAllMessages().get(0).getMsgId();// 設定第一條資訊的id
Log.e(TAG, "mConversation.getAllMessages()=" + mConversation.getAllMessages());
if (mConversation.getAllMessages() != null) {
adapter = new ChatAdapter(mConversation.getAllMessages());
listView.setAdapter(adapter);
listView.setSelection(listView.getBottom());
}
int count = mConversation.getAllMessages().size();
if (count < mConversation.getAllMsgCount() && count < 20) {
// 獲取已經在列表中的最上邊的一條訊息id
String msgId = mConversation.getAllMessages().get(0).getMsgId();
// 分頁載入更多訊息,需要傳遞已經載入的訊息的最上邊一條訊息的id,以及需要載入的訊息的條數
mConversation.loadMoreMsgFromDB(msgId, 20 - count);
}
}
/**
* 自定義實現Handler,主要用於重新整理UI操作
*/
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
mConversation = EMClient.getInstance().chatManager().getConversation(userName, null, true);
adapter.emMessages.add(mConversation.getLastMessage());
adapter.notifyDataSetChanged();
listView.setSelection(listView.getBottom());
break;
}
}
};
@Override
protected void onResume() {
super.onResume();
// 新增訊息監聽
EMClient.getInstance().chatManager().addMessageListener(mMessageListener);
}
@Override
protected void onStop() {
super.onStop();
// 移除訊息監聽
EMClient.getInstance().chatManager().removeMessageListener(mMessageListener);
}
@Override
protected void onPause() {
super.onPause();
try {
//停止語音播放
if (mPlayer.isPlaying()) {
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 收到新訊息
*
* @param messages
*/
@Override
public void onMessageReceived(List<EMMessage> messages) {
//收到訊息
// 迴圈遍歷當前收到的訊息
for (EMMessage message : messages) {
if (message.getFrom().equals(userName)) {
// 設定訊息為已讀
mConversation.markMessageAsRead(message.getMsgId());
// 因為訊息監聽回撥這裡是非ui執行緒,所以要用handler去更新ui
Message msg = mHandler.obtainMessage();
msg.what = 0;
msg.obj = message;
mHandler.sendMessage(msg);
} else {
// 如果訊息不是當前會話的訊息傳送通知欄通知
}
}
}
/**
* 收到新的 CMD 訊息
*
* @param list
*/
@Override
public void onCmdMessageReceived(List<EMMessage> list) {
for (int i = 0; i < list.size(); i++) {
// 透傳訊息
EMMessage cmdMessage = list.get(i);
EMCmdMessageBody body = (EMCmdMessageBody) cmdMessage.getBody();
Log.e("nsc", body.action());
}
}
/**
* 收到新的已讀回執
*
* @param list
*/
@Override
public void onMessageReadAckReceived(List<EMMessage> list) {
}
/**
* 收到新的傳送回執
*
* @param list
*/
@Override
public void onMessageDeliveryAckReceived(List<EMMessage> list) {
}
/**
* 訊息的狀態改變
*
* @param emMessage
* @param o
*/
@Override
public void onMessageChanged(EMMessage emMessage, Object o) {
}
class ChatAdapter extends BaseAdapter {
List<EMMessage> emMessages;
ChatAdapter(List<EMMessage> emMessages) {
this.emMessages = emMessages;
}
@Override
public int getCount() {
return emMessages.size();
}
@Override
public Object getItem(int i) {
return emMessages.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
final EMMessage message = emMessages.get(i);//每條訊息
if (message.getFrom().equals(userName)) {
view = getLayoutInflater().inflate(R.layout.chat_item1, null);
} else {
view = getLayoutInflater().inflate(R.layout.chat_item2, null);
}
final TextView time = (TextView) view.findViewById(R.id.time);
ImageView head = (ImageView) view.findViewById(R.id.head);
// Bitmap b = message.getBody()
// head.setImageBitmap();
TextView tv = (TextView) view.findViewById(R.id.tv);
final DraweeView image = (DraweeView) view.findViewById(R.id.image);
long msgTime = message.getMsgTime(); // 資訊時間
if (i == 0 || msgTime - emMessages.get(i - 1).getMsgTime() > 120000) {
time.setVisibility(View.VISIBLE);
long dateTaken = System.currentTimeMillis(); // 當前系統時間
String currentDate = (String) DateFormat.format("yyyy/MM/dd",
dateTaken); // 當前系統日期
String messageDate = (String) DateFormat.format("yyyy/MM/dd",
msgTime); // 資訊的日期
if (currentDate.equals(messageDate)) { // 如果是當天
time.setText(DateFormat.format("kk:mm:ss", msgTime));// 只顯示時間
} else {
time.setText(DateFormat.format("yyyy/MM/dd kk:mm:ss",// 顯示日期加時間
msgTime));
}
}
if (message.getType() == EMMessage.Type.TXT) {//文字顯示
String mess = ((EMTextMessageBody) message.getBody()).getMessage();
tv.setText(mess);
} else if (message.getType() == EMMessage.Type.IMAGE) {//圖片顯示
tv.setVisibility(View.GONE);
image.setVisibility(View.VISIBLE);
if (message.getFrom().equals(userName)) { // 對方發的訊息
String ThumbnailUrl = ((EMImageMessageBody) message.getBody()).getThumbnailUrl(); // 獲取縮圖片地址
String thumbnailPath = ImageUtils.getScaledImage(getApplication(), ThumbnailUrl);
String imageRemoteUrl = ((EMImageMessageBody) message.getBody()).getRemoteUrl();// 獲取遠端原圖片地址
fb.display(image, thumbnailPath);//顯示圖片
imageClick(image, imageRemoteUrl);//圖片新增監聽
} else {
// 自己發的訊息
String LocalUrl = ((EMImageMessageBody) message.getBody()).getLocalUrl(); // 獲取本地圖片地址
Bitmap bm = ImageUtils.decodeScaleImage(LocalUrl, 160, 160);//獲取縮圖
image.setImageBitmap(bm);//顯示圖片
Log.e(TAG, "bm=" + bm + "==LocalUrl=" + LocalUrl);
imageClick(image, LocalUrl);//圖片新增監聽
}
} else if (message.getType() == EMMessage.Type.VOICE) {//語音
tv.setVisibility(View.GONE);
tv.setGravity(Gravity.TOP);
image.setVisibility(View.VISIBLE);
tv.setText(((EMVoiceMessageBody) message.getBody()).getLength() + "”"); // 設定語音的時長
// 設定為語音的圖片
if (message.direct() == EMMessage.Direct.RECEIVE) {
image.setImageResource(R.drawable.chatfrom_voice_playing);
} else {
image.setImageResource(R.drawable.chatto_voice_playing);
}
image.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// 開始播放錄音
startPlay(message, image);
}
});
}
return view;
}
// 圖片點選監聽
private void imageClick(ImageView image, final String imageUrl) {
image.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
//new PopWindow_Image(Chat.this, imageUrl).showAtLocation(arg0, 0, 0, 0);
new PopWindow_image(fb, Chat.this, imageUrl).showAtLocation(arg0, 0, 0, 0);
}
});
}
}
// 開始播放
private void startPlay(final EMMessage message, ImageView image) {
EMVoiceMessageBody voiceBody = (EMVoiceMessageBody) message.getBody();
if (message.direct() == EMMessage.Direct.SEND) {
// for sent msg, we will try to play the voice file directly
playVoice(voiceBody.getLocalUrl(), message, image);
} else {
if (message.status() == EMMessage.Status.SUCCESS) {
playVoice(voiceBody.getLocalUrl(), message, image);
} else if (message.status() == EMMessage.Status.INPROGRESS) {
//toast("資訊還在傳送中");
Toast.makeText(getApplication(), "資訊還在傳送中", Toast.LENGTH_SHORT).show();
} else if (message.status() == EMMessage.Status.FAIL) {
// toast("接收失敗");
Toast.makeText(getApplication(), "接收失敗", Toast.LENGTH_SHORT).show();
}
}
}
// 播放錄音
public void playVoice(String filePath, final EMMessage message, final ImageView image) {
File file = new File(filePath);
if (!file.exists() || !file.isFile()) {
System.err.println("file not exist");
// toast("語音檔案不存在");
return;
}
playMsgId = message.getMsgId();
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(filePath);
mPlayer.prepare();
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
if (mPlayer == null) // 表示因為要播放其他語音時已經被停止了,所以不需要再次呼叫停止
return;
stopPlayVoice(message); // stop animation
}
});
isPlaying = true;
mPlayer.start();
playIv = image;
showAnimation(message);
} catch (Exception e) {
}
}
/**
* 停止語音
*
* @param message
*/
public void stopPlayVoice(final EMMessage message) {
voiceAnimation.stop();
if (message.direct() == EMMessage.Direct.RECEIVE) {
playIv.setImageResource(R.drawable.chatfrom_voice_playing);
} else {
playIv.setImageResource(R.drawable.chatto_voice_playing);
}
// stop play voice
if (mPlayer != null) {
mPlayer.stop();
mPlayer.release();
}
isPlaying = false;
playMsgId = null;
adapter.notifyDataSetChanged();
}
// show the voice playing animation
private void showAnimation(final EMMessage message) {
// play voice, and start animation
if (message.direct() == EMMessage.Direct.RECEIVE) {
playIv.setImageResource(R.drawable.voice_from_icon);
} else {
playIv.setImageResource(R.drawable.voice_to_icon);
}
voiceAnimation = (AnimationDrawable) playIv.getDrawable();
voiceAnimation.start();
}
/**
* 選取圖片
*
* @param requestCode
* @param resultCode
* @param data
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == REQUEST_CODE_LOCAL) {//傳送圖片
if (data != null) {
Uri selectedImage = data.getData();
if (selectedImage != null) {
sendPicByUri(selectedImage);//傳送圖片
}
}
}
}
}
/**
* send image
*
* @param selectedImage
*/
protected void sendPicByUri(Uri selectedImage) {
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getApplication().getContentResolver().query(selectedImage, filePathColumn, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
cursor = null;
if (picturePath == null || picturePath.equals("null")) {
Toast toast = Toast.makeText(getApplication(), R.string.cant_find_pictures, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
return;
}
sendImageMessage(picturePath);
} else {
File file = new File(selectedImage.getPath());
if (!file.exists()) {
Toast toast = Toast.makeText(getApplication(), R.string.cant_find_pictures, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
return;
}
sendImageMessage(file.getAbsolutePath());
}
}
/**
* 傳送圖片
*
* @param imagePath
*/
protected void sendImageMessage(String imagePath) {
EMMessage message = EMMessage.createImageSendMessage(imagePath, false, userName);
if (message == null) {
return;
}
EMClient.getInstance().chatManager().sendMessage(message);
Message msg2 = mHandler.obtainMessage();
msg2.what = 0;
mHandler.sendMessage(msg2);
}
}
程式碼下載地址:由於工程太大,所以上傳到github上了,https://github.com/ningxingxing/-demo