weizhengliang 1 năm trước cách đây
mục cha
commit
d38f62f52f
20 tập tin đã thay đổi với 585 bổ sung46 xóa
  1. 2 3
      android_host/build.gradle
  2. 6 7
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/activity/CallingHostActivationActivity.kt
  3. 79 1
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/activity/NurseHomeActivity.kt
  4. 3 3
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dialog/SystemDialogHelper.java
  5. 7 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/fragment/BaseCallFragment.kt
  6. 2 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/fragment/EntraceGuardVideoFragment.kt
  7. 66 2
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/fragment/SipCallFragment.kt
  8. 230 15
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/fragment/SkyCallFragment.kt
  9. 5 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/hardware/HardTools.java
  10. 10 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/hardware/imp/Z3128HardTools.java
  11. 13 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/hardware/imp/ZKEHardTools.java
  12. 13 3
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/service/WdklSipService.java
  13. 18 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/settingconfig/SettingConfig.java
  14. 8 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/util/VoiceManagerUtil.java
  15. BIN
      android_host/src/main/res/drawable/ic_camera.png
  16. 95 7
      android_host/src/main/res/layout/sky_voice_call_layout.xml
  17. 5 0
      build.gradle
  18. 13 4
      middleware/src/main/code/com/wdkl/ncs/android/middleware/common/Constant.java
  19. 9 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/channel/VideoUtil.java
  20. 1 1
      settings.gradle

+ 2 - 3
android_host/build.gradle

@@ -115,9 +115,8 @@ dependencies {
 
     compile project(':listenvision')
 
-//
-//    //广播喊话组件
-    compile project(':gstream')
+
+
 
 }
 

+ 6 - 7
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/activity/CallingHostActivationActivity.kt

@@ -47,7 +47,6 @@ import kotlinx.android.synthetic.main.activity_register.*
 import kotlinx.android.synthetic.main.callinghost_activation.*
 import okhttp3.OkHttpClient
 import okhttp3.Request
-import org.freedesktop.gstreamer.GStreamer
 import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
 import java.util.concurrent.TimeUnit
@@ -99,12 +98,12 @@ class CallingHostActivationActivity  : BaseActivity<DevicePresenter, Callinghost
 
         AppUtil.checkCameraSupport()
 
-        try {
-            GStreamer.init(BaseApplication.appContext)
-            Constant.gstreamer_init = true
-        } catch (e: Exception) {
-            e.printStackTrace()
-        }
+//        try {
+//            GStreamer.init(BaseApplication.appContext)
+//            Constant.gstreamer_init = true
+//        } catch (e: Exception) {
+//            e.printStackTrace()
+//        }
 
         checkServer()
     }

+ 79 - 1
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/activity/NurseHomeActivity.kt

@@ -1239,12 +1239,90 @@ class NurseHomeActivity  : BaseActivity<NurseHomeActivityPresenter,ActivityNewNu
      */
     inner class TimeReceiver: BroadcastReceiver() {
         override fun onReceive(context: Context, intent: Intent) {
-            if (intent.action == ConnectivityManager.CONNECTIVITY_ACTION) {
+            if (intent.action == Constant.HOOK_ON) {
+                Log.e(TAG,"手柄放下 ")
+                if (System.currentTimeMillis() - hookonTime > 2000) {
+                    Constant.hookOn = true
+                    VoiceManagerUtil.switchAudioMode(activity, true)
+                    VoiceManagerUtil.setCallVoice(activity, SettingConfig.getHostCallVolume(activity))
+
+                    if (Constant.CALL_STATE == Constant.CALL_OUTGOING) {
+                        //呼出取消
+                        Constant.CALL_STATE = Constant.CALL_STANDBY
+                        DeviceChannel.calling = false
+                        //VoiceUtil.cancelAudioCall(Constants.ids, Constants.targetDeviceId)
+                        EventBus.getDefault().post(MessageEvent("cancel", Constant.EVENT_END_CALL))
+                    } else if (Constant.CALL_STATE == Constant.CALL_CALLING) {
+                        Constant.CALL_STATE = Constant.CALL_STANDBY
+                        DeviceChannel.calling = false
+                        EventBus.getDefault().post(MessageEvent("handoff", Constant.EVENT_END_CALL))
+                    }
+                }
+
+                hookonTime = System.currentTimeMillis()
+            } else if (intent.action == Constant.HOOK_OFF) {
+                Log.e(TAG,"手柄拿起 ")
+                EventBus.getDefault().post(MessageEvent(false, Constant.EVENT_TOGGLE_SPEAKER))
+                if (System.currentTimeMillis() - hookoffTime > 2000) {
+                    Constant.hookOn = false
+                    VoiceManagerUtil.switchAudioMode(activity, false)
+                    VoiceManagerUtil.setCallVoice(activity, SettingConfig.getHostCallVolume(activity))
+
+                    if (Constant.CALL_STATE == Constant.CALL_STANDBY) {
+                        //不是呼出也不是通话状态则接听电话
+                        EventBus.getDefault().post(MessageEvent("hookoff", Constant.EVENT_HOOK_OFF))
+                    } else if (Constant.CALL_STATE == Constant.CALL_VISITING || Constant.CALL_STATE == Constant.CALL_INCOMING) {
+                        EventBus.getDefault().post(MessageEvent("hookoff", Constant.EVENT_V_HOOK_OFF))
+                    }
+                }
+
+                hookoffTime = System.currentTimeMillis()
+            }else if (intent.action == ConnectivityManager.CONNECTIVITY_ACTION) {
                 updateNetState()
             }
         }
     }
+    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
+        Log.d(TAG, "keyDown ====> keyCode: $keyCode, action: ${event?.action}")
+        if (keyCode == 135) {
+            //手柄拿起
+            EventBus.getDefault().post(MessageEvent(false, Constant.EVENT_TOGGLE_SPEAKER))
+            if (System.currentTimeMillis() - hookoffTime > 2000) {
+                Constant.hookOn = false
+                VoiceManagerUtil.switchAudioMode(activity, false)
+                VoiceManagerUtil.setCallVoice(activity, SettingConfig.getHostCallVolume(activity))
+
+                if (Constant.CALL_STATE == Constant.CALL_STANDBY) {
+                    //不是呼出也不是通话状态则接听电话
+                    EventBus.getDefault().post(MessageEvent("hookoff", Constant.EVENT_HOOK_OFF))
+                } else if (Constant.CALL_STATE == Constant.CALL_VISITING || Constant.CALL_STATE == Constant.CALL_INCOMING) {
+                    EventBus.getDefault().post(MessageEvent("hookoff", Constant.EVENT_V_HOOK_OFF))
+                }
+            }
+            hookoffTime = System.currentTimeMillis()
+        } else if (keyCode == 134) {
+            //手柄放下
+            if (System.currentTimeMillis() - hookonTime > 2000) {
+                Constant.hookOn = true
+                VoiceManagerUtil.switchAudioMode(activity, true)
+                VoiceManagerUtil.setCallVoice(activity, SettingConfig.getHostCallVolume(activity))
 
+                if (Constant.CALL_STATE == Constant.CALL_OUTGOING) {
+                    //呼出取消
+                    Constant.CALL_STATE = Constant.CALL_STANDBY
+                    DeviceChannel.calling = false
+                    //VoiceUtil.cancelAudioCall(Constants.ids, Constants.targetDeviceId)
+                    EventBus.getDefault().post(MessageEvent("cancel", Constant.EVENT_END_CALL))
+                } else if (Constant.CALL_STATE == Constant.CALL_CALLING) {
+                    Constant.CALL_STATE = Constant.CALL_STANDBY
+                    DeviceChannel.calling = false
+                    EventBus.getDefault().post(MessageEvent("handoff", Constant.EVENT_END_CALL))
+                }
+            }
+            hookonTime = System.currentTimeMillis()
+        }
+        return super.onKeyDown(keyCode, event)
+    }
     /**
      * 设置系统音量
      */

