package com.fanxin.huangfangyi.ui;
import com.fanxin.huangfangyi.Constant;
import com.hyphenate.chat.EMCallStateChangeListener;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMMessage;
import com.hyphenate.chat.EMMessage.Status;
import com.hyphenate.chat.EMTextMessageBody;
import com.fanxin.huangfangyi.R;
import com.hyphenate.exceptions.EMServiceNotReadyException;
import com.hyphenate.media.EMLocalSurfaceView;
import com.hyphenate.media.EMOppositeSurfaceView;
import com.hyphenate.util.EMLog;
import com.hyphenate.util.NetUtils;
import android.content.Context;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.SoundPool;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.widget.Toast;
public class CallActivity extends BaseActivity {
protected final int MSG_CALL_MAKE_VIDEO = 0;
protected final int MSG_CALL_MAKE_VOICE = 1;
protected final int MSG_CALL_ANSWER = 2;
protected final int MSG_CALL_REJECT = 3;
protected final int MSG_CALL_END = 4;
protected final int MSG_CALL_RLEASE_HANDLER = 5;
protected final int MSG_CALL_SWITCH_CAMERA = 6;
protected boolean isInComingCall;
protected String username;
protected CallingState callingState = CallingState.CANCED;
protected String callDruationText;
protected String msgid;
protected AudioManager audioManager;
protected SoundPool soundPool;
protected Ringtone ringtone;
protected int outgoing;
protected EMCallStateChangeListener callStateListener;
protected EMLocalSurfaceView localSurface;
protected EMOppositeSurfaceView oppositeSurface;
protected boolean isAnswered = false;
protected int streamID = -1;
/**
* 0:voice call,1:video call
*/
protected int callType = 0;
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
audioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
}
@Override
protected void onDestroy() {
if (soundPool != null)
soundPool.release();
if (ringtone != null && ringtone.isPlaying())
ringtone.stop();
audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager.setMicrophoneMute(false);
if(callStateListener != null)
EMClient.getInstance().callManager().removeCallStateChangeListener(callStateListener);
releaseHandler();
super.onDestroy();
}
@Override
public void onBackPressed() {
handler.sendEmptyMessage(MSG_CALL_END);
saveCallRecord();
finish();
super.onBackPressed();
}
Runnable timeoutHangup = new Runnable() {
@Override
public void run() {
handler.sendEmptyMessage(MSG_CALL_END);
}
};
HandlerThread callHandlerThread = new HandlerThread("callHandlerThread");
{ callHandlerThread.start(); }
protected Handler handler = new Handler(callHandlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
EMLog.d("EMCallManager CallActivity", "handleMessage ---enter--- msg.what:" + msg.what);
switch (msg.what) {
case MSG_CALL_MAKE_VIDEO:
case MSG_CALL_MAKE_VOICE:
try {
streamID = playMakeCallSounds();
if (msg.what == MSG_CALL_MAKE_VIDEO) {
EMClient.getInstance().callManager().makeVideoCall(username);
} else {
EMClient.getInstance().callManager().makeVoiceCall(username);
}
final int MAKE_CALL_TIMEOUT = 50 * 1000;
handler.removeCallbacks(timeoutHangup);
handler.postDelayed(timeoutHangup, MAKE_CALL_TIMEOUT);
} catch (EMServiceNotReadyException e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
public void run() {
final String st2 = getResources().getString(R.string.Is_not_yet_connected_to_the_server);
Toast.makeText(CallActivity.this, st2, Toast.LENGTH_SHORT).show();
}
});
}
break;
case MSG_CALL_ANSWER:
if (ringtone != null)
ringtone.stop();
if (isInComingCall) {
try {
if (NetUtils.hasDataConnection(CallActivity.this)) {
EMClient.getInstance().callManager().answerCall();
isAnswered = true;
} else {
runOnUiThread(new Runnable() {
public void run() {
final String st2 = getResources().getString(R.string.Is_not_yet_connected_to_the_server);
Toast.makeText(CallActivity.this, st2, Toast.LENGTH_SHORT).show();
}
});
throw new Exception();
}
} catch (Exception e) {
e.printStackTrace();
saveCallRecord();
finish();
return;
}
}
break;
case MSG_CALL_REJECT:
if (ringtone != null)
ringtone.stop();
try {
EMClient.getInstance().callManager().rejectCall();
} catch (Exception e1) {
e1.printStackTrace();
saveCallRecord();
finish();
}
callingState = CallingState.REFUESD;
break;
case MSG_CALL_END:
if (soundPool != null)
soundPool.stop(streamID);
try {
EMClient.getInstance().callManager().endCall();
} catch (Exception e) {
saveCallRecord();
finish();
}
break;
case MSG_CALL_RLEASE_HANDLER:
try {
EMClient.getInstance().callManager().endCall();
} catch (Exception e) {
}
handler.removeCallbacks(timeoutHangup);
handler.removeMessages(MSG_CALL_MAKE_VIDEO);
handler.removeMessages(MSG_CALL_MAKE_VOICE);
handler.removeMessages(MSG_CALL_ANSWER);
handler.removeMessages(MSG_CALL_REJECT);
handler.removeMessages(MSG_CALL_END);
callHandlerThread.quit();
break;
case MSG_CALL_SWITCH_CAMERA:
EMClient.getInstance().callManager().switchCamera();
break;
default:
break;
}
EMLog.d("EMCallManager CallActivity", "handleMessage ---exit--- msg.what:" + msg.what);
}
};
void releaseHandler() {
handler.sendEmptyMessage(MSG_CALL_RLEASE_HANDLER);
}
/**
* play the incoming call ringtone
*
*/
protected int playMakeCallSounds() {
try {
// max volume
float audioMaxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_RING);
// current volume
float audioCurrentVolume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
float volumeRatio = audioCurrentVolume / audioMaxVolume;
audioManager.setMode(AudioManager.MODE_RINGTONE);
audioManager.setSpeakerphoneOn(false);
// play
int id = soundPool.play(outgoing, // sound resource
0.3f, // left volume
0.3f, // right volume
1, // priority
-1, // loop,0 is no loop,-1 is loop forever
1); // playback rate (1.0 = normal playback, range 0.5 to 2.0)
return id;
} catch (Exception e) {
return -1;
}
}
protected void openSpeakerOn() {
try {
if (!audioManager.isSpeakerphoneOn())
audioManager.setSpeakerphoneOn(true);
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
} catch (Exception e) {
e.printStackTrace();
}
}
protected void closeSpeakerOn() {
try {
if (audioManager != null) {
// int curVolume =
// audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
if (audioManager.isSpeakerphoneOn())
audioManager.setSpeakerphoneOn(false);
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
// audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,
// curVolume, AudioManager.STREAM_VOICE_CALL);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* save call record
*/
protected void saveCallRecord() {
EMMessage message = null;
EMTextMessageBody txtBody = null;
if (!isInComingCall) { // outgoing call
message = EMMessage.createSendMessage(EMMessage.Type.TXT);
message.setReceipt(username);
} else {
message = EMMessage.createReceiveMessage(EMMessage.Type.TXT);
message.setFrom(username);
}
String st1 = getResources().getString(R.string.call_duration);
String st2 = getResources().getString(R.string.Refused);
String st3 = getResources().getString(R.string.The_other_party_has_refused_to);
String st4 = getResources().getString(R.string.The_other_is_not_online);
String st5 = getResources().getString(R.string.The_other_is_on_the_phone);
String st6 = getResources().getString(R.string.The_other_party_did_not_answer);
String st7 = getResources().getString(R.string.did_not_answer);
String st8 = getResources().getString(R.string.Has_been_cancelled);
switch (callingState) {
case NORMAL:
txtBody = new EMTextMessageBody(st1 + callDruationText);
break;
case REFUESD:
txtBody = new EMTextMessageBody(st2);
break;
case BEREFUESD:
txtBody = new EMTextMessageBody(st3);
break;
case OFFLINE:
txtBody = new EMTextMessageBody(st4);
break;
case BUSY:
txtBody = new EMTextMessageBody(st5);
break;
case NORESPONSE:
txtBody = new EMTextMessageBody(st6);
break;
case UNANSWERED:
txtBody = new EMTextMessageBody(st7);
break;
case VERSION_NOT_SAME:
txtBody = new EMTextMessageBody(getString(R.string.call_version_inconsistent));
default:
txtBody = new EMTextMessageBody(st8);
break;
}
// set message extension
if(callType == 0)
message.setAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, true);
else
message.setAttribute(Constant.MESSAGE_ATTR_IS_VIDEO_CALL, true);
// set message body
message.addBody(txtBody);
message.setMsgId(msgid);
message.setStatus(Status.SUCCESS);
// save
EMClient.getInstance().chatManager().saveMessage(message);
}
enum CallingState {
CANCED, NORMAL, REFUESD, BEREFUESD, UNANSWERED, OFFLINE, NORESPONSE, BUSY, VERSION_NOT_SAME
}
}