Browse Source

<增加紧急按钮呼叫>

weizhengliang 4 năm trước cách đây
mục cha
commit
774873f456
27 tập tin đã thay đổi với 441 bổ sung65 xóa
  1. 3 3
      app/build.gradle
  2. 3 3
      app/src/main/code/com/wdkl/app/ncs/application/Application.kt
  3. 69 0
      common/src/main/code/com/wdkl/ncs/android/lib/widget/SOSDialog.kt
  4. BIN
      common/src/main/res/drawable/ic_sos_m.png
  5. 61 0
      common/src/main/res/layout/sos_dialog_lay.xml
  6. 6 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/common/Constants.kt
  7. 10 3
      middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/channel/DeviceChannel.java
  8. 38 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/channel/OtherUtil.java
  9. 3 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/dto/TcpModel.java
  10. 9 6
      middleware/src/main/code/com/wdkl/ncs/android/middleware/utils/MessageEvent.kt
  11. 42 2
      nursehome/src/main/java/com/wdkl/ncs/android/component/nursehome/activity/NurseHomeActivity.kt
  12. 71 25
      nursehome/src/main/java/com/wdkl/ncs/android/component/nursehome/adapter/CallRecordsItemAdapter.kt
  13. 3 2
      nursehome/src/main/java/com/wdkl/ncs/android/component/nursehome/fragment/CallRecordsFragment.kt
  14. 15 12
      nursehome/src/main/java/com/wdkl/ncs/android/component/nursehome/util/CallDialogHelper.java
  15. 27 0
      nursehome/src/main/java/com/wdkl/ncs/android/component/nursehome/util/RingPlayHelper.java
  16. BIN
      nursehome/src/main/res/drawable-mdpi/ic_night.png
  17. BIN
      nursehome/src/main/res/drawable-mdpi/ic_sos.png
  18. 16 6
      nursehome/src/main/res/layout/adapter_call_records_item.xml
  19. 1 1
      settings.gradle
  20. 8 0
      webrtc/src/main/java/com/wdkl/core/base/BaseActivity.java
  21. 6 0
      webrtc/src/main/java/com/wdkl/core/socket/SocketManager.java
  22. 10 0
      webrtc/src/main/java/com/wdkl/core/voip/AsyncPlayer.java
  23. 9 0
      webrtc/src/main/java/com/wdkl/core/voip/CallMultiActivity.java
  24. 24 1
      webrtc/src/main/java/com/wdkl/core/voip/CallSingleActivity.java
  25. 2 1
      webrtc/src/main/java/com/wdkl/core/voip/FragmentAudio.java
  26. 4 0
      webrtc/src/main/java/com/wdkl/core/voip/SingleCallFragment.java
  27. 1 0
      webrtc/src/main/java/com/wdkl/core/voip/SpeechUtil.java

+ 3 - 3
app/build.gradle