+ 3 - 3
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dialog/SystemDialogHelper.java

@@ -51,9 +51,9 @@ public class SystemDialogHelper {
             if (alertDialog != null && alertDialog.isShowing()) {
                 String passwprd =password_ed.getText().toString();
                 if (passwprd.equals("888")){
-//                    Intent intent = new Intent();
-//                    intent.setClass(activity, SystemActivity.class);
-//                    activity.startActivity(intent);
+                    Intent intent = new Intent();
+                    intent.setClass(activity, SystemActivity.class);
+                    activity.startActivity(intent);
                 } else {
                     showMessage(R.string.invalid_password);
                 }

+ 7 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/fragment/BaseCallFragment.kt

@@ -9,6 +9,7 @@ import androidx.fragment.app.Fragment
 import com.enation.javashop.utils.base.tool.BaseToolActivity
 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 org.greenrobot.eventbus.EventBus
 
 abstract class BaseCallFragment: Fragment(), View.OnTouchListener {
@@ -24,9 +25,11 @@ abstract class BaseCallFragment: Fragment(), View.OnTouchListener {
     protected var targetId: String? = null
     //是否探视
     protected var visiting: Boolean = false
+    protected var interactionVO: InteractionVO? = null
     //呼叫名称
     protected var callName: String? = null
     protected var tid: String? = ""
+    protected var fromId: Int = -1
 
     //protected var gEngineKit: SkyEngineKit? = null
 
@@ -40,6 +43,10 @@ abstract class BaseCallFragment: Fragment(), View.OnTouchListener {
         visiting = requireArguments().getBoolean("visiting")
         callName = requireArguments().getString("call_name")
         tid = requireArguments().getString("tcp_tid")
+        if (arguments?.getSerializable("interaction") != null) {
+            interactionVO = requireArguments().getSerializable("interaction") as InteractionVO
+            fromId = interactionVO!!.fromDeviceId
+        }
     }
 
     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

+ 2 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/fragment/EntraceGuardVideoFragment.kt

@@ -118,6 +118,7 @@ class EntraceGuardVideoFragment : Fragment(), CallSessionCallback, View.OnTouchL
         WebRTCEngine.getInstance().toggleSpeaker(false)
         RingPlayHelper.playRingTone(activity, R.raw.door_bell, true)
         speaker_on.isSelected = isMute
+        Constant.IN_CALL = true
     }
 
     private fun bindEvent() {
@@ -153,6 +154,7 @@ class EntraceGuardVideoFragment : Fragment(), CallSessionCallback, View.OnTouchL
     private fun backToMain() {
         DeviceChannel.calling = false
         Constant.CALL_STATE = Constant.CALL_STANDBY
+        Constant.IN_CALL = false
         RingPlayHelper.stopRingTone()
         EventBus.getDefault().post(MessageEvent("BackCall", Constant.EVENT_REMOVE_CALL_FRAGMENT))
     }

+ 66 - 2
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/fragment/SipCallFragment.kt

@@ -7,10 +7,14 @@ import android.os.SystemClock
 import android.text.TextUtils
 import android.util.Log
 import android.view.View
+import android.widget.SeekBar
 import com.google.gson.Gson
+import com.wdkl.ncs.android.component.nursehome.BuildConfig
 import com.wdkl.ncs.android.component.nursehome.R
 import com.wdkl.ncs.android.component.nursehome.service.WdklSipService
+import com.wdkl.ncs.android.component.nursehome.settingconfig.SettingConfig
 import com.wdkl.ncs.android.component.nursehome.util.RingPlayHelper
+import com.wdkl.ncs.android.component.nursehome.util.VoiceManagerUtil
 import com.wdkl.ncs.android.lib.base.BaseApplication
 import com.wdkl.ncs.android.lib.utils.showMessage
 import com.wdkl.ncs.android.middleware.common.Constant
@@ -41,6 +45,8 @@ class SipCallFragment: BaseCallFragment() {
     //呼叫倒计时
     lateinit var countDownTimer: CountDownTimer
 
+    private var volume = 60
+
 
     private var sipCore: Core? = null
 
@@ -53,6 +59,16 @@ class SipCallFragment: BaseCallFragment() {
 
         sipCore = WdklSipService.getCore()
 
+        volume = SettingConfig.getHostCallVolume(activity)
+        if (volume < 0 || volume > 100) {
+            volume = 60
+        }
+        call_volume_bar.progress = volume/10
+        tv_volume.text = "" + volume/10
+
+        VoiceManagerUtil.setCallVoice(activity, volume)
+        sipCore?.isMicEnabled = true
+
         Log.d(TAG, "callState: $callState, local sip: ${Constant.SIP_ID}, target sip: ${Constant.targetSipId}")
         when (callState) {
             0 -> {
@@ -61,6 +77,7 @@ class SipCallFragment: BaseCallFragment() {
                 showCallView(true)
                 Constant.CALL_STATE = Constant.CALL_OUTGOING
                 DeviceChannel.calling = true
+                Constant.IN_CALL = true
                 RingPlayHelper.playRingTone(BaseApplication.appContext, R.raw.ring_back2, true)
             }
 
@@ -70,6 +87,11 @@ class SipCallFragment: BaseCallFragment() {
                 showCallView(false)
                 Constant.CALL_STATE = Constant.CALL_CALLING
                 DeviceChannel.calling = true
+                    //发送accept消息
+                val callTcp = VoiceUtil.voiceAccept(tid, Constant.DEVICE_ID, Constant.fromId, Constant.interactionId)
+                 TcpClient.getInstance().sendMsg(callTcp.toJson())
+
+
             }
         }
     }
@@ -111,6 +133,42 @@ class SipCallFragment: BaseCallFragment() {
             Constant.CALL_STATE = Constant.CALL_STANDBY
             DeviceChannel.calling = false
         }
+
+        sky_voice_call_mute.setOnClickListener {
+            val micEnable = sipCore!!.isMicEnabled
+            Log.d(TAG,"mic enable: $micEnable")
+
+            if (micEnable) {
+                sipCore!!.isMicEnabled = false
+                sky_voice_call_mute.isSelected = true
+            } else {
+                sipCore!!.isMicEnabled = true
+                sky_voice_call_mute.isSelected = false
+            }
+        }
+
+        call_volume_bar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener{
+            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
+                tv_volume.text = "" + progress
+                if (seekBar!!.progress <= 1) {
+                    tv_volume.text = "1"
+                } else {
+                    tv_volume.text = "" + progress
+                }
+            }
+
+            override fun onStartTrackingTouch(seekBar: SeekBar?) {
+                //
+            }
+
+            override fun onStopTrackingTouch(seekBar: SeekBar?) {
+                if (seekBar!!.progress <= 2) {
+                    VoiceManagerUtil.setCallVoice(activity, 20)
+                } else {
+                    VoiceManagerUtil.setCallVoice(activity, seekBar.progress*10)
+                }
+            }
+        })
     }
 
     private fun callTerminate() {
@@ -124,6 +182,8 @@ class SipCallFragment: BaseCallFragment() {
     }
 
     override fun destroy() {
+        Constant.showCall = false
+        Constant.IN_CALL = false
         RingPlayHelper.stopRingTone()
         Constant.CALL_STATE = Constant.CALL_STANDBY
         DeviceChannel.calling = false
@@ -144,6 +204,7 @@ class SipCallFragment: BaseCallFragment() {
         }
         sky_voice_call_outgoing.visibility = View.VISIBLE
         sky_voice_call_timer.visibility = View.GONE
+        Constant.showCall = true
     }
 
     private fun showCalling(audioOnly: Boolean) {
@@ -176,6 +237,8 @@ class SipCallFragment: BaseCallFragment() {
         sky_voice_call_timer.visibility = View.VISIBLE
         sky_voice_call_timer.base = SystemClock.elapsedRealtime()
         sky_voice_call_timer.start()
+        sky_voice_call_mute.visibility = View.VISIBLE
+        ll_voice_volume_bar.visibility = View.VISIBLE
     }
 
     private fun cancelCall(fromId: Int, toId: Int?, interactionId: Int?) {
@@ -262,13 +325,13 @@ class SipCallFragment: BaseCallFragment() {
                                 val params = sipCore!!.createCallParams(null)
                                 params?.isVideoEnabled = false
                                 if (addressToCall != null) {
+                                    Log.d(TAG, ">>>>>>>>>>> invite address: " + addressToCall.asString()+params!!.toString())
                                     sipCore!!.inviteAddressWithParams(addressToCall, params!!)
-                                    Log.d(TAG, ">>>>>>>>>>> invite address: " + addressToCall.asString())
                                 }
                             }
                         } else if (curTcpModel.action == TcpAction.VoiceAction.REJECT) {//对方拒绝
                             if (Constant.interactionId == curIt.id) {
-                                showMessage("对方拒绝")
+                                showMessage(R.string.call_reject)
                                 Constant.CALL_STATE = Constant.CALL_STANDBY
                                 DeviceChannel.calling = false
                                 callEnd(false)
@@ -292,6 +355,7 @@ class SipCallFragment: BaseCallFragment() {
             }
 
             Constant.SIP_CONNECTED -> {
+                Constant.IN_CALL = true
                 showCalling(true)
             }
 

+ 230 - 15
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/fragment/SkyCallFragment.kt

@@ -6,13 +6,19 @@ import android.os.Looper
 import android.os.SystemClock
 import android.util.Log
 import android.view.View
+import android.view.ViewGroup
 import com.alibaba.android.vlayout.VirtualLayoutManager
 import com.alibaba.fastjson.JSONObject
 import com.google.gson.Gson
 import com.wdkl.ncs.android.component.nursehome.R
 import com.wdkl.ncs.android.component.nursehome.adapter.BedItemAdapter
+import com.wdkl.ncs.android.component.nursehome.hardware.HardWareFactroy
+import com.wdkl.ncs.android.component.nursehome.settingconfig.SettingConfig
 import com.wdkl.ncs.android.middleware.common.Constant
 import com.wdkl.ncs.android.component.nursehome.util.RingPlayHelper
+import com.wdkl.ncs.android.component.nursehome.util.SpeechUtil
+import com.wdkl.ncs.android.component.nursehome.util.Util
+import com.wdkl.ncs.android.component.nursehome.util.VoiceManagerUtil
 import com.wdkl.ncs.android.lib.base.BaseApplication
 import com.wdkl.ncs.android.lib.utils.AppTool
 import com.wdkl.ncs.android.lib.utils.showMessage
@@ -61,6 +67,10 @@ class SkyCallFragment: BaseCallFragment(), CallSessionCallback {
     private var room: Room?=null
     private var videoRoomCallback: VideoRoomCallback? = null
 
+    private var visitUserId: BigInteger? = null
+
+    private var inVisiting = false
+
     //呼叫倒计时
     lateinit var countDownTimer: CountDownTimer
 
@@ -70,6 +80,8 @@ class SkyCallFragment: BaseCallFragment(), CallSessionCallback {
 
     override fun init() {
         initCountDownTimer()
+        HardWareFactroy.getHardTools().setAudioMute(BaseApplication.appContext, false)
+
         //初始化 engine
         WebRTCEngine.getInstance().init(true, BaseApplication.appContext)
         //初始化 janusClient
@@ -298,9 +310,10 @@ class SkyCallFragment: BaseCallFragment(), CallSessionCallback {
     }
 
     override fun didChangeState(var1: EnumType.CallState?) {
+
+        Log.e(TAG, "didChangeState: " + var1)
         handler.post {
             if (var1 == EnumType.CallState.Connected) {
-                Log.e(TAG, "didChangeState: " + var1)
                 if (var1 == EnumType.CallState.Connected && !callEnded) {
                     RingPlayHelper.stopRingTone()
                     Constant.CALL_STATE = Constant.CALL_CALLING
@@ -330,6 +343,58 @@ class SkyCallFragment: BaseCallFragment(), CallSessionCallback {
     }
 
     override fun didCreateLocalVideoTrack() {
+        Log.e(TAG, "didCreateLocalVideoTrack")
+        handler.post {
+            if (!callEnded) {
+                if (visiting) {
+                    //探视
+                    /*if (localSurfaceView == null) {
+                        val surfaceView = WebRTCEngine.getInstance().startPreview(true)
+                        Log.e(TAG, "didCreateLocalVideoTrack visit surfaceView: $surfaceView")
+                        if (surfaceView != null) {
+                            localSurfaceView = surfaceView as SurfaceViewRenderer
+                        }
+                    }
+
+                    if (localSurfaceView!!.parent != null) {
+                        (localSurfaceView!!.parent as ViewGroup).removeView(localSurfaceView)
+                    }
+                    video_frame2.addView(localSurfaceView)*/
+                } else {
+                    //普通视频通话
+                    if (localSurfaceView == null) {
+                        val surfaceView = WebRTCEngine.getInstance().startPreview(true)
+                        Log.e(TAG, "didCreateLocalVideoTrack surfaceView: $surfaceView")
+                        if (surfaceView != null) {
+                            localSurfaceView = surfaceView as SurfaceViewRenderer
+                        }
+                    } else {
+                        localSurfaceView!!.setZOrderMediaOverlay(true)
+                    }
+
+                    if (localSurfaceView!!.parent != null) {
+                        (localSurfaceView!!.parent as ViewGroup).removeView(localSurfaceView)
+                    }
+
+                    if (outGoing && remoteSurfaceView == null) {
+                        if (fullscreen_video_frame != null) {
+                            if (fullscreen_video_frame.getChildCount() != 0) {
+                                fullscreen_video_frame.removeAllViews()
+                            }
+                            fullscreen_video_frame.addView(localSurfaceView)
+                        }
+                    } else {
+                        if (pip_video_frame != null) {
+                            if (pip_video_frame.getChildCount() != 0) {
+                                pip_video_frame.removeAllViews()
+                            }
+                            pip_video_frame.addView(localSurfaceView)
+                        }
+                    }
+                }
+            }
+        }
+
     }
 
     override fun didError(error: String?) {
@@ -348,12 +413,112 @@ class SkyCallFragment: BaseCallFragment(), CallSessionCallback {
     }
 
     override fun didReceiveRemoteVideoTrack(userId: BigInteger?) {
-        // TODO("Not yet implemented")
+        Log.e(TAG, "didReceiveRemoteVideoTrack  userId: $userId")
+        handler.post {
+            if (!callEnded) {
+                if (visiting) {
+                    //探视: 首先探视机和护士主机加入视频通话,然后床位分机加入视频通话
+                    if (visitUserId == null) {
+                        //当前只有探视机和主机视频
+                        visitUserId = userId
+                        visit_list_view.visibility = View.VISIBLE
+                        val surfaceView = WebRTCEngine.getInstance().setupRemoteVideo(userId, false)
+                        Log.e(TAG, "didReceiveRemoteVideoTrack, visit surfaceView = $surfaceView")
+                        //探视机端画面添加到左侧frame layout中
+                        if (surfaceView != null && visit_video_frame2 != null) {
+                            remoteSurfaceView = surfaceView as SurfaceViewRenderer
+                            visit_video_frame2.removeAllViews()
+                            if (remoteSurfaceView!!.parent != null) {
+                                (remoteSurfaceView!!.parent as ViewGroup).removeView(remoteSurfaceView)
+                            }
+                            visit_video_frame2.addView(remoteSurfaceView)
+                        }
+                    } else {
+                        //分机加入视频通话,显示探视双方画面,并静音
+                        visit_list_view.visibility = View.GONE
+                        sky_call_speaker_on.visibility = View.VISIBLE
+                        inVisiting = true
+                        WebRTCEngine.getInstance().muteAudio(true)
+                        HardWareFactroy.getHardTools().setAudioMute(BaseApplication.appContext, true)
+                        val surfaceView = WebRTCEngine.getInstance().setupRemoteVideo(userId, false)
+                        Log.e(TAG, "didReceiveRemoteVideoTrack, visit bed surfaceView = $surfaceView")
+                        //床位分机端画面添加到右侧frame layout中
+                        if (surfaceView != null && visit_video_frame1 != null) {
+                            tv_visit_title.visibility = View.VISIBLE
+                            localSurfaceView = surfaceView as SurfaceViewRenderer
+                            visit_video_frame1.removeAllViews()
+                            if (localSurfaceView!!.parent != null) {
+                                (localSurfaceView!!.parent as ViewGroup).removeView(localSurfaceView)
+                            }
+                            visit_video_frame1.addView(localSurfaceView)
+                        }
+                    }
+                } else {
+                    //本地画面
+                    if (localSurfaceView != null) {
+                        localSurfaceView!!.setZOrderMediaOverlay(true)
+                        if (outGoing) {
+                            if (localSurfaceView!!.parent != null) {
+                                (localSurfaceView!!.parent as ViewGroup).removeView(localSurfaceView)
+                            }
+                            if (pip_video_frame != null) {
+                                pip_video_frame.addView(localSurfaceView)
+                            }
+                        }
+                    }
+
+                    //远端画面
+                    val surfaceView = WebRTCEngine.getInstance().setupRemoteVideo(userId, false)
+                    Log.e(TAG, "didReceiveRemoteVideoTrack,surfaceView = $surfaceView")
+                    if (surfaceView != null && fullscreen_video_frame != null) {
+                        remoteSurfaceView = surfaceView as SurfaceViewRenderer
+                        fullscreen_video_frame.removeAllViews()
+                        if (remoteSurfaceView!!.parent != null) {
+                            (remoteSurfaceView!!.parent as ViewGroup).removeView(remoteSurfaceView)
+                        }
+                        fullscreen_video_frame.addView(remoteSurfaceView)
+                    }
+                }
+            }
+        }
     }
 
 
     override fun didCallEndWithReason(var1: EnumType.CallEndReason?) {
-        //
+        handler.post {
+            /*when (callEndReason) {
+                EnumType.CallEndReason.Busy -> {
+                    showMessage("对方忙线中")
+                }
+                EnumType.CallEndReason.AcceptByOtherClient -> {
+                    showMessage("通话中")
+                }
+                EnumType.CallEndReason.Hangup -> {
+                    showMessage("通话结束")
+                }
+                EnumType.CallEndReason.MediaError -> {
+                    showMessage("媒体错误")
+                }
+                EnumType.CallEndReason.OpenCameraFailure -> {
+                    showMessage("打开摄像头错误")
+                }
+                EnumType.CallEndReason.RemoteHangup -> {
+                    showMessage("对方挂断")
+                }
+                EnumType.CallEndReason.RemoteSignalError -> {
+                    showMessage("对方网络断开")
+                }
+                EnumType.CallEndReason.SignalError -> {
+                    showMessage("连接断开")
+                }
+                EnumType.CallEndReason.Timeout -> {
+                    showMessage("对方未接听")
+                }
+            }*/
+
+            showMessage(R.string.call_end)
+            callEnd(true)
+        }
     }
 
     override fun didUserLeave(userId: BigInteger?) {
@@ -396,21 +561,53 @@ class SkyCallFragment: BaseCallFragment(), CallSessionCallback {
                                 DeviceChannel.calling = false
                                 callEnd(false)
                             }
-                        } /*else if (curTcpModel.getAction() == TcpAction.VoiceAction.CALLING) {//对方通话中
-                            showMessage(R.string.call_busy)
-                            AppTool.Time.delay(800) {
-                                Constants.CALL_STATE = Constants.CALL_STANDBY
-                                DeviceChannel.calling = false
+                        } else if (curTcpModel.action == TcpAction.VoiceAction.CANCEL || curTcpModel.action == TcpAction.VoiceAction.VOICE_OFF) {
+                            if (Constant.interactionId == curInteractionVO.id) {
+                                if (SettingConfig.getTtsMode(activity) == SettingConfig.TTS_ON) {
+                                    //val frameName = curInteractionVO.fromFrameFullName.replace("-", "")
+                                    val frameName = Util.appendSpace(curInteractionVO.fromFrameFullName.replace("-", ","))
+                                    val text = BaseApplication.appContext.getString(R.string.call_video, frameName)
+                                    SpeechUtil.getInstance().removeSpeak(text)
+                                } else {
+                                    RingPlayHelper.stopRingTone()
+                                }
+
                                 callEnd(false)
                             }
-                        } else if (curTcpModel.getAction() == TcpAction.VoiceAction.FAILED) {//对方不在线 呼叫失败
-                            //showMessage("对方离线或不存在,呼叫失败")
-                            AppTool.Time.delay(800) {
-                                Constants.CALL_STATE = Constants.CALL_STANDBY
-                                DeviceChannel.calling = false
-                                callEnd(false)
+                        } else if (curTcpModel.type == TcpType.VIDEO) {
+                            val curInteractionVO = Gson().fromJson(curTcpModel.data.toString(), InteractionVO::class.java)
+                            if (curTcpModel.action == TcpAction.VideoAction.CANCEL) {
+                                //对方取消
+                                if (Constant.interactionId == curInteractionVO.id) {
+                                    if (SettingConfig.getTtsMode(activity) == SettingConfig.TTS_ON) {
+                                        SpeechUtil.getInstance().removeSpeak(StringUtil.getResString(R.string.call_visiting))
+                                    } else {
+                                        RingPlayHelper.stopRingTone()
+                                    }
+
+                                    callEnd(false)
+                                }
+                            } else if (curTcpModel.action == TcpAction.VideoAction.HANDOFF) {
+                                //挂断
+                                if (Constant.interactionId == curInteractionVO.id) {
+                                    callEnd(false)
+                                }
+                            } else if (curTcpModel.action == TcpAction.VideoAction.SUCCESS) {
+                                //分机加入探视成功
+                                /*Constants.CALL_STATE = Constants.CALL_VISITING
+                                DeviceChannel.calling = true
+                                VisitingWindow.createFloatView(activity, Constants.visit_bed_name)*/
+                            } else if (curTcpModel.action == TcpAction.VideoAction.FAILED) {
+                                //分机加入视频失败
+                                showMessage(R.string.extension_connect_fail)
+                            } else if (curTcpModel.action == TcpAction.VideoAction.CALLING) {
+                                //分机正在通话
+                                showMessage(R.string.extension_call_busy)
+                            } else if (curTcpModel.action == TcpAction.VideoAction.REJECT) {
+                                //分机加入视频通话失败
+                                showMessage(R.string.extension_call_error)
                             }
-                        }*/
+                        }
                     }
                 }
             }
@@ -426,7 +623,25 @@ class SkyCallFragment: BaseCallFragment(), CallSessionCallback {
                     }
                 }
             }
+
+            Constant.EVENT_V_HOOK_OFF -> {
+                if (!onlyAudio) {
+                    //视频接听
+                    RingPlayHelper.stopRingTone()
+                    SpeechUtil.getInstance().stopSpeak(true)
+                    if (visiting) {
+                        val callTcp = VideoUtil.videoInCall(tid, Constant.DEVICE_ID, fromId, interactionVO?.id)
+                        TcpClient.getInstance().sendMsg(callTcp.toJson())
+                    } else {
+                        val callTcp = VoiceUtil.voiceAccept(tid, Constant.DEVICE_ID, fromId, interactionVO?.id)
+                        TcpClient.getInstance().sendMsg(callTcp.toJson())
+                    }
+
+                    janusClient!!.connect(-1, false)
+                }
+            }
         }
+
     }
 
 }

+ 5 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/hardware/HardTools.java

@@ -25,6 +25,11 @@ public  class HardTools {
   public void setSerial(NurseHomeActivity activity){}
     //导航栏隐藏或者显示
     public void toggleStatusBar(Context context,boolean is){}
+
+    public void setAudioMute(Context context,boolean mute){}
+
+    public void setAudioMode(Context context,int mode){}
+
     //检查launch版本
     public void checkLaunch(){}
     //紧急按钮Start

+ 10 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/hardware/imp/Z3128HardTools.java

@@ -61,6 +61,16 @@ public class Z3128HardTools extends HardTools {
     }
 
     @Override
+    public void setAudioMode(Context context, int mode) {
+        super.setAudioMode(context, mode);
+    }
+
+    @Override
+    public void setAudioMute(Context context, boolean mute) {
+        super.setAudioMute(context, mute);
+    }
+
+    @Override
     public void toggleStatusBar(Context context,boolean is) {
 
 

+ 13 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/hardware/imp/ZKEHardTools.java

@@ -13,6 +13,8 @@ import com.wdkl.ncs.android.component.nursehome.hardware.HardTools;
 import com.wdkl.ncs.android.component.nursehome.util.AppUpdateHelper;
 import com.wdkl.ncs.android.component.nursehome.util.NetHelper;
 import com.wdkl.ncs.android.component.nursehome.util.StatusBarHelper;
+import com.wdkl.ncs.android.component.nursehome.util.VoiceManagerUtil;
+import com.wdkl.ncs.android.lib.base.BaseApplication;
 import com.wdkl.ncs.android.middleware.common.Constant;
 import com.wdkl.ncs.android.middleware.utils.AppUtil;
 
@@ -59,6 +61,17 @@ public class ZKEHardTools extends HardTools {
     public void resetDevice() {
 //        SerialPortHelper.resetDevice();
     }
+
+    @Override
+    public void setAudioMode(Context context, int mode) {
+
+    }
+
+    @Override
+    public void setAudioMute(Context context, boolean mute) {
+        VoiceManagerUtil.setAudioMute(BaseApplication.appContext, mute);
+    }
+
     @Override
     public void resetDevicex(Application application) {
         AppUpdateHelper.reboot(application);

+ 13 - 3
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/service/WdklSipService.java

@@ -108,7 +108,10 @@ public class WdklSipService extends Service {
         Factory.instance().setDebugMode(false, getString(R.string.wdkl_app_name));
 
         //收集一些设备信息
-        Log.i("sipCall", START_SIPPHONE_LOGS);
+        Log.i("  String basePath = getFilesDir().getAbsolutePath();\n" +
+                "        Factory.instance().setLogCollectionPath(basePath);\n" +
+                "        Factory.instance().enableLogCollection(LogCollectionState.Enabled);\n" +
+                "        Factory.instance().setDebugMode(false, getString(R.string.wdkl_app_name));", START_SIPPHONE_LOGS);
         dumpDeviceInformation();
         dumpInstalledLinphoneInformation();
 
@@ -128,8 +131,15 @@ public class WdklSipService extends Service {
                 if (state == Call.State.IncomingReceived || state == Call.State.IncomingEarlyMedia) {
                     //Toast.makeText(WdklSipService.this, "Incoming call", Toast.LENGTH_LONG).show();
                     //来电时将自动接听
-                    CallParams params = getCore().createCallParams(call);
-                    call.acceptWithParams(params);
+//                    CallParams params = getCore().createCallParams(call);
+//                    call.acceptWithParams(params);
+
+                    if (Constant.showCall) {
+                        CallParams params = getCore().createCallParams(call);
+                        call.acceptWithParams(params);
+                    } else {
+                        call.terminate();
+                    }
                 } else if (state == Call.State.Connected) {
                     if (sipTesting) {
                         //通话已建立完成,打开通话界面

+ 18 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/settingconfig/SettingConfig.java

@@ -141,6 +141,10 @@ public class SettingConfig {
 
     private static final String KEY_SP_VOICE_NUMERIC = "KEY_SP_VOICE_NUMERIC";
 
+    //主机通话音量
+    private static final String KEY_SP_HOST_CALL_VOLUME = "KEY_SP_HOST_CALL_VOLUME";
+    private static final int default_host_call_volume = 80;
+
     //语音播报模式
     public static int getTtsMode(Context context) {
         return getSP(context).getInt(KEY_SP_TTS_MODE, TTS_ON);
@@ -243,7 +247,21 @@ public class SettingConfig {
         }
         getEditor(context).putInt(KEY_SP_CALL_NUMBER, value).apply();
     }
+    /**
+     * 设置主机手柄播放音量
+     *
+     */
+    /*public static void setHostGamepadPlayVolume(Context context, int value) {
+        getEditor(context).putInt(KEY_SP_HOST_GAMEPAD_PLAY_VOLUME, value).apply();
+    }*/
+
+    public static int getHostCallVolume(Context context) {
+        return getSP(context).getInt(KEY_SP_HOST_CALL_VOLUME, default_host_call_volume);
+    }
 
+    public static void setHostCallVolume(Context context, int value) {
+        getEditor(context).putInt(KEY_SP_HOST_CALL_VOLUME, value).apply();
+    }
 
     /**
      * 获取主机白天亮度

+ 8 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/util/VoiceManagerUtil.java

@@ -190,5 +190,13 @@ public class VoiceManagerUtil {
             audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
         }
     }
+    public static void setAudioMode(Context context, int mode) {
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        audioManager.setMode(mode);
+    }
 
+    public static void setAudioMute(Context context, boolean mute) {
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        audioManager.setMicrophoneMute(mute);
+    }
 }

BIN
android_host/src/main/res/drawable/ic_camera.png


+ 95 - 7
android_host/src/main/res/layout/sky_voice_call_layout.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<layout>
+<layout xmlns:app="http://schemas.android.com/apk/res-auto">
     <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
@@ -22,6 +22,29 @@
             android:layout_marginTop="10dp"
             android:visibility="gone"/>
 
+        <LinearLayout
+            android:id="@+id/video_visit_call_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:visibility="gone">
+            <FrameLayout
+                android:id="@+id/visit_video_frame1"
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1">
+                <ImageView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center"
+                    android:src="@drawable/ic_camera"/>
+            </FrameLayout>
+
+            <FrameLayout
+                android:id="@+id/visit_video_frame2"
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"/>
+        </LinearLayout>
         <RelativeLayout
             android:layout_width="match_parent"
             android:layout_height="match_parent">
@@ -32,6 +55,15 @@
                 android:layout_height="match_parent"
                 android:background="@color/color_transparent"
                 android:visibility="gone"/>
+            <TextView
+                android:id="@+id/tv_visit_title"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_centerInParent="true"
+                android:text="@string/str_visiting"
+                android:textSize="36sp"
+                android:textColor="@color/white"
+                android:visibility="gone"/>
 
             <LinearLayout
                 android:id="@+id/ll_voice_call"
@@ -87,13 +119,69 @@
                     android:text="00:00"
                     android:textColor="@color/white"
                     android:textSize="24sp" />
+                <LinearLayout
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="32dp">
 
-                <ImageView
-                    android:id="@+id/sky_voice_call_hangup"
-                    android:layout_width="80dp"
-                    android:layout_height="80dp"
-                    android:layout_marginTop="20dp"
-                    android:src="@drawable/selector_call_hangup" />
+                    <ImageView
+                        android:id="@+id/sky_voice_call_mute"
+                        android:layout_width="100dp"
+                        android:layout_height="100dp"
+                        android:layout_marginRight="40dp"
+                        android:src="@drawable/av_mute_selector"
+                        android:visibility="gone"/>
+
+                    <ImageView
+                        android:id="@+id/sky_voice_call_hangup"
+                        android:layout_width="80dp"
+                        android:layout_height="80dp"
+                        android:src="@drawable/selector_call_hangup" />
+
+                    <ImageView
+                        android:id="@+id/sky_call_speaker_on"
+                        android:layout_width="84dp"
+                        android:layout_height="84dp"
+                        android:layout_marginStart="40dp"
+                        android:src="@drawable/ic_speaker_on"
+                        android:visibility="gone"/>
+                </LinearLayout>
+            </LinearLayout>
+            <LinearLayout
+                android:id="@+id/ll_voice_volume_bar"
+                android:layout_width="60dp"
+                android:layout_height="match_parent"
+                android:layout_alignParentRight="true"
+                android:layout_marginRight="120dp"
+                android:layout_marginTop="100dp"
+                android:layout_marginBottom="100dp"
+                android:clipChildren="true"
+                android:orientation="vertical"
+                android:gravity="center"
+                android:visibility="gone">
+                <TextView
+                    android:id="@+id/tv_volume"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center"
+                    android:textSize="24sp"
+                    android:textColor="@color/title_text"/>
+
+                <com.wdkl.ncs.android.lib.widget.VerticalSeekBarWrapper
+                    android:layout_width="32dp"
+                    android:layout_height="match_parent">
+                    <com.wdkl.ncs.android.lib.widget.VerticalSeekBar
+                        android:id="@+id/call_volume_bar"
+                        android:layout_width="0dp"
+                        android:layout_height="0dp"
+                        android:padding="8dp"
+                        android:max="10"
+                        android:progress="6"
+                        android:splitTrack="false"
+                        android:progressDrawable="@drawable/seek_bar_bg"
+                        android:thumb="@drawable/seek_bar_thumb"
+                        app:seekBarRotation="CW270" /> <!-- Rotation: CW90 or CW270 -->
+                </com.wdkl.ncs.android.lib.widget.VerticalSeekBarWrapper>
             </LinearLayout>
         </RelativeLayout>
     </FrameLayout>

+ 5 - 0
build.gradle

@@ -123,6 +123,11 @@ allprojects {
         maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
         maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
         maven { url "https://jitpack.io" }
+
+        maven {
+            // Replace snapshots by releases for releases !
+            url "https://linphone.org/maven_repository"
+        }
         jcenter()
         mavenCentral()
         google()

+ 13 - 4
middleware/src/main/code/com/wdkl/ncs/android/middleware/common/Constant.java

@@ -92,6 +92,15 @@ public class Constant {
     //通话中
     public final static int CALL_CALLING = 3;
 
+    //紧急呼叫
+    public final static int CALL_SOS = 4;
+
+    //紧急呼叫
+    public final static int CALL_VISITING = 5;
+
+    //紧急呼叫
+    public final static int CALL_VISIT_CALLING = 6;
+
     //通话状态
     public static int CALL_STATE = CALL_STANDBY;
 
@@ -228,8 +237,10 @@ public class Constant {
     public static int back_id = -1;      //后备设备id
     public static int reader_idle_time = 60;//tcp心跳
     public static String targetSipId = "";   //来电设备id
+    public static boolean  showCall = false;
+    public static boolean  IN_CALL = false;
 
-    public static boolean gstreamer_init = false;
+    public static boolean /**/gstreamer_init = false;
 
 
     public static int targetDeviceId = 60;//呼叫对方设备id
@@ -249,7 +260,6 @@ public class Constant {
      */
     public static String DEVICE_NAME = "护士主机";
     public static boolean autoUpdate = true;
-    public static boolean IN_CALL = false;
 
     //灵信LED字体文件路径
 
@@ -332,8 +342,6 @@ public class Constant {
     //护士主机
     public static final int EVENT_REJECT_CALL = 0x107;
 
-    //探视中
-    public static final int CALL_VISIT_CALLING = 6;
 
     public static final int EVENT_UPDATE_LED = 0x108;
 
@@ -344,6 +352,7 @@ public class Constant {
     //患者信息
     public static final int EVENT_Host_INFO = 0x112;
 
+    public static final int EVENT_V_HOOK_OFF = 0x113;
 
     /**
      * 串口消息

+ 9 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/channel/VideoUtil.java

@@ -29,6 +29,15 @@ public class VideoUtil {
         tcpModel.setData(interactionId);
         return tcpModel;
     }
+    public static TcpModel videoInCall(String tid, Integer fromId, Integer toId, Integer interactionId){
+        TcpModel tcpModel = new TcpModel(tid);
+        tcpModel.setType(TcpType.VIDEO);
+        tcpModel.setAction(TcpAction.VideoAction.VIDEO_IN_CALL);
+        tcpModel.setFromId(fromId);
+        tcpModel.setToId(toId);
+        tcpModel.setData(interactionId);
+        return tcpModel;
+    }
 
     public static TcpModel videoReject(String tid, Integer fromId, Integer toId,Integer interactionId){
         TcpModel tcpModel = new TcpModel(tid);

+ 1 - 1
settings.gradle

@@ -1,3 +1,3 @@
 include ':app', ':common', ':welcome',  ':resource', ':middleware',
         ':callingdoor',  ':android_bed', ':android_host',
-        ':bedlib', ':janus', ':listenvision', ':gstream'
+        ':bedlib', ':janus', ':listenvision'