|
@@ -0,0 +1,380 @@
|
|
|
|
+package com.wdkl.app.ncs.callingbed.fragment
|
|
|
|
+
|
|
|
|
+import android.os.Handler
|
|
|
|
+import android.os.Looper
|
|
|
|
+import android.os.SystemClock
|
|
|
|
+import android.text.TextUtils
|
|
|
|
+import android.util.Log
|
|
|
|
+import android.view.View
|
|
|
|
+import com.google.gson.Gson
|
|
|
|
+import com.wdkl.app.ncs.callingbed.R
|
|
|
|
+import com.wdkl.app.ncs.callingbed.helper.RingPlayHelper
|
|
|
|
+import com.wdkl.ncs.android.lib.utils.AppTool
|
|
|
|
+import com.wdkl.ncs.android.lib.utils.showMessage
|
|
|
|
+import com.wdkl.ncs.android.middleware.common.Constant
|
|
|
|
+import com.wdkl.ncs.android.middleware.common.MessageEvent
|
|
|
|
+import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
|
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.channel.VoiceUtil
|
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel
|
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpAction
|
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpType
|
|
|
|
+import kotlinx.android.synthetic.main.sip_voice_call_layout.*
|
|
|
|
+import org.greenrobot.eventbus.Subscribe
|
|
|
|
+import org.greenrobot.eventbus.ThreadMode
|
|
|
|
+
|
|
|
|
+class SipCallFragment: BaseCallFragment() {
|
|
|
|
+ private val TAG = "SipCallFragment"
|
|
|
|
+
|
|
|
|
+ //来电设备id
|
|
|
|
+ var fromId: Int = -1
|
|
|
|
+
|
|
|
|
+ private var interactionVO: InteractionVO? = null
|
|
|
|
+
|
|
|
|
+ private val handler = Handler(Looper.getMainLooper())
|
|
|
|
+
|
|
|
|
+ private var callEnded: Boolean = false
|
|
|
|
+
|
|
|
|
+ private var outGoing: Boolean = false
|
|
|
|
+
|
|
|
|
+ private var callSuccess: Boolean = false
|
|
|
|
+
|
|
|
|
+ override fun getLayId(): Int {
|
|
|
|
+ return R.layout.sip_voice_call_layout
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override fun init() {
|
|
|
|
+ //初始化计时器
|
|
|
|
+ initCountDownTimer(sip_voice_call_timeout)
|
|
|
|
+ //tcp参数
|
|
|
|
+ if (tcpModel != null) {
|
|
|
|
+ fromId = tcpModel!!.fromId
|
|
|
|
+ interactionVO = Gson().fromJson(tcpModel!!.data.toString(), InteractionVO::class.java)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ when (callState) {
|
|
|
|
+ 0 -> {
|
|
|
|
+ //去电
|
|
|
|
+ outGoing = true
|
|
|
|
+ startOutgoing()
|
|
|
|
+ RingPlayHelper.playRingTone(baseActivity, R.raw.ring_back2, true)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ 1 -> {
|
|
|
|
+ //来电
|
|
|
|
+ outGoing = false
|
|
|
|
+ showIncomingCall()
|
|
|
|
+ RingPlayHelper.playRingTone(baseActivity, R.raw.ring_tone, true)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override fun bindEvent() {
|
|
|
|
+ //去电取消或通话挂断
|
|
|
|
+ sip_voice_call_hangup.setOnClickListener {
|
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
|
+ if (Constant.CALL_STATE == Constant.CALL_CALLING) {
|
|
|
|
+ //结束sip通话
|
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
|
+ if (sip_voice_call_timer != null) {
|
|
|
|
+ sip_voice_call_timer.stop()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ VoiceUtil.handoffAudioCall(Constant.DEVICE_ID, fromId, interactionVO?.id)
|
|
|
|
+ callEnd()
|
|
|
|
+ } else {
|
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
|
+ VoiceUtil.cancelAudioCall(Constant.DEVICE_ID)
|
|
|
|
+ cancelCall()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //来电拒绝
|
|
|
|
+ sip_voice_call_ring_reject.setOnClickListener {
|
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
|
+ VoiceUtil.rejectAudioCall(Constant.DEVICE_ID, fromId, interactionVO?.id)
|
|
|
|
+ callEnd()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //来电接听
|
|
|
|
+ sip_voice_call_ring_pickup_audio.setOnClickListener {
|
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
|
+ Constant.CALL_STATE = Constant.CALL_INCOMING
|
|
|
|
+ VoiceUtil.acceptAudioCall(Constant.DEVICE_ID, fromId, interactionVO?.id)
|
|
|
|
+ acceptCall()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override fun destroy() {
|
|
|
|
+ cancelTimer()
|
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
|
+ if (sip_voice_call_timer != null) {
|
|
|
|
+ sip_voice_call_timer.stop()
|
|
|
|
+ }
|
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private fun startOutgoing() {
|
|
|
|
+ callSuccess = false
|
|
|
|
+ sip_voice_call_hangup.isEnabled = false
|
|
|
|
+ VoiceUtil.startAudioCall(Constant.DEVICE_ID)
|
|
|
|
+ Constant.CALL_STATE = Constant.CALL_OUTGOING
|
|
|
|
+ sip_voice_call_timeout.visibility = View.VISIBLE
|
|
|
|
+ sip_voice_call_timer.visibility = View.GONE
|
|
|
|
+ startTimer()
|
|
|
|
+
|
|
|
|
+ AppTool.Time.delay(3000) {
|
|
|
|
+ Log.d("tcp", "call success: $callSuccess")
|
|
|
|
+ if (!callSuccess) {
|
|
|
|
+ //呼叫失败
|
|
|
|
+ showMessage("呼叫失败,服务器无响应或网络故障!")
|
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
|
+ cancelCall()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //去电界面
|
|
|
|
+ private fun showOutgoingCall() {
|
|
|
|
+ Constant.CALL_STATE = Constant.CALL_OUTGOING
|
|
|
|
+ sip_voice_call_calling_text.text = "呼叫成功,等待接听..."
|
|
|
|
+ ll_sip_voice_call_outgoing.visibility = View.VISIBLE
|
|
|
|
+ ll_sip_voice_call_incoming.visibility = View.GONE
|
|
|
|
+ sip_voice_call_timeout.visibility = View.VISIBLE
|
|
|
|
+ sip_voice_call_timer.visibility = View.GONE
|
|
|
|
+ startTimer()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //来电界面
|
|
|
|
+ private fun showIncomingCall() {
|
|
|
|
+ Constant.CALL_STATE = Constant.CALL_INCOMING
|
|
|
|
+ sip_voice_call_calling_text.text = "有新来电..."
|
|
|
|
+ ll_sip_voice_call_outgoing.visibility = View.GONE
|
|
|
|
+ ll_sip_voice_call_incoming.visibility = View.GONE
|
|
|
|
+ sip_voice_call_timeout.visibility = View.GONE
|
|
|
|
+ sip_voice_call_timer.visibility = View.GONE
|
|
|
|
+ cancelTimer()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //开始接听
|
|
|
|
+ private fun acceptCall() {
|
|
|
|
+ sip_voice_call_calling_text.text = "连接中..."
|
|
|
|
+ ll_sip_voice_call_outgoing.visibility = View.VISIBLE
|
|
|
|
+ ll_sip_voice_call_incoming.visibility = View.GONE
|
|
|
|
+ sip_voice_call_timeout.visibility = View.GONE
|
|
|
|
+ sip_voice_call_timer.visibility = View.GONE
|
|
|
|
+ cancelTimer()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //呼叫取消
|
|
|
|
+ private fun cancelCall() {
|
|
|
|
+ cancelTimer()
|
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
|
+ callEnd()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private fun showCalling() {
|
|
|
|
+ if (callEnded) {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Constant.CALL_STATE = Constant.CALL_CALLING
|
|
|
|
+ sip_voice_call_calling_text.text = "通话中..."
|
|
|
|
+ sip_voice_call_timeout.visibility = View.GONE
|
|
|
|
+ cancelTimer()
|
|
|
|
+ sip_voice_call_timer.visibility = View.VISIBLE
|
|
|
|
+ sip_voice_call_timer.base = SystemClock.elapsedRealtime()
|
|
|
|
+ sip_voice_call_timer.start()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //通话结束
|
|
|
|
+ override fun callEnd() {
|
|
|
|
+ synchronized(this) {
|
|
|
|
+ if (callEnded) {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ callEnded = true
|
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
|
+ if (sip_voice_call_timer != null) {
|
|
|
|
+ sip_voice_call_timer.stop()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Log.e(TAG, "call end !!!!!!!!!!!!!!!!!!")
|
|
|
|
+
|
|
|
|
+ backToMain()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /********************************************************
|
|
|
|
+ ********************* 通话回调 ********************
|
|
|
|
+ * 注意: 如涉及到UI更新的需要在主线程处理,务必注意
|
|
|
|
+ ********************************************************/
|
|
|
|
+ /*override fun didChangeState(var1: EnumType.CallState?) {
|
|
|
|
+ if (var1 == EnumType.CallState.Connected) {
|
|
|
|
+ handler.post {
|
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
|
+ //更新界面显示
|
|
|
|
+ showCalling()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override fun didDisconnected(userId: String?) {
|
|
|
|
+ Log.i(TAG, "disconnected user:" + userId + ",call user:" + Constant.TARGET_SIP)
|
|
|
|
+ if (userId.equals(Constant.TARGET_SIP)) {
|
|
|
|
+ Log.w(TAG, "didDisconnected: $userId")
|
|
|
|
+ handler.post {
|
|
|
|
+ showMessage("$userId 失去连接")
|
|
|
|
+ callEnd()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override fun didCreateLocalVideoTrack() {
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override fun didError(error: String?) {
|
|
|
|
+ Log.e(TAG, "didError: $error")
|
|
|
|
+ handler.post {
|
|
|
|
+ showMessage("通话错误")
|
|
|
|
+ callEnd()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override fun didHangUp(handlerId: BigInteger) {
|
|
|
|
+ Log.e("hangup", "socket hangup")
|
|
|
|
+ handler.post {
|
|
|
|
+ callEnd()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override fun didReceiveRemoteVideoTrack(userId: BigInteger?) {
|
|
|
|
+ // TODO("Not yet implemented")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ override fun didCallEndWithReason(var1: EnumType.CallEndReason?) {
|
|
|
|
+ handler.post {
|
|
|
|
+ callEnd()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override fun didChangeMode(isAudioOnly: Boolean) {
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override fun didUserLeave(userId: BigInteger?) {
|
|
|
|
+ Log.w(TAG, "didUserLeave:"+userId)
|
|
|
|
+ handler.post {
|
|
|
|
+ callEnd()
|
|
|
|
+ }
|
|
|
|
+ }*/
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ @Subscribe(threadMode = ThreadMode.MAIN)
|
|
|
|
+ fun onMoonEvent(messageEvent: MessageEvent) {
|
|
|
|
+ when (messageEvent.type) {
|
|
|
|
+ Constant.EVENT_TCP_MSG -> {
|
|
|
|
+ if (messageEvent.message is TcpModel) {
|
|
|
|
+ val curTcpModel = messageEvent.message as TcpModel
|
|
|
|
+ if (curTcpModel.getType() == TcpType.VOICE) {
|
|
|
|
+ if (curTcpModel.action == TcpAction.VoiceAction.CANCEL_BY_DOOR) {
|
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
|
+ VoiceUtil.cancelAudioCall(Constant.DEVICE_ID)
|
|
|
|
+ cancelCall()
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (curTcpModel.data != null) {
|
|
|
|
+ val curInteractionVO = Gson().fromJson(curTcpModel.data.toString(), InteractionVO::class.java)
|
|
|
|
+ if (curTcpModel.getAction() == TcpAction.VoiceAction.ACCEPT) {
|
|
|
|
+ //我方呼出,对方接受
|
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
|
+ Constant.interactionId = curInteractionVO.id
|
|
|
|
+ fromId = curTcpModel.fromId
|
|
|
|
+ acceptCall()
|
|
|
|
+ if (TextUtils.isEmpty(curInteractionVO.toSipId)) {
|
|
|
|
+ //通话失败,重置并返回主界面
|
|
|
|
+ showMessage("targetSipId为空!")
|
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
|
+ VoiceUtil.handoffAudioCall(Constant.DEVICE_ID, fromId, Constant.interactionId)
|
|
|
|
+ callEnd()
|
|
|
|
+ }
|
|
|
|
+ } else if (curTcpModel.getAction() == TcpAction.VoiceAction.REJECT) {
|
|
|
|
+ //我方呼出,对方拒绝
|
|
|
|
+ showMessage("对方已拒绝!")
|
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
|
+ cancelCall()
|
|
|
|
+ } else if (curTcpModel.getAction() == TcpAction.VoiceAction.CALLING) {
|
|
|
|
+ //我方呼出,对方通话中
|
|
|
|
+ showMessage("对方正在忙线中,暂时无法接听!")
|
|
|
|
+ /*AppTool.Time.delay(1000) {
|
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
|
+ cancelCall()
|
|
|
|
+ }*/
|
|
|
|
+ } else if (curTcpModel.getAction() == TcpAction.VoiceAction.SUCCESS) {
|
|
|
|
+ //呼叫成功
|
|
|
|
+ //本机呼叫的时候tcpModel为空,只有呼叫成功的时候才能获得对应tcp相关数据
|
|
|
|
+ callSuccess = true
|
|
|
|
+ sip_voice_call_hangup.isEnabled = true
|
|
|
|
+ interactionVO = curInteractionVO
|
|
|
|
+ Constant.interactionId = curInteractionVO.id
|
|
|
|
+ showOutgoingCall()
|
|
|
|
+ } else if (curTcpModel.getAction() == TcpAction.VoiceAction.FAILED) {
|
|
|
|
+ //我方呼出,对方不在线,设备离线或其它错误
|
|
|
|
+ callSuccess = true
|
|
|
|
+ showMessage("呼叫失败,找不到设备或对方不在线!")
|
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
|
+ cancelCall()
|
|
|
|
+ } else if (curTcpModel.getAction() == TcpAction.VoiceAction.HANDOFF) {
|
|
|
|
+ //对方挂断,不论我方呼出或呼入
|
|
|
|
+ if (Constant.interactionId == curInteractionVO.id) {
|
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
|
+ cancelCall()
|
|
|
|
+ }
|
|
|
|
+ } else if (curTcpModel.getAction() == TcpAction.VoiceAction.CANCEL) {
|
|
|
|
+ //对方呼叫时取消
|
|
|
|
+ if (Constant.interactionId == curInteractionVO.id) {
|
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
|
+ cancelCall()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //外部呼叫按键
|
|
|
|
+ Constant.EVENT_SERIAL_EVENT -> {
|
|
|
|
+ if (messageEvent.message is String) {
|
|
|
|
+ val serialAction = messageEvent.message as String
|
|
|
|
+ if (serialAction.equals("cancel")) {
|
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
|
+ VoiceUtil.cancelAudioCall(Constant.DEVICE_ID)
|
|
|
|
+ cancelCall()
|
|
|
|
+ } else if (serialAction.equals("accept")) {
|
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
|
+ Constant.CALL_STATE = Constant.CALL_CALLING
|
|
|
|
+ VoiceUtil.acceptAudioCall(Constant.DEVICE_ID, fromId, interactionVO?.id)
|
|
|
|
+ acceptCall()
|
|
|
|
+ } else if (serialAction.equals("handoff")) {
|
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
|
+ VoiceUtil.handoffAudioCall(Constant.DEVICE_ID, fromId, Constant.interactionId)
|
|
|
|
+ callEnd()
|
|
|
|
+ } else if (serialAction.equals("reject")) {
|
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
|
+ VoiceUtil.rejectAudioCall(Constant.DEVICE_ID, fromId, interactionVO?.id)
|
|
|
|
+ callEnd()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|