@@ -116,10 +116,10 @@ dependencies {
     if (!componentTag) {
         compile project(':welcome') // ===> 开始模块  建议在模块内添加广告 欢迎页 等页面
         compile project(':home')   // ===> 主页模块  里面一般是App的首页 分类楼层页面
-        compile project(':shop')      // ===> 店铺模块 店铺列表 详细 等
-        compile project(':setting')   // ===> 设置模块 设置 缓存 App分享等
+        //compile project(':shop')      // ===> 店铺模块 店铺列表 详细 等
+        //compile project(':setting')   // ===> 设置模块 设置 缓存 App分享等
         compile project(':extra')    // ===> 额外的一些页面 比如二维码扫描等一些附加功能
-        compile project(':hello')
+        //compile project(':hello')
         compile project(':nursehome')
     }
     /**

+ 3 - 3
app/src/main/code/com/wdkl/app/ncs/application/Application.kt

@@ -47,11 +47,11 @@ class Application : BaseApplication() {
         JRouter.openLog()
         JRouter.prepare().create("/welcome/launch").seek()
         JRouter.prepare().create("/home/launch").seek()
-        JRouter.prepare().create("/setting/launch").seek()
-        JRouter.prepare().create("/shop/launch").seek()
+        //JRouter.prepare().create("/setting/launch").seek()
+        //JRouter.prepare().create("/shop/launch").seek()
         JRouter.prepare().create("/extra/launch").seek()
 
-        JRouter.prepare().create("/hello/launch").seek()
+        //JRouter.prepare().create("/hello/launch").seek()
         JRouter.prepare().create("/nursehome/launch").seek()
     }
 

+ 69 - 0
common/src/main/code/com/wdkl/ncs/android/lib/widget/SOSDialog.kt

@@ -0,0 +1,69 @@
+package com.wdkl.ncs.android.lib.widget
+
+import android.app.Dialog
+import android.content.Context
+import android.graphics.Color
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.WindowManager
+import android.widget.TextView
+import com.enation.javashop.utils.base.tool.ScreenTool
+import com.wdkl.ncs.android.lib.R
+import com.wdkl.ncs.android.lib.utils.reLayout
+import java.lang.Exception
+
+
+class SOSDialog {
+
+    private val context : Context
+
+    companion object {
+
+        fun build(context: Context):SOSDialog{
+            return SOSDialog(context)
+        }
+
+    }
+
+    private constructor(context: Context) {
+        this.context = context
+    }
+
+    fun configShow(sosCancel :(()->Unit)? = null, sosText :String) {
+        val contentView = LayoutInflater.from(context).inflate(R.layout.sos_dialog_lay, null)
+        val dialog = Dialog(context, R.style.Dialog)
+        dialog.setContentView(contentView)
+        contentView.reLayout<ViewGroup.LayoutParams> {
+            params ->
+            params.width = 800
+            params.height = 400
+        }
+        val sosTv = contentView.findViewById<TextView>(R.id.tv_sos_content)
+        val cancelTv = contentView.findViewById<TextView>(R.id.tv_sos_cancel)
+        sosTv.text = sosText
+
+        cancelTv.setOnClickListener {
+            dialog.dismiss()
+            sosCancel?.invoke()
+        }
+        dialog.setCanceledOnTouchOutside(false)
+        dialog.setCancelable(false)
+
+        try {
+            val window = dialog.window
+            window?.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
+            dialog.show()
+            window!!.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+                    or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+                    or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+                    or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+                    or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+                    or View.SYSTEM_UI_FLAG_FULLSCREEN)
+            window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
+        } catch (e :Exception) {
+            e.printStackTrace()
+        }
+
+    }
+}

BIN
common/src/main/res/drawable/ic_sos_m.png


+ 61 - 0
common/src/main/res/layout/sos_dialog_lay.xml

@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#00000000"
+    android:gravity="center">
+
+
+    <View
+        android:id="@+id/vcode_dialog_bg"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:background="@drawable/radis"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintDimensionRatio="h,1.7:1"
+        app:layout_constraintHorizontal_bias="0.632"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.405"
+        app:layout_constraintWidth_percent="0.8" />
+
+    <ImageView
+        android:id="@+id/img_sos"
+        android:layout_width="80dp"
+        android:layout_height="80dp"
+        app:layout_constraintBottom_toBottomOf="@+id/vcode_dialog_bg"
+        app:layout_constraintEnd_toEndOf="@+id/vcode_dialog_bg"
+        app:layout_constraintHorizontal_bias="0.0"
+        app:layout_constraintStart_toStartOf="@+id/vcode_dialog_bg"
+        app:layout_constraintTop_toTopOf="@+id/vcode_dialog_bg"
+        app:srcCompat="@drawable/ic_sos_m" />
+
+    <TextView
+        android:id="@+id/tv_sos_content"
+        android:layout_width="320dp"
+        android:layout_height="80dp"
+        android:background="#87CEFA"
+        android:gravity="center"
+        android:text="--紧急呼叫"
+        android:textSize="48sp"
+        android:textColor="@color/color_red"
+        app:layout_constraintBottom_toBottomOf="@+id/vcode_dialog_bg"
+        app:layout_constraintStart_toEndOf="@+id/img_sos"
+        app:layout_constraintTop_toTopOf="@+id/vcode_dialog_bg" />
+
+    <TextView
+        android:id="@+id/tv_sos_cancel"
+        android:layout_width="0dp"
+        android:layout_height="80dp"
+        android:background="#87CEFA"
+        android:gravity="center"
+        android:text="取消"
+        android:textSize="32sp"
+        app:layout_constraintBottom_toBottomOf="@+id/vcode_dialog_bg"
+        app:layout_constraintEnd_toEndOf="@+id/vcode_dialog_bg"
+        app:layout_constraintStart_toEndOf="@+id/tv_sos_content"
+        app:layout_constraintTop_toTopOf="@+id/vcode_dialog_bg" />
+
+</android.support.constraint.ConstraintLayout>

+ 6 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/common/Constants.kt

@@ -73,6 +73,9 @@ class Constants {
         //新的来电
         val EVENT_NEW_CALL = 0x05
 
+        //紧急呼叫
+        val EVENT_SOS_CALL = 0x06
+
         //手柄拿起
         val HOOK_OFF = "com.android.PhoneWinowManager.HOOK_OFF"
         //手柄放下
@@ -92,6 +95,9 @@ class Constants {
         //通话中
         val CALL_CALLING = 3
 
+        //紧急呼叫
+        val CALL_SOS = 4
+
         //通话状态
         var CALL_STATE = CALL_STANDBY
     }

+ 10 - 3
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/channel/DeviceChannel.java

@@ -4,7 +4,6 @@ import android.util.Log;
 
 import com.google.gson.Gson;
 import com.wdkl.ncs.android.component.nursehome.common.Constants;
-import com.wdkl.ncs.android.middleware.logic.contract.nursehome.CallRecordsFragmentContract;
 import com.wdkl.ncs.android.middleware.model.vo.InteractionVO;
 import com.wdkl.ncs.android.middleware.tcp.TcpClient;
 import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel;
@@ -23,10 +22,10 @@ public class DeviceChannel {
     //通话中模拟
     public static boolean calling = false;
 
-    public static TcpModel handleTcpReceived(TcpModel tcpModel){
+    public static TcpModel handleTcpReceived(final TcpModel tcpModel){
         TcpModel responseTcpModel = null;
 
-        Log.e(TAG,"DeviceChannel tcpType: "+tcpModel.getType() + ", calling: " + calling);
+        Log.e(TAG,"DeviceChannel tcpType: "+tcpModel.getType() + ", action: " + tcpModel.getAction() + ", calling: " + calling);
 
         switch (tcpModel.getType()){
             case CALLBACK:
@@ -124,6 +123,14 @@ public class DeviceChannel {
                     EventBus.getDefault().post(new MessageEvent(tcpModel,Constants.Companion.getEVENT_TCP_MSG()));
                 }
                 break;
+            case SOS:
+                //紧急呼叫优先级最高,如果当前正在通话需要将其打断
+                if (Constants.Companion.getCALL_STATE() == Constants.Companion.getCALL_CALLING()) {
+                    EventBus.getDefault().post(new MessageEvent(tcpModel,Constants.Companion.getEVENT_SOS_CALL()));
+                } else {
+                    EventBus.getDefault().post(new MessageEvent(tcpModel, Constants.Companion.getEVENT_TCP_MSG()));
+                }
+                break;
         }
 
         return responseTcpModel;

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

@@ -0,0 +1,38 @@
+package com.wdkl.ncs.android.middleware.tcp.channel;
+
+import com.wdkl.ncs.android.middleware.tcp.TcpClient;
+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;
+
+public class OtherUtil {
+    //分机SOS呼叫,不需要传toId
+    public static TcpModel SOSCall(Integer fromId){
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.SOS);
+        tcpModel.setAction(TcpAction.SOSAction.CALL);
+        tcpModel.setFromId(fromId);
+        return tcpModel;
+    }
+
+    public static TcpModel SOSCancel(Integer fromId, Integer toId, Integer interactionId){
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.SOS);
+        tcpModel.setAction(TcpAction.SOSAction.CANCEL);
+        tcpModel.setFromId(fromId);
+        tcpModel.setToId(toId);
+        tcpModel.setData(interactionId);
+        return tcpModel;
+    }
+
+    //发送sos相关tcp
+    public static void sendSosCall(Integer fromId) {
+        TcpModel tcpModel = OtherUtil.SOSCall(fromId);
+        TcpClient.getInstance().sendMsg(tcpModel.toJson());
+    }
+
+    public static void cancelSosCall(Integer fromId, Integer toId, Integer interactionId) {
+        TcpModel tcpModel = OtherUtil.SOSCancel(fromId, toId, interactionId);
+        TcpClient.getInstance().sendMsg(tcpModel.toJson());
+    }
+}

+ 3 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/dto/TcpModel.java

@@ -129,6 +129,9 @@ public class TcpModel implements Serializable {
             case EVENT:
                 tcpAction = TcpAction.EventAction.fromString(action);
                 break;
+            case SOS:
+                tcpAction = TcpAction.SOSAction.fromString(action);
+                break;
         }
 
         tcpModel.setType(tcpType);

+ 9 - 6
middleware/src/main/code/com/wdkl/ncs/android/middleware/utils/MessageEvent.kt

@@ -1,16 +1,21 @@
 package com.wdkl.ncs.android.middleware.utils
 
-class MessageEvent(var tcpModel: Any,var type: Int) {
+class MessageEvent {
 
     private var message: Any? = null
     private var types: Int? =0
 
+    constructor(tcpModel: Any, type: Int) {
+        message = tcpModel
+        types = type
+    }
+
     fun getMessage(): Any? {
-        return tcpModel
+        return message
     }
 
-    fun setMessage(tcpModel: Any?) {
-        this.message = tcpModel
+    fun setMessage(msg: Any?) {
+        this.message = msg
     }
 
     fun getType(): Int? {
@@ -21,6 +26,4 @@ class MessageEvent(var tcpModel: Any,var type: Int) {
         this.types = type
     }
 
-
-
 }

+ 42 - 2
nursehome/src/main/java/com/wdkl/ncs/android/component/nursehome/activity/NurseHomeActivity.kt

@@ -49,6 +49,7 @@ import com.wdkl.ncs.android.lib.utils.AppTool
 import com.wdkl.ncs.android.lib.utils.debugLog
 import com.wdkl.ncs.android.lib.utils.push
 import com.wdkl.ncs.android.lib.utils.showMessage
+import com.wdkl.ncs.android.lib.widget.SOSDialog
 import com.wdkl.ncs.android.middleware.logic.contract.nursehome.NurseHomeActivityContract
 import com.wdkl.ncs.android.middleware.logic.presenter.nursehome.NurseHomeActivityPresenter
 import com.wdkl.ncs.android.middleware.model.ChildCategoryShell
@@ -59,6 +60,7 @@ import com.wdkl.ncs.android.middleware.model.vo.FrameBedVO
 import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
 import com.wdkl.ncs.android.middleware.tcp.TcpClient
 import com.wdkl.ncs.android.middleware.tcp.channel.DeviceChannel
+import com.wdkl.ncs.android.middleware.tcp.channel.OtherUtil
 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
@@ -669,7 +671,7 @@ fun call(tyte:Int){
 
             override fun onFinish() {
                 //呼叫超时,退出呼叫界面
-                showMessage("无人应答...")
+                showMessage("无人接听...")
                 VoiceUtil.cancelAudioCall(Integer.parseInt(Constants.ids), callTargetId)
                 CallDialogHelper.dismissCallDialog()
             }
@@ -709,7 +711,7 @@ fun call(tyte:Int){
 
     @Subscribe(threadMode = ThreadMode.MAIN)
     fun onMoonEvent(messageEvent: MessageEvent) {
-        when (messageEvent.type) {
+        when (messageEvent.getType()) {
             Constants.EVENT_TCP_MSG -> {
                 var tcpModel = messageEvent.getMessage() as TcpModel
                 var interactionVO = Gson().fromJson(tcpModel.data.toString(), InteractionVO::class.java)
@@ -784,6 +786,7 @@ fun call(tyte:Int){
                         CallDialogHelper.dismissCallDialog()
                         CallDialogHelper.showCallDialog(this@NurseHomeActivity, 0, "", View.OnClickListener {
                             //呼出取消
+                            Constants.CALL_STATE = Constants.CALL_STANDBY
                             DeviceChannel.calling = false
                             VoiceUtil.cancelAudioCall(Integer.parseInt(Constants.ids), callTargetId)
                             CallDialogHelper.dismissCallDialog()
@@ -796,6 +799,43 @@ fun call(tyte:Int){
 
                         EventBus.getDefault().post(MessageEvent(0, Constants.EVENT_REFRESH_CALL_LIST))
                     }
+                } else if (tcpModel.type == TcpType.SOS) {
+                    if (tcpModel.action == TcpAction.SOSAction.CALL) {
+                        //紧急呼叫优先级最高,如果当前有通话或正在呼叫的需要将其打断
+                        if (Constants.CALL_STATE == Constants.CALL_INCOMING) {
+                            VoiceUtil.rejectAudioCall(Integer.parseInt(Constants.ids), Constants.fromId, Constants.interactionId)
+                        } else if (Constants.CALL_STATE == Constants.CALL_OUTGOING) {
+                            VoiceUtil.cancelAudioCall(Integer.parseInt(Constants.ids), callTargetId)
+                        }
+                        DeviceChannel.calling = true
+                        CallDialogHelper.dismissCallDialog()
+
+                        val sosRoom = interactionVO.fromFrameFullName.substringBefore("-")
+                        if (Constants.CALL_STATE != Constants.CALL_SOS) {
+                            SOSDialog.build(this).configShow(sosCancel = {
+                                Constants.CALL_STATE = Constants.CALL_STANDBY
+                                DeviceChannel.calling = false
+                                OtherUtil.cancelSosCall(Integer.parseInt(Constants.ids), interactionVO.fromDeviceId, interactionVO.id)
+                                EventBus.getDefault().post(MessageEvent(0, Constants.EVENT_REFRESH_CALL_LIST))
+
+                                if (SettingConfig.getTtsMode(activity) == SettingConfig.TTS_OFF) {
+                                    RingPlayHelper.stopRingTone()
+                                } else {
+                                    SpeechUtil.getInstance().stopSpeak()
+                                }
+                            }, sosText = sosRoom + "紧急呼叫")
+                        }
+
+                        //语音
+                        if (SettingConfig.getTtsMode(activity) == SettingConfig.TTS_OFF) {
+                            RingPlayHelper.playRingTone(activity, R.raw.incoming_call, false)
+                        } else {
+                            SpeechUtil.getInstance().addSpeech(sosRoom + "紧急呼叫", true)
+                        }
+                        Constants.CALL_STATE = Constants.CALL_SOS
+
+                        EventBus.getDefault().post(MessageEvent(0, Constants.EVENT_REFRESH_CALL_LIST))
+                    }
                 }
             }
 

+ 71 - 25
nursehome/src/main/java/com/wdkl/ncs/android/component/nursehome/adapter/CallRecordsItemAdapter.kt

@@ -11,10 +11,15 @@ import com.wdkl.ncs.android.component.nursehome.databinding.AdapterCallRecordsIt
 import com.wdkl.ncs.android.component.nursehome.util.TimeTransition
 import com.wdkl.ncs.android.lib.adapter.BaseDelegateAdapter
 import com.wdkl.ncs.android.lib.utils.BaseRecyclerViewHolder
+import com.wdkl.ncs.android.lib.utils.showMessage
 import com.wdkl.ncs.android.middleware.model.dos.CallingHistoryDO
 import com.wdkl.ncs.android.middleware.model.vo.CallingHistoryVO
 import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
+import com.wdkl.ncs.android.middleware.tcp.channel.OtherUtil
 import com.wdkl.ncs.android.middleware.tcp.channel.VoiceUtil
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpType
+import com.wdkl.ncs.android.middleware.utils.MessageEvent
+import org.greenrobot.eventbus.EventBus
 
 /**
  * 呼叫记录适配器
@@ -66,38 +71,79 @@ class CallRecordsItemAdapter(val data:ArrayList<InteractionVO>) : BaseDelegateAd
 
             //是否已处理
             if (itemData.actionEnd != null) {
-                //判断是呼入还是呼出 1 分机到主机 2主机到分机
-                if (itemData.actionDirectionType == 1) {
-                    binding.sickbedTv.text = itemData.fromFrameFullName
-                    binding.nameTv.text = itemData.fromMemberName
-                    binding.callStatusImagev.setImageResource(R.drawable.hu_ru_yi_jie)
-                } else if (itemData.actionDirectionType == 2 || itemData.actionDirectionType == 3) {
-                    binding.sickbedTv.text = itemData.toFrameFullName
-                    binding.nameTv.text = itemData.toMemberName
-                    binding.callStatusImagev.setImageResource(R.drawable.hu_chu_yi_jie)
+                binding.processingTimeTv.text = TimeTransition().stampToDateTime(itemData.actionEnd * 1000)
+
+                if (TcpType.SOS.name == itemData.actionType) {
+                    //紧急呼叫已处理: 因为紧急按钮是连接在某个分机上,所以收到的紧急呼叫信息会携带该分机的信息,实际需要显示的是该房间的信息
+                    val roomNo = itemData.fromFrameFullName.substringBefore("-")
+                    binding.sickbedTv.text = roomNo
+                    binding.nameTv.text = "紧急呼叫"
+                    binding.callStatusImagev.visibility = View.GONE
+                    binding.tabImagev.setImageResource(R.drawable.ic_sos)
+                } else {
+                    binding.callStatusImagev.visibility = View.VISIBLE
+                    binding.tabImagev.setImageResource(R.drawable.lai_dian_tou_xiang_bg)
+                    //判断是呼入还是呼出 1 分机到主机 2主机到分机
+                    if (itemData.actionDirectionType == 1) {
+                        binding.sickbedTv.text = itemData.fromFrameFullName
+                        binding.nameTv.text = itemData.fromMemberName
+                        binding.callStatusImagev.setImageResource(R.drawable.hu_ru_yi_jie)
+                    } else if (itemData.actionDirectionType == 2 || itemData.actionDirectionType == 3) {
+                        binding.sickbedTv.text = itemData.toFrameFullName
+                        binding.nameTv.text = itemData.toMemberName
+                        binding.callStatusImagev.setImageResource(R.drawable.hu_chu_yi_jie)
+                    }
                 }
                 binding.callListReply.visibility = View.GONE
+                binding.callSosReply.visibility = View.GONE
             } else {
-                //判断是呼入还是呼出 1 分机到主机 2主机到分机
-                if (itemData.actionDirectionType == 1) {
-                    binding.sickbedTv.text = itemData.fromFrameFullName
-                    binding.nameTv.text = itemData.fromMemberName
-                    binding.callStatusImagev.setImageResource(R.drawable.hu_ru_wei_jie)
-                } else if (itemData.actionDirectionType == 2 || itemData.actionDirectionType == 3) {
-                    binding.sickbedTv.text = itemData.toFrameFullName
-                    binding.nameTv.text = itemData.toMemberName
-                    binding.callStatusImagev.setImageResource(R.drawable.hu_chu_wei_jie)
+                if (TcpType.SOS.name == itemData.actionType) {
+                    //紧急呼叫未处理
+                    val roomNo = itemData.fromFrameFullName.substringBefore("-")
+                    binding.sickbedTv.text = roomNo
+                    binding.nameTv.text = "紧急呼叫"
+                    binding.callStatusImagev.visibility = View.GONE
+                    binding.tabImagev.setImageResource(R.drawable.ic_sos)
+                    binding.callListReply.visibility = View.GONE
+                    binding.callSosReply.visibility = View.VISIBLE
+                } else {
+                    binding.callStatusImagev.visibility = View.VISIBLE
+                    binding.tabImagev.setImageResource(R.drawable.lai_dian_tou_xiang_bg)
+                    //判断是呼入还是呼出 1 分机到主机 2主机到分机
+                    if (itemData.actionDirectionType == 1) {
+                        binding.sickbedTv.text = itemData.fromFrameFullName
+                        binding.nameTv.text = itemData.fromMemberName
+                        binding.callStatusImagev.setImageResource(R.drawable.hu_ru_wei_jie)
+                    } else if (itemData.actionDirectionType == 2 || itemData.actionDirectionType == 3) {
+                        binding.sickbedTv.text = itemData.toFrameFullName
+                        binding.nameTv.text = itemData.toMemberName
+                        binding.callStatusImagev.setImageResource(R.drawable.hu_chu_wei_jie)
+                    }
+                    binding.callListReply.visibility = View.VISIBLE
+                    binding.callSosReply.visibility = View.GONE
                 }
-                binding.callListReply.visibility = View.VISIBLE
             }
 
             binding.callListReply.setOnClickListener {
-                if (itemData.actionDirectionType == 1 && itemData.fromDeviceId != null && itemData.fromDeviceId != Constants.ids!!.toInt()) {
-                    VoiceUtil.startAudioCall(Integer.parseInt(Constants.ids), itemData.fromDeviceId)
-                    Constants.call_type = 0
-                } else if (itemData.actionDirectionType == 2 && itemData.toDeviceId != null && itemData.toDeviceId != Constants.ids!!.toInt()) {
-                    VoiceUtil.startAudioCall(Integer.parseInt(Constants.ids), itemData.toDeviceId)
-                    Constants.call_type = 0
+                if (!Constants.ids.equals("")) {
+                    if (itemData.actionDirectionType == 1 && itemData.fromDeviceId != null && itemData.fromDeviceId != Constants.ids!!.toInt()) {
+                        VoiceUtil.startAudioCall(Integer.parseInt(Constants.ids), itemData.fromDeviceId)
+                        Constants.call_type = 0
+                    } else if (itemData.actionDirectionType == 2 && itemData.toDeviceId != null && itemData.toDeviceId != Constants.ids!!.toInt()) {
+                        VoiceUtil.startAudioCall(Integer.parseInt(Constants.ids), itemData.toDeviceId)
+                        Constants.call_type = 0
+                    }
+                } else {
+                    showMessage("获取不到当给前设备id")
+                }
+            }
+
+            binding.callSosReply.setOnClickListener {
+                if (!Constants.ids.equals("")) {
+                    OtherUtil.cancelSosCall(Integer.parseInt(Constants.ids), itemData.fromDeviceId, itemData.id)
+                    EventBus.getDefault().post(MessageEvent(0, Constants.EVENT_REFRESH_CALL_LIST))
+                } else {
+                    showMessage("获取不到当给前设备id")
                 }
             }
         }

+ 3 - 2
nursehome/src/main/java/com/wdkl/ncs/android/component/nursehome/fragment/CallRecordsFragment.kt

@@ -57,7 +57,7 @@ class CallRecordsFragment: BaseFragment<CallRecordsFragmentPresenter, FragmentCa
     private var eventName = ""
 
     //加载历史记录条数
-    private val pageSize: Int = 15
+    private val pageSize: Int = 10
     //数据的初始页数
     private var page: Int = 1
     //查询历史记录类型
@@ -344,7 +344,8 @@ class CallRecordsFragment: BaseFragment<CallRecordsFragmentPresenter, FragmentCa
 
     @Subscribe(threadMode = ThreadMode.MAIN)
     fun onMoonEvent(messageEvent: MessageEvent) {
-        if (messageEvent.type == Constants.EVENT_REFRESH_CALL_LIST) {
+        if (messageEvent.getType() == Constants.EVENT_REFRESH_CALL_LIST) {
+            Log.d("tcp", "refresh call list")
             page = 1
             presenter.loadFloor(page, pageSize, Constants.part_id, listType, eventName)
         }

+ 15 - 12
nursehome/src/main/java/com/wdkl/ncs/android/component/nursehome/util/CallDialogHelper.java

@@ -23,13 +23,7 @@ public class CallDialogHelper {
 
     private static AlertDialog callDialog;
 
-    private static AsyncPlayer ringPlayer;
-
     public static void showCallDialog(Activity activity, int callType, String name, View.OnClickListener hangupCall, View.OnClickListener acceptCall, View.OnClickListener rejectCall) {
-        if (ringPlayer == null) {
-            ringPlayer = new AsyncPlayer(null);
-        }
-
         View contentView = LayoutInflater.from(activity).inflate(R.layout.call_dialog_lay, null);
         AlertDialog.Builder builder = new AlertDialog.Builder(activity);
         builder.setView(contentView);
@@ -46,14 +40,16 @@ public class CallDialogHelper {
             //去电
             outCall.setVisibility(View.VISIBLE);
             inCall.setVisibility(View.GONE);
-            ringPlayer.play(activity, R.raw.wr_ringback, true, AudioManager.STREAM_MUSIC);
+            //ringPlayer.play(activity, R.raw.wr_ringback, true, AudioManager.STREAM_MUSIC);
+            RingPlayHelper.playRingTone(activity, R.raw.wr_ringback, true);
         } else {
             //来电
             outCall.setVisibility(View.GONE);
             inCall.setVisibility(View.VISIBLE);
             textName.setText("有新的通话请求: " + name);
             if (SettingConfig.getTtsMode(activity) == SettingConfig.TTS_OFF) {
-                ringPlayer.play(activity, R.raw.incoming_call, true, AudioManager.STREAM_MUSIC);
+                //ringPlayer.play(activity, R.raw.incoming_call, true, AudioManager.STREAM_MUSIC);
+                RingPlayHelper.playRingTone(activity, R.raw.incoming_call, false);
             }
         }
 
@@ -64,17 +60,26 @@ public class CallDialogHelper {
         callDialog = builder.create();
         callDialog.setCanceledOnTouchOutside(false);
         callDialog.setCancelable(false);
-        callDialog.show();
 
         //设置dialog宽高及位置
         try {
             Window window = callDialog.getWindow();
+            window.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
+            callDialog.show();
             WindowManager.LayoutParams lp = window.getAttributes();
             lp.width = 800;
             lp.height = 400;
             lp.gravity = Gravity.CENTER;
             //lp.alpha = 0.8f;//设置透明度
             window.setAttributes(lp);
+
+            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+                    | View.SYSTEM_UI_FLAG_FULLSCREEN);
+            window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
         } catch (Exception e) {
             e.printStackTrace();
         }
@@ -83,9 +88,7 @@ public class CallDialogHelper {
     public static void dismissCallDialog() {
         if (callDialog != null && callDialog.isShowing()) {
             callDialog.dismiss();
-            if (ringPlayer != null) {
-                ringPlayer.stop();
-            }
+            RingPlayHelper.stopRingTone();
             SpeechUtil.getInstance().stopSpeak();
         }
     }

+ 27 - 0
nursehome/src/main/java/com/wdkl/ncs/android/component/nursehome/util/RingPlayHelper.java

@@ -0,0 +1,27 @@
+package com.wdkl.ncs.android.component.nursehome.util;
+
+import android.content.Context;
+import android.media.AudioManager;
+
+import com.wdkl.core.voip.AsyncPlayer;
+
+public class RingPlayHelper {
+
+    private static AsyncPlayer ringPlayer;
+
+    public static void playRingTone(Context context, int res, boolean loop) {
+        if (ringPlayer == null) {
+            ringPlayer = new AsyncPlayer(null);
+        }
+
+        if (!ringPlayer.isPlay()) {
+            ringPlayer.play(context, res, loop, AudioManager.STREAM_MUSIC);
+        }
+    }
+
+    public static void stopRingTone() {
+        if (ringPlayer != null) {
+            ringPlayer.stop();
+        }
+    }
+}

BIN
nursehome/src/main/res/drawable-mdpi/ic_night.png


BIN
nursehome/src/main/res/drawable-mdpi/ic_sos.png


+ 16 - 6
nursehome/src/main/res/layout/adapter_call_records_item.xml

@@ -3,7 +3,7 @@
 
     <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+        android:layout_height="68dp"
         android:background="#ffffff"
         android:layout_marginTop="6px"
         android:paddingTop="4dp"
@@ -42,14 +42,14 @@
                 android:id="@+id/room_name_linlyout"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_marginLeft="6px">
+                android:layout_marginLeft="10px">
 
                 <TextView
                     android:id="@+id/sickbed_tv"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:text=""
-                    android:textSize="14px" />
+                    android:textSize="16px" />
 
                 <TextView
                     android:id="@+id/call_time_tv"
@@ -57,7 +57,7 @@
                     android:layout_height="wrap_content"
                     android:layout_alignParentRight="true"
                     android:text=""
-                    android:textSize="12px"
+                    android:textSize="16px"
                     android:visibility="gone"/>
 
             </RelativeLayout>
@@ -67,7 +67,7 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_below="@+id/room_name_linlyout"
-                android:layout_marginLeft="6px"
+                android:layout_marginLeft="10px"
                 android:layout_marginTop="4px"
                 android:orientation="vertical">
 
@@ -76,7 +76,7 @@
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:text=""
-                    android:textSize="14px" />
+                    android:textSize="16px" />
 
                 <TextView
                     android:id="@+id/call_list_reply"
@@ -89,6 +89,16 @@
                     android:textSize="14px"
                     android:text="回拨" />
 
+                <TextView
+                    android:id="@+id/call_sos_reply"
+                    android:layout_width="59px"
+                    android:layout_height="20px"
+                    android:gravity="center"
+                    android:layout_alignParentRight="true"
+                    android:background="@drawable/sp_event_unhandled_bg"
+                    android:textSize="16px"
+                    android:text="未处理"/>
+
                 <LinearLayout
                     android:id="@+id/incident_linlyou"
                     android:layout_width="wrap_content"

+ 1 - 1
settings.gradle

@@ -1 +1 @@
-include ':app', ':common', ':welcome', ':home', ':resource', ':middleware', ':shop', ':setting', ':extra', ':hello', ':nursehome', ':starRTC', ':AmDemo_R', 'webrtc', 'rtc-chat', 'libwebrtc'
+include ':app', ':common', ':welcome', ':home', ':resource', ':middleware', ':extra', ':nursehome', ':starRTC', ':AmDemo_R', 'webrtc', 'rtc-chat', 'libwebrtc'

+ 8 - 0
webrtc/src/main/java/com/wdkl/core/base/BaseActivity.java

@@ -7,17 +7,25 @@ import android.support.v7.app.AppCompatActivity;
 
 import com.wdkl.core.util.ActivityStackManager;
 
+import org.greenrobot.eventbus.EventBus;
+
 public class BaseActivity extends AppCompatActivity {
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         // 添加Activity到堆栈
         ActivityStackManager.getInstance().onCreated(this);
         super.onCreate(savedInstanceState);
+        if (!EventBus.getDefault().isRegistered(this)) {
+            EventBus.getDefault().register(this);
+        }
     }
 
     @Override
     protected void onDestroy() {
         ActivityStackManager.getInstance().onDestroyed(this);
         super.onDestroy();
+        if (EventBus.getDefault().isRegistered(this)) {
+            EventBus.getDefault().unregister(this);
+        }
     }
 }

+ 6 - 0
webrtc/src/main/java/com/wdkl/core/socket/SocketManager.java

@@ -376,4 +376,10 @@ public class SocketManager implements IEvent {
         iUserState = new WeakReference<>(userState);
     }
 
+    public void endCall() {
+        CallSession session = SkyEngineKit.Instance().getCurrentSession();
+        if (session != null) {
+            SkyEngineKit.Instance().endCall();
+        }
+    }
 }

+ 10 - 0
webrtc/src/main/java/com/wdkl/core/voip/AsyncPlayer.java

@@ -46,6 +46,12 @@ public class AsyncPlayer {
             player.setVolume(1.0f, 1.0f);
             //player.prepare();
             player.start();
+            player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+                @Override
+                public void onCompletion(MediaPlayer mp) {
+                    mState = STOP;
+                }
+            });
             if (mPlayer != null) {
                 mPlayer.release();
             }
@@ -139,6 +145,10 @@ public class AsyncPlayer {
         }
     }
 
+    public boolean isPlay() {
+        return mState == PLAY;
+    }
+
     private void enqueueLocked(Command cmd) {
         mCmdQueue.add(cmd);
         if (mThread == null) {

+ 9 - 0
webrtc/src/main/java/com/wdkl/core/voip/CallMultiActivity.java

@@ -15,6 +15,7 @@ import android.view.WindowManager;
 import android.widget.ImageView;
 
 import com.wdkl.core.base.BaseActivity;
+import com.wdkl.ncs.android.middleware.utils.MessageEvent;
 import com.wdkl.permission.Permissions;
 import com.wdkl.skywebrtc.CallSession;
 import com.wdkl.skywebrtc.EnumType;
@@ -22,6 +23,9 @@ import com.wdkl.skywebrtc.SkyEngineKit;
 import com.wdkl.skywebrtc.except.NotInitializedException;
 import com.wdkl.webrtc.R;
 
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+
 import java.util.UUID;
 
 /**
@@ -195,4 +199,9 @@ public class CallMultiActivity extends BaseActivity implements CallSession.CallS
         SkyEngineKit.Instance().leaveRoom();
         this.finish();
     }
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    public void onMoonEvent(MessageEvent messageEvent) {
+        //
+    }
 }

+ 24 - 1
webrtc/src/main/java/com/wdkl/core/voip/CallSingleActivity.java

@@ -22,9 +22,11 @@ import android.widget.Toast;
 
 
 import com.wdkl.core.base.BaseActivity;
+import com.wdkl.core.socket.SocketManager;
 import com.wdkl.ncs.android.component.nursehome.common.Constants;
 import com.wdkl.ncs.android.middleware.tcp.channel.DeviceChannel;
 import com.wdkl.ncs.android.middleware.tcp.channel.VoiceUtil;
+import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel;
 import com.wdkl.ncs.android.middleware.utils.MessageEvent;
 import com.wdkl.permission.Permissions;
 import com.wdkl.skywebrtc.CallSession;
@@ -34,6 +36,8 @@ import com.wdkl.skywebrtc.except.NotInitializedException;
 import com.wdkl.webrtc.R;
 
 import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
 
 import java.util.UUID;
 
@@ -64,6 +68,9 @@ public class CallSingleActivity extends BaseActivity implements CallSession.Call
 
     private BroadcastReceiver receiver;
 
+    private boolean sosCallIn = false;
+    private TcpModel tcpModel = null;
+
     public static Intent getCallIntent(Context context, String targetId, boolean isOutgoing, String inviteUserName,
                                        boolean isAudioOnly, boolean isClearTop) {
         Intent voip = new Intent(context, CallSingleActivity.class);
@@ -92,6 +99,9 @@ public class CallSingleActivity extends BaseActivity implements CallSession.Call
         setStatusBarOrScreenStatus(this);
         setContentView(R.layout.activity_single_call);
 
+        //进入通话状态
+        Constants.Companion.setCALL_STATE(Constants.Companion.getCALL_CALLING());
+
         try {
             gEngineKit = SkyEngineKit.Instance();
         } catch (NotInitializedException e) {
@@ -345,7 +355,20 @@ public class CallSingleActivity extends BaseActivity implements CallSession.Call
         unregisterReceiver(receiver);
         Constants.Companion.setCALL_STATE(Constants.Companion.getCALL_STANDBY());
         DeviceChannel.calling = false;
-        VoiceUtil.handoffAudioCall(Integer.parseInt(Constants.Companion.getIds()), Constants.Companion.getFromId(), Constants.Companion.getInteractionId());
         EventBus.getDefault().post(new MessageEvent(0, Constants.Companion.getEVENT_REFRESH_CALL_LIST()));
+        if (sosCallIn && tcpModel != null) {
+            EventBus.getDefault().post(new MessageEvent(tcpModel, Constants.Companion.getEVENT_TCP_MSG()));
+        }
+    }
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    public void onMoonEvent(MessageEvent messageEvent) {
+        if (messageEvent.getType() != null && messageEvent.getType() == Constants.Companion.getEVENT_SOS_CALL()) {
+            sosCallIn = true;
+            if (messageEvent.getMessage() instanceof TcpModel) {
+                tcpModel = (TcpModel) messageEvent.getMessage();
+            }
+            SocketManager.getInstance().endCall();
+        }
     }
 }

+ 2 - 1
webrtc/src/main/java/com/wdkl/core/voip/FragmentAudio.java

@@ -65,6 +65,7 @@ public class FragmentAudio extends SingleCallFragment implements View.OnClickLis
             startRefreshTime();
         } else {
             // 如果未接通
+            descTextView.setText("正在建立连接...");
             if (isOutgoing) {
                 descTextView.setText(R.string.av_waiting);
                 outgoingActionContainer.setVisibility(View.VISIBLE);
@@ -92,7 +93,7 @@ public class FragmentAudio extends SingleCallFragment implements View.OnClickLis
                 incomingActionContainer.setVisibility(View.GONE);
                 outgoingActionContainer.setVisibility(View.VISIBLE);
                 //minimizeImageView.setVisibility(View.VISIBLE);
-                descTextView.setVisibility(View.GONE);
+                descTextView.setText("正在通话中...");
 
                 startRefreshTime();
             } else {

+ 4 - 0
webrtc/src/main/java/com/wdkl/core/voip/SingleCallFragment.java

@@ -21,6 +21,8 @@ import android.widget.ImageView;
 import android.widget.TextView;
 
 import com.wdkl.core.ui.event.MsgEvent;
+import com.wdkl.ncs.android.component.nursehome.common.Constants;
+import com.wdkl.ncs.android.middleware.tcp.channel.VoiceUtil;
 import com.wdkl.skywebrtc.CallSession;
 import com.wdkl.skywebrtc.EnumType;
 import com.wdkl.skywebrtc.SkyEngineKit;
@@ -197,6 +199,8 @@ public abstract class SingleCallFragment extends Fragment {
                 break;
             }
             case Hangup: {
+                //自己挂断
+                VoiceUtil.handoffAudioCall(Integer.parseInt(Constants.Companion.getIds()), Constants.Companion.getFromId(), Constants.Companion.getInteractionId());
                 tvStatus.setText("挂断");
                 break;
             }

+ 1 - 0
webrtc/src/main/java/com/wdkl/core/voip/SpeechUtil.java

@@ -71,6 +71,7 @@ public class SpeechUtil {
             Log.d(TAG, "truely add text speech: " + text);
 
             if (emergency) {
+                stopSpeak();
                 speechTextList.add(0, text);
             } else {
                 speechTextList.add(text);