package com.partynetwork.iparty.imessage; import java.io.File; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.List; import org.jivesoftware.smack.Chat; import org.jivesoftware.smack.MessageListener; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Message.Type; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.Cursor; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Handler.Callback; import android.provider.MediaStore; import android.provider.MediaStore.Images.Media; import android.text.Editable; import android.text.TextWatcher; import android.text.format.DateFormat; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.WindowManager; import android.view.View.OnKeyListener; import android.view.View.OnTouchListener; import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.EditText; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import com.baidu.mobstat.StatService; import com.lidroid.xutils.util.LogUtils; import com.openfire.manager.XmppConnection; import com.partynetwork.dataprovider.util.ActionUtil.user; import com.partynetwork.dataprovider.util.BitmapUtil; import com.partynetwork.dataprovider.util.OpenfireUtil; import com.partynetwork.dataprovider.util.T; import com.partynetwork.dataprovider.util.TimeUtil; import com.partynetwork.iparty.R; import com.partynetwork.iparty.app.AppContext; import com.partynetwork.iparty.app.AppException; import com.partynetwork.iparty.app.entities.CommonUser; import com.partynetwork.iparty.app.entities.IMessage; import com.partynetwork.iparty.app.manager.MessageManager; import com.partynetwork.iparty.app.manager.UserManager; import com.partynetwork.iparty.app.util.StringUtils; import com.partynetwork.iparty.imessage.RecordStatus.RecordListener; import com.partynetwork.myview.mylistview.XListView; import com.partynetwork.myview.mylistview.XListView.IXListViewListener; public class ChatActivity extends Activity implements OnTouchListener, IXListViewListener, OnKeyListener, TextWatcher, OnClickListener, Callback { public static String WITH_USER = "withUser"; public static final int SELECT_PICTURE = 100;// 相片 public static final int SELECT_CAMER = 101;// 拍照 private String imagePath;// 本次生成的路径 private String filePath;// 最后选择的图片地址 private int voiceTime;// 录音时长 private InputMethodManager imm;// 输入法管理 private WindowManager.LayoutParams params; private boolean isFaceShow = false; private boolean isMoreShow = false; private TextView titieName; private ChatAdapter adapter; private XListView mMsgListView; /************************************************ 底部控件 */ private ImageButton voiceBtn;// 录音,文字功能选择 private Button recarder;// 录音按钮 private EditText msgEt;// 消息输入文本框 private ImageButton faceBtn;// 表情 private Button sendBtn;// 发送按钮 private ImageButton moreBtn;// 更多功能 /************************************************ 功能面板 */ private LinearLayout faceOutLayout;// private LinearLayout faceLinearLayout;// 表情功能按钮 private LinearLayout moreLinearLayout;// 更多功能布局 private LinearLayout recardStatusLayout;// 录音状态布局 private FacePageInit facePageInit; private MorePageInit morePageInit; private RecordStatus recordStatus; private CommonUser mFromUser;// 聊天对象 private String withUser;// 聊天对象用户名 private Chat chat;// 聊天链接 private XmppConnection xmppConnection; private XMPPConnection connection; private List<IMessage> message_pool = new ArrayList<IMessage>();// 聊天数据集合 private Handler mHandler;// 更新界面的Handler // 更多功能面板的功能监听 private MorePageListener morePageListener = new MorePageListener() { public void click(int position) { switch (position) { case 0: // 照片 Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null); intent.setType("image/*"); ChatActivity.this .startActivityForResult(intent, SELECT_PICTURE); break; case 1: // 拍照 Intent intent2 = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); imagePath = BitmapUtil.getImagePath(); Uri uri = Uri.fromFile(new File(imagePath)); intent2.putExtra(MediaStore.EXTRA_OUTPUT, uri); ChatActivity.this.startActivityForResult(intent2, SELECT_CAMER); break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); withUser = getIntent().getStringExtra(WITH_USER); // System.out.println("withUser=========="+withUser); setContentView(R.layout.chat_main); initView(); initData(); } @Override protected void onResume() { List<IMessage> list = MessageManager.getInstance(this) .getMessageListByFrom(withUser, 1, 10); if (list != null) { message_pool.removeAll(message_pool); message_pool.addAll(list); } if (null != message_pool && message_pool.size() > 0) { Collections.sort(message_pool); refreshMessage(); } IntentFilter filter = new IntentFilter(); filter.addAction(OpenfireConstant.NEW_MESSAGE_ACTION); registerReceiver(receiver, filter); StatService.onResume(this); super.onResume(); } @Override protected void onPause() { unregisterReceiver(receiver); StatService.onPause(this); MessageManager.getInstance(this).updateStatusByFrom(withUser); super.onPause(); } protected List<IMessage> getMessages() { return message_pool; } private void initView() { imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); titieName = (TextView) this.findViewById(R.id.chat_title_name); findViewById(R.id.chat_title_back).setOnClickListener(this); mMsgListView = (XListView) findViewById(R.id.msg_listView); mMsgListView.setOnTouchListener(this); mMsgListView.setPullLoadEnable(false); mMsgListView.setPullRefreshEnable(false); mMsgListView.setXListViewListener(this); voiceBtn = (ImageButton) this.findViewById(R.id.voice_btn); voiceBtn.setOnClickListener(this); recarder = (Button) this.findViewById(R.id.recarder); msgEt = (EditText) this.findViewById(R.id.msg_et); msgEt.setOnKeyListener(this); msgEt.addTextChangedListener(this); msgEt.setOnTouchListener(this); sendBtn = (Button) this.findViewById(R.id.send_btn); sendBtn.setOnClickListener(this); moreBtn = (ImageButton) findViewById(R.id.more_btn); moreBtn.setOnClickListener(this); faceBtn = (ImageButton) findViewById(R.id.face_btn); faceBtn.setOnClickListener(this); faceOutLayout = (LinearLayout) findViewById(R.id.face_out_ll); faceLinearLayout = (LinearLayout) findViewById(R.id.face_ll); moreLinearLayout = (LinearLayout) findViewById(R.id.more_ll); recardStatusLayout = (LinearLayout) findViewById(R.id.record_status); } private void initData() { mHandler = new Handler(this); params = getWindow().getAttributes();// 触摸ListView隐藏表情和输入法 new Thread() { @Override public void run() { // 获得聊天对象 //XmppConnection.getInstance().login(user, password); System.out.println("获得聊天对象"); xmppConnection = XmppConnection.getInstance(); System.out.println("聊天xmppConnection = XmppConnection.getInstance()"); connection = xmppConnection.getConnection(); System.out.println("聊天connection = xmppConnection.getConnection();"); chat = connection.getChatManager().createChat(OpenfireUtil.getJidByName(withUser), null); System.out.println("获取登陆用户"); // 获取登陆用户 mFromUser = UserManager.getInstance(ChatActivity.this) .getUserbyId(OpenfireUtil.getUserNameByJid(withUser)); // 触摸ListView隐藏表情和输入法 adapter = new ChatAdapter(ChatActivity.this, message_pool); mHandler.sendEmptyMessage(1);// 刷新 } }.start(); } /** * 发送消息 * * @param messageContent * @throws Exception */ protected void sendMessage(String messageContent, int contentType) throws XMPPException { if (StringUtils.isEmpty(messageContent)) { return; } String time = TimeUtil.date2Str(Calendar.getInstance(), OpenfireConstant.MS_FORMART); Message message = new Message(); message.setProperty(IMessage.KEY_TIME, time); message.setProperty(IMessage.CONTENT_TYPE, contentType); message.setBody(messageContent); chat.sendMessage(message); IMessage newMessage = new IMessage(); newMessage.setState(1); newMessage.setWithUser(OpenfireUtil.getUserNameByJid(withUser)); newMessage.setIsCome(0); newMessage.setContent(messageContent); newMessage.setContentType(contentType); newMessage.setTime(time); if (contentType == IMessage.VOICE) { newMessage.setVoiceTime(voiceTime); voiceTime = 0; } message_pool.add(newMessage); MessageManager.getInstance(this).saveIMessage(newMessage); chat.addMessageListener(new MessageListener() { @Override public void processMessage(Chat arg0, Message arg1) { if (arg1.getType() == Type.error) { T.showLong(ChatActivity.this, "消息发送失败!"); LogUtils.i(arg1.toString()); IMessage newMessage = new IMessage(); newMessage.setState(1); newMessage.setWithUser(withUser); newMessage.setIsCome(0); newMessage.setContent(arg1.getBody()); newMessage.setContentType(StringUtils.toInt(arg1.getProperty(IMessage.CONTENT_TYPE).toString(),0)); newMessage.setTime(arg1.getProperty(IMessage.CONTENT_TYPE).toString()); MessageManager.getInstance(ChatActivity.this) .delLastChatWithSb(newMessage); } } }); mHandler.sendEmptyMessage(0); } protected void refreshMessage() { if (adapter == null) { return; } adapter.setList(message_pool); adapter.refreshList(); mMsgListView.setSelection(message_pool.size() - 1); } /** * 广播接收消息 */ private BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (OpenfireConstant.NEW_MESSAGE_ACTION.equals(action)) { IMessage message = intent .getParcelableExtra(IMessage.IMMESSAGE_KEY); if (message.getWithUser().equals(withUser)) { MessageManager.getInstance(ChatActivity.this).updateStatus( message); message_pool.add(message); mHandler.sendEmptyMessage(0); // NoticeManager.getInstance(ChatActivity.this) // .updateStatusByFrom(to, Notice.READ); } } } }; @Override public void onRefresh() { List<IMessage> newMsgList = new ArrayList<IMessage>(); newMsgList = MessageManager.getInstance(this).getMessageListByFrom( withUser, message_pool.size(), 10); if (newMsgList != null && newMsgList.size() > 0) { message_pool.addAll(newMsgList); Collections.sort(message_pool); mHandler.sendEmptyMessage(0); } mMsgListView.stopRefresh(); } @Override public void onLoadMore() { } @Override public boolean onTouch(View v, MotionEvent event) { switch (v.getId()) { case R.id.msg_listView: imm.hideSoftInputFromWindow(msgEt.getWindowToken(), 0); hideFace(); hideMore(); break; case R.id.msg_et: imm.showSoftInput(msgEt, 0); hideFace(); hideMore(); break; default: break; } return false; } @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (params.softInputMode == WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE || isFaceShow) { faceOutLayout.setVisibility(View.GONE); isFaceShow = false; // imm.showSoftInput(msgEt, 0); return true; } } return false; } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { if (s.length() > 0) { moreBtn.setVisibility(View.GONE); sendBtn.setVisibility(View.VISIBLE); sendBtn.setEnabled(true); } else { moreBtn.setVisibility(View.VISIBLE); sendBtn.setVisibility(View.GONE); sendBtn.setEnabled(false); } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.send_btn: String message = msgEt.getText().toString(); if ("".equals(message)) { Toast.makeText(ChatActivity.this, "不能为空", Toast.LENGTH_SHORT) .show(); } else { try { message=new String(message.getBytes(), "UTF-8"); sendMessage(message, IMessage.TEXT); msgEt.setText(""); } catch (Exception e) { T.showShort(this, "信息发送失败"); msgEt.setText(message); } closeInput(); } break; case R.id.face_btn: if (!isFaceShow) { imm.hideSoftInputFromWindow(msgEt.getWindowToken(), 0); try { Thread.sleep(80);// 解决此时会黑一下屏幕的问题 } catch (InterruptedException e) { e.printStackTrace(); } showFace(); } else { hideFace(); } break; case R.id.chat_title_back: finish(); break; case R.id.voice_btn: // 音频按钮 showOrHideRecarder(); break; case R.id.more_btn: if (!isMoreShow) { imm.hideSoftInputFromWindow(msgEt.getWindowToken(), 0); try { Thread.sleep(80);// 解决此时会黑一下屏幕的问题 } catch (InterruptedException e) { e.printStackTrace(); } showMore(); } else { hideMore(); } break; default: break; } } private void showMore() { if (isFaceShow) { hideFace(); } if (morePageInit == null) { morePageInit = new MorePageInit(this, moreLinearLayout, morePageListener); } isMoreShow = true; moreLinearLayout.setVisibility(View.VISIBLE); } private void hideMore() { if (morePageInit == null) { morePageInit = new MorePageInit(this, moreLinearLayout, morePageListener); } isMoreShow = false; moreLinearLayout.setVisibility(View.GONE); } private void showFace() { if (isMoreShow) { hideMore(); } if (facePageInit == null) { facePageInit = new FacePageInit(this, faceLinearLayout, msgEt); } isFaceShow = true; faceOutLayout.setVisibility(View.VISIBLE); } private void hideFace() { if (facePageInit == null) { facePageInit = new FacePageInit(this, faceLinearLayout, msgEt); } isFaceShow = false; faceOutLayout.setVisibility(View.GONE); } // 显示录音操作 private void showOrHideRecarder() { // 隐藏软键盘 imm.hideSoftInputFromWindow(msgEt.getWindowToken(), 0); // 隐藏表情 hideFace(); if (voiceBtn.getTag() == null) { showRecareder(); } else { hideRecareder(); } } private RecordListener recordListener = new RecordListener() { @Override public void recordEnd(File amrFile, final int voiceTime) { final List<File> lists = new ArrayList<File>(); lists.add(amrFile); new Thread() { public void run() { android.os.Message msg = new android.os.Message(); try { AppContext ac = (AppContext) getApplication(); List<String> lis = ac.upFiles4Url(lists); ChatActivity.this.voiceTime = voiceTime; msg.what = 2;// 成功 msg.obj = lis; } catch (AppException e) { e.printStackTrace(); msg.what = -1; msg.obj = e; } mHandler.sendMessage(msg); } }.start(); } }; // 显示录制操作选项 private void showRecareder() { voiceBtn.setTag(1); voiceBtn.setImageResource(R.drawable.chat_bottombar_keybord); msgEt.setVisibility(View.GONE); faceBtn.setVisibility(View.GONE); moreBtn.setVisibility(View.VISIBLE); sendBtn.setVisibility(View.GONE); recarder.setVisibility(View.VISIBLE); if (recordStatus == null) { recordStatus = new RecordStatus(this, recarder, recordListener); recarder.setOnTouchListener(recordStatus); recardStatusLayout.addView(recordStatus); } recardStatusLayout.setVisibility(View.VISIBLE); } // 隐藏录制操作选项 private void hideRecareder() { voiceBtn.setTag(null); voiceBtn.setImageResource(R.drawable.chat_bottombar_voice); faceBtn.setVisibility(View.VISIBLE); recarder.setVisibility(View.GONE); msgEt.setVisibility(View.VISIBLE); if (msgEt.length() > 0) { moreBtn.setVisibility(View.GONE); sendBtn.setVisibility(View.VISIBLE); } else { moreBtn.setVisibility(View.VISIBLE); sendBtn.setVisibility(View.GONE); } recardStatusLayout.setVisibility(View.GONE); } /** * * 关闭键盘事件 * * @update 2012-7-4 下午2:34:34 */ public void closeInput() { InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); if (inputMethodManager != null && this.getCurrentFocus() != null) { inputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus() .getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } } @Override public boolean handleMessage(android.os.Message msg) { switch (msg.what) { case 0: // 刷新视图 refreshMessage(); break; case 1: // 设置聊天对象 if (mFromUser != null) { titieName.setText(mFromUser.getUserName()); } mMsgListView.setAdapter(adapter); mMsgListView.setSelection(adapter.getCount() - 1); break; case 2: // 语音成功 List<String> lis = (List<String>) msg.obj; if (lis != null) { for (String str : lis) { try { ChatActivity.this.sendMessage(str, IMessage.VOICE); } catch (XMPPException e) { AppException.im(e).makeToast(ChatActivity.this); } } } break; case 3: // 图片 List<String> lis2 = (List<String>) msg.obj; if (lis2 != null) { for (String str : lis2) { try { ChatActivity.this.sendMessage(str, IMessage.PICTURE); } catch (XMPPException e) { AppException.im(e).makeToast(ChatActivity.this); } } } break; case -1: AppException e = (AppException) msg.obj; e.makeToast(ChatActivity.this); break; default: break; } return false; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Object object = null; // 选择照片的返回结果 filePath = null; if (data == null && requestCode == SELECT_CAMER) { filePath = imagePath; } else if (resultCode == Activity.RESULT_OK) { switch (requestCode) { case SELECT_PICTURE: // 相册 Uri uri = data.getData(); String[] proj = { MediaStore.Images.Media.DATA }; Cursor cursor = this.managedQuery(uri, proj, null, null, null); int column_index = cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); filePath = cursor.getString(column_index); break; case SELECT_CAMER: // 相机拍照 if (data.getData() != null) { // 根据返回的URI获取对应的SQLite信息 Cursor cursor2 = this.getContentResolver().query( data.getData(), null, null, null, null); if (cursor2.moveToFirst()) { filePath = cursor2.getString(cursor2 .getColumnIndex(Media.DATA));// 获取绝对路径 } cursor2.close(); } else {// 三星 小米(小米手机不会自动存储DCIM... 这点让哥又爱又恨...) object = (Bitmap) (data.getExtras() == null ? null : data .getExtras().get("data")); Bitmap bitmap = object == null ? null : (Bitmap) object; if (bitmap != null) { try { filePath = BitmapUtil.saveImg(bitmap, DateFormat .format("yyyyMMddhhmmss", new Date()) .toString()); } catch (Exception e) { e.printStackTrace(); } } } filePath = !filePath.equals("") ? filePath : getRealFilePath(); break; default: break; } } else { Toast.makeText(this, "请重新选择图片", Toast.LENGTH_SHORT).show(); } if (!StringUtils.isEmpty(filePath)) { final List<File> lists = new ArrayList<File>(); lists.add(new File(filePath)); new Thread() { public void run() { android.os.Message msg = new android.os.Message(); try { AppContext ac = (AppContext) getApplication(); List<String> lis = ac.upFiles4Url(lists); msg.what = 3;// 成功 msg.obj = lis; } catch (AppException e) { e.printStackTrace(); msg.what = -1; msg.obj = e; } mHandler.sendMessage(msg); } }.start(); } } /** * 获取系统默认存储真实文件路径 两个路径 一个是最后一张所拍图片路径 * (由于设置了存储路径所以DCIM中会存储两张一模一样的图片,所以在此获取两张图片路径以便于缩放处理后全部删除) * * @param filePath * @return */ protected String getRealFilePath() { String filePath = ""; // MediaStore.Images.Media.EXTERNAL_CONTENT_URI // content://media/external/images/media Cursor cursor = this.getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, Media.DATE_MODIFIED + " desc"); if (cursor.moveToNext()) { /** * _data:文件的绝对路径 Media.DATA='_data' */ filePath = cursor.getString(cursor.getColumnIndex(Media.DATA)); } return filePath; } public interface MorePageListener { public abstract void click(int position); } }