فهرست منبع

分机:
1 新功能板适配:增加功能板选择配置,增加新功能板串口解析逻辑 增加新的loar信号板串口逻辑
2 生产测试模块调整,生产线模式下快速测试设备状况,激活界面增加串口数据解析
3 宿舍版本UI调整
4,增加自定义按键功能
5 增加断网情况下发送loar信号的功能
6,增加接收到loar信号上传的功能
护士主机
增加宿舍版本

xunchuanzhi 7 ماه پیش
والد
کامیت
be39116dcb
100فایلهای تغییر یافته به همراه7231 افزوده شده و 1060 حذف شده
  1. 2 0
      android_bed/build.gradle
  2. 4 0
      android_bed/src/main/AndroidManifest.xml
  3. 50 0
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/Bean/ButtonType.java
  4. 303 0
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/activity/AppTextActivity.kt
  5. 178 11
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/activity/CallingbedActivationActivity.kt
  6. 187 1
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/activity/CallingbedActivity.kt
  7. 175 150
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/activity/CallingbedDormitoryActivity.kt
  8. 5 0
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/activity/CallingbedMomActivity.kt
  9. 58 0
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/activity/OfflineCallingbedActivity.kt
  10. 3 4
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/activity/SystemActivity.kt
  11. 39 14
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/activity/TextActivity.kt
  12. 1 2
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/di/CallingbedComponent.kt
  13. 106 0
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/dialog/SystemDialogHelper2.java
  14. 0 1
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/fragment/DormSipCallFragment.kt
  15. 8 7
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/fragment/DromMianFragment.kt
  16. 7 0
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/hardware/HardTools.java
  17. 41 14
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/hardware/imp/A133HardTools.java
  18. 8 0
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/helper/AlarmMessageUtil.java
  19. 63 0
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/helper/DrawingView.java
  20. 11 7
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/helper/SerialPortHelper.java
  21. 1 1
      android_bed/src/main/java/com/wdkl/app/ncs/callingbed/sleep/SleepService.java
  22. 43 13
      android_bed/src/main/res/layout-land/callingbed_test_main.xml
  23. 162 0
      android_bed/src/main/res/layout/test_lay.xml
  24. BIN
      android_bed/src/main/res/mipmap-mdpi/integ_arrow_icon.png
  25. 4 0
      android_host/src/main/AndroidManifest.xml
  26. 2 2
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/activity/CallingHostActivationActivity.kt
  27. 0 38
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/activity/HostbedinfoActivity.kt
  28. 213 786
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/activity/NurseHome2Activity.kt
  29. 0 3
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/activity/NurseHomeActivity.kt
  30. 259 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/adapter/DormCallingItemAdapter.kt
  31. 17 1
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/di/NurseHomeComponent.kt
  32. 499 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/DormCallRecordsFragment.kt
  33. 305 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/DormDialCallFragment.kt
  34. 374 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/DormSipCallFragment.kt
  35. 798 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/DormSkyCallFragment.kt
  36. 136 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/DormThemeFragment.kt
  37. 212 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/DromMianFragment.kt
  38. 135 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/VolumeSetFragment.kt
  39. 208 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/adapter/DormCallRecordsItemAdapter.kt
  40. 63 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/adapter/DormDialCallSearchAdapter.kt
  41. 103 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/adapter/DormThemeAdapter.kt
  42. 35 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/search/DefaultFuzzySearchRule.java
  43. 45 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/search/DeviceSearchItem.java
  44. 87 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/search/FuzzySearchBaseAdapter.java
  45. 12 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/search/IAZItem.java
  46. 24 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/search/IFuzzySearchItem.java
  47. 20 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/search/IFuzzySearchRule.java
  48. 897 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/search/PinyinUtil.java
  49. 1 1
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/fragment/BedinfoFragment.kt
  50. 0 1
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/fragment/CallRecordsFragment.kt
  51. 15 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/fragment/IotDeviceFragment.kt
  52. 49 1
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/fragment/SipCallFragment.kt
  53. 15 2
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/fragment/WorkFragment.kt
  54. 1 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/helper/SoundPoolManager.java
  55. 36 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/settingconfig/SettingConfig.java
  56. 8 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/util/MediaPlayHelper.java
  57. 83 0
      android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/window/ImPlayDialogHelper.java
  58. BIN
      android_host/src/main/res/drawable/ic_accept_call.png
  59. 5 0
      android_host/src/main/res/drawable/ic_baseline_backspace.xml
  60. 5 0
      android_host/src/main/res/drawable/ic_baseline_cancel.xml
  61. 5 0
      android_host/src/main/res/drawable/ic_baseline_pause.xml
  62. 5 0
      android_host/src/main/res/drawable/ic_baseline_play.xml
  63. BIN
      android_host/src/main/res/drawable/ic_call_main.png
  64. BIN
      android_host/src/main/res/drawable/ic_end_call.png
  65. BIN
      android_host/src/main/res/drawable/ic_receptacle.png
  66. BIN
      android_host/src/main/res/drawable/ic_records_call.png
  67. BIN
      android_host/src/main/res/drawable/ic_records_miss_call.png
  68. BIN
      android_host/src/main/res/drawable/ic_records_voice_message.png
  69. 5 0
      android_host/src/main/res/drawable/ic_search_48.xml
  70. BIN
      android_host/src/main/res/drawable/ic_theme_bg.png
  71. BIN
      android_host/src/main/res/drawable/ic_theme_check.png
  72. 12 0
      android_host/src/main/res/drawable/records_action_bg.xml
  73. 12 0
      android_host/src/main/res/drawable/records_action_bg2.xml
  74. 12 0
      android_host/src/main/res/drawable/records_bg_1.xml
  75. 12 0
      android_host/src/main/res/drawable/records_bg_2.xml
  76. 12 0
      android_host/src/main/res/drawable/records_bg_3.xml
  77. 12 0
      android_host/src/main/res/drawable/records_bg_4.xml
  78. 12 0
      android_host/src/main/res/drawable/records_bg_5.xml
  79. 5 0
      android_host/src/main/res/drawable/selector_dial_num_bg.xml
  80. 14 0
      android_host/src/main/res/drawable/shape_accept_call.xml
  81. 12 0
      android_host/src/main/res/drawable/shape_dial_num.xml
  82. 12 0
      android_host/src/main/res/drawable/shape_dial_num_press.xml
  83. 11 0
      android_host/src/main/res/drawable/shape_dorm_bg.xml
  84. 13 0
      android_host/src/main/res/drawable/shape_dorm_call_item_bg.xml
  85. 7 0
      android_host/src/main/res/drawable/shape_drom_curtain_bg.xml
  86. 13 0
      android_host/src/main/res/drawable/shape_end_call.xml
  87. 11 0
      android_host/src/main/res/drawable/shape_main_drom_bg.xml
  88. 10 0
      android_host/src/main/res/drawable/shape_main_drom_f_bg.xml
  89. 12 0
      android_host/src/main/res/drawable/shape_main_drom_f_bg2.xml
  90. 11 0
      android_host/src/main/res/drawable/theme_button_bg.xml
  91. 8 0
      android_host/src/main/res/layout/activity_calling.xml
  92. 55 0
      android_host/src/main/res/layout/adapter_dorm_call_records_item.xml
  93. 84 0
      android_host/src/main/res/layout/adapter_dorm_calling_item.xml
  94. 45 0
      android_host/src/main/res/layout/adapter_dorm_dial_call_item.xml
  95. 2 0
      android_host/src/main/res/layout/callingbed_setting_main.xml
  96. 50 0
      android_host/src/main/res/layout/dorm_call_records.xml
  97. 275 0
      android_host/src/main/res/layout/dorm_dial_call.xml
  98. 339 0
      android_host/src/main/res/layout/dorm_sky_voice_call_layout.xml
  99. 22 0
      android_host/src/main/res/layout/dorm_theme_item.xml
  100. 0 0
      android_host/src/main/res/layout/dorm_theme_layout.xml

+ 2 - 0
android_bed/build.gradle

@@ -42,6 +42,7 @@ android {
         buildConfigField 'String', 'open_433', "\"${project.rootProject.ext.open_433}\""
         buildConfigField 'String', 'device_type', "\"${project.rootProject.ext.device_type}\""
         buildConfigField 'String', 'sleep_type', "\"${project.rootProject.ext.sleep_type}\""
+        buildConfigField 'String', 'feature_type', "\"${project.rootProject.ext.feature_type}\""
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
 
     }
@@ -229,6 +230,7 @@ dependencies {
     implementation 'com.google.android.exoplayer:exoplayer-ui:2.15.1'
     implementation 'com.google.android.exoplayer:exoplayer-hls:2.15.1'
     implementation 'com.google.android.exoplayer:exoplayer-dash:2.15.1'
+    implementation 'org.apache.commons:commons-lang3:3.12.0'
 
     //implementation 'com.jakewharton.timber:timber:5.0.1'
 }

+ 4 - 0
android_bed/src/main/AndroidManifest.xml

@@ -213,6 +213,10 @@
             android:turnScreenOn="true"
             android:screenOrientation="nosensor"
             android:launchMode="singleTask"/>
+        <activity android:name="com.wdkl.app.ncs.callingbed.activity.AppTextActivity"
+            android:turnScreenOn="true"
+            android:screenOrientation="nosensor"
+            android:launchMode="singleTask"/>
 
 
         <service android:name="com.wdkl.app.ncs.callingbed.bt_gateway.BluetoothService"/>

+ 50 - 0
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/Bean/ButtonType.java

@@ -0,0 +1,50 @@
+package com.wdkl.app.ncs.callingbed.Bean;
+
+import java.io.Serializable;
+
+public class ButtonType implements Serializable {
+
+
+    /**
+     * key : KEY;
+     * type : EVENT
+     * value : 30
+     */
+
+    private String key;
+    private String type;
+    private Object value;
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public Object getValue() {
+        return value;
+    }
+
+    public void setValue(Object value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return "ButtonType{" +
+                "key='" + key + '\'' +
+                ", type='" + type + '\'' +
+                ", value=" + value +
+                '}';
+    }
+}

+ 303 - 0
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/activity/AppTextActivity.kt

@@ -0,0 +1,303 @@
+package com.wdkl.app.ncs.callingbed.activity
+
+import android.graphics.Color
+import android.hardware.Camera
+import android.os.Bundle
+import android.text.method.ScrollingMovementMethod
+import android.view.SurfaceHolder
+import android.view.View
+import com.enation.javashop.android.jrouter.external.annotation.Router
+import com.enation.javashop.net.engine.model.NetState
+import com.wdkl.app.ncs.callingbed.R
+import com.wdkl.app.ncs.callingbed.databinding.TestLayBinding
+import com.wdkl.app.ncs.callingbed.databinding.UpdateLayBinding
+import com.wdkl.app.ncs.callingbed.helper.*
+import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
+import com.wdkl.app.ncs.callingbed.settings.SettingConfig
+import com.wdkl.ncs.android.lib.base.BaseActivity
+import com.wdkl.ncs.android.lib.utils.showMessage
+import com.wdkl.ncs.android.lib.vo.filter
+import com.wdkl.ncs.android.middleware.common.Constant
+import com.wdkl.ncs.android.middleware.common.MessageEvent
+import com.wdkl.ncs.android.middleware.logic.contract.callingbed.BedTextActivityContract
+import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.BedTextActivityPresenter
+import kotlinx.android.synthetic.main.test_lay.*
+import org.greenrobot.eventbus.EventBus
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+
+
+@Router(path = "/callingbed/text")
+class AppTextActivity :BaseActivity<BedTextActivityPresenter, TestLayBinding>(), BedTextActivityContract.View{
+    private val TAG = "AppTextActivity"
+
+    var info = ""
+    var buttonTest = false
+    var is_startTest = false
+    var testButton1 = false
+    var testButton2 = false
+    var testButton3 = false
+
+    var sosState = 0
+    var netOff = false
+
+    private var mCamera: Camera? = null
+    val colors = arrayOf(
+            Color.BLACK,
+            Color.WHITE,
+            Color.RED,
+            Color.parseColor("#FFA500"), // 橙色
+            Color.YELLOW,
+            Color.GREEN,
+            Color.CYAN,
+            Color.BLUE,
+            Color.MAGENTA
+    )
+    var colorIndex = 0
+
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+    }
+
+    override fun getLayId(): Int {
+        return R.layout.test_lay
+    }
+
+    override fun bindDagger() {
+        CallingbedLaunch.component.inject(this)
+    }
+
+    override fun init() {
+        Constant.isText=true
+        tv_test_info.movementMethod = ScrollingMovementMethod.getInstance()
+        tv_ip.text = "IP:" + NetHelper.getInstance().localIP
+
+        startCameraPreview()
+
+
+    }
+    private var red = 0
+    var is_cm = false
+    override fun bindEvent() {
+        view_title_layout_img.setOnClickListener {
+            finish()
+        }
+        btn_fist.setOnClickListener {
+            slayout.visibility = View.GONE
+            btn_fist.visibility = View.GONE
+            color_view.visibility = View.GONE
+
+        }
+
+        btn_color.setOnClickListener {
+            SoundPoolManager.getInstance().playSound(6, 1.0f, 1.0f, 0)
+            color_view.bringToFront()
+            color_view.visibility = View.VISIBLE
+            btn_fist.visibility = View.VISIBLE
+
+        }
+        color_view.setOnClickListener {
+            btn_fist.visibility = View.VISIBLE
+            color_view.setBackgroundColor(colors[colorIndex])
+            colorIndex = (colorIndex + 1) % colors.size
+        }
+        btn_cm.setOnClickListener {
+            SoundPoolManager.getInstance().playSound(7, 1.0f, 1.0f, 0)
+            is_cm=true
+            slayout.bringToFront()
+            slayout.visibility = View.VISIBLE
+            btn_fist.visibility = View.VISIBLE
+        }
+
+        btn_sos_test.setOnClickListener {
+            if (sosState == 0) {
+                sosState = 1
+                SerialPortHelper.setSosLight("1")
+            } else if (sosState == 1) {
+                sosState = 2
+                SerialPortHelper.setSosLight("2")
+            } else {
+                sosState = 0
+                SerialPortHelper.setSosLight("0")
+            }
+        }
+    }
+    private fun startTest() {
+        is_startTest=true
+        Thread {
+            info += "\r\n--> 麦克风测试:\r\n"
+            showInfo(info)
+            SoundPoolManager.getInstance().playSound(3, 1.0f, 1.0f, 0)
+            Thread.sleep(2000)
+            info += "开始录音...\r\n"
+            showInfo(info)
+            RecordHelper.getInstance().recordTestStart()
+            Thread.sleep(2500)
+            RecordHelper.getInstance().recordTestStop()
+            Thread.sleep(500)
+            info += "播放录音...\r\n"
+            showInfo(info)
+            MediaPlayHelper.getInstance().playUrlMusic(RecordHelper.getInstance().audiofilePath, 1.0f, false)
+
+            Thread.sleep(3000)
+            RecordHelper.getInstance().deleteAudioFile()
+
+            info += "--> 指示灯测试\r\n"
+            showInfo(info)
+            SerialPortHelper.setCallStatus("1")
+            Thread.sleep(2000)
+            SerialPortHelper.setCallStatus("0")
+
+            info += "===测试结束!===\r\n"
+            showInfo(info)
+            is_startTest=false
+        }.start()
+    }
+
+    private fun showInfo(text: String) {
+        activity.runOnUiThread {
+            if (tv_test_info != null) {
+                tv_test_info.text = text
+            }
+        }
+    }
+
+    private fun startCameraPreview() {
+        val num = Camera.getNumberOfCameras()
+        if (num > 0) {
+            val info = Camera.CameraInfo()
+            for (i in 0 until num) {
+                Camera.getCameraInfo(i, info)
+                if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
+                    try {
+                        mCamera = Camera.open(i)
+                    } catch (e: Exception) {
+                        e.printStackTrace()
+                    }
+                    break
+                }
+            }
+
+            if (mCamera == null) {
+                try {
+                    mCamera = Camera.open()
+                } catch (e: Exception) {
+                    showMessage(R.string.str_open_camera_failed)
+                    e.printStackTrace()
+                }
+            }
+
+            camera_preview_surface.getHolder().addCallback(object : SurfaceHolder.Callback {
+                override fun surfaceCreated(holder: SurfaceHolder) {
+                    /**
+                     * The SurfaceHolder must already contain a surface when this method is called.
+                     * If you are using SurfaceView, you will need to register a SurfaceHolder.Callback
+                     * with SurfaceHolder#addCallback(SurfaceHolder.Callback) and wait for
+                     * SurfaceHolder.Callback#surfaceCreated(SurfaceHolder) before
+                     * calling setPreviewDisplay() or starting preview.
+                     * 相机的预览必须在surfaceCreated后调用,否则黑屏且没有任何提示哦
+                     */
+
+                    try {
+                        mCamera?.setPreviewDisplay(camera_preview_surface.getHolder())
+                        mCamera?.startPreview()
+                    } catch (e: Exception) {
+                        e.printStackTrace()
+                    }
+                }
+
+                override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
+                    //
+                }
+
+                override fun surfaceDestroyed(holder: SurfaceHolder) {
+                    //
+                }
+            })
+        } else {
+            showMessage(R.string.str_no_camera)
+        }
+    }
+
+    override fun onStart() {
+        EventBus.getDefault().register(this)
+        super.onStart()
+    }
+
+    override fun onStop() {
+        EventBus.getDefault().unregister(this)
+        Constant.isText=false
+        super.onStop()
+    }
+
+    override fun destory() {
+        if (mCamera != null) {
+            mCamera!!.stopPreview()
+            mCamera!!.release()
+            mCamera = null
+        }
+        Constant.isText=false
+    }
+
+    override fun onResume() {
+        super.onResume()
+//        camera_preview.onResume(this)
+
+    }
+
+    override fun onPause() {
+//        camera_preview.onPause()
+        super.onPause()
+
+    }
+
+
+
+    override fun onError(message: String, type: Int) {
+        //
+    }
+
+    override fun complete(message: String, type: Int) {
+    }
+
+    override fun start() {
+    }
+
+    override fun networkMonitor(state: NetState) {
+        state.filter(onWifi = {
+
+        }, onMobile = {
+
+        }, offline = {
+
+        })
+    }
+
+
+
+
+
+
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    fun onMoonEvent(messageEvent: MessageEvent) {
+
+    }
+
+
+
+//    override fun onTouch(v: View?, event: MotionEvent?): Boolean {
+//        when (event?.action) {
+//            MotionEvent.ACTION_DOWN -> {
+//                if (is_cm){
+//                    v?.setBackgroundColor(Color.RED)
+//                }
+//                return true
+//            }
+//            MotionEvent.ACTION_MOVE -> {}
+//            MotionEvent.ACTION_UP -> {}
+//        }
+//        return false
+//    }
+}

+ 178 - 11
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/activity/CallingbedActivationActivity.kt

@@ -1,9 +1,11 @@
 package com.wdkl.app.ncs.callingbed.activity
 
 import android.app.zhyl.ZhylManager
+import android.content.Context
 import android.content.Intent
-import android.net.Uri
+import android.net.*
 import android.net.wifi.WifiManager
+import android.net.wifi.WifiNetworkSpecifier
 import android.os.Build
 import android.os.Environment
 import android.os.Handler
@@ -12,6 +14,7 @@ import android.provider.Settings
 import android.text.TextUtils
 import android.util.Log
 import android.view.View
+import androidx.annotation.RequiresApi
 import com.enation.javashop.android.jrouter.external.annotation.Router
 import com.enation.javashop.net.engine.config.NetEngineConfig
 import com.enation.javashop.net.engine.model.NetState
@@ -22,7 +25,7 @@ import com.wdkl.app.ncs.callingbed.BuildConfig
 import com.wdkl.app.ncs.callingbed.R
 import com.wdkl.app.ncs.callingbed.databinding.CallingbedActivationBinding
 import com.wdkl.app.ncs.callingbed.dialog.ServicesDialogHelper
-import com.wdkl.app.ncs.callingbed.dialog.SystemDialogHelper
+import com.wdkl.app.ncs.callingbed.dialog.SystemDialogHelper2
 import com.wdkl.app.ncs.callingbed.hardware.HardWareFactory
 import com.wdkl.app.ncs.callingbed.helper.*
 import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
@@ -48,16 +51,22 @@ import com.wdkl.ncs.android.middleware.utils.CommonUtils
 import kotlinx.android.synthetic.main.callingbed_activation.*
 import okhttp3.OkHttpClient
 import okhttp3.Request
+import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
+import serialporttest.utils.SerialPortUtil
+import serialporttest.utils.SerialPortUtil433
+import serialporttest.utils.SerialPortUtilLoar
+import serialporttest.utils.StringUtils
 import java.util.*
 import java.util.concurrent.TimeUnit
 
+
 /**
   * 激活页面
 * */
 @Router(path = "/callingbed/activation")
-class CallingbedActivationActivity  : BaseActivity<CallingbedActivationPresenter, CallingbedActivationBinding>(), CallingbedActivationContract.View {
+class CallingbedActivationActivity  : BaseActivity<CallingbedActivationPresenter, CallingbedActivationBinding>(), CallingbedActivationContract.View  , SerialPortUtil.ISerialPortBedOnclickEvent, SerialPortUtil.ISerialPortBedOnclickString,  SerialPortUtilLoar.ISerialPortLoarData{
     private val TAG = "CallingbedActivationActivity"
     val QR_CODE_PATH = "http://m.wdklian.com/care/apk/care.user?type=NCS_DEVICE"
     private val uninstallApk = false
@@ -65,6 +74,8 @@ class CallingbedActivationActivity  : BaseActivity<CallingbedActivationPresenter
     private val handler by lazy { Handler(Looper.getMainLooper()) }
     //服务器是否请求成功
     private var serverSuccess = false
+    //是否是出厂测试模式
+    private var  isFactoryTxt= false
     //是否重启
     private var cancelRestart = false
     private var offlineLoad = false
@@ -73,9 +84,15 @@ class CallingbedActivationActivity  : BaseActivity<CallingbedActivationPresenter
     private var clickTimes: Int = 1
 
     private val REQUEST_MANAGER_PERMISSION = 11
+    //是否有网络
+//    private var isserver = false
 
     var viewService: ViewService? = null
 
+
+
+
+
     override fun getLayId(): Int {
 
         val currentLanguage: String = Locale.getDefault().getLanguage()
@@ -91,6 +108,7 @@ class CallingbedActivationActivity  : BaseActivity<CallingbedActivationPresenter
         CallingbedLaunch.component.inject(this)
     }
 
+    @RequiresApi(Build.VERSION_CODES.Q)
     override fun init() {
         BaseConfig.getInstance().addActivity("WelcomeActivity", "AppUpdateActivity", "CallingbedActivity",
                 "CallingbedActivationActivity", "SystemActivity", "TextActivity",
@@ -131,6 +149,7 @@ class CallingbedActivationActivity  : BaseActivity<CallingbedActivationPresenter
 
         if(BuildConfig.device_type.equals("4")) {
             tv_data_care.visibility = View.GONE
+//            connectToWifi(activity)
         }
 
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
@@ -142,6 +161,8 @@ class CallingbedActivationActivity  : BaseActivity<CallingbedActivationPresenter
         } else {
             checkServer()
         }
+
+        setSerialListener()
     }
 
     private fun requestManagerPermission() {
@@ -179,7 +200,16 @@ class CallingbedActivationActivity  : BaseActivity<CallingbedActivationPresenter
         }
         //系统设置
         activation_system_button.setOnClickListener {
-            SystemDialogHelper.showDialog(activity, 1)
+
+            SystemDialogHelper2.showDialog(activity, object : SystemDialogHelper2.ClickListener {
+                override fun onClick() {
+                    isFactoryTxt = true
+                    val intent = Intent()
+                    intent.setClass(activity, SystemActivity::class.java)
+                    activity.startActivity(intent)
+                }
+            })
+
         }
         //服务器设置
         activation_services_button.setOnClickListener {
@@ -236,7 +266,6 @@ class CallingbedActivationActivity  : BaseActivity<CallingbedActivationPresenter
 //                //wifi管理
 ////                showMessage("Network connection failed")
 //            }
-
 //            LanguageSetDialogHelper.showDialog(activity)
         }
     }
@@ -245,9 +274,6 @@ class CallingbedActivationActivity  : BaseActivity<CallingbedActivationPresenter
         super.onResume()
         showUI()
         HardWareFactory.getHardTools().startbar(false)
-        if (BuildConfig.flag == Constant.DEV_W_A133) {
-           ZhylManager.getInstance(BaseApplication.appContext).sys_setDaemonsActivity("com.wdkl.app.ncs.callingbed2/com.wdkl.ncs.android.component.welcome.activity.WelcomeActivity", 10000, true)
-        }
         val serviceIntent = Intent(this, ViewService::class.java)
         stopService(serviceIntent)
 
@@ -257,6 +283,15 @@ class CallingbedActivationActivity  : BaseActivity<CallingbedActivationPresenter
         serverSuccess = true
         val serviceIntent = Intent(this, ViewService::class.java)
         stopService(serviceIntent)
+        if (isFactoryTxt ){
+            //主要是用了新的功能板
+            SerialPortUtil.getInstance().closeSerialPort()
+            if (BuildConfig.device_type == "4") {
+                SerialPortUtilLoar.getInstance().closeSerialPort()
+            } else {
+                SerialPortUtil433.getInstance().closeSerialPort()
+            }
+        }
     }
 
     private fun showUI(){
@@ -333,16 +368,17 @@ class CallingbedActivationActivity  : BaseActivity<CallingbedActivationPresenter
     private fun checkServer() {
         if (SettingConfig.getOfflineModeRunning(activity)) {
             Log.e(TAG, "goto offline mode...")
+            if(BuildConfig.device_type.equals("4")) {
+                return
+            }
             if (!TextUtils.isEmpty(NetHelper.getInstance().localIP)) {
                 //进入离线模式
                 AppTool.Time.delay(5000) {
                     if (!offlineLoad) {
                         offlineLoad = true
-
                         val intent = Intent()
                         intent.setClass(activity, OfflineCallingbedActivity::class.java)
                         activity.startActivity(intent)
-
                         finish()
                     }
                 }
@@ -351,7 +387,7 @@ class CallingbedActivationActivity  : BaseActivity<CallingbedActivationPresenter
             }
         } else {
             Thread {
-                while (!serverSuccess) {
+                while (!serverSuccess && !isFactoryTxt) {
                     val okHttpClient = OkHttpClient().newBuilder()
                         .connectTimeout(15 * 1000L, TimeUnit.MILLISECONDS)
                         .readTimeout(15 * 1000L, TimeUnit.MILLISECONDS)
@@ -541,10 +577,69 @@ class CallingbedActivationActivity  : BaseActivity<CallingbedActivationPresenter
         Log.e(TAG, message)
         showMessage(message)
     }
+
+
     //数据加载完成
     override fun complete(message: String, type: Int) {
 
     }
+    @RequiresApi(Build.VERSION_CODES.Q)
+    fun connectToWifi(context: Context) {
+
+        // 获取 WifiManager 实例
+        val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
+        val connectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
+
+        // 获取当前连接的网络信息
+        val currentNetwork = wifiManager.connectionInfo
+        val currentSsid = currentNetwork.ssid
+
+        // 目标网络的 SSID
+        val targetSsid = "\"xjbyjhj\""
+        // 检查设备是否已经连接到目标Wi-Fi
+        if (currentSsid != targetSsid) {
+            // 如果没有连接到目标Wi-Fi,检查Wi-Fi是否已启用
+            if (!wifiManager.isWifiEnabled) {
+                wifiManager.isWifiEnabled = true  // 开启 Wi-Fi
+            }
+
+            // 设置 Wi-Fi 网络连接的参数
+            val wifiNetworkSpecifier = WifiNetworkSpecifier.Builder()
+                    .setSsid("xjbyjhj")  // Wi-Fi SSID
+                    .setWpa2Passphrase("XJBgyyjhj123")  // Wi-Fi 密码
+                    .build()
+
+            // 创建网络请求
+            val networkRequest = NetworkRequest.Builder()
+                    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+                    .setNetworkSpecifier(wifiNetworkSpecifier)
+                    .build()
+
+            // 请求网络连接
+            connectivityManager.requestNetwork(networkRequest, object : ConnectivityManager.NetworkCallback() {
+                override fun onAvailable(network: Network) {
+                    super.onAvailable(network)
+                    // 连接成功后的操作
+                    connectivityManager.bindProcessToNetwork(network)
+                    Utils.hideStatusBar(activity, false)
+                    AppUpdateHelper.restartApp(activity)
+                    println("Successfully connected to Wi-Fi: $targetSsid")
+                }
+
+                override fun onUnavailable() {
+                    super.onUnavailable()
+                    // 连接失败后的操作
+                    println("Failed to connect to Wi-Fi: $targetSsid")
+                }
+            })
+        } else {
+            // 如果已经连接到目标Wi-Fi,直接跳过连接逻辑
+            println("Already connected to the target Wi-Fi: $targetSsid")
+        }
+
+
+
+    }
 
     //开始获取数据
     override fun start() {
@@ -562,5 +657,77 @@ class CallingbedActivationActivity  : BaseActivity<CallingbedActivationPresenter
 
         })
     }
+    //设置串口监听
+    fun setSerialListener() {
+        SerialPortUtil.getInstance().setOnDataReceiveListener(this)
+        SerialPortUtil.getInstance().setOnDataReceiveStringListener(this)
+
+        if (BuildConfig.device_type == "4") {
+            SerialPortUtilLoar.getInstance().setOnLoarDataReceiveListener(this)
+        }
+
+    }
+
+
+
+    override fun serialPortBedOnclick(buffer: ByteArray) {
+        //测试模式
+        if (Constant.isText) {
+            if (buffer[5].toInt() == 1 || buffer[5].toInt() == 2) {
+                EventBus.getDefault().post(MessageEvent("call1", Constant.EVENT_SERIAL_TEST))
+                //面板呼叫
+            } else if (buffer[8].toInt() == 1 || buffer[8].toInt() == 2) {
+                EventBus.getDefault().post(MessageEvent("call_end", Constant.EVENT_SERIAL_TEST))
+                //面板挂断
+            } else if (buffer[6].toInt() == 1 || buffer[6].toInt() == 2) {
+                //手柄按键
+                EventBus.getDefault().post(MessageEvent("call2", Constant.EVENT_SERIAL_TEST))
+            }else  if (buffer[7].toInt() == 1 || buffer[7].toInt() == 2) {
+                //紧急按钮
+                EventBus.getDefault().post(MessageEvent("call_sos", Constant.EVENT_SERIAL_TEST))
+            }
+            return
+        }
+    }
+
+    override fun serialPortBedOnclick2(status: String?) {
+        Log.d("serialPortBedOnclick", "面板按键: " + status)
+        //测试模式
+        if (Constant.isText) {
+            if (status==">") {
+                EventBus.getDefault().post(MessageEvent("button4", Constant.EVENT_SERIAL_TEST))
+            } else if (status=="5") {
+                EventBus.getDefault().post(MessageEvent("button3", Constant.EVENT_SERIAL_TEST))
+            } else if (status=="<") {
+                EventBus.getDefault().post(MessageEvent("button2", Constant.EVENT_SERIAL_TEST))
+            } else if (status==";") {
+                EventBus.getDefault().post(MessageEvent("button1", Constant.EVENT_SERIAL_TEST))
+            }
+            return
+        }
+        if (status==">") {
+            //发送sos消息
+            SerialPortUtilLoar.getInstance().sendSOS( Constant.DEVICE_REGISTER_ID)
+        }
+
+    }
+
+    override fun serialPortSOSCall(status: String?) {
+
+    }
+
+    override fun onSerialLoarData(buffer: ByteArray?, size: Int) {
+        val bytes = Arrays.copyOfRange(buffer, 0, size)
+        val receiveData: String = StringUtils.bytesToHex(bytes)
+        Log.e(TAG, "serialPortLoar: $receiveData")
+        if (Constant.isText) {
+            EventBus.getDefault().post(MessageEvent("Loar", Constant.EVENT_SERIAL_TEST))
+            return
+        }
+
+    }
+    override fun serialPortBedOnclickString(str: String) {
+
+    }
 
 }

+ 187 - 1
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/activity/CallingbedActivity.kt

@@ -32,8 +32,10 @@ import com.clj.fastble.utils.HexUtil
 import com.enation.javashop.android.jrouter.external.annotation.Router
 import com.enation.javashop.net.engine.model.NetState
 import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
 import com.jni.JniClient
 import com.konka.android.tv.XJManager
+import com.wdkl.app.ncs.callingbed.Bean.ButtonType
 import com.wdkl.app.ncs.callingbed.BuildConfig
 import com.wdkl.app.ncs.callingbed.R
 import com.wdkl.app.ncs.callingbed.agreement.CallingbedAgreement
@@ -98,6 +100,7 @@ import kotlinx.android.synthetic.main.callingbed_main_new.*
 import kotlinx.android.synthetic.main.callingbed_setting_main.*
 import kotlinx.android.synthetic.main.callingbed_test_main.*
 import kotlinx.android.synthetic.main.view_title_layout.*
+import org.apache.commons.lang3.StringEscapeUtils
 import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
@@ -106,6 +109,7 @@ import org.linphone.core.Call
 import org.linphone.core.TransportType
 import serialporttest.utils.SerialPortUtil
 import serialporttest.utils.SerialPortUtil433
+import serialporttest.utils.SerialPortUtilLoar
 import serialporttest.utils.StringUtils
 import java.io.File
 import java.io.FileOutputStream
@@ -240,6 +244,7 @@ class CallingbedActivity :BaseActivity<BedCallingbedActivityPresenter, Callingbe
     }
 
     override fun init() {
+        //打开串口
         NfcUtils.getInstance().init(this)
         mNfcAdapter= NfcUtils.getInstance().nfcAdapter
         NfcUtils.getInstance().setReadNdefListener(this)
@@ -1193,6 +1198,12 @@ class CallingbedActivity :BaseActivity<BedCallingbedActivityPresenter, Callingbe
                 SettingConfig.setOfflineMode(activity, false)
             }
 
+            //设备的按钮功能
+            //自定义角色呼叫
+            if (partSetting.deviceButtonFunction != null) {
+                Constant.device_button_function = partSetting.deviceButtonFunction
+            }
+
         } catch (ex: Exception) {
             showMessage(StringUtil.getResString(R.string.setting_params_error) + ex.message)
             ex.printStackTrace()
@@ -1506,13 +1517,146 @@ class CallingbedActivity :BaseActivity<BedCallingbedActivityPresenter, Callingbe
             }
         }
     }
+
+    override fun serialPortBedOnclick2(status: String?) {
+        Log.d("serialPortBedOnclick", "面板按键: " + status)
+        //测试模式
+        if (Constant.isText) {
+            if (status==">") {
+                EventBus.getDefault().post(MessageEvent("button4", Constant.EVENT_SERIAL_TEST))
+            } else if (status=="5") {
+                EventBus.getDefault().post(MessageEvent("button3", Constant.EVENT_SERIAL_TEST))
+            } else if (status=="<") {
+                EventBus.getDefault().post(MessageEvent("button2", Constant.EVENT_SERIAL_TEST))
+            } else if (status==";") {
+                EventBus.getDefault().post(MessageEvent("button1", Constant.EVENT_SERIAL_TEST))
+            }else if (status=="6") {
+                //手柄呼叫
+                EventBus.getDefault().post(MessageEvent("button5", Constant.EVENT_SERIAL_TEST))
+            }else if (status=="=") {
+                //换药
+                EventBus.getDefault().post(MessageEvent("button6", Constant.EVENT_SERIAL_TEST))
+            }else if (status=="?") {
+                //拔针
+                EventBus.getDefault().post(MessageEvent("button7", Constant.EVENT_SERIAL_TEST))
+            }else if (status=="@") {
+                //卫生间取消按键 需要同时发送命令关灯
+                EventBus.getDefault().post(MessageEvent("button9", Constant.EVENT_SERIAL_TEST))
+            }else if (status=="7") {
+                //卫生间按键 需要同时发送命令开灯
+                EventBus.getDefault().post(MessageEvent("button8", Constant.EVENT_SERIAL_TEST))
+            }
+            return
+        }
+        setButtonType(status)
+    }
+    /**
+     * 设置 按钮功能
+     * */
+    /**
+     * 设置 按钮功能
+     */
+    fun setButtonType(status: String?) {
+        if (Constant.device_button_function.isNullOrEmpty()) {
+            showMessage(R.string.str_set_button)
+            return
+        }
+        val jsonWithEscapes = Constant.device_button_function
+        val decodedJson = StringEscapeUtils.unescapeHtml4(jsonWithEscapes)
+        val buttonListType = object : TypeToken<List<ButtonType>>() {}.type
+        val buttonList: List<ButtonType> = Gson().fromJson(Constant.device_button_function, buttonListType)
+        val type = "KEY$status"
+        val currentTime = System.currentTimeMillis()
+
+        for (button in buttonList) {
+            if (type == button.key) {
+                when (button.type) {
+                    "SOS" -> handleSOSButton(currentTime)
+                    "VOICE" -> handleVoiceButton(button.value, currentTime)
+                    "EVENT" -> handleEventButton(button.value, currentTime)
+                    "REINFORCE" -> handleReinforceButton(currentTime)
+                    "NURSING" -> handleNursingButton(currentTime)
+                    else -> return // Ignore unknown types
+                }
+                return
+            }
+        }
+    }
+
+    private fun handleSOSButton(currentTime: Long) {
+        if (currentTime - clickTime > 2000) {
+            if (Constant.TCP_CONNECTED) {
+                val tcpModel = OtherUtil.SOSCall(Constant.DEVICE_ID)
+                TcpClient.getInstance().sendMsg(tcpModel.toJson())
+            }
+            clickTime = currentTime
+        } else {
+            showMessage(R.string.wait_moment)
+        }
+    }
+
+    private fun handleVoiceButton(value: Any?, currentTime: Long) {
+        if (currentTime - clickTime > 2000) {
+            if (Constant.TCP_CONNECTED) {
+                when {
+                    Constant.CALL_STATE != Constant.CALL_STANDBY -> showMessage("通话忙...")
+                    TextUtils.isEmpty(Constant.SIP_ID) -> showMessage(R.string.no_custom)
+                    else -> startCallRoleName(value.toString())
+                }
+            } else {
+                SerialPortUtilLoar.getInstance().sendSOS(Constant.DEVICE_REGISTER_ID)
+            }
+            clickTime = currentTime
+        } else {
+            showMessage(R.string.wait_moment)
+        }
+    }
+
+    private fun handleEventButton(value: Any?, currentTime: Long) {
+        if (currentTime - clickTime > 2000) {
+            if (Constant.TCP_CONNECTED) {
+                val tcpModel = EventUtil.eventKeyClick(Constant.DEVICE_ID, value as Int?)
+                TcpClient.getInstance().sendMsg(tcpModel.toJson())
+            }
+            clickTime = currentTime
+        } else {
+            showMessage(R.string.wait_moment)
+        }
+    }
+
+    private fun handleReinforceButton(currentTime: Long) {
+        if (currentTime - clickTime > 3000) {
+            if (Constant.TCP_CONNECTED) {
+                if (Constant.DEVICE_ID != -1) {
+                    OtherUtil.sendReinforce(Constant.DEVICE_ID)
+                    ReinforcementsDialogHelper.showDialog(activity, 1)
+                    SoundPoolManager.getInstance().playSound(4, 1.0f, 1.0f, 0)
+                } else {
+                    showMessage("null device id!")
+                }
+            } else {
+                showMessage(R.string.net_error)
+            }
+            clickTime = currentTime
+        } else {
+            showMessage(R.string.wait_moment)
+        }
+    }
+
+    private fun handleNursingButton(currentTime: Long) {
+        if (currentTime - clickTime > 2000) {
+            // YhUtil.sendReinforceResponsed(Constant.DEVICE_ID) // Uncomment if needed
+            clickTime = currentTime
+        } else {
+            showMessage(R.string.wait_moment)
+        }
+    }
     private var trans433Data: Trans433Data? = null
     //433串口处理
     override fun onSerial433Data(buffer: ByteArray?, size: Int) {
         val bytes = Arrays.copyOfRange(buffer, 0, size)
         val receiveData: String = StringUtils.bytesToHex(bytes)
         Log.e(TAG, "onSerial433Data: $receiveData")
-
         try {
             if (receiveData.startsWith("fd") && receiveData.endsWith("df")) {
                 //当前系统时间
@@ -1633,7 +1777,49 @@ class CallingbedActivity :BaseActivity<BedCallingbedActivityPresenter, Callingbe
             showMessage(R.string.custom_empty)
         }
     }
+    fun startCallRoleName(roleType: String) {
+        if (Constant.DEVICE_STATUS == 0) {
+            showMessage(R.string.device_disable)
+            return
+        }
 
+        if (Constant.CUSTOM_ID != -1) {
+            if (playing) {
+                stopBroadcast(true)
+            }
+
+            //通话之前先判断webrtc socket和tcp是否连接正常,否则不能建立通话
+            if (Constant.TCP_CONNECTED && !TextUtils.isEmpty(Constant.SIP_ID)) {
+                //去电界面
+                Constant.CALL_TYPE = Constant.VOICE_CALL
+                Constant.CALL_STATE = Constant.CALL_OUTGOING
+                if (SettingConfig.getSipEnabled(activity)) {
+                    val intent = Intent(activity, CallingActivity::class.java)
+                    intent.putExtra(Constant.calling_type, 1)
+                    intent.putExtra(Constant.calling_state, 0)
+                    intent.putExtra(Constant.role_id, -1)
+                    intent.putExtra(Constant.role_type, roleType)
+                    intent.putExtra(Constant.call_device_id, -1)
+                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                    startActivity(intent)
+                } else {
+                    val intent = Intent(activity, CallingActivity::class.java)
+                    intent.putExtra(Constant.calling_type, 0)
+                    intent.putExtra(Constant.calling_state, 0)
+                    intent.putExtra(Constant.bc_play, broadcastOn)
+                    intent.putExtra(Constant.role_id, -1)
+                    intent.putExtra(Constant.role_type, roleType)
+                    intent.putExtra(Constant.call_device_id, -1)
+                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                    startActivity(intent)
+                }
+            } else {
+                showMessage(R.string.call_init_error)
+            }
+        } else {
+            showMessage(R.string.custom_empty)
+        }
+    }
     @Subscribe(threadMode = ThreadMode.MAIN)
     fun onMoonEvent(messageEvent: MessageEvent) {
         //代码同步

+ 175 - 150
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/activity/CallingbedDormitoryActivity.kt

@@ -25,6 +25,8 @@ import com.clj.fastble.utils.HexUtil
 import com.enation.javashop.android.jrouter.external.annotation.Router
 import com.enation.javashop.net.engine.model.NetState
 import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.wdkl.app.ncs.callingbed.Bean.ButtonType
 import com.wdkl.app.ncs.callingbed.BuildConfig
 import com.wdkl.app.ncs.callingbed.R
 import com.wdkl.app.ncs.callingbed.agreement.CallingbedAgreement
@@ -33,6 +35,7 @@ import com.wdkl.app.ncs.callingbed.bt_gateway.*
 import com.wdkl.app.ncs.callingbed.databinding.CallingbedMainDormBinding
 import com.wdkl.app.ncs.callingbed.dialog.ReinforcementsDialogHelper
 import com.wdkl.app.ncs.callingbed.fragment.*
+import com.wdkl.app.ncs.callingbed.hardware.HardWareFactory
 import com.wdkl.app.ncs.callingbed.helper.*
 import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
 import com.wdkl.app.ncs.callingbed.settings.SettingConfig
@@ -45,6 +48,7 @@ import com.wdkl.ncs.android.lib.core.locale.SettingConfigNew
 import com.wdkl.ncs.android.lib.utils.*
 import com.wdkl.ncs.android.lib.vo.filter
 import com.wdkl.ncs.android.middleware.api.UrlManager
+import com.wdkl.ncs.android.middleware.bean.Trans433Data
 import com.wdkl.ncs.android.middleware.common.Constant
 import com.wdkl.ncs.android.middleware.common.MessageEvent
 import com.wdkl.ncs.android.middleware.common.SipStatus
@@ -59,10 +63,7 @@ import com.wdkl.ncs.android.middleware.model.dos.RoleDO
 import com.wdkl.ncs.android.middleware.model.dto.TcpSeverDTO
 import com.wdkl.ncs.android.middleware.model.vo.*
 import com.wdkl.ncs.android.middleware.tcp.TcpClient
-import com.wdkl.ncs.android.middleware.tcp.channel.ImUtil
-import com.wdkl.ncs.android.middleware.tcp.channel.OtherUtil
-import com.wdkl.ncs.android.middleware.tcp.channel.VideoUtil
-import com.wdkl.ncs.android.middleware.tcp.channel.VoiceUtil
+import com.wdkl.ncs.android.middleware.tcp.channel.*
 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
@@ -74,14 +75,14 @@ import com.wdkl.ncs.janus.client.StreamingCallback
 import com.wdkl.ncs.janus.rtc.WebRTCEngine
 import com.wdkl.ncs.janus.util.JanusConstant
 import kotlinx.android.synthetic.main.callingbed_main_dorm.*
+import org.apache.commons.lang3.StringEscapeUtils
 import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
 import org.linphone.core.Call
 import org.linphone.core.TransportType
 import serialporttest.utils.SerialPortUtil
-import java.io.File
-import java.io.FileOutputStream
+import serialporttest.utils.SerialPortUtilLoar
 import java.util.*
 import kotlin.collections.ArrayList
 
@@ -92,7 +93,7 @@ import kotlin.collections.ArrayList
 
 @Router(path = "/dormitoryActivity/main")
 class CallingbedDormitoryActivity :BaseActivity<BedCallingbedActivityPresenter, CallingbedMainDormBinding>(), BedCallingbedActivityContract.View, CallingbedAgreement,
-    SerialPortUtil.ISerialPortBedOnclickEvent, SerialPortUtil.ISerialPortBedOnclickString, DataParse.OnDataCallback {
+    SerialPortUtil.ISerialPortBedOnclickEvent,  SerialPortUtilLoar.ISerialPortLoarData,DataParse.OnDataCallback {
     var TAG = CallingbedDormitoryActivity::class.java.getSimpleName()
 
     private lateinit var receiver: TimeReceiver
@@ -180,6 +181,7 @@ class CallingbedDormitoryActivity :BaseActivity<BedCallingbedActivityPresenter,
     }
 
     override fun init() {
+        //打开串口
         language = LocaleMangerUtils.getApplicationLocale().language
 
         //设置主题背景
@@ -267,7 +269,7 @@ class CallingbedDormitoryActivity :BaseActivity<BedCallingbedActivityPresenter,
         brightenTheScreenBroadcastReceiver()
         RecordHelper.getInstance().init()
         EventBus.getDefault().register(this)
-
+        HardWareFactory.getHardTools().setSerial2(this)
         SoundPoolManager.getInstance().init()
 
         //更新状态图标
@@ -308,48 +310,6 @@ class CallingbedDormitoryActivity :BaseActivity<BedCallingbedActivityPresenter,
     }
 
 
-    private fun updateLaunchApk() {
-        Thread {
-            val apkName = "launch.apk"
-            copyAssetsToDst(applicationContext, apkName, Environment.getExternalStorageDirectory().path + "/" + Environment.DIRECTORY_DOWNLOADS)
-            if (copyDone) {
-                val fileName = Environment.getExternalStorageDirectory().path + "/" + Environment.DIRECTORY_DOWNLOADS + "/" + apkName
-                //升级
-                AppUpdateHelper.rootSilenceInstall(fileName)
-                //5分钟后重启设备
-                AppTool.Time.delay(300000) {
-                    AppUpdateHelper.reboot(BaseApplication.appContext)
-                }
-            }
-        }.start()
-    }
-
-    //拷贝assets下面的文件到sd卡
-    private fun copyAssetsToDst(context: Context, fileName: String, dstPath: String) {
-        try {
-            copyDone = false
-            val file = File(dstPath)
-            if (!file.exists()) {
-                file.mkdirs()
-            }
-            val outFile = File("$dstPath/$fileName")
-            val `is` = context.assets.open(fileName)
-            val fos = FileOutputStream(outFile)
-            val buffer = ByteArray(1024)
-            var byteCount: Int
-            while (`is`.read(buffer).also { byteCount = it } != -1) {
-                fos.write(buffer, 0, byteCount)
-            }
-            fos.flush()
-            `is`.close()
-            fos.close()
-            copyDone = true
-        } catch (e: java.lang.Exception) {
-            copyDone = false
-            e.printStackTrace()
-        }
-    }
-
     private fun showMsgMain(msg: String) {
         runOnUiThread {
             showMessage(msg)
@@ -468,7 +428,7 @@ class CallingbedDormitoryActivity :BaseActivity<BedCallingbedActivityPresenter,
     //设置串口监听
      fun setSerialListener() {
         SerialPortUtil.getInstance().setOnDataReceiveListener(this)
-        SerialPortUtil.getInstance().setOnDataReceiveStringListener(this)
+        SerialPortUtilLoar.getInstance().setOnLoarDataReceiveListener(this)
     }
 
     override fun checkAppVersion() {
@@ -508,8 +468,7 @@ class CallingbedDormitoryActivity :BaseActivity<BedCallingbedActivityPresenter,
         EventBus.getDefault().unregister(this)
         Constant.CALL_STATE = Constant.CALL_STANDBY
         SOSHelper.sosStop()
-        SerialPortUtil.getInstance().closeHeart()
-        SerialPortUtil.getInstance().closeSerialPort()
+        HardWareFactory.getHardTools().unInit()
         handler.removeCallbacksAndMessages(null)
         stopBroadcast(false)
         SoundPoolManager.getInstance().release()
@@ -609,7 +568,7 @@ class CallingbedDormitoryActivity :BaseActivity<BedCallingbedActivityPresenter,
     override fun showCallRecords(record: CallRecordVO) {
         //
     }
-
+    //科室设置
     override fun setPartSettings(partSetting: PartSettingDO) {
         try {
             //设置白昼起止时间
@@ -671,6 +630,11 @@ class CallingbedDormitoryActivity :BaseActivity<BedCallingbedActivityPresenter,
             if (partSetting.customizeRoleCallThird != null) {
                 Constant.customize_role_call_3 = partSetting.customizeRoleCallThird
             }
+            //设备的按钮功能
+            //自定义角色呼叫
+            if (partSetting.deviceButtonFunction != null) {
+                Constant.device_button_function = partSetting.deviceButtonFunction
+            }
 
         } catch (ex: Exception) {
             showMessage(StringUtil.getResString(R.string.setting_params_error) + ex.message)
@@ -679,6 +643,7 @@ class CallingbedDormitoryActivity :BaseActivity<BedCallingbedActivityPresenter,
 
         updateSettings(true)
 
+
         EventBus.getDefault().post(MessageEvent("updateCustom", Constant.EVENT_UPDATE_CUSTOM))
 
         //配置sip账号并连接sip服务器
@@ -893,120 +858,179 @@ class CallingbedDormitoryActivity :BaseActivity<BedCallingbedActivityPresenter,
         registerReceiver(receiver, intentFilter)
     }
 
-    private fun unRegReceiver() {
-        unregisterReceiver(receiver)
+    /**
+     * 设置 按钮功能
+     * */
+    /**
+     * 设置 按钮功能
+     */
+    fun setButtonType(status: String?) {
+        if (Constant.device_button_function.isNullOrEmpty()) {
+            showMessage(R.string.str_set_button)
+            return
+        }
+        val jsonWithEscapes = Constant.device_button_function
+        val decodedJson = StringEscapeUtils.unescapeHtml4(jsonWithEscapes)
+        val buttonListType = object : TypeToken<List<ButtonType>>() {}.type
+        val buttonList: List<ButtonType> = Gson().fromJson(decodedJson, buttonListType)
+        val type = "KEY$status"
+        val currentTime = System.currentTimeMillis()
+
+        for (button in buttonList) {
+            if (type == button.key) {
+                when (button.type) {
+                    "SOS" -> handleSOSButton(currentTime)
+                    "VOICE" -> handleVoiceButton(button.value, currentTime)
+                    "EVENT" -> handleEventButton(button.value, currentTime)
+                    "REINFORCE" -> handleReinforceButton(currentTime)
+                    "NURSING" -> handleNursingButton(currentTime)
+                    else -> return // Ignore unknown types
+                }
+                return
+            }
+        }
     }
 
-    override fun serialPortBedOnclick(buffer: ByteArray) {
-        Log.d("serialPortBedOnclick", "buffer[0]:" + buffer[0] + ", buffer[1]:" + buffer[1] + ", buffer[2]:" + buffer[2]
-                + ", buffer[3]:" + buffer[3] + ", buffer[4]:" + buffer[4] + ", buffer[5]:" + buffer[5] + ", buffer[6]:" + buffer[6]
-                + ", buffer[7]:" + buffer[7] + ", buffer[8]:" + buffer[8])
-        //测试模式
-        if (Constant.isText) {
-            if (buffer[5].toInt() == 1 || buffer[5].toInt() == 2) {
-                EventBus.getDefault().post(MessageEvent("call1", Constant.EVENT_SERIAL_TEST))
-                //面板呼叫
-            } else if (buffer[8].toInt() == 1 || buffer[8].toInt() == 2) {
-                EventBus.getDefault().post(MessageEvent("call_end", Constant.EVENT_SERIAL_TEST))
-                //面板挂断
-            } else if (buffer[6].toInt() == 1 || buffer[6].toInt() == 2) {
-                //手柄按键
-                EventBus.getDefault().post(MessageEvent("call2", Constant.EVENT_SERIAL_TEST))
-            }else  if (buffer[7].toInt() == 1 || buffer[7].toInt() == 2) {
-                //紧急按钮
-                EventBus.getDefault().post(MessageEvent("call_sos", Constant.EVENT_SERIAL_TEST))
-            }
-            return
+    private fun handleSOSButton(currentTime: Long) {
+        if (currentTime - clickTime > 2000) {
+        if (Constant.TCP_CONNECTED) {
+            val tcpModel = OtherUtil.SOSCall(Constant.DEVICE_ID)
+            TcpClient.getInstance().sendMsg(tcpModel.toJson())
         }
+            clickTime = currentTime
+        } else {
+            showMessage(R.string.wait_moment)
+        }
+    }
 
-        if (buffer[5].toInt() == 1 || buffer[5].toInt() == 2) {
-            //面板呼叫键
-            //大朝华改为获取系统按键code,注销掉
-            if (Constant.NursingTitle.equals(getString(R.string.enter_nursing)))  return
-            runOnUiThread {
-                if (Constant.CALL_STATE == Constant.CALL_STANDBY) {
-                    if (!TextUtils.isEmpty(Constant.SIP_ID)) {
-                        startCall(Constant.VOICE_CALL)
-                    } else {
-                        showMessage(R.string.no_custom)
-                    }
-                } else if (Constant.CALL_STATE == Constant.CALL_INCOMING) {
-                    //来电接听
-                    EventBus.getDefault().post(MessageEvent("accept", Constant.EVENT_SERIAL_EVENT))
+    private fun handleVoiceButton(value: Any?, currentTime: Long) {
+        if (currentTime - clickTime > 2000) {
+            if (Constant.TCP_CONNECTED) {
+                when {
+                    Constant.CALL_STATE != Constant.CALL_STANDBY -> showMessage("通话忙...")
+                    TextUtils.isEmpty(Constant.SIP_ID) -> showMessage(R.string.no_custom)
+                    else -> startCallRoleName(value.toString())
                 }
+            } else {
+                SerialPortUtilLoar.getInstance().sendSOS(Constant.DEVICE_REGISTER_ID)
             }
-        } else if (buffer[8].toInt() == 1 || buffer[8].toInt() == 2) {
-            //面板挂断键
-            runOnUiThread {
-                if (Constant.CALL_STATE == Constant.CALL_CALLING) {
-                    //通话中挂断
-                    EventBus.getDefault().post(MessageEvent("handoff", Constant.EVENT_SERIAL_EVENT))
-                } else if (Constant.CALL_STATE == Constant.CALL_OUTGOING) {
-                    //呼叫取消
-                    EventBus.getDefault().post(MessageEvent("cancel", Constant.EVENT_SERIAL_EVENT))
-                } else if (Constant.CALL_STATE == Constant.CALL_INCOMING) {
-                    //来电拒接
-                    EventBus.getDefault().post(MessageEvent("reject", Constant.EVENT_SERIAL_EVENT))
-                }
+            clickTime = currentTime
+        } else {
+            showMessage(R.string.wait_moment)
+        }
+    }
+
+    private fun handleEventButton(value: Any?, currentTime: Long) {
+        if (currentTime - clickTime > 2000) {
+            if (Constant.TCP_CONNECTED) {
+                val tcpModel = EventUtil.eventKeyClick(Constant.DEVICE_ID, value.toString().toDouble().toInt())
+                TcpClient.getInstance().sendMsg(tcpModel.toJson())
             }
-        } else if (buffer[6].toInt() == 1 || buffer[6].toInt() == 2) {
+            clickTime = currentTime
+        } else {
+            showMessage(R.string.wait_moment)
+        }
+    }
 
-            if ( Constant.NursingTitle .equals(getString(R.string.enter_nursing))){
-                if (Constant.CALL_STATE == Constant.CALL_CALLING) {
-                    //通话中挂断
-                    EventBus.getDefault().post(MessageEvent("handoff", Constant.EVENT_SERIAL_EVENT))
-                }
-            }else {
-                //手柄按键
-                runOnUiThread {
-                    if (Constant.CALL_STATE == Constant.CALL_STANDBY) {
-                        if (!TextUtils.isEmpty(Constant.SIP_ID)) {
-                            startCall(Constant.VOICE_CALL)
-                        } else {
-                            showMessage(R.string.no_custom)
-                        }
-                    } else if (Constant.CALL_STATE == Constant.CALL_INCOMING) {
-                        //来电接听
-                        EventBus.getDefault().post(MessageEvent("accept", Constant.EVENT_SERIAL_EVENT))
-                    } else if (Constant.CALL_STATE == Constant.CALL_CALLING) {
-                        //通话中挂断
-                        EventBus.getDefault().post(MessageEvent("handoff", Constant.EVENT_SERIAL_EVENT))
-                    } else if (Constant.CALL_STATE == Constant.CALL_OUTGOING) {
-                        //呼叫取消
-                        EventBus.getDefault().post(MessageEvent("cancel", Constant.EVENT_SERIAL_EVENT))
-                    }
+    private fun handleReinforceButton(currentTime: Long) {
+        if (currentTime - clickTime > 3000) {
+            if (Constant.TCP_CONNECTED) {
+                if (Constant.DEVICE_ID != -1) {
+                    OtherUtil.sendReinforce(Constant.DEVICE_ID)
+                    ReinforcementsDialogHelper.showDialog(activity, 1)
+                    SoundPoolManager.getInstance().playSound(4, 1.0f, 1.0f, 0)
+                } else {
+                    showMessage("null device id!")
                 }
+            } else {
+                showMessage(R.string.net_error)
             }
+            clickTime = currentTime
+        } else {
+            showMessage(R.string.wait_moment)
+        }
+    }
 
-        } else if (buffer[7].toInt() == 1 || buffer[7].toInt() == 2) {
-            //卫生间紧急按钮: 一定时间内重复多次按无效
-            if (System.currentTimeMillis() - clickSosTime > 10000) {
-                runOnUiThread {
-                    clickSosTime = System.currentTimeMillis()
-                    if (Constant.TCP_CONNECTED) {
-                        SOSHelper.sosStart()
-                    }
-                }
+    private fun handleNursingButton(currentTime: Long) {
+        if (currentTime - clickTime > 2000) {
+            // YhUtil.sendReinforceResponsed(Constant.DEVICE_ID) // Uncomment if needed
+            clickTime = currentTime
+        } else {
+            showMessage(R.string.wait_moment)
+        }
+    }
+
+
+    private fun unRegReceiver() {
+        unregisterReceiver(receiver)
+    }
+
+    override fun serialPortBedOnclick(buffer: ByteArray) {
+
+    }
+
+    override fun serialPortBedOnclick2(status: String?) {
+        Log.d("serialPortBedOnclick", "面板按键: " + status)
+        //测试模式
+        if (Constant.isText) {
+            if (status==">") {
+                EventBus.getDefault().post(MessageEvent("button4", Constant.EVENT_SERIAL_TEST))
+            } else if (status=="5") {
+                EventBus.getDefault().post(MessageEvent("button3", Constant.EVENT_SERIAL_TEST))
+            } else if (status=="<") {
+                EventBus.getDefault().post(MessageEvent("button2", Constant.EVENT_SERIAL_TEST))
+            } else if (status==";") {
+                EventBus.getDefault().post(MessageEvent("button1", Constant.EVENT_SERIAL_TEST))
             }
+            return
         }
+        setButtonType(status)
     }
 
     override fun serialPortSOSCall(status: String?) {
 
     }
+    private var trans433Data: Trans433Data? = null
+    override fun onSerialLoarData(buffer: ByteArray?, size: Int) {
 
-    override fun serialPortBedOnclickString(str: String) {
+        val receiveData = String(buffer!!, 0, size)
+        Log.d(TAG, "onSerialLoarData: " + receiveData)
+        if (Constant.isText) {
+            EventBus.getDefault().post(MessageEvent("Loar", Constant.EVENT_SERIAL_TEST))
+            return
+        }
         try {
-            val newStr = str.substring(str.indexOf("$") + 1, str.indexOf("#"))
-            Log.d("serialPort", "newStr==$newStr")
-            if (newStr.startsWith("V")) {
-                Constant.MCU_VERSION_NUMBER = newStr.substring(newStr.indexOf(",") + 1, 16)
+            if (receiveData.contains("$") && receiveData.contains("#")) {
+                //当前系统时间
+                val curTime = System.currentTimeMillis()
+                //收到的按键数据掐头去尾: fdb50831df --> b50831
+                val cmd = BluetoothUtil.strTo16(receiveData.substring(1, receiveData.indexOf("#")))
+//                val cmd = receiveData
+                if (trans433Data != null) {
+                    //如果与上次数据相同,1500毫秒内不再重复发
+                    if (trans433Data!!.cmd == cmd && curTime - trans433Data!!.time < 1500) {
+                        return
+                    }
+                    trans433Data!!.time = curTime
+                    trans433Data!!.cmd = cmd
+                } else {
+                    trans433Data = Trans433Data(curTime, cmd)
+                }
+                //发送数据: ffcc020006b50831
+                if (Constant.TCP_CONNECTED && !TextUtils.isEmpty(trans433Data!!.cmd)) {
+                    TcpClient.getInstance().sendMsg(AlarmMessageUtil.getAlarmMessage2(trans433Data!!.cmd))
+                }
+            }else{
+//                Log.e(TAG, "onSerialLoarData 数据结构不对: "+receiveData)
             }
-        } catch (e: Exception) {
-            e.printStackTrace()
+        } catch (ex: Exception) {
+            ex.printStackTrace()
         }
+
     }
 
+
+
     //开始呼叫
      fun startCall(type: Int) {
         if (Constant.DEVICE_STATUS == 0) {
@@ -1296,12 +1320,12 @@ class CallingbedDormitoryActivity :BaseActivity<BedCallingbedActivityPresenter,
                             if (!responsed.contains(interactionVO.id)) { //没播报过的才播报
                                 if (Locale.CHINESE.getLanguage().equals(language)) {
                                     val speakStr = (interactionVO.actionEndMemberName
-                                        ?: "") + "已响应紧急呼叫//正在赶来"
+                                            ?: "") + "已响应紧急呼叫//正在赶来"
                                     SpeechUtil.getInstance().stopSpeak()
                                     SpeechUtil.getInstance().speak(speakStr)
                                 }
                                 responsed.add(interactionVO.id)
-                            }else if (tcpModel.action == TcpAction.SOSAction.CALL) { //遥控器按键按下
+                            } else if (tcpModel.action == TcpAction.SOSAction.CALL) { //遥控器按键按下
                                 if (Locale.CHINESE.getLanguage().equals(language)) {
                                     SpeechUtil.getInstance().stopSpeak()
                                     SpeechUtil.getInstance().speak("紧急呼叫已发出")
@@ -1334,7 +1358,7 @@ class CallingbedDormitoryActivity :BaseActivity<BedCallingbedActivityPresenter,
                             checkAppVersion()
                         } else if (tcpModel.action == TcpAction.DeviceAction.RESTART) {
                             //后台做了重发此消息的机制.防止网络不好的时候没收到app重启,设备信息不刷新
-                            if(!TextUtils.isEmpty(tcpModel.tid)) {
+                            if (!TextUtils.isEmpty(tcpModel.tid)) {
                                 TcpClient.getInstance().sendMsg(tcpModel.toJson())
                             }
                             Util.wakeUpAndUnlock()
@@ -1415,7 +1439,7 @@ class CallingbedDormitoryActivity :BaseActivity<BedCallingbedActivityPresenter,
                             if (!responsed.contains(interactionVO.id)) { //已响应过的事件不在播报
                                 if (Locale.CHINESE.getLanguage().equals(language)) {
                                     val speakStr = (interactionVO.actionEndMemberName
-                                        ?: "") + "已响应" + interactionVO.data + "//请稍候"
+                                            ?: "") + "已响应" + interactionVO.data + "//请稍候"
                                     SpeechUtil.getInstance().stopSpeak()
                                     SpeechUtil.getInstance().speak(speakStr)
                                 } else {
@@ -1440,7 +1464,7 @@ class CallingbedDormitoryActivity :BaseActivity<BedCallingbedActivityPresenter,
                             val tcpModelRead = ImUtil.imRead(Constant.DEVICE_ID, interactionVO.fromDeviceId, interactionVO.id)
                             TcpClient.getInstance().sendTcp(tcpModelRead, false, null)
                         }
-                    }else if (tcpModel.action == TcpAction.EventAction.KEY_CLICK && tcpModel.type == TcpType.EVENT) { //遥控器按键发送,分机播报
+                    } else if (tcpModel.action == TcpAction.EventAction.KEY_CLICK && tcpModel.type == TcpType.EVENT) { //遥控器按键发送,分机播报
                         val interactionVO = Gson().fromJson(tcpModel.data.toString(), InteractionVO::class.java)
                         if (Locale.CHINESE.getLanguage().equals(language)) {
                             val speakStr = "已发送" + interactionVO.data + "事件//请耐心等待"
@@ -1784,7 +1808,6 @@ class CallingbedDormitoryActivity :BaseActivity<BedCallingbedActivityPresenter,
 
     private fun updateSettings(forceSet: Boolean) {
         val  currentTimestamp = System.currentTimeMillis()
-
         //白天起始时间戳
         val date = TimeHandle.getDateTime("yyyy-MM-dd")
         val dayStartTimeStamp = TimeHandle.dateToStamp(date + " " + SettingConfig.getInitialDayTime(this) + ":00", "yyyy-MM-dd HH:mm:ss")
@@ -2204,4 +2227,6 @@ class CallingbedDormitoryActivity :BaseActivity<BedCallingbedActivityPresenter,
         override fun onServiceDisconnected(componentName: ComponentName) {}
     }
 
+
+
 }

+ 5 - 0
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/activity/CallingbedMomActivity.kt

@@ -42,6 +42,7 @@ import com.wdkl.app.ncs.callingbed.databinding.CallingbedMainMomBinding
 import com.wdkl.app.ncs.callingbed.dialog.ReinforcementsDialogHelper
 import com.wdkl.app.ncs.callingbed.dialog.SystemDialogHelper
 import com.wdkl.app.ncs.callingbed.fragment.*
+import com.wdkl.app.ncs.callingbed.hardware.HardWareFactory
 import com.wdkl.app.ncs.callingbed.helper.*
 import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
 import com.wdkl.app.ncs.callingbed.settings.SettingConfig
@@ -1114,6 +1115,10 @@ class CallingbedMomActivity :BaseActivity<BedCallingbedActivityPresenter, Callin
         }
     }
 
+    override fun serialPortBedOnclick2(status: String?) {
+      //新功能板
+    }
+
     override fun serialPortSOSCall(status: String?) {
 
     }

+ 58 - 0
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/activity/OfflineCallingbedActivity.kt

@@ -47,6 +47,7 @@ import com.wdkl.ncs.android.middleware.model.dos.PartSettingDO
 import com.wdkl.ncs.android.middleware.model.dos.RoleDO
 import com.wdkl.ncs.android.middleware.model.dto.TcpSeverDTO
 import com.wdkl.ncs.android.middleware.model.vo.*
+import com.wdkl.ncs.android.middleware.tcp.TcpClient
 import com.wdkl.ncs.android.middleware.tcp.channel.*
 import com.wdkl.ncs.android.middleware.udp2.UdpHelper
 import com.wdkl.ncs.android.middleware.udp2.UdpIndex
@@ -617,6 +618,63 @@ class OfflineCallingbedActivity :BaseActivity<BedCallingbedActivityPresenter, Ca
         }
     }
 
+    override fun serialPortBedOnclick2(status: String?) {
+        Log.d("serialPortBedOnclick", "面板按键: " + status)
+        //测试模式
+        if (Constant.isText) {
+            if (status==">") {
+                EventBus.getDefault().post(MessageEvent("button4", Constant.EVENT_SERIAL_TEST))
+            } else if (status=="5") {
+                EventBus.getDefault().post(MessageEvent("button3", Constant.EVENT_SERIAL_TEST))
+            } else if (status=="<") {
+                EventBus.getDefault().post(MessageEvent("button2", Constant.EVENT_SERIAL_TEST))
+            } else if (status==";") {
+                EventBus.getDefault().post(MessageEvent("button1", Constant.EVENT_SERIAL_TEST))
+            }
+            return
+        }
+
+        if (status==">") {
+            //面板呼叫键
+            //呼叫
+            val time = System.currentTimeMillis()
+            if (time - clickTime > 2000) {
+                if (Constant.CALL_STATE == Constant.CALL_STANDBY) {
+                    if (!TextUtils.isEmpty(Constant.SIP_ID)) {
+                        startCall(Constant.VOICE_CALL)
+                    } else {
+                        showMessage(R.string.no_custom)
+                    }
+                } else {
+                    showMessage("通话忙...")
+                }
+
+                clickTime = time
+            } else {
+                showMessage(R.string.wait_moment)
+            }
+
+        } else if (status=="5") {
+            //面板取消
+            if (Constant.TCP_CONNECTED) {
+                val tcpModel = OtherUtil.SOSCall(Constant.DEVICE_ID)
+                TcpClient.getInstance().sendMsg(tcpModel.toJson())
+            }
+        } else if (status=="<") {
+            //面板增援
+            if (Constant.TCP_CONNECTED) {
+                val tcpModel = EventUtil.eventKeyClick(Constant.DEVICE_ID, 3)
+                TcpClient.getInstance().sendMsg(tcpModel.toJson())
+            }
+        } else if (status==";") {
+            //面板护理
+            if (Constant.TCP_CONNECTED) {
+                val tcpModel = EventUtil.eventKeyClick(Constant.DEVICE_ID, 2)
+                TcpClient.getInstance().sendMsg(tcpModel.toJson())
+            }
+        }
+    }
+
     //433串口处理
     override fun onSerial433Data(buffer: ByteArray?, size: Int) {
 

+ 3 - 4
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/activity/SystemActivity.kt

@@ -56,10 +56,9 @@ class SystemActivity : BaseActivity<SystemActivityPresenter, CallingbedSettingMa
 
     override fun init() {
         showui()
-
-        if(BuildConfig.device_type.equals("4")) {
-            settings_main_top_3_ll.visibility = View.GONE
-        }
+//        if(BuildConfig.device_type.equals("4")) {
+//            settings_main_top_3_ll.visibility = View.GONE
+//        }
     }
 
     override fun bindEvent() {

+ 39 - 14
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/activity/TextActivity.kt

@@ -1,6 +1,8 @@
 package com.wdkl.app.ncs.callingbed.activity
 
+import android.content.Intent
 import android.hardware.Camera
+import android.util.Log
 import android.view.KeyEvent
 import android.view.SurfaceHolder
 import android.view.View
@@ -30,6 +32,9 @@ import kotlinx.android.synthetic.main.view_title_layout.*
 import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
+import serialporttest.utils.SerialPortUtil
+import serialporttest.utils.SerialPortUtilLoar
+import java.util.*
 
 class TextActivity : BaseActivity<BedTextActivityPresenter, CallingbedTestMainBinding>(), BedTextActivityContract.View {
 
@@ -52,6 +57,8 @@ class TextActivity : BaseActivity<BedTextActivityPresenter, CallingbedTestMainBi
 
     override fun init() {
         Constant.isText=true
+        LinphoneManager.sipTesting = true
+        linphoneManager = LinphoneManager.getInstance(BaseApplication.appContext)
 
         showui()
         RecordHelper.getInstance().init()
@@ -107,6 +114,12 @@ class TextActivity : BaseActivity<BedTextActivityPresenter, CallingbedTestMainBi
                 //
             }
         }
+        sos_button.setOnClickListener {
+            finish()
+            val intent = Intent()
+            intent.setClass(activity, AppTextActivity::class.java)
+            activity.startActivity(intent)
+        }
     }
 
     override fun destory() {
@@ -117,21 +130,12 @@ class TextActivity : BaseActivity<BedTextActivityPresenter, CallingbedTestMainBi
         }
     }
 
-    fun setfuq(){
-        settings_main_10_tx.text= CommonUtils.getUrl(this)
-        showMessage(R.string.reboot_register)
-    }
 
     private fun showui(){
         view_title_layout_tv_hospital_name.setText(R.string.str_back)
         view_title_layout_img.visibility = View.VISIBLE
         view_title_layout_tv_no.visibility =View.VISIBLE
         view_title_layout_tv_no.setText(R.string.device_test)
-        if (BuildConfig.FLAVOR.equals("rk3128")){
-            text_ll_2.visibility =View.GONE
-        }else if (BuildConfig.FLAVOR.equals("dch_7")){
-            text_ll_4.visibility =View.GONE
-        }
         text_sbaj_button.setBackgroundResource(R.drawable.shape_main_hos_txt_bg)
         sbaj_img.visibility=View.INVISIBLE
         text_sbqx_button.setBackgroundResource(R.drawable.shape_main_hos_txt_bg)
@@ -144,6 +148,18 @@ class TextActivity : BaseActivity<BedTextActivityPresenter, CallingbedTestMainBi
         sos_img.visibility=View.INVISIBLE
         lycs_button.setBackgroundResource(R.drawable.shape_main_hos_txt_bg)
         lycs_img.visibility=View.INVISIBLE
+        if (BuildConfig.FLAVOR.equals("rk3128")){
+            text_ll_2.visibility =View.GONE
+        }else if (BuildConfig.FLAVOR.equals("dch_7")){
+            text_ll_4.visibility =View.GONE
+        }
+        if (BuildConfig.device_type == "4"){
+            text_sbaj_button.text = "按键1测试"
+            text_sbqx_button.text = "按键2测试"
+            mbhj_button.text = "按键3测试"
+            mbhjqx_button.text = "SOS按键测试"
+            sos_button.text = "相机测试"
+        }
 
         //网络图标
         if ( Constant.network_state == 1){
@@ -268,7 +284,8 @@ class TextActivity : BaseActivity<BedTextActivityPresenter, CallingbedTestMainBi
     fun onMoonEvent(messageEvent: MessageEvent) {
         if (Constant.EVENT_SERIAL_TEST == messageEvent.type) {
             val message = messageEvent.message as String
-           if (message == "call1" || message == "dch_mb_zy") {
+            Log.d("serialPortBedOnclick", "面板按键: " + message)
+           if (message == "call1" || message == "dch_mb_zy"|| message == "button3") {
                //面版增援/呼叫按键
                mbhj_button.setBackgroundResource(R.drawable.shape_reinforcements_dialog_bt_bg)
                mbh_img.visibility=View.VISIBLE
@@ -277,15 +294,15 @@ class TextActivity : BaseActivity<BedTextActivityPresenter, CallingbedTestMainBi
                SerialPortHelper.setSosLight("2")
                sos_button.setBackgroundResource(R.drawable.shape_reinforcements_dialog_bt_bg)
                sos_img.visibility=View.VISIBLE
-           }else if(message == "call2"|| message == "dch_sb_h"){
+           }else if(message == "call2"|| message == "dch_sb_h"|| message == "button1"){
                //手柄按键或者呼叫
                text_sbaj_button.setBackgroundResource(R.drawable.shape_reinforcements_dialog_bt_bg)
                sbaj_img.visibility=View.VISIBLE
-           }else if(message == "call_end"){
+           }else if(message == "call_end"|| message == "button4"){
                //面板挂断
                mbhjqx_button.setBackgroundResource(R.drawable.shape_reinforcements_dialog_bt_bg)
                mbhjjqx_img.visibility=View.VISIBLE
-           }else if(message == "dch_sb_q"){
+           }else if(message == "dch_sb_q"|| message == "button2"){
                //手柄取消
                text_sbqx_button.setBackgroundResource(R.drawable.shape_reinforcements_dialog_bt_bg)
                sbqx_img.visibility=View.VISIBLE
@@ -300,8 +317,13 @@ class TextActivity : BaseActivity<BedTextActivityPresenter, CallingbedTestMainBi
                lycs_img.visibility=View.VISIBLE
            }else if(message == "lu"){
                lycs_button.setText(R.string.str_recording)
+           }else if(message == "Loar") {
+               //loar信号
+               loar_button.setBackgroundResource(R.drawable.shape_reinforcements_dialog_bt_bg)
+               loar_img.visibility = View.VISIBLE
            }
-        }else if (Constant.EVENT_FINISHh == messageEvent.type){
+
+           }else if (Constant.EVENT_FINISHh == messageEvent.type){
             finish()
 
         }
@@ -345,4 +367,7 @@ class TextActivity : BaseActivity<BedTextActivityPresenter, CallingbedTestMainBi
 
         })
     }
+
+
+
 }

+ 1 - 2
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/di/CallingbedComponent.kt

@@ -13,9 +13,8 @@ interface CallingbedComponent {
     fun inject(activity: AppUpdateActivity)
 
     fun inject(activity: CallingbedActivationActivity)
-
-
     fun inject(activity: SystemActivity)
+    fun inject(activity: AppTextActivity)
 
     fun inject(activity: TextActivity)
 

+ 106 - 0
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/dialog/SystemDialogHelper2.java

@@ -0,0 +1,106 @@
+package com.wdkl.app.ncs.callingbed.dialog;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.zhyl.ZhylManager;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.provider.Settings;
+import android.util.DisplayMetrics;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+
+import com.wdkl.app.ncs.callingbed.BuildConfig;
+import com.wdkl.app.ncs.callingbed.R;
+import com.wdkl.app.ncs.callingbed.activity.SystemActivity;
+import com.wdkl.app.ncs.callingbed.hardware.HardWareFactory;
+import com.wdkl.app.ncs.callingbed.helper.Utils;
+import com.wdkl.ncs.android.lib.base.BaseApplication;
+import com.wdkl.ncs.android.middleware.common.Constant;
+
+import static com.wdkl.ncs.android.lib.utils.ExtendMethodsKt.showMessage;
+/**
+ * 激活页面-进入系统设置
+ * */
+public class SystemDialogHelper2 {
+
+    private static AlertDialog alertDialog;
+
+
+
+    public static void showDialog(Activity activity, ClickListener clickListener) {
+
+        View contentView = LayoutInflater.from(activity).inflate(R.layout.main_password_dialog, null);
+        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+        builder.setView(contentView);
+
+        LinearLayout layout = contentView.findViewById(R.id.ll_password_view);
+        Button password_cancel_button = contentView.findViewById(R.id.password_cancel_button);
+        Button password_determine_button = contentView.findViewById(R.id.password_determine_button);
+        EditText password_ed = contentView.findViewById(R.id.password_ed);
+
+        layout.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                try {
+                    Utils.hideInputKeyboard(alertDialog.getWindow().getDecorView().getWindowToken());
+                } catch (Exception e) {
+                    //
+                }
+            }
+        });
+
+        password_cancel_button.setOnClickListener(v -> {
+            if (alertDialog != null && alertDialog.isShowing()) {
+                alertDialog.dismiss();
+            }
+        });
+        password_determine_button.setOnClickListener(v -> {
+            if (alertDialog != null && alertDialog.isShowing()) {
+                String passwprd =password_ed.getText().toString();
+                if (passwprd.equals("888")){
+                    if (clickListener != null) {
+
+                        clickListener.onClick();
+                    }
+
+
+                } else {
+                    showMessage(R.string.invalid_password);
+                }
+                alertDialog.dismiss();
+            }
+        });
+        alertDialog = builder.create();
+        alertDialog.setCanceledOnTouchOutside(true);
+        alertDialog.setCancelable(true);
+        alertDialog.show();
+
+        DisplayMetrics metrics = new DisplayMetrics();
+        activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
+        int screenWidth = metrics.widthPixels;
+        int orientation = activity.getResources().getConfiguration().orientation;
+        if (orientation == Configuration.ORIENTATION_PORTRAIT && screenWidth>600) {
+            try {
+                Window window = alertDialog.getWindow();
+                WindowManager.LayoutParams lp = window.getAttributes();
+                lp.width = 800;
+                lp.height = 650;
+                lp.gravity = Gravity.CENTER;
+                window.setAttributes(lp);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public interface ClickListener{
+        void onClick( );
+    }
+}

+ 0 - 1
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/fragment/DormSipCallFragment.kt

@@ -172,7 +172,6 @@ class DormSipCallFragment: BaseCallFragment() {
             if (Constant.TCP_CONNECTED) {
                 val tcpModel = OtherUtil.SOSCall(Constant.DEVICE_ID)
                 TcpClient.getInstance().sendMsg(tcpModel.toJson())
-
                 SoundPoolManager.getInstance().playSound(4, 1.0f, 1.0f, 0)
             }
         }

+ 8 - 7
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/fragment/DromMianFragment.kt

@@ -53,13 +53,14 @@ class DromMianFragment: BaseFragment<BedMomMianFragmentPresenter, MainView4Layou
     override fun bindEvent() {
         //智能家居
         main_view4_1_ll.setOnClickListener {
-            val time = System.currentTimeMillis()
-            if (time - clickBtnTime > 3000) {
-                clickBtnTime = time
-                (activity as CallingbedDormitoryActivity).showSmartHomeFragment()
-            } else {
-                showMessage(R.string.wait_moment)
-            }
+            showMessage("暂未开通,敬请期待")
+//            val time = System.currentTimeMillis()
+//            if (time - clickBtnTime > 3000) {
+//                clickBtnTime = time
+//                (activity as CallingbedDormitoryActivity).showSmartHomeFragment()
+//            } else {
+//                showMessage(R.string.wait_moment)
+//            }
         }
 
         //交互历史

+ 7 - 0
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/hardware/HardTools.java

@@ -7,6 +7,7 @@ import android.content.Context;
 import com.wdkl.app.ncs.callingbed.activity.AppUpdateActivity;
 import com.wdkl.app.ncs.callingbed.activity.CallingbedActivationActivity;
 import com.wdkl.app.ncs.callingbed.activity.CallingbedActivity;
+import com.wdkl.app.ncs.callingbed.activity.CallingbedDormitoryActivity;
 
 
 public  class HardTools {
@@ -16,12 +17,18 @@ public  class HardTools {
     }
     //初始化
     public void init(CallingbedActivationActivity callingbedActivationActivity){}
+
+    //打开
+    public void openLoar(){}
     //退出
     public void unInit(){}
     //是否卸载旧版本
     public void uninstallApp(Context context , boolean isuninstall, String name){}
     //串口设置
     public void setSerial(CallingbedActivity callingbedActivity){}
+
+    public void setSerial2(CallingbedDormitoryActivity CallingbedDormitoryActivity){}
+
     //检查launch版本
     public void checkLaunch(){}
     //紧急按钮Start

+ 41 - 14
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/hardware/imp/A133HardTools.java

@@ -5,13 +5,13 @@ import android.app.zhyl.ZhylManager;
 import android.content.Context;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.os.Build;
 import android.os.RemoteException;
 import android.util.Log;
 
 import com.wdkl.app.ncs.callingbed.BuildConfig;
 import com.wdkl.app.ncs.callingbed.activity.CallingbedActivationActivity;
 import com.wdkl.app.ncs.callingbed.activity.CallingbedActivity;
+import com.wdkl.app.ncs.callingbed.activity.CallingbedDormitoryActivity;
 import com.wdkl.app.ncs.callingbed.hardware.HardTools;
 import com.wdkl.app.ncs.callingbed.helper.AppUpdateHelper;
 import com.wdkl.app.ncs.callingbed.helper.SOSHelper;
@@ -31,6 +31,7 @@ import kotlin.Unit;
 import kotlin.jvm.functions.Function0;
 import serialporttest.utils.SerialPortUtil;
 import serialporttest.utils.SerialPortUtil433;
+import serialporttest.utils.SerialPortUtilLoar;
 
 /**
  * W——A133主机硬件控制类
@@ -51,19 +52,30 @@ public class A133HardTools extends HardTools {
     @Override
     public void init(CallingbedActivationActivity callingbedActivationActivity) {
         SerialPortUtil.getInstance().openSerialPortA133();
-        if (Boolean.parseBoolean(BuildConfig.open_433)){
-            SerialPortUtil433.getInstance().openSerialPort();
-            SettingConfig.set433GatewayOn(callingbedActivationActivity, true);
-        }
         if (Boolean.parseBoolean(BuildConfig.open_sleep)){
             SettingConfig.setSLEEPGatewayOn(callingbedActivationActivity, true);
         }
+        if (BuildConfig.device_type.equals("4")){
+            SerialPortUtilLoar.getInstance().openSerialPort();
+        }else {
+            if (Boolean.parseBoolean(BuildConfig.open_433)){
+                SerialPortUtil433.getInstance().openSerialPort();
+                SettingConfig.set433GatewayOn(callingbedActivationActivity, true);
+            }
+        }
     }
 
     @Override
     public void unInit() {
+        //主要是用了新的功能板
         SerialPortUtil.getInstance().closeSerialPort();
-        SerialPortUtil433.getInstance().closeSerialPort();
+        if (BuildConfig.device_type.equals("4")){
+            SerialPortUtilLoar.getInstance().closeSerialPort();
+        }else {
+            SerialPortUtil433.getInstance().closeSerialPort();
+        }
+
+
     }
 
     @Override
@@ -106,16 +118,31 @@ public class A133HardTools extends HardTools {
     @Override
     public void setSerial(CallingbedActivity callingbedActivity) {
         try {
+                callingbedActivity.setSerialListener();
+                Thread.sleep(1500); // 延时1500毫秒 (1.5秒)
+                SerialPortHelper.setSosLight("0");
+                SerialPortHelper.setCallStatus("0");
+                //默认门灯白色
+                SerialPortHelper.setDoorLight(1, "111");
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void setSerial2(CallingbedDormitoryActivity CallingbedDormitoryActivity) {
+        try {
             // 串口监听
-            callingbedActivity.setSerialListener();
-            Thread.sleep(1500); // 延时1500毫秒 (1.5秒)
-            // 打开MICsetSerialListener
+                CallingbedDormitoryActivity.setSerialListener();
+                Thread.sleep(1500); // 延时1500毫秒 (1.5秒)
+                // 打开MICsetSerialListener
 //            SerialPortHelper.setMIC(false);
 //            SerialPortHelper.setHandsFree(true);
-            SerialPortHelper.setSosLight("0");
-            SerialPortHelper.setCallStatus("0");
-            //默认门灯白色
-            SerialPortHelper.setDoorLight(1, "111");
+                SerialPortHelper.setSosLight("0");
+                SerialPortHelper.setCallStatus("0");
+                //默认门灯白色
+                SerialPortHelper.setDoorLight(1, "111");
+
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
@@ -167,7 +194,7 @@ public class A133HardTools extends HardTools {
             zhylManager.disp_setNavigationBar(false);
 
             ZhylManager.getInstance(BaseApplication.appContext).sys_setDacVolume(BaseApplication.appContext,140);
-            ZhylManager.getInstance(BaseApplication.appContext).sys_setMic1gain(BaseApplication.appContext,18);
+            ZhylManager.getInstance(BaseApplication.appContext).sys_setMic1gain(BaseApplication.appContext,30);
 
             //系统默认语言
             switch (SettingConfigNew.getLanguageId(context)) {

+ 8 - 0
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/helper/AlarmMessageUtil.java

@@ -10,5 +10,13 @@ public class AlarmMessageUtil {
         sb.append(cmd);
         return sb.toString();
     }
+    public static String getAlarmMessage2(String cmd){
+        //----> ffee04020006b50831
+        StringBuilder sb = new StringBuilder();
+        sb.append("ffee04");
+        sb.append(String.format("%04X",cmd.length()));
+        sb.append(cmd);
+        return sb.toString();
+    }
 
 }

+ 63 - 0
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/helper/DrawingView.java

@@ -0,0 +1,63 @@
+package com.wdkl.app.ncs.callingbed.helper;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+
+public class DrawingView extends View {
+    private Paint paint;
+    private Path path;
+
+    public DrawingView(Context context) {
+        super(context);
+        init();
+    }
+
+    public DrawingView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    private void init() {
+        paint = new Paint();
+        paint.setColor(Color.RED);
+        paint.setStyle(Paint.Style.STROKE);
+        paint.setStrokeWidth(20);
+
+        path = new Path();
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        canvas.drawPath(path, paint);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        float x = event.getX();
+        float y = event.getY();
+
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                path.moveTo(x, y);
+                break;
+            case MotionEvent.ACTION_MOVE:
+                path.lineTo(x, y);
+                break;
+            case MotionEvent.ACTION_UP:
+                // 可以在此处进行一些额外的操作
+                break;
+        }
+
+        invalidate(); // 刷新视图
+
+        return true;
+    }
+}
+

+ 11 - 7
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/helper/SerialPortHelper.java

@@ -2,6 +2,8 @@ package com.wdkl.app.ncs.callingbed.helper;
 
 import android.os.Build;
 
+import com.wdkl.app.ncs.callingbed.BuildConfig;
+
 import serialporttest.utils.SerialPortUtil;
 
 public class SerialPortHelper {
@@ -24,7 +26,8 @@ public class SerialPortHelper {
      * data: 0 -- 正常,  1 -- 呼叫中, 2 -- 通话中
      */
     public static void setCallStatus(String data) {
-            SerialPortUtil.getInstance().sendCommand(SerialPortUtil.CALL_STATUS, data, "F");
+
+        SerialPortUtil.getInstance().sendCommand(SerialPortUtil.CALL_STATUS, data, "F");
 
     }
 
@@ -32,9 +35,9 @@ public class SerialPortHelper {
      * 设置卫生间紧急按钮灯状态: 0关闭1打开2闪烁
      */
     public static void setSosLight(String state) {
-        //if (Build.MODEL.equals("rk3128")) {
-            SerialPortUtil.getInstance().sendCommand(SerialPortUtil.ULED, state, "F");
-        //}
+
+        SerialPortUtil.getInstance().sendCommand(SerialPortUtil.ULED, state, "F");
+
     }
 
     /**
@@ -51,12 +54,13 @@ public class SerialPortHelper {
             command = color;
         }
         SerialPortUtil.getInstance().sendCommand(SerialPortUtil.DOORLIGHT, command, "F");
+
+
     }
 
     //重置设备
     public static void resetDevice() {
-        if (Build.MODEL.equals("rk3128")) {
-            SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NET_STATUS, "1", "F");
-        }
+        SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NET_STATUS, "1", "F");
+
     }
 }

+ 1 - 1
android_bed/src/main/java/com/wdkl/app/ncs/callingbed/sleep/SleepService.java

@@ -147,7 +147,7 @@ public class SleepService extends Service implements BeaconConsumer, SleepSocket
     }
     private  WebSockeClient webSockeClient;
 
-    //蓝牙模式
+    //wifi模式
     private void BtPattern(){
         String baseurl = "ws://api.base.wdklian.com/sleep_report/monitor";
         webSockeClient = new WebSockeClient(baseurl);

+ 43 - 13
android_bed/src/main/res/layout-land/callingbed_test_main.xml

@@ -22,8 +22,8 @@
                 android:layout_width="@dimen/d475"
                 android:layout_height="match_parent"
                 android:layout_marginLeft="@dimen/d24"
-                android:layout_marginTop="@dimen/d63"
-                android:layout_marginBottom="@dimen/d50"
+                android:layout_marginTop="@dimen/d10"
+                android:layout_marginBottom="@dimen/d20"
                 android:background="@drawable/shape_bed_bg"
                 android:gravity="center_horizontal"
                 android:orientation="vertical">
@@ -77,15 +77,16 @@
                     android:textColor="@drawable/selector_bottom_btn_text_color"
                     android:textSize="16sp" />
 
+
             </LinearLayout>
 
             <LinearLayout
                 android:layout_width="@dimen/d491"
                 android:layout_height="match_parent"
                 android:layout_marginLeft="@dimen/d16"
-                android:layout_marginTop="@dimen/d63"
+                android:layout_marginTop="@dimen/d10"
                 android:layout_marginRight="@dimen/d28"
-                android:layout_marginBottom="@dimen/d50"
+                android:layout_marginBottom="@dimen/d20"
                 android:background="@drawable/shape_bed_bg"
                 android:gravity="center_horizontal"
                 android:orientation="vertical">
@@ -93,7 +94,7 @@
                 <TextView
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:layout_marginTop="66dp"
+                    android:layout_marginTop="16dp"
                     android:gravity="center"
                     android:text="@string/test_peripheral"
                     android:textColor="@color/black"
@@ -113,7 +114,7 @@
                     android:id="@+id/text_ll_1"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:layout_marginTop="@dimen/d23"
+                    android:layout_marginTop="@dimen/d15"
                     android:gravity="center"
                     android:orientation="horizontal">
 
@@ -140,7 +141,7 @@
                     android:id="@+id/text_ll_2"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:layout_marginTop="@dimen/d23"
+                    android:layout_marginTop="@dimen/d15"
                     android:gravity="center"
                     android:orientation="horizontal">
 
@@ -217,35 +218,38 @@
                         android:visibility="invisible" />
                 </LinearLayout>
 
+
+
                 <LinearLayout
-                    android:id="@+id/text_ll_5"
+                    android:id="@+id/text_ll_6"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:layout_marginTop="@dimen/d16"
+                    android:clickable="true"
                     android:gravity="center"
                     android:orientation="horizontal">
 
                     <Button
-                        android:id="@+id/sos_button"
+                        android:id="@+id/loar_button"
                         android:layout_width="@dimen/d383"
                         android:layout_height="@dimen/d48"
                         android:background="@drawable/shape_main_hos_txt_bg"
+                        android:clickable="true"
                         android:gravity="center"
-                        android:text="@string/test_sos_button"
+                        android:text="loar信号测试"
                         android:textColor="@drawable/selector_bottom_btn_text_color"
                         android:textSize="16sp" />
 
                     <ImageView
-                        android:id="@+id/sos_img"
+                        android:id="@+id/loar_img"
                         android:layout_width="@dimen/d16"
                         android:layout_height="@dimen/d16"
                         android:layout_marginLeft="@dimen/d8"
                         android:background="@mipmap/gou"
                         android:visibility="invisible" />
                 </LinearLayout>
-
                 <LinearLayout
-                    android:id="@+id/text_ll_6"
+                    android:id="@+id/text_ll_7"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:layout_marginTop="@dimen/d16"
@@ -275,6 +279,32 @@
                         android:background="@mipmap/gou"
                         android:visibility="invisible" />
                 </LinearLayout>
+                <LinearLayout
+                    android:id="@+id/text_ll_5"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="@dimen/d16"
+                    android:gravity="center"
+                    android:orientation="horizontal">
+
+                    <Button
+                        android:id="@+id/sos_button"
+                        android:layout_width="@dimen/d383"
+                        android:layout_height="@dimen/d48"
+                        android:background="@drawable/shape_main_hos_txt_bg"
+                        android:gravity="center"
+                        android:text="@string/test_sos_button"
+                        android:textColor="@drawable/selector_bottom_btn_text_color"
+                        android:textSize="16sp" />
+
+                    <ImageView
+                        android:id="@+id/sos_img"
+                        android:layout_width="@dimen/d16"
+                        android:layout_height="@dimen/d16"
+                        android:layout_marginLeft="@dimen/d8"
+                        android:background="@mipmap/gou"
+                        android:visibility="invisible" />
+                </LinearLayout>
 
             </LinearLayout>
 

+ 162 - 0
android_bed/src/main/res/layout/test_lay.xml

@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:background="@color/white">
+
+    <RelativeLayout
+        android:id="@+id/text_top"
+        android:layout_width="match_parent"
+        android:layout_height="50dp"
+        android:background="@color/main_color">
+        <LinearLayout
+            android:id="@+id/view_title_layout_img"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:gravity="center"
+            android:clickable="true">
+        <ImageView
+            android:layout_width="15dp"
+            android:layout_height="25dp"
+            android:layout_marginLeft="30dp"
+            android:clickable="true"
+            android:background="@mipmap/integ_arrow_icon"
+            android:layout_centerVertical="true" />
+        </LinearLayout>
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textSize="28sp"
+            android:text="测试界面"
+            android:layout_centerHorizontal="true"
+            android:layout_centerVertical="true"
+            android:textColor="@color/white"/>
+
+    </RelativeLayout>
+
+
+
+    <com.wdkl.app.ncs.callingbed.helper.DrawingView
+        android:id="@+id/slayout"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@color/white"
+        android:visibility="gone" />
+
+    <View
+        android:id="@+id/color_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@color/black"
+        android:clickable="true"
+        android:visibility="gone" />
+
+    <LinearLayout
+        android:id="@+id/text_mian"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical"
+        android:layout_below="@+id/text_top">
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+
+            <SurfaceView
+                android:id="@+id/camera_preview_surface"
+                android:layout_width="240dp"
+                android:layout_height="240dp" />
+
+            <Button
+                android:id="@+id/btn_sos_test"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_margin="10dp"
+                android:layout_toRightOf="@id/camera_preview_surface"
+                android:text="SOS"
+                android:visibility="gone"
+                android:textSize="28sp"/>
+
+            <Button
+                android:id="@+id/btn_reset"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_margin="10dp"
+                android:layout_toRightOf="@id/btn_sos_test"
+                android:text="重置"
+                android:visibility="gone"
+                android:textSize="28sp"/>
+
+            <Button
+                android:id="@+id/btn_net_off"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_margin="10dp"
+                android:layout_toRightOf="@id/btn_reset"
+                android:text="网络开关"
+                android:visibility="gone"
+                android:textSize="28sp"/>
+
+            <Button
+                android:id="@+id/btn_color"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_margin="10dp"
+                android:layout_toRightOf="@id/btn_net_off"
+                android:text="屏幕颜色"
+                android:textSize="28sp"/>
+
+            <Button
+                android:id="@+id/btn_cm"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_margin="10dp"
+                android:layout_toRightOf="@id/btn_color"
+                android:text="屏幕触摸"
+                android:textSize="28sp"/>
+
+            <TextView
+                android:id="@+id/tv_ip"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="10dp"
+                android:layout_toRightOf="@id/camera_preview_surface"
+                android:layout_below="@id/btn_cm"
+                android:textSize="20sp"
+                android:text="IP:"/>
+        </RelativeLayout>
+
+        <TextView
+            android:id="@+id/tv_camera"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:textSize="20sp"
+            android:visibility="gone"/>
+
+        <TextView
+            android:id="@+id/tv_test_info"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:textSize="24sp"/>
+    </LinearLayout>
+
+    <Button
+        android:id="@+id/btn_fist"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="10dp"
+        android:layout_alignParentBottom="true"
+        android:layout_centerHorizontal="true"
+        android:textColor="@color/white"
+        android:text="退出测试"
+        android:background="@drawable/shape_main_hos_txt_bg"
+        android:textSize="28sp"
+        android:visibility="gone"/>
+
+</RelativeLayout>
+</layout>

BIN
android_bed/src/main/res/mipmap-mdpi/integ_arrow_icon.png


+ 4 - 0
android_host/src/main/AndroidManifest.xml

@@ -96,6 +96,10 @@
             android:screenOrientation="landscape"
             android:launchMode="singleInstance">
         </activity>
+        <activity android:name=".activity.NurseHome2Activity"
+            android:screenOrientation="landscape"
+            android:launchMode="singleInstance">
+        </activity>
 
         <activity android:name=".activity.OfflineHomeActivity"
             android:screenOrientation="landscape"

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

@@ -534,8 +534,8 @@ class CallingHostActivationActivity : BaseActivity<DevicePresenter, CallinghostA
 
         if (BuildConfig.device_type.equals("4")){//宿舍
             val intent = Intent()
-//            intent.setClass(activity, CallingbedDormitoryActivity::class.java)
-//            activity.startActivity(intent)
+            intent.setClass(activity, NurseHome2Activity::class.java)
+            activity.startActivity(intent)
 
         } else {
             val intent = Intent()

+ 0 - 38
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/activity/HostbedinfoActivity.kt

@@ -165,45 +165,7 @@ class HostbedinfoActivity : BaseActivity<BedHospitalInfoActivityPresenter, Activ
             showMiddleFragment(fragment)
         }
         menu_call_nurse.setOnClickListener {
-            //语音呼叫
-            if (System.currentTimeMillis() - clickTime < 3000) {
-                showMessage(R.string.call_wait)
-            } else {
-                if (frame.bedDeviceId != null && (!TextUtils.isEmpty(frame.customerName) || !TextUtils.isEmpty(frame.deviceSipId))) {
-                    //呼出时停止语音播报及铃声
-                    SpeechUtil.getInstance().stopSpeak(true)
-                    RingPlayHelper.stopRingTone()
-                    if (NurseHomeActivity.checkIncomingCall(frame.bedDeviceId)) {
-                        showMessage(R.string.call_in_list)
-                    } else {
-                        //通话之前先判断webrtc socket是否连接上,否则不能建立通话
-                        if (Constant.TCP_CONNECTED) {
-                            Constant.targetDeviceId = frame.bedDeviceId
-                            Constant.CALL_TYPE = 0
-                            val callTcp = VoiceUtil.voiceCall(Constant.DEVICE_ID, frame.bedDeviceId)
-                            val transaction = object : TcpCallback(callTcp.tid) {
-                                override fun onSuccess(jsonObject: JSONObject) {
-                                    super.onSuccess(jsonObject)
-                                }
 
-                                override fun onFailed(jsonObject: JSONObject) {
-                                    // 这里写发送失败的方法
-                                    val callbackString = jsonObject.getString(CALLBACK)
-                                    showMessage("call fail: $callbackString")
-                                    super.onFailed(jsonObject)
-                                }
-                            }
-                            TcpClient.getInstance().sendTcp(callTcp, false, transaction)
-                            finish()
-                        } else {
-                            showMessage(R.string.net_error)
-                        }
-                    }
-                } else {
-                    showMessage(R.string.no_custom)
-                }
-            }
-            clickTime = System.currentTimeMillis()
         }
 
         menu_video_call_nurse.setOnClickListener {

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 213 - 786
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/activity/NurseHome2Activity.kt


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

@@ -831,9 +831,6 @@ class NurseHomeActivity  : BaseActivity<NurseHomeActivityPresenter, ActivityNewN
 
         if (data.ledControl != null) {
             SettingConfig.setLedControl(activity, data.ledControl)
-            if (data.ledControl) {
-                led_settings_radio_bt.visibility = View.GONE
-            }
         }
 
         //通过服务端设置语言

+ 259 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/adapter/DormCallingItemAdapter.kt

@@ -0,0 +1,259 @@
+package com.wdkl.ncs.android.component.nursehome.adapter
+
+import android.content.Context
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import com.wdkl.ncs.android.component.nursehome.R
+import com.wdkl.ncs.android.component.nursehome.activity.NurseHome2Activity
+import com.wdkl.ncs.android.component.nursehome.activity.NurseHomeActivity
+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.SpeechUtil
+import com.wdkl.ncs.android.component.nursehome.util.TimeTransition
+import com.wdkl.ncs.android.middleware.common.Constant
+import com.wdkl.ncs.android.middleware.common.MessageEvent
+import com.wdkl.ncs.android.middleware.entity.CallingItem
+import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
+import com.wdkl.ncs.android.middleware.tcp.enums.DeviceTypeEnum
+import com.wdkl.ncs.android.middleware.udp2.UdpIndex
+import com.wdkl.ncs.android.middleware.udp2.UdpItem
+import com.wdkl.ncs.android.middleware.udp2.UdpSendUtil
+import org.greenrobot.eventbus.EventBus
+
+class DormCallingItemAdapter : RecyclerView.Adapter<DormCallingItemAdapter.ParentViewHolder> {
+    private var context: Context
+    private var callingData: ArrayList<CallingItem>
+    private var updateCallback: UpdateCallback? = null
+
+    constructor(context: Context, data: ArrayList<CallingItem>) {
+        this.context = context
+        this.callingData = data
+    }
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ParentViewHolder {
+        val view = LayoutInflater.from(parent.context).inflate(R.layout.adapter_dorm_calling_item, parent, false)
+        val viewHolder = ParentViewHolder(view)
+
+        return viewHolder
+    }
+
+    override fun onBindViewHolder(holder: ParentViewHolder, position: Int) {
+        try {
+            val callingItem = callingData.get(position)
+            if (callingItem.type == 1) {
+                //udp
+                val itemData = callingItem.udpItem
+                holder.callingBedName.text = itemData.fromFrameName
+                holder.callingName.text = itemData.patientName
+                holder.callingTime.text = TimeTransition.stampToDateTime(callingItem.startTime)
+
+                if (SettingConfig.getOfflineModeRunning(context)) {
+                    holder.callingAccept.visibility = View.VISIBLE
+                    holder.callingAccept.setOnClickListener {
+                        EventBus.getDefault().post(MessageEvent(itemData, Constant.EVENT_ACCEPT_CALL))
+                        removeCall(itemData, true)
+                    }
+                } else {
+                    holder.callingAccept.visibility = View.GONE
+                }
+            } else {
+                //tcp
+                val itemData = callingItem.interactionVO
+                var frameName: String? = ""
+                var memberName: String? = ""
+                if (DeviceTypeEnum.DOCTOR_HOST.value() == itemData.fromDeviceType
+                    || DeviceTypeEnum.NURSE_HOST.value() == itemData.fromDeviceType
+                    || DeviceTypeEnum.OTHER_HOST.value() == itemData.fromDeviceType
+                ) {
+                    //医生机,护士主机,其他主机,总控主机等
+                    frameName = itemData.fromDeviceName
+                } else if (DeviceTypeEnum.NURSE_WATCH.value() == itemData.fromDeviceType) {
+                    //移动设备
+                    frameName = itemData.fromMemberName
+                } else {
+                    //其他
+                    frameName = itemData.fromFrameFullName
+                    memberName = itemData.fromMemberName
+                }
+
+                holder.callingBedName.text = frameName
+                holder.callingName.text = memberName
+                if (itemData.createDate != null) {
+                    holder.callingTime.text = TimeTransition.stampToDateTime(itemData.createDate * 1000)
+                }
+
+                holder.callingAccept.visibility = View.VISIBLE
+                holder.callingAccept.setOnClickListener {
+                    EventBus.getDefault().post(MessageEvent(callingItem, Constant.EVENT_ACCEPT_CALL))
+                    removeCall(itemData, true)
+                }
+            }
+        } catch (ex : Exception) {
+            ex.printStackTrace()
+        }
+    }
+
+    override fun getItemCount(): Int {
+        return callingData.size
+    }
+
+    fun addCall(callingItem: CallingItem) {
+        synchronized(this) {
+            try {
+                val iterator = NurseHome2Activity.callingList.iterator()
+                while (iterator.hasNext()) {
+                    val it = iterator.next()
+                    if (callingItem.type == 1) {
+                        if (callingItem.udpItem.fromMacAddr.equals(it.udpItem.fromMacAddr)) {
+                            iterator.remove()
+                        }
+                    } else {
+                        //同样设备的呼叫只显示一个
+                        if (callingItem.interactionVO.fromDeviceId == it.interactionVO.fromDeviceId) {
+                            iterator.remove()
+                        }
+                    }
+                }
+                NurseHome2Activity.callingList.add(callingItem)
+                updateCallList()
+            } catch (e: Exception) {
+                e.printStackTrace()
+            }
+        }
+    }
+
+    private fun updateCallList() {
+        callingData.clear()
+        callingData.addAll(NurseHome2Activity.callingList)
+        notifyDataSetChanged()
+
+        if (updateCallback != null) {
+            updateCallback?.onUpdate()
+        }
+    }
+
+    fun removeCall(interactionVO: InteractionVO, stop: Boolean) {
+        if (stop) {
+            RingPlayHelper.stopRingTone()
+            SpeechUtil.getInstance().stopSpeak(true)
+        }
+
+        synchronized(this) {
+            val iterator = NurseHome2Activity.callingList.iterator()
+            while (iterator.hasNext()) {
+                val it = iterator.next()
+                if (interactionVO.id.equals(it.interactionVO.id)) {
+                    iterator.remove()
+                }
+            }
+
+            updateCallList()
+        }
+    }
+
+    fun removeCall(udpItem: UdpItem, stop: Boolean) {
+        if (stop) {
+            RingPlayHelper.stopRingTone()
+            SpeechUtil.getInstance().stopSpeak(true)
+        }
+
+        synchronized(this) {
+            val iterator = NurseHome2Activity.callingList.iterator()
+            while (iterator.hasNext()) {
+                val it = iterator.next()
+                if (udpItem.fromMacAddr.equals(it.udpItem.fromMacAddr)) {
+                    iterator.remove()
+                }
+            }
+
+            updateCallList()
+        }
+    }
+
+    fun removeCallByPos(position: Int, stop: Boolean) {
+        if (stop) {
+            RingPlayHelper.stopRingTone()
+            SpeechUtil.getInstance().stopSpeak(true)
+        }
+
+        synchronized(this) {
+            try {
+                val removeItem = callingData.get(position)
+                if (removeItem.type == 1) {
+                    rejectCall(removeItem.udpItem)
+                } else {
+                    EventBus.getDefault().post(MessageEvent(removeItem, Constant.EVENT_REJECT_CALL))
+                }
+
+                val iterator = NurseHome2Activity.callingList.iterator()
+                while (iterator.hasNext()) {
+                    val it = iterator.next()
+                    if (removeItem.type == 1) {
+                        if (removeItem.udpItem.fromMacAddr.equals(it.udpItem.fromMacAddr)) {
+                            iterator.remove()
+                        }
+                    } else {
+                        if (removeItem.interactionVO.id.equals(it.interactionVO.id)) {
+                            iterator.remove()
+                        }
+                    }
+                }
+
+                updateCallList()
+            } catch (e: Exception) {
+                e.printStackTrace()
+            }
+        }
+    }
+
+    fun setUpdateCallback(callBack: UpdateCallback) {
+        updateCallback = callBack
+    }
+
+    private fun rejectCall(item: UdpItem) {
+        //发送udp拒接呼叫
+        UdpSendUtil.getInstance().sendUdpData(
+            UdpIndex.BED_CALL_REJECT,
+            item.fromFrameName,
+            "",
+            item.patientName,
+            Constant.DEVICE_REGISTER_ID,
+            item.fromMacAddr,
+            "",
+            "",
+            "",
+            "",
+            "",
+            Constant.DEVICE_ID,
+            item.fromDeviceId,
+            Constant.PART_ID)
+
+        //LedHelper.updateLedInfo(item, false, false)
+    }
+
+
+    class ParentViewHolder : RecyclerView.ViewHolder {
+        var callingBedName : TextView
+        var callingName : TextView
+        var callingTime : TextView
+        var callingAccept : ImageView
+        var callingReject : ImageView
+
+        constructor(itemView: View): super(itemView) {
+            callingBedName = itemView.findViewById(R.id.dorm_tv_calling_bed_name)
+            callingName = itemView.findViewById(R.id.dorm_tv_calling_custom_name)
+            callingTime = itemView.findViewById(R.id.dorm_tv_calling_time)
+            callingAccept = itemView.findViewById(R.id.dorm_btn_call_accept)
+            callingReject = itemView.findViewById(R.id.dorm_btn_call_reject)
+        }
+    }
+
+    interface UpdateCallback {
+        fun onUpdate()
+    }
+}

+ 17 - 1
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/di/NurseHomeComponent.kt

@@ -1,6 +1,7 @@
 package com.wdkl.ncs.android.component.nursehome.di
 
 import com.wdkl.ncs.android.component.nursehome.activity.*
+import com.wdkl.ncs.android.component.nursehome.dorm.*
 import com.wdkl.ncs.android.component.nursehome.fragment.*
 import com.wdkl.ncs.android.component.nursehome.visit.frgment.VisitCallFragment
 import com.wdkl.ncs.android.component.nursehome.visit.frgment.VisitMainFragment
@@ -63,7 +64,22 @@ interface NurseHomeComponent{
     fun inject(fragment: PushMessageOrdinaryFragment)
     fun inject(fragment: PushMessageTemplateFragment)
     fun inject(fragment: PushMessageListFragment)
-
+    //宿舍端
     fun inject(activity: NurseHome2Activity)
 
+    fun inject(fragment: DromMianFragment)
+
+    fun inject(fragment: DormCallRecordsFragment)
+
+    fun inject(fragment: DormDialCallFragment)
+
+    fun inject(fragment: VolumeSetFragment)
+
+    fun inject(fragment: DormThemeFragment)
+
+    fun inject(fragment: DormSipCallFragment)
+
+
+    fun inject(fragment: DormSkyCallFragment)
+
 }

+ 499 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/DormCallRecordsFragment.kt

@@ -0,0 +1,499 @@
+package com.wdkl.ncs.android.component.nursehome.dorm
+
+import android.text.TextUtils
+import android.util.Log
+import android.view.View
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.ItemTouchHelper
+import androidx.recyclerview.widget.RecyclerView
+import com.alibaba.android.vlayout.DelegateAdapter
+import com.alibaba.android.vlayout.VirtualLayoutManager
+import com.enation.javashop.net.engine.model.NetState
+import com.google.gson.Gson
+import com.scwang.smartrefresh.layout.footer.ClassicsFooter
+import com.wdkl.ncs.android.component.nursehome.R
+import com.wdkl.ncs.android.component.nursehome.activity.NurseHome2Activity
+import com.wdkl.ncs.android.component.nursehome.activity.NurseHomeActivity
+import com.wdkl.ncs.android.component.nursehome.adapter.CallingItemAdapter
+import com.wdkl.ncs.android.component.nursehome.adapter.DormCallingItemAdapter
+import com.wdkl.ncs.android.component.nursehome.databinding.DormCallRecordsBinding
+import com.wdkl.ncs.android.component.nursehome.dorm.adapter.DormCallRecordsItemAdapter
+import com.wdkl.ncs.android.component.nursehome.launch.NurseHomeLaunch
+import com.wdkl.ncs.android.component.nursehome.settingconfig.SettingConfig
+import com.wdkl.ncs.android.component.nursehome.util.*
+import com.wdkl.ncs.android.lib.base.BaseApplication
+
+import com.wdkl.ncs.android.lib.base.BaseFragment
+import com.wdkl.ncs.android.lib.core.locale.LocaleMangerUtils
+import com.wdkl.ncs.android.lib.utils.showMessage
+import com.wdkl.ncs.android.lib.vo.filter
+import com.wdkl.ncs.android.middleware.common.Constant
+import com.wdkl.ncs.android.middleware.common.MessageEvent
+import com.wdkl.ncs.android.middleware.entity.CallingItem
+import com.wdkl.ncs.android.middleware.logic.contract.callingbed.BedCallRecordsFragmentContract
+import com.wdkl.ncs.android.middleware.logic.contract.nursehome.CallRecordsFragmentContract
+import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.BedCallRecordsFragmentPresenter
+import com.wdkl.ncs.android.middleware.logic.presenter.nursehome.CallRecordsFragmentPresenter
+import com.wdkl.ncs.android.middleware.model.dos.EventDO
+import com.wdkl.ncs.android.middleware.model.vo.CallRecordVO
+import com.wdkl.ncs.android.middleware.model.vo.DeviceVO
+import com.wdkl.ncs.android.middleware.model.vo.EventVO
+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.VoiceUtil
+import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel
+import com.wdkl.ncs.android.middleware.tcp.enums.DeviceTypeEnum
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpAction
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpType
+import com.wdkl.ncs.android.middleware.udp2.UdpIndex
+import com.wdkl.ncs.android.middleware.udp2.UdpItem
+import kotlinx.android.synthetic.main.dorm_call_records.*
+
+import kotlinx.android.synthetic.main.fragment_call_records.*
+import org.greenrobot.eventbus.EventBus
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+import java.util.*
+import kotlin.collections.ArrayList
+
+class DormCallRecordsFragment : BaseFragment<CallRecordsFragmentPresenter, DormCallRecordsBinding>(), CallRecordsFragmentContract.View,
+    DormCallRecordsItemAdapter.ActionClickListener , DormCallingItemAdapter.UpdateCallback{
+    var TAG = DormCallRecordsFragment::class.java.getSimpleName()
+
+    private lateinit var adapter: DormCallRecordsItemAdapter
+    private var callingAdapter: DormCallingItemAdapter? = null
+    private lateinit var virtualLayoutManager: VirtualLayoutManager
+    private lateinit var delegateAdapter: DelegateAdapter
+
+    private var language = "zh"
+
+    //加载历史记录条数
+    private val pageSize: Int = 15
+    //数据的初始页数
+    private var page: Int = 1
+    //查询历史记录类型
+    private var listType: Int = 0
+
+    private var clickCallTime: Long = 0
+
+    override fun getLayId(): Int {
+        return R.layout.dorm_call_records
+    }
+
+    override fun bindDagger() {
+        NurseHomeLaunch.component.inject(this)
+    }
+
+    override fun init() {
+        adapter = DormCallRecordsItemAdapter(activity, ArrayList())
+
+        /**初始化LayoutMannager*/
+        virtualLayoutManager = VirtualLayoutManager(this.activity)
+        val layoutManager = GridLayoutManager(getActivity(), 1)
+        call_records_rv.setLayoutManager(layoutManager)
+
+        /**初始化适配器*/
+        delegateAdapter = DelegateAdapter(virtualLayoutManager)
+        delegateAdapter.addAdapter(adapter)
+        mViewDataBinding.callRecordsRefresh.setRefreshFooter(ClassicsFooter(activity))
+
+//        language = LocaleMangerUtils.getApplicationLocale().language
+
+        /**配置到RecycleView*/
+        call_records_rv.layoutManager = virtualLayoutManager
+        call_records_rv.adapter = delegateAdapter
+
+        callingAdapter = DormCallingItemAdapter(activity, ArrayList())
+        dorm_rv_calling_list.layoutManager = VirtualLayoutManager(activity)
+        dorm_rv_calling_list.adapter = callingAdapter
+
+        val touchCallback: ItemTouchHelper.Callback =
+                object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
+                    override fun onMove(
+                            recyclerView: RecyclerView,
+                            viewHolder: RecyclerView.ViewHolder,
+                            target: RecyclerView.ViewHolder
+                    ): Boolean {
+                        return false
+                    }
+
+                    override fun onSwiped(
+                            viewHolder: RecyclerView.ViewHolder,
+                            direction: Int
+                    ) {
+                        val pos = viewHolder.adapterPosition
+                        if (callingAdapter != null && pos < callingAdapter!!.itemCount) {
+                            callingAdapter!!.removeCallByPos(pos, true)
+                        }
+                    }
+                }
+        val itemTouchHelper = ItemTouchHelper(touchCallback)
+        itemTouchHelper.attachToRecyclerView(dorm_rv_calling_list)
+        callingAdapter?.setUpdateCallback(this)
+        adapter.setActionClickListener(this)
+    }
+
+    fun showCallList() {
+        dorm_ll_call_list.visibility = View.VISIBLE
+
+        call_records_refresh.visibility = View.GONE
+    }
+    override fun onStart() {
+        super.onStart()
+        if (!EventBus.getDefault().isRegistered(this)) {
+            // 未注册的逻辑处理
+            EventBus.getDefault().register(this)
+        }
+
+    }
+
+    override fun onStop() {
+        super.onStop()
+        if (EventBus.getDefault().isRegistered(this)) {
+            // 已注册的逻辑处理
+            EventBus.getDefault().unregister(this)
+        }
+
+    }
+    override fun onResume() {
+        super.onResume()
+        presenter.loadFloor(page, pageSize, Constant.PART_ID, 0, "")
+    }
+
+    override fun bindEvent() {
+        configRefresh()
+    }
+
+    override fun destory() {
+        MediaPlayHelper.getInstance().stopMusic(true)
+    }
+
+    private fun configRefresh(){
+        //下拉刷新
+        mViewDataBinding.callRecordsRefresh.setOnRefreshListener {
+            page = 1
+            presenter.loadFloor(page, pageSize, Constant.PART_ID, 0, "")
+
+        }
+        //上拉加载更多
+        mViewDataBinding.callRecordsRefresh.setOnLoadMoreListener {
+            page += 1
+            presenter.loadFloor(page, pageSize, Constant.PART_ID, 0, "")
+
+        }
+    }
+
+    override fun renderFloor(data: ArrayList<InteractionVO>) {
+        mViewDataBinding.callRecordsRefresh.resetNoMoreData()
+        if (page == 1) {
+            mViewDataBinding.callRecordsRefresh.resetNoMoreData()
+            if (data.size > 0) {
+                adapter.data.clear()
+                adapter.data.addAll(data)
+                Log.i("abc1"," " + adapter.data.size)
+                adapter.notifyDataSetChanged()
+            }
+            mViewDataBinding.callRecordsRefresh.finishRefresh()
+        } else {
+            if (data.size > 0) {
+                adapter.data.addAll(data)
+                adapter.notifyDataSetChanged()
+                mViewDataBinding.callRecordsRefresh.finishLoadMore()
+            } else {
+                mViewDataBinding.callRecordsRefresh.finishLoadMoreWithNoMoreData()
+            }
+        }
+    }
+
+    override fun showEventdata(data: EventVO) {
+
+    }
+
+
+
+
+    override fun onError(message: String, type: Int) {
+        mViewDataBinding.callRecordsRefresh.finishRefresh()
+        showMessage(message)
+    }
+
+    override fun complete(message: String, type: Int) {
+    }
+
+    override fun start() {
+    }
+
+    override fun networkMonitor(state: NetState) {
+        state.filter(onWifi = {
+
+        },onMobile = {
+
+        },offline = {
+
+        })
+    }
+
+    /**
+     * 增加呼叫角色
+     * */
+    override fun onCallRole(role: String?) {
+//        if (TextUtils.isEmpty(role)) {
+//            showMessage("角色为空")
+//        } else {
+//            val time = System.currentTimeMillis()
+//            if (time - clickCallTime > 3000) {
+//                (activity as NurseHome2Activity).startCallRoleName(role!!)
+//            } else {
+//                showMessage(R.string.wait_moment)
+//            }
+//        }
+    }
+
+    override fun onCallDevice(deviceId: Int?) {
+        if (deviceId == null) {
+            showMessage("设备id为空")
+        } else {
+            val time = System.currentTimeMillis()
+            if (time - clickCallTime > 3000) {
+                (activity as NurseHome2Activity).startCallDevice(deviceId)
+            } else {
+                showMessage(R.string.wait_moment)
+            }
+        }
+    }
+    private fun updateRecord() {
+        page = 1
+        presenter.loadFloor(page, pageSize, Constant.PART_ID, 0, "")
+    }
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    fun onMoonEvent(messageEvent: MessageEvent) {
+        when (messageEvent.getType()) {
+            Constant.EVENT_REFRESH_CALL_LIST -> {
+                Log.d("tcp", "refresh call list")
+                updateRecord()
+            }
+            //离线状态udp消息
+            Constant.EVENT_UDP -> {
+                if (messageEvent.message is UdpItem) {
+                    val udpItem = messageEvent.message as UdpItem
+                    Log.d(TAG, "EVENT_UDP ==> $udpItem")
+                    if (UdpIndex.BED_CALL_OUT == udpItem.index) {
+                        val mainActivity = activity as? NurseHomeActivity
+                        EventBus.getDefault().post(MessageEvent("finish", Constant.EVENT_FINISHh))
+                        mainActivity?.showLeftFragment()
+
+                        //1.更新点阵屏信息显示
+                        //LedHelper.updateLedInfo(interactionVO, true, false)
+                        //2.语音播报并显示呼叫
+                        if (Constant.CALL_STATE != Constant.CALL_CALLING
+                                && Constant.CALL_STATE != Constant.CALL_OUTGOING
+                                && Constant.CALL_STATE != Constant.CALL_VISITING
+                                && Constant.CALL_STATE != Constant.CALL_V_INCOMING
+                                && Constant.CALL_STATE != Constant.CALL_ACCEPT
+                        ) {
+                            if (SettingConfig.getTtsMode(activity) == SettingConfig.TTS_ON) {
+                                val frameName: String
+                                if (Locale.CHINESE.getLanguage().equals(language)) {
+                                    frameName = Util.appendSpace(udpItem.fromFrameName.replace("-", ","))
+                                } else {
+                                    frameName = udpItem.fromFrameName.replace("-", "")
+                                }
+                                val text = BaseApplication.appContext.getString(R.string.voice_call_speech, frameName)
+                                SpeechUtil.getInstance().addSpeech(text, false)
+                            } else if (SettingConfig.getTtsMode(activity) == SettingConfig.RING_ON) {
+                                RingPlayHelper.playRingTone(activity, R.raw.ring_tone, true)
+                            } else if (SettingConfig.getTtsMode(activity) == SettingConfig.MUSIC_ON) {
+                                RingPlayHelper.playRingTone(activity, R.raw.incoming_call, true)
+                            }
+                        }
+
+                        val item = CallingItem(System.currentTimeMillis(), "", null, null, 1, udpItem)
+                        if (callingAdapter != null) {
+                            callingAdapter?.addCall(item)
+                        }
+                    } else if (UdpIndex.BED_CALL_CANCEL.equals(udpItem.index)) {
+                        //对方取消呼叫
+                        //LedHelper.updateLedInfo(interactionVO, false, false)
+                        if (SettingConfig.getTtsMode(activity) == SettingConfig.TTS_ON) {
+                            val frameName: String
+                            if (Locale.CHINESE.getLanguage().equals(language)) {
+                                frameName = Util.appendSpace(udpItem.fromFrameName.replace("-", ","))
+                            } else {
+                                frameName = udpItem.fromFrameName.replace("-", "")
+                            }
+                            val text = BaseApplication.appContext.getString(R.string.voice_call_speech, frameName)
+                            SpeechUtil.getInstance().removeSpeak(text)
+                        } else {
+                            //如果呼叫列表只有一个呼叫了,说明删除这个之后就清空了,此时关闭铃声或音乐
+                            if (NurseHomeActivity.callingList.size == 1) {
+                                RingPlayHelper.stopRingTone()
+                            }
+                        }
+
+                        if (callingAdapter != null) {
+                            callingAdapter?.removeCall(udpItem, false)
+                        }
+                    }
+                }
+            }
+
+            Constant.EVENT_TCP_MSG -> {
+                val tcpModel = messageEvent.getMessage() as TcpModel
+                Log.d("tcp", "tcpType: " + tcpModel.type + ", tcpAction: " + tcpModel.action)
+                if (tcpModel.type == TcpType.VOICE) {
+                    val interactionVO = Gson().fromJson(tcpModel.data.toString(), InteractionVO::class.java)
+                    if (tcpModel.action == TcpAction.VoiceAction.CALL) {
+                        //检查呼叫是否已经接听中或通话中
+                        if (Constant.callingId == tcpModel.fromId) {
+                            return
+                        }
+
+                        val mainActivity = activity as? NurseHomeActivity
+                        EventBus.getDefault().post(MessageEvent("finish", Constant.EVENT_FINISHh))
+                        mainActivity?.showLeftFragment()
+                        //返回呼叫成功tcp
+                        //val responseTcpModel = VoiceUtil.voiceSuccessHost(tcpModel.tid, tcpModel.toId, tcpModel.fromId)
+                        //TcpClient.getInstance().sendMsg(responseTcpModel.toJson())
+
+                        //1.更新点阵屏信息显示
+                        LedHelper.updateLedInfo(interactionVO, true, false)
+
+                        //2.语音播报
+                        if (Constant.CALL_STATE != Constant.CALL_CALLING
+                                && Constant.CALL_STATE != Constant.CALL_OUTGOING
+                                && Constant.CALL_STATE != Constant.CALL_VISITING
+                                && Constant.CALL_STATE != Constant.CALL_V_INCOMING
+                                && Constant.CALL_STATE != Constant.CALL_ACCEPT
+                        ) {
+                            if (SettingConfig.getTtsMode(activity) == SettingConfig.TTS_ON) {
+                                var frameName: String? = ""
+                                if (DeviceTypeEnum.DOCTOR_HOST.value() == interactionVO.fromDeviceType
+                                        || DeviceTypeEnum.NURSE_HOST.value() == interactionVO.fromDeviceType
+                                        || DeviceTypeEnum.OTHER_HOST.value() == interactionVO.fromDeviceType) {
+                                    //医生机,护士主机,其他主机,总控主机等
+                                    frameName = interactionVO.fromDeviceName
+                                } else if (DeviceTypeEnum.NURSE_WATCH.value() == interactionVO.fromDeviceType) {
+                                    //移动设备
+                                    frameName = interactionVO.fromMemberName
+                                } else {
+                                    //其他
+                                    if (Locale.CHINESE.getLanguage().equals(language)) {
+                                        frameName = Util.appendSpace(interactionVO.fromFrameFullName.replace("-", ","))
+                                    } else {
+                                        frameName = interactionVO.fromFrameFullName.replace("-", "")
+                                    }
+                                }
+                                val text = BaseApplication.appContext.getString(R.string.voice_call_speech, frameName)
+                                SpeechUtil.getInstance().addSpeech(text, false)
+                            } else if (SettingConfig.getTtsMode(activity) == SettingConfig.RING_ON) {
+                                RingPlayHelper.playRingTone(activity, R.raw.ring_tone, true)
+                            } else if (SettingConfig.getTtsMode(activity) == SettingConfig.MUSIC_ON) {
+                                RingPlayHelper.playRingTone(activity, R.raw.incoming_call, true)
+                            }
+                        }
+                        //3.刷新呼叫列表
+                        updateRecord()
+                        val item = CallingItem(System.currentTimeMillis(), tcpModel.tid, interactionVO, tcpModel.action, 0, null)
+                        if (callingAdapter != null) {
+                            callingAdapter?.addCall(item)
+                        }
+                    } else if (tcpModel.action == TcpAction.VoiceAction.CANCEL || tcpModel.action == TcpAction.VoiceAction.VOICE_OFF) {
+                        //对方取消呼叫视为未接到
+                        //if (tcpModel.action == TcpAction.VoiceAction.CANCEL) {
+                        Constant.newMissedCall = true
+                        //}
+
+                        //对方取消呼叫或者呼叫已被其他主机处理(接听或拒绝)
+                        LedHelper.updateLedInfo(interactionVO, false, false)
+                        if (SettingConfig.getTtsMode(activity) == SettingConfig.TTS_ON) {
+                            var frameName: String? = ""
+                            if (DeviceTypeEnum.DOCTOR_HOST.value() == interactionVO.fromDeviceType
+                                    || DeviceTypeEnum.NURSE_HOST.value() == interactionVO.fromDeviceType
+                                    || DeviceTypeEnum.OTHER_HOST.value() == interactionVO.fromDeviceType) {
+                                //医生机,护士主机,其他主机,总控主机等
+                                frameName = interactionVO.fromDeviceName
+                            } else if (DeviceTypeEnum.NURSE_WATCH.value() == interactionVO.fromDeviceType) {
+                                //移动设备
+                                frameName = interactionVO.fromMemberName
+                            } else {
+                                //其他
+                                if (Locale.CHINESE.getLanguage().equals(language)) {
+                                    frameName = Util.appendSpace(interactionVO.fromFrameFullName.replace("-", ","))
+                                } else {
+                                    frameName = interactionVO.fromFrameFullName.replace("-", "")
+                                }
+                            }
+                            val text = BaseApplication.appContext.getString(R.string.voice_call_speech, frameName)
+                            SpeechUtil.getInstance().removeSpeak(text)
+                        } else {
+                            //如果呼叫列表只有一个呼叫了,说明删除这个之后就清空了,此时关闭铃声或音乐
+                            if (NurseHomeActivity.callingList.size == 1) {
+                                RingPlayHelper.stopRingTone()
+                            }
+                        }
+
+                        if (callingAdapter != null) {
+                            callingAdapter?.removeCall(interactionVO, false)
+                        }
+                    }
+                }
+            }
+
+            Constant.EVENT_HOOK_OFF -> {
+                //接听呼叫列表中第一个电话
+                if (NurseHomeActivity.callingList.size > 0) {
+                    val callingItem = NurseHomeActivity.callingList.get(0)
+                    val itemData = callingItem.interactionVO
+                    //LedHelper.updateLedInfo(itemData, false, false)
+
+                    if (callingItem.type == 0) {
+                        //tcp
+                        EventBus.getDefault().post(MessageEvent(callingItem, Constant.EVENT_ACCEPT_CALL))
+                        if (callingAdapter != null) {
+                            callingAdapter?.removeCall(itemData, true)
+                        }
+                    }
+                }
+            }
+
+            Constant.EVENT_TRANSFER_CALL -> {
+                val callingItem = messageEvent.getMessage() as CallingItem
+                if (callingItem.type == 0) {
+                    if (callingAdapter != null) {
+                        callingAdapter?.removeCall(callingItem.interactionVO, false)
+                    }
+                }
+            }
+
+            Constant.EVENT_REMOVE_CALL -> {
+                val callingItem = messageEvent.getMessage() as CallingItem
+                if (callingItem.type == 0) {
+                    val callTcp = VoiceUtil.voiceReject(
+                            callingItem.tid,
+                            Constant.DEVICE_ID,
+                            callingItem.interactionVO.fromDeviceId,
+                            callingItem.interactionVO.id
+                    )
+                    TcpClient.getInstance().sendMsg(callTcp.toJson())
+                    LedHelper.updateLedInfo(callingItem.interactionVO, false, false)
+
+                    if (callingAdapter != null) {
+                        callingAdapter?.removeCall(callingItem.interactionVO, false)
+                    }
+                }
+            }
+        }
+    }
+
+    override fun onUpdate() {
+        val num = NurseHome2Activity.callingList.size
+        if (num > 9) {
+            showCallList()
+        } else if (num > 0) {
+            showCallList()
+        } else {
+            dorm_ll_call_list.visibility =View.GONE
+            call_records_refresh.visibility = View.VISIBLE
+        }
+    }
+}

+ 305 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/DormDialCallFragment.kt

@@ -0,0 +1,305 @@
+package com.wdkl.ncs.android.component.nursehome.dorm
+
+import android.text.Editable
+import android.text.TextUtils
+import android.text.TextWatcher
+import android.util.Log
+import androidx.recyclerview.widget.GridLayoutManager
+import com.alibaba.android.vlayout.VirtualLayoutManager
+import com.enation.javashop.net.engine.model.NetState
+import com.scwang.smartrefresh.layout.footer.ClassicsFooter
+import com.wdkl.ncs.android.component.nursehome.R
+import com.wdkl.ncs.android.component.nursehome.activity.NurseHome2Activity
+import com.wdkl.ncs.android.component.nursehome.databinding.DormDialCallBinding
+import com.wdkl.ncs.android.component.nursehome.dorm.adapter.DormDialCallSearchAdapter
+import com.wdkl.ncs.android.component.nursehome.dorm.search.DeviceSearchItem
+import com.wdkl.ncs.android.component.nursehome.dorm.search.PinyinUtil
+import com.wdkl.ncs.android.component.nursehome.launch.NurseHomeLaunch
+
+import com.wdkl.ncs.android.lib.base.BaseFragment
+import com.wdkl.ncs.android.lib.core.locale.LocaleMangerUtils
+import com.wdkl.ncs.android.lib.utils.showMessage
+import com.wdkl.ncs.android.lib.vo.filter
+import com.wdkl.ncs.android.middleware.common.Constant
+import com.wdkl.ncs.android.middleware.logic.contract.callingbed.BedCallRecordsFragmentContract
+import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.BedCallRecordsFragmentPresenter
+import com.wdkl.ncs.android.middleware.model.dos.EventDO
+import com.wdkl.ncs.android.middleware.model.vo.CallRecordVO
+import com.wdkl.ncs.android.middleware.model.vo.DeviceVO
+import com.wdkl.ncs.android.middleware.tcp.enums.DeviceTypeEnum
+import kotlinx.android.synthetic.main.dorm_dial_call.*
+import java.util.*
+import kotlin.collections.ArrayList
+
+class  DormDialCallFragment : BaseFragment<BedCallRecordsFragmentPresenter, DormDialCallBinding>(), BedCallRecordsFragmentContract.View,
+    DormDialCallSearchAdapter.ActionClickListener {
+    var TAG = DormDialCallFragment::class.java.getSimpleName()
+
+    private lateinit var adapter: DormDialCallSearchAdapter
+    private lateinit var virtualLayoutManager: VirtualLayoutManager
+
+    private var language = "zh"
+    private var clickCallTime: Long = 0
+
+    private var searchText = ""
+    private val reg = Regex("[a-z]+", RegexOption.IGNORE_CASE)
+
+    override fun getLayId(): Int {
+        return R.layout.dorm_dial_call
+    }
+
+    override fun bindDagger() {
+        NurseHomeLaunch.component.inject(this)
+    }
+
+    override fun init() {
+        adapter = DormDialCallSearchAdapter(null, ArrayList(), activity)
+
+        /**初始化LayoutMannager*/
+        virtualLayoutManager = VirtualLayoutManager(this.activity)
+        val layoutManager = GridLayoutManager(getActivity(), 1)
+        frame_device_rv.setLayoutManager(layoutManager)
+
+        mViewDataBinding.dialCallRefresh.setRefreshFooter(ClassicsFooter(activity))
+
+        language = LocaleMangerUtils.getApplicationLocale().language
+
+        /**配置到RecycleView*/
+        frame_device_rv.layoutManager = virtualLayoutManager
+        frame_device_rv.adapter = adapter
+
+        adapter.setActionClickListener(this)
+
+        if (Constant.PART_ID != null) {
+            presenter.loadFrameDevices(DeviceTypeEnum.DIGIT_BED_DEVICE.value(), Constant.PART_ID)
+        }
+    }
+
+    override fun bindEvent() {
+        //下拉刷新
+        mViewDataBinding.dialCallRefresh.setOnRefreshListener {
+            presenter.loadFrameDevices(DeviceTypeEnum.DIGIT_BED_DEVICE.value(), Constant.PART_ID)
+        }
+
+        //监听搜索框输入
+        dial_call_search.addTextChangedListener(object : TextWatcher {
+            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+                Log.e(TAG, "onTextChanged: $s")
+                if (TextUtils.isDigitsOnly(s)) {
+                    //搜索过滤
+                    adapter.filter.filter(s)
+                } else {
+                    adapter.filter.filter("")
+                }
+            }
+
+            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
+                //
+            }
+
+            override fun afterTextChanged(s: Editable) {
+                //
+            }
+        })
+
+        tv_search_num_1.setOnClickListener {
+            if (searchText.length > 10) {
+                showMessage("超出最大长度")
+            } else {
+                searchText += "1"
+                dial_call_search.text = searchText
+            }
+        }
+
+        tv_search_num_2.setOnClickListener {
+            if (searchText.length > 10) {
+                showMessage("超出最大长度")
+            } else {
+                searchText += "2"
+                dial_call_search.text = searchText
+            }
+        }
+
+        tv_search_num_3.setOnClickListener {
+            if (searchText.length > 10) {
+                showMessage("超出最大长度")
+            } else {
+                searchText += "3"
+                dial_call_search.text = searchText
+            }
+        }
+
+        tv_search_num_4.setOnClickListener {
+            if (searchText.length > 10) {
+                showMessage("超出最大长度")
+            } else {
+                searchText += "4"
+                dial_call_search.text = searchText
+            }
+        }
+
+        tv_search_num_5.setOnClickListener {
+            if (searchText.length > 10) {
+                showMessage("超出最大长度")
+            } else {
+                searchText += "5"
+                dial_call_search.text = searchText
+            }
+        }
+
+        tv_search_num_6.setOnClickListener {
+            if (searchText.length > 10) {
+                showMessage("超出最大长度")
+            } else {
+                searchText += "6"
+                dial_call_search.text = searchText
+            }
+        }
+
+        tv_search_num_7.setOnClickListener {
+            if (searchText.length > 10) {
+                showMessage("超出最大长度")
+            } else {
+                searchText += "7"
+                dial_call_search.text = searchText
+            }
+        }
+
+        tv_search_num_8.setOnClickListener {
+            if (searchText.length > 10) {
+                showMessage("超出最大长度")
+            } else {
+                searchText += "8"
+                dial_call_search.text = searchText
+            }
+        }
+
+        tv_search_num_9.setOnClickListener {
+            if (searchText.length > 10) {
+                showMessage("超出最大长度")
+            } else {
+                searchText += "9"
+                dial_call_search.text = searchText
+            }
+        }
+
+        tv_search_num_0.setOnClickListener {
+            if (searchText.length > 10) {
+                showMessage("超出最大长度")
+            } else {
+                searchText += "0"
+                dial_call_search.text = searchText
+            }
+        }
+
+        tv_search_num_del.setOnClickListener {
+            val len = searchText.length
+            if (len == 1) {
+                searchText = ""
+                dial_call_search.text = "房号搜索"
+            } else if (len > 1) {
+                searchText = searchText.substring(0, len-1)
+                dial_call_search.text = searchText
+            }
+        }
+
+
+
+
+
+
+
+
+
+    }
+
+    override fun destory() {
+
+    }
+
+
+    override fun showCallRecords(record: CallRecordVO) {
+
+    }
+
+    override fun showEvents(data: ArrayList<EventDO>) {
+        //
+    }
+
+    override fun showFrameDevices(data: ArrayList<DeviceVO>) {
+        mViewDataBinding.dialCallRefresh.finishRefresh()
+
+        if (data.size > 0) {
+            val sortList = ArrayList<DeviceSearchItem>()
+            for (device in data) {
+                var letter: String
+                if (device.id != Constant.DEVICE_ID) {
+                    //排除本机设备
+                    val pinyinList = PinyinUtil.getPinYinList(device.fullName)
+                    letter = if (pinyinList != null && pinyinList.isNotEmpty()) {
+                        // A-Z导航
+                        val letters = pinyinList[0].substring(0, 1)
+                        // 正则表达式,判断首字母是否是英文字母
+                        if (letters.matches(reg)) {
+                            letters.toUpperCase(Locale.ROOT)
+                        } else {
+                            "#"
+                        }
+                    } else {
+                        "#"
+                    }
+
+                    val item = DeviceSearchItem(
+                        device.fullName,
+                        device.id,
+                        letter,
+                        pinyinList
+                    )
+                    sortList.add(item)
+                }
+            }
+
+            adapter.setDataList(sortList)
+        }
+    }
+
+
+    override fun onError(message: String, type: Int) {
+        mViewDataBinding.dialCallRefresh.finishRefresh()
+        showMessage(message)
+    }
+
+    override fun complete(message: String, type: Int) {
+    }
+
+    override fun start() {
+    }
+
+    override fun networkMonitor(state: NetState) {
+        state.filter(onWifi = {
+
+        },onMobile = {
+
+        },offline = {
+
+        })
+    }
+
+    override fun onCallRole(role: String?) {
+
+    }
+
+    override fun onCallDevice(deviceId: Int?) {
+        if (deviceId == null) {
+            showMessage("设备id为空")
+        } else {
+            val time = System.currentTimeMillis()
+            if (time - clickCallTime > 3000) {
+                clickCallTime = time
+                (activity as NurseHome2Activity).startCallDevice(deviceId)
+            } else {
+                showMessage(R.string.wait_moment)
+            }
+        }
+    }
+}

+ 374 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/DormSipCallFragment.kt

@@ -0,0 +1,374 @@
+package com.wdkl.ncs.android.component.nursehome.dorm
+
+import android.os.*
+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.R
+import com.wdkl.ncs.android.component.nursehome.fragment.BaseCallFragment
+import com.wdkl.ncs.android.component.nursehome.helper.SoundPoolManager
+import com.wdkl.ncs.android.component.nursehome.settingconfig.SettingConfig
+import com.wdkl.ncs.android.component.nursehome.sip.core.LinphoneManager
+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
+import com.wdkl.ncs.android.middleware.common.MessageEvent
+import com.wdkl.ncs.android.middleware.model.bean.SettingConfiguration
+import com.wdkl.ncs.android.middleware.model.dos.InteractionDO
+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
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpType
+import kotlinx.android.synthetic.main.dorm_sky_voice_call_layout.*
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+import org.linphone.core.Core
+
+class DormSipCallFragment: BaseCallFragment() {
+    private val TAG = "SipCallFragment"
+
+    private val handler = Handler(Looper.getMainLooper())
+
+    private var callEnded: Boolean = false
+
+    private var outGoing: Boolean = false
+
+    //呼叫倒计时
+    lateinit var countDownTimer: CountDownTimer
+
+    private var volume = 60
+
+    private var linphoneManager: LinphoneManager? = null
+
+    override fun getLayId(): Int {
+        return R.layout.dorm_sky_voice_call_layout
+    }
+
+    override fun init() {
+        //设置主题背景
+        try {
+            val resId = SettingConfig.getDormThemeBgId(BaseApplication.appContext)
+            if (resId != 0) {
+                dorm_calling_bed_layout_call_main.setBackgroundResource(resId)
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+
+        initCountDownTimer()
+
+        linphoneManager = LinphoneManager.getInstance(BaseApplication.appContext)
+        linphoneManager?.setMicGainDb(0f)
+
+        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)
+        linphoneManager?.enableMic(true)
+
+        Log.d(TAG, "callState: $callState, local sip: ${Constant.SIP_ID}, target sip: ${Constant.targetSipId}")
+        when (callState) {
+            0 -> {
+                //发起通话
+                outGoing = true
+                showCallView(true)
+                Constant.CALL_STATE = Constant.CALL_OUTGOING
+                DeviceChannel.calling = true
+                Constant.IN_CALL = true
+                RingPlayHelper.playRingTone(BaseApplication.appContext, R.raw.ring_back2, true)
+            }
+
+            1 -> {
+                //接受通话
+                outGoing = false
+                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())
+            }
+        }
+    }
+
+    private fun initCountDownTimer() {
+        if (SettingConfiguration.getInstance().sipOvertime <= 0) {
+            SettingConfiguration.getInstance().sipOvertime = 30
+        }
+
+        countDownTimer = object: CountDownTimer(SettingConfiguration.getInstance().sipOvertime * 1000L, 1000) {
+            override fun onTick(millisUntilFinished: Long) {
+                val time = millisUntilFinished/1000
+                val timeText = getString(R.string.countdown_time, time)
+                sky_voice_call_timer.setText(timeText)
+            }
+
+            override fun onFinish() {
+                //呼叫超时,退出呼叫界面
+                showMessage(R.string.no_response)
+                DeviceChannel.calling = false
+                Constant.CALL_STATE = Constant.CALL_STANDBY
+                cancelCall(Constant.DEVICE_ID, Constant.targetDeviceId, Constant.interactionId)
+                callEnd(false)
+            }
+        }
+    }
+
+    override fun bindEvent() {
+
+        dorm_sos_but.setOnClickListener {
+            //紧急呼叫
+            if (Constant.TCP_CONNECTED) {
+                val tcpModel = OtherUtil.SOSCall(Constant.DEVICE_ID)
+                TcpClient.getInstance().sendMsg(tcpModel.toJson())
+
+                SoundPoolManager.getInstance().playSound(7, 1.0f, 1.0f, 0)
+            }
+        }
+        //通话挂断
+        sky_voice_call_hangup.setOnClickListener {
+            if (Constant.CALL_STATE == Constant.CALL_CALLING) {
+                callEnd(true)
+            } else {
+                countDownTimer.cancel()
+                cancelCall(Constant.DEVICE_ID, Constant.targetDeviceId, Constant.interactionId)
+                callEnd(false)
+            }
+
+            Constant.CALL_STATE = Constant.CALL_STANDBY
+            DeviceChannel.calling = false
+        }
+
+        sky_voice_call_mute.setOnClickListener {
+            val micEnable = linphoneManager?.micEnabled()
+            Log.d(TAG,"mic enable: $micEnable")
+
+            if (micEnable == true) {
+                linphoneManager?.enableMic(false)
+                sky_voice_call_mute.isSelected = true
+            } else {
+                linphoneManager?.enableMic(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() {
+        linphoneManager?.terminateCall()
+    }
+
+    override fun destroy() {
+        Constant.showCall = false
+        Constant.IN_CALL = false
+        RingPlayHelper.stopRingTone()
+        Constant.CALL_STATE = Constant.CALL_STANDBY
+        DeviceChannel.calling = false
+        if (sky_voice_call_timer != null) {
+            sky_voice_call_timer.stop()
+        }
+        handler.removeCallbacksAndMessages(null)
+    }
+
+    //开始接听
+    private fun showCallView(outgoing: Boolean) {
+        dorm_sky_call_name.text = callName
+        if (outgoing) {
+            countDownTimer.start()
+            sky_voice_call_calling_text.setText(R.string.call_in_calling)
+        } else {
+            sky_voice_call_calling_text.setText(R.string.call_connecting)
+        }
+        sky_voice_call_outgoing.visibility = View.VISIBLE
+        sky_voice_call_timer.visibility = View.GONE
+        Constant.showCall = true
+    }
+
+    private fun showCalling(audioOnly: Boolean) {
+        if (callEnded) {
+            return
+        }
+
+        showMessage("Call connected!")
+
+        if (Constant.hookOn) {
+            //免提
+            toggleSpeaker(true)
+        } else {
+            //听筒
+            toggleSpeaker(false)
+        }
+
+        if (audioOnly) {
+            ll_voice_call.visibility = View.VISIBLE
+        } else {
+            //显示视频画面
+            fullscreen_video_frame.visibility = View.VISIBLE
+            pip_video_frame.visibility = View.VISIBLE
+            ll_voice_call.visibility = View.GONE
+
+//            if (visiting) {
+//                visit_list_view.setVisibility(View.VISIBLE)
+//            }
+        }
+
+        sky_voice_call_calling_text.setText(R.string.call_in_call)
+        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?) {
+        val callTcp = VoiceUtil.voiceCancel(tid, fromId, toId, interactionId)
+        TcpClient.getInstance().sendMsg(callTcp.toJson())
+    }
+
+    //通话结束
+    private fun callEnd(handoff: Boolean) {
+        Log.e(TAG, ">>>>>>>>>>> call end !!!!!!!!!!!!!!!!!!")
+        RingPlayHelper.stopRingTone()
+        countDownTimer.cancel()
+        synchronized(this) {
+            if (callEnded) {
+                return
+            }
+            callEnded = true
+
+            if (sky_voice_call_timer != null) {
+                sky_voice_call_timer.stop()
+            }
+
+            callTerminate()
+
+            Constant.CALL_STATE = Constant.CALL_STANDBY
+            DeviceChannel.calling = false
+            if (handoff) {
+                val callTcp = VoiceUtil.voiceHandoff(tid, Constant.DEVICE_ID, Constant.fromId, Constant.interactionId)
+                TcpClient.getInstance().sendMsg(callTcp.toJson())
+            }
+            Constant.interactionId = null
+
+            backToMain()
+        }
+    }
+
+    private fun toggleSpeaker(enable: Boolean) {
+        Log.d(TAG, "toggle speaker: $enable")
+
+        //rk3128主机无需免提切换
+        if (Build.MODEL != "rk3128") {
+            linphoneManager?.enableSpeaker(enable)
+        }
+    }
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    fun onMoonEvent(messageEvent: MessageEvent) {
+        when (messageEvent.getType()) {
+            Constant.EVENT_TCP_MSG -> {
+                if (messageEvent.getMessage() is TcpModel) {
+                    val curTcpModel = messageEvent.getMessage() as TcpModel
+                    if (curTcpModel.type == TcpType.VOICE) {
+                        val curIt = Gson().fromJson(curTcpModel.data.toString(), InteractionDO::class.java)
+                        if (curTcpModel.action == TcpAction.VoiceAction.HANDOFF) {
+                            //对方挂断,不论我方呼出或呼入
+                            if (Constant.interactionId == curIt.id) {
+                                callEnd(false)
+                            }
+                        } else if (curTcpModel.action == TcpAction.VoiceAction.ACCEPT) {//对方接受语音
+                            RingPlayHelper.stopRingTone()
+                            sky_voice_call_calling_text.setText(R.string.call_connecting)
+                            Constant.interactionId = curIt.id
+                            Constant.fromId = curTcpModel.fromId
+                            DeviceChannel.calling = true
+                            Constant.CALL_STATE = Constant.CALL_CALLING
+                            countDownTimer.cancel()
+
+                            if (TextUtils.isEmpty(curIt.toSipId)) {
+                                //通话失败,重置并返回主界面
+                                showMessage("targetSipId is null!")
+                                Constant.CALL_STATE = Constant.CALL_STANDBY
+                                if (sky_voice_call_timer != null) {
+                                    sky_voice_call_timer.stop()
+                                }
+                                callEnd(true)
+                            } else {
+                                linphoneManager?.startCall(curIt.toSipId, false)
+                            }
+                        } else if (curTcpModel.action == TcpAction.VoiceAction.REJECT) {//对方拒绝
+                            if (Constant.interactionId == curIt.id) {
+                                showMessage(R.string.call_reject)
+                                Constant.CALL_STATE = Constant.CALL_STANDBY
+                                DeviceChannel.calling = false
+                                callEnd(false)
+                            }
+                        }
+                    }
+                }
+            }
+
+            Constant.EVENT_END_CALL -> {
+                Log.d(TAG, ">>>>>>>>>>>>>> EVENT_END_CALL")
+                showMessage("Call end!")
+                if (messageEvent.getMessage() is String) {
+                    val str = messageEvent.getMessage() as String
+                    if (str.equals("cancel")) {
+                        cancelCall(Constant.DEVICE_ID, Constant.targetDeviceId, Constant.interactionId)
+                        callEnd(false)
+                    } else {
+                        callEnd(true)
+                    }
+                }
+            }
+
+            Constant.SIP_CONNECTED -> {
+                Constant.IN_CALL = true
+                showCalling(true)
+            }
+
+            Constant.EVENT_TOGGLE_SPEAKER -> {
+                if (Constant.hookOn) {
+                    //手柄放下
+                    toggleSpeaker(true)
+                } else {
+                    toggleSpeaker(false)
+                }
+            }
+        }
+    }
+
+}

+ 798 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/DormSkyCallFragment.kt

@@ -0,0 +1,798 @@
+package com.wdkl.ncs.android.component.nursehome.dorm
+
+import android.media.AudioManager
+import android.os.CountDownTimer
+import android.os.Handler
+import android.os.Looper
+import android.os.SystemClock
+import android.util.Log
+import android.view.View
+import android.view.ViewGroup
+import android.widget.SeekBar
+import com.alibaba.android.vlayout.VirtualLayoutManager
+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.fragment.BaseCallFragment
+import com.wdkl.ncs.android.component.nursehome.helper.SoundPoolManager
+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.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.showMessage
+import com.wdkl.ncs.android.middleware.common.Constant
+import com.wdkl.ncs.android.middleware.common.MessageEvent
+import com.wdkl.ncs.android.middleware.model.bean.SettingConfiguration
+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.VideoUtil
+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.DeviceTypeEnum
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpAction
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpType
+import com.wdkl.ncs.android.middleware.utils.CommonUtils
+import com.wdkl.ncs.android.middleware.utils.StringUtil
+import com.wdkl.ncs.janus.client.CallSessionCallback
+import com.wdkl.ncs.janus.client.JanusClient
+import com.wdkl.ncs.janus.client.VideoRoomCallback
+import com.wdkl.ncs.janus.entity.Room
+import com.wdkl.ncs.janus.rtc.WebRTCEngine
+import com.wdkl.ncs.janus.util.EnumType
+import com.wdkl.ncs.janus.util.JanusConstant
+import kotlinx.android.synthetic.main.dorm_sky_voice_call_layout.*
+import kotlinx.android.synthetic.main.dorm_sky_voice_call_layout.call_volume_bar
+import kotlinx.android.synthetic.main.dorm_sky_voice_call_layout.fullscreen_video_frame
+import kotlinx.android.synthetic.main.dorm_sky_voice_call_layout.ll_voice_call
+import kotlinx.android.synthetic.main.dorm_sky_voice_call_layout.ll_voice_volume_bar
+import kotlinx.android.synthetic.main.dorm_sky_voice_call_layout.pip_video_frame
+import kotlinx.android.synthetic.main.dorm_sky_voice_call_layout.sky_voice_call_calling_text
+import kotlinx.android.synthetic.main.dorm_sky_voice_call_layout.sky_voice_call_hangup
+import kotlinx.android.synthetic.main.dorm_sky_voice_call_layout.sky_voice_call_incoming
+import kotlinx.android.synthetic.main.dorm_sky_voice_call_layout.sky_voice_call_mute
+import kotlinx.android.synthetic.main.dorm_sky_voice_call_layout.sky_voice_call_outgoing
+import kotlinx.android.synthetic.main.dorm_sky_voice_call_layout.sky_voice_call_timer
+import kotlinx.android.synthetic.main.dorm_sky_voice_call_layout.tv_volume
+import kotlinx.android.synthetic.main.sky_voice_call_layout.*
+
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+import org.webrtc.SurfaceViewRenderer
+import java.math.BigInteger
+
+class DormSkyCallFragment: BaseCallFragment(), CallSessionCallback {
+    private val TAG = "SkyCallFragment"
+
+    private var localSurfaceView: SurfaceViewRenderer? = null
+    private var remoteSurfaceView: SurfaceViewRenderer? = null
+
+    private var bedItemAdapter: BedItemAdapter? = null
+    private val handler = Handler(Looper.getMainLooper())
+
+    private var callEnded: Boolean = false
+    private var outGoing: Boolean = false
+    private var acceptCall = false
+
+    //呼叫倒计时
+    lateinit var countDownTimer: CountDownTimer
+
+    private var janusClient: JanusClient? = null
+    private var room: Room?=null
+    private var videoRoomCallback: VideoRoomCallback? = null
+
+    private var visitUserId: BigInteger? = null
+    private var inVisiting = false
+    private var inCallShow = false
+    private var invitedBed = false
+    private var speakerMute = false
+
+    private var micMute: Boolean = false // 是否关闭麦克风
+
+    private var volume = 60
+
+    override fun getLayId(): Int {
+        return R.layout.dorm_sky_voice_call_layout
+    }
+
+    override fun init() {
+        //设置主题背景
+        try {
+            val resId = SettingConfig.getDormThemeBgId(BaseApplication.appContext)
+            if (resId != 0) {
+                dorm_calling_bed_layout_call_main.setBackgroundResource(resId)
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+
+        showui()
+        initCountDownTimer()
+        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)
+        VoiceManagerUtil.setAudioMute(BaseApplication.appContext, false)
+
+        //初始化 engine
+        if (onlyAudio) {
+            WebRTCEngine.getInstance().init(true, BaseApplication.appContext)
+        } else {
+            WebRTCEngine.getInstance().init(false, BaseApplication.appContext)
+        }
+        //初始化 janusClient
+        janusClient = JanusClient(JanusConstant.JANUS_URL, Constant.SIP_ID!!.toBigInteger())
+
+
+        Log.d(TAG, "out call callState: $callState, local sip: ${Constant.SIP_ID}, target sip: ${Constant.targetSipId}")
+        when (callState) {
+            0 -> {
+                //发起通话
+                outGoing = true
+                janusClient!!.callState = EnumType.CallState.Outgoing
+                room = Room(Constant.SIP_ID!!.toBigInteger())
+                showCallView(true)
+                Constant.CALL_STATE = Constant.CALL_OUTGOING
+                DeviceChannel.calling = true
+                RingPlayHelper.playRingTone(BaseApplication.appContext, R.raw.ring_back2, true)
+                Constant.IN_CALL = true
+            }
+
+            1 -> {
+                //来电,如果是模拟分机呼叫则需要主机来创建房间发起通过
+                if (Constant.fromDeviceType == DeviceTypeEnum.SIMULATE_BED_DEVICE.value()) {
+                    outGoing = true
+                    janusClient!!.callState = EnumType.CallState.Outgoing
+                    room = Room(Constant.SIP_ID!!.toBigInteger())
+                    showCallView(false)
+                } else {
+                    //接受通话
+                    outGoing = false
+                    janusClient!!.callState = EnumType.CallState.Incoming
+                    room = Room(Constant.targetSipId!!.toBigInteger())
+                    showCallView(false)
+                }
+
+                if (!visiting && onlyAudio) {
+                    //接听呼叫
+                    acceptCall = true
+                }
+                Constant.CALL_STATE = Constant.CALL_CALLING
+            }
+        }
+
+        videoRoomCallback = VideoRoomCallback(janusClient, room, Constant.SIP_ID!!.toBigInteger())
+        videoRoomCallback!!.callSessionCallback = this
+        janusClient!!.setJanusCallback(videoRoomCallback)
+
+        if (!visiting) {
+            if (onlyAudio || outGoing) {
+                if (outGoing) {
+                    if (SettingConfig.getRecordEnable(activity)) {
+                        janusClient!!.connect(interactionVO!!.id, true)
+                    } else {
+                        janusClient!!.connect(-1, false)
+                    }
+                } else {
+                    janusClient!!.connect(-1, false)
+                }
+            }
+        }
+
+        WebRTCEngine.getInstance().setVolumeMute(false)
+    }
+    private fun showui(){
+        //网络图标
+        if (Constant.network_state == 1){
+            title_layout_iv_hl_wifi.visibility = View.VISIBLE
+            title_layout_iv_hl_ethernet.visibility = View.GONE
+            title_layout_iv_hl_wifi.setImageResource(R.mipmap.ic_wifi_fail)
+        }else if ( Constant.network_state == 2){
+            title_layout_iv_hl_wifi.visibility = View.GONE
+            title_layout_iv_hl_ethernet.visibility = View.VISIBLE
+            title_layout_iv_hl_ethernet.setImageResource(R.mipmap.ic_ethernet_success_w)
+        }else{
+            title_layout_iv_hl_wifi.visibility = View.GONE
+            title_layout_iv_hl_ethernet.visibility = View.VISIBLE
+            title_layout_iv_hl_ethernet.setImageResource(R.mipmap.ic_ethernet_fail)
+        }
+
+        if (SettingConfig.getSipEnabled(activity)) {
+            title_layout_tv_hl_point.visibility = View.VISIBLE
+        } else {
+            title_layout_tv_hl_point.visibility = View.GONE
+        }
+
+        //蓝牙图标
+        if (Constant.BT_state == 0) {
+            title_layout_iv_hl_bt.setImageResource(R.mipmap.lanya_b)
+            title_layout_iv_hl_bt.visibility = View.VISIBLE
+        } else {
+            title_layout_iv_hl_bt.visibility = View.GONE
+        }
+
+        //白天/黑夜
+        if (Constant.day_state == 0){
+            title_layout_iv_day_hl_night.setImageResource(R.mipmap.ic_daylight_w)
+        }else{
+            title_layout_iv_day_hl_night.setImageResource(R.mipmap.ic_night_w)
+        }
+    }
+    private fun initCountDownTimer() {
+        if (SettingConfiguration.getInstance().sipOvertime <= 0) {
+            SettingConfiguration.getInstance().sipOvertime = 30
+        }
+
+        countDownTimer = object: CountDownTimer(SettingConfiguration.getInstance().sipOvertime*1000L, 1000) {
+            override fun onTick(millisUntilFinished: Long) {
+                //
+            }
+
+            override fun onFinish() {
+                //呼叫超时,退出呼叫界面
+                showMessage(R.string.no_response)
+                DeviceChannel.calling = false
+                Constant.CALL_STATE = Constant.CALL_STANDBY
+                cancelCall(Constant.DEVICE_ID, Constant.targetDeviceId, Constant.interactionId)
+                callEnd(false)
+            }
+        }
+    }
+
+    private fun bindListener() {
+        bedItemAdapter!!.setInvitClickListener { bedVO ->
+            if (!invitedBed) {
+                invitedBed = true
+                Constant.visitedId = bedVO.bedDeviceId
+                visit_list_view.visibility = View.GONE
+                Constant.visit_bed_name = bedVO.frameBed.fullName
+
+                //邀请分机加入探视
+                val callTcp = VideoUtil.videoInvite(tid, Constant.DEVICE_ID, bedVO.bedDeviceId, Constant.interactionId, Constant.targetSipId)
+                TcpClient.getInstance().sendMsg(callTcp.toJson())
+            } else {
+                showMessage("invited..." + Constant.visit_bed_name)
+            }
+        }
+    }
+
+    override fun bindEvent() {
+        //通话挂断
+        sky_voice_call_hangup.setOnClickListener {
+            if (Constant.CALL_STATE == Constant.CALL_CALLING) {
+                callEnd(true)
+            } else if (Constant.CALL_STATE == Constant.CALL_OUTGOING) {
+                countDownTimer.cancel()
+                cancelCall(Constant.DEVICE_ID, Constant.targetDeviceId, Constant.interactionId)
+                callEnd(false)
+            } else {
+                callEnd(true)
+            }
+
+            Constant.CALL_STATE = Constant.CALL_STANDBY
+            DeviceChannel.calling = false
+        }
+
+
+        dorm_sos_but.setOnClickListener {
+            //紧急呼叫
+            if (Constant.TCP_CONNECTED) {
+                val tcpModel = OtherUtil.SOSCall(Constant.DEVICE_ID)
+                TcpClient.getInstance().sendMsg(tcpModel.toJson())
+                SoundPoolManager.getInstance().playSound(7, 1.0f, 1.0f, 0)
+            }
+        }
+
+//        iv_accept_call.setOnClickListener {
+//            //视频接听
+//            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)
+//        }
+
+//        iv_reject_call.setOnClickListener {
+//            //视频拒绝
+//            RingPlayHelper.stopRingTone()
+//            SpeechUtil.getInstance().stopSpeak(true)
+//            if (visiting) {
+//                val callTcp = VideoUtil.videoReject(tid, Constant.DEVICE_ID, fromId, interactionVO?.id)
+//                TcpClient.getInstance().sendMsg(callTcp.toJson())
+//            } else {
+//                val callTcp = VoiceUtil.voiceReject(tid, Constant.DEVICE_ID, fromId, interactionVO?.id)
+//                TcpClient.getInstance().sendMsg(callTcp.toJson())
+//            }
+//
+//            callEnd(false)
+//        }
+
+        sky_voice_call_speaker.setOnClickListener {
+            speakerMute = !speakerMute
+            Log.d(TAG,"Speaker enable: $speakerMute")
+
+            WebRTCEngine.getInstance().setVolumeMute(speakerMute)
+            sky_voice_call_speaker.isSelected = speakerMute
+        }
+
+        sky_voice_call_mute.setOnClickListener {
+            micMute = !micMute
+            Log.d(TAG,"静音切换: $micMute")
+
+            WebRTCEngine.getInstance().muteAudio(micMute)
+            sky_voice_call_mute.isSelected = micMute
+        }
+
+        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)
+                }
+            }
+        })
+    }
+
+    override fun destroy() {
+        Constant.IN_CALL = false
+        Constant.CALL_STATE = Constant.CALL_STANDBY
+        DeviceChannel.calling = false
+        if (sky_voice_call_timer != null) {
+            sky_voice_call_timer.stop()
+        }
+        handler.removeCallbacksAndMessages(null)
+        VoiceManagerUtil.setAudioMode(BaseApplication.appContext, AudioManager.MODE_NORMAL)
+    }
+
+    //开始接听
+    private fun showCallView(outgoing: Boolean) {
+        if (outgoing) {
+            countDownTimer.start()
+            sky_voice_call_calling_text.text = StringUtil.getResString(R.string.call_in_calling) + " " + callName
+            sky_voice_call_outgoing.visibility = View.VISIBLE
+            sky_voice_call_incoming.visibility = View.GONE
+
+            if (!onlyAudio) {
+                //显示视频画面
+                fullscreen_video_frame.visibility = View.VISIBLE
+                pip_video_frame.visibility = View.VISIBLE
+            }
+        } else {
+            dorm_sky_call_name.text = callName
+            if (onlyAudio) {
+                sky_voice_call_calling_text.setText(R.string.call_connecting)
+                sky_voice_call_outgoing.visibility = View.VISIBLE
+                sky_voice_call_incoming.visibility = View.GONE
+            } else {
+                if (visiting) {
+                    sky_voice_call_calling_text.setText(R.string.call_visiting)
+                } else {
+                    sky_voice_call_calling_text.setText(R.string.call_video_call)
+                }
+                sky_voice_call_outgoing.visibility = View.GONE
+                sky_voice_call_incoming.visibility = View.VISIBLE
+            }
+        }
+        //sky_voice_call_outgoing.visibility = View.VISIBLE
+        sky_voice_call_timer.visibility = View.GONE
+    }
+
+    private fun showCalling(audioOnly: Boolean) {
+        if (callEnded || inCallShow) {
+            return
+        }
+
+        inCallShow = true
+        dorm_sky_call_name.text = callName
+        if (audioOnly) {
+            ll_voice_call.visibility = View.VISIBLE
+        } else {
+            //显示视频画面
+            fullscreen_video_frame.visibility = View.VISIBLE
+            pip_video_frame.visibility = View.VISIBLE
+
+//            if (visiting) {
+//                video_visit_call_view.visibility = View.VISIBLE
+//                video_call_view.visibility = View.GONE
+//            } else {
+//                video_visit_call_view.visibility = View.GONE
+//                video_call_view.visibility = View.VISIBLE
+//            }
+            ll_voice_call.visibility = View.GONE
+        }
+
+        sky_voice_call_outgoing.visibility = View.VISIBLE
+        sky_voice_call_incoming.visibility = View.GONE
+
+        sky_voice_call_calling_text.setText(R.string.call_in_call)
+        sky_voice_call_timer.visibility = View.VISIBLE
+        sky_voice_call_timer.base = SystemClock.elapsedRealtime()
+        sky_voice_call_timer.start()
+
+        sky_voice_call_speaker.visibility = View.VISIBLE
+        sky_voice_call_mute.visibility = View.VISIBLE
+        ll_voice_volume_bar.visibility = View.VISIBLE
+
+        if (Constant.hookOn) {
+            //手柄放下,免提模式
+            //VoiceManagerUtil.switchAudioMode(BaseApplication.appContext, true)
+            WebRTCEngine.getInstance().toggleSpeaker(true)
+        } else {
+            //手柄拿起,听筒模式
+            //VoiceManagerUtil.switchAudioMode(BaseApplication.appContext, false)
+            WebRTCEngine.getInstance().toggleSpeaker(false)
+        }
+    }
+
+    private fun cancelCall(fromId: Int, toId: Int?, interactionId: Int?) {
+        val callTcp = VoiceUtil.voiceCancel(tid, fromId, toId, interactionId)
+        TcpClient.getInstance().sendMsg(callTcp.toJson())
+    }
+
+    //通话结束
+    private fun callEnd(handoff: Boolean) {
+        Log.e(TAG, "call end !!!!!!!!!!!!!!!!!!")
+        RingPlayHelper.stopRingTone()
+        countDownTimer.cancel()
+
+        Constant.CALL_STATE = Constant.CALL_STANDBY
+        DeviceChannel.calling = false
+
+        synchronized(this) {
+            if (callEnded) {
+                return
+            }
+            callEnded = true
+
+            if (sky_voice_call_timer != null) {
+                sky_voice_call_timer.stop()
+            }
+
+            if (janusClient != null && janusClient!!.webSocketChannel !=null) {
+                janusClient!!.callState = EnumType.CallState.Idle
+                if (outGoing){
+                    if (janusClient!!.currentHandleId !=null) {
+                        janusClient!!.destroyRoom(janusClient!!.currentHandleId, null)
+                    }
+                } else {
+                    janusClient!!.leaveRoom()
+                }
+
+                janusClient!!.setJanusCallback(null)
+                janusClient!!.disConnect()
+            }
+
+            if (handoff) {
+                if (visiting) {
+                    val callTcp = VideoUtil.videoHandoff(tid, Constant.DEVICE_ID, Constant.fromId, Constant.interactionId)
+                    TcpClient.getInstance().sendMsg(callTcp.toJson())
+                } else {
+                    val callTcp = VoiceUtil.voiceHandoff(tid, Constant.DEVICE_ID, Constant.fromId, Constant.interactionId)
+                    TcpClient.getInstance().sendMsg(callTcp.toJson())
+                }
+            }
+            Constant.interactionId = null
+
+            backToMain()
+        }
+    }
+
+
+    /********************************************************
+     ********************* webrtc通话回调 ********************
+     * 注意: 如涉及到UI更新的需要在主线程处理,务必注意
+     *******************************************************/
+    override fun didRoomCreated() {
+        //房间创建成功,如果是接听通话则通知对方加入通话
+        if (!callEnded && acceptCall) {
+            Log.d(TAG, "room created, accept call...")
+            val callTcp = VoiceUtil.voiceAccept(tid, Constant.DEVICE_ID, fromId, interactionVO?.id)
+            TcpClient.getInstance().sendMsg(callTcp.toJson())
+        }
+    }
+
+    override fun didIceConnectFail() {
+
+    }
+
+    override fun didSlowLink() {
+
+    }
+
+    override fun didChangeState(state: EnumType.CallState?) {
+        Log.e(TAG, "didChangeState: " + state)
+        handler.post {
+            if (state == EnumType.CallState.Connected && !callEnded) {
+                RingPlayHelper.stopRingTone()
+                Constant.CALL_STATE = Constant.CALL_CALLING
+                DeviceChannel.calling = true
+                Constant.IN_CALL = true
+                //更新界面显示
+                showCalling(onlyAudio)
+
+                if (!outGoing) {
+                    //被叫接听时开始录音录像
+                    if (SettingConfig.getRecordEnable(activity)) {
+                        janusClient!!.beginRecord()
+                    }
+                }
+            }
+        }
+    }
+
+    override fun didDisconnected(userId: String?) {
+        handler.post {
+            if (userId.equals(Constant.targetSipId)) {
+                showMessage(R.string.call_disconnect)
+                callEnd(true)
+            }
+        }
+    }
+
+    override fun didError(error: String?) {
+        handler.post {
+            showMessage(R.string.call_error)
+            callEnd(true)
+        }
+    }
+
+    override fun didHangUp(handlerId: BigInteger) {
+        Log.e("hangup", "socket hangup")
+        handler.post {
+            callEnd(true)
+        }
+    }
+
+    //处理本地视频画面
+    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 didReceiveRemoteVideoTrack(userId: BigInteger?) {
+        Log.e(TAG, "didReceiveRemoteVideoTrack  userId: $userId")
+        handler.post {
+            if (!callEnded) {
+                //本地画面
+                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(callEndReason: EnumType.CallEndReason?) {
+        handler.post {
+
+
+            showMessage(R.string.call_end)
+            callEnd(true)
+        }
+    }
+
+    override fun didChangeMode(isAudioOnly: Boolean) {
+        //
+    }
+
+    override fun didUserLeave(userId: BigInteger?) {
+        handler.post {
+            showMessage(R.string.call_end)
+            callEnd(true)
+        }
+    }
+
+
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    fun onMoonEvent(messageEvent: MessageEvent) {
+        when (messageEvent.getType()) {
+            Constant.EVENT_TCP_MSG -> {
+                if (messageEvent.getMessage() is TcpModel) {
+                    val curTcpModel = messageEvent.getMessage() as TcpModel
+                    if (curTcpModel.type == TcpType.VOICE) {
+                        val curInteractionVO = Gson().fromJson(curTcpModel.data.toString(), InteractionVO::class.java)
+                        if (curTcpModel.action == TcpAction.VoiceAction.HANDOFF) {
+                            //对方挂断,不论我方呼出或呼入
+                            if (Constant.interactionId == curInteractionVO.id) {
+                                callEnd(false)
+                            }
+                        } else if (curTcpModel.action == TcpAction.VoiceAction.ACCEPT) {//对方接受语音
+                            RingPlayHelper.stopRingTone()
+                            sky_voice_call_calling_text.setText(R.string.call_connecting)
+                            Constant.interactionId = curInteractionVO.id
+                            Constant.fromId = curTcpModel.fromId
+                            interactionVO = curInteractionVO
+                            fromId = curTcpModel.fromId
+                            DeviceChannel.calling = true
+                            Constant.CALL_STATE = Constant.CALL_CALLING
+                            countDownTimer.cancel()
+                        } else if (curTcpModel.action == TcpAction.VoiceAction.REJECT) {//对方拒绝
+                            if (Constant.interactionId == curInteractionVO.id) {
+                                showMessage(R.string.call_reject)
+                                callEnd(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.type == TcpType.VIDEO) {
+                        if (curTcpModel.action == TcpAction.VideoAction.FAILED) {
+                            //分机加入视频失败
+                            showMessage(R.string.extension_connect_fail)
+
+                            return
+                        } else if (curTcpModel.action == TcpAction.VideoAction.CALLING) {
+                            //分机正在通话
+                            showMessage(R.string.extension_call_busy)
+
+                            return
+                        } else if (curTcpModel.action == TcpAction.VideoAction.REJECT) {
+                            //分机加入视频通话失败
+                            showMessage(R.string.extension_call_error)
+
+                            return
+                        }
+
+                        val curInteractionVO = Gson().fromJson(curTcpModel.data.toString(), InteractionVO::class.java)
+                        if (curTcpModel.action == TcpAction.VideoAction.CANCEL || curTcpModel.action == TcpAction.VideoAction.VIDEO_OFF) {
+                            //对方取消或被其他设备处理
+                            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)*/
+                        }
+                    }
+                }
+            }
+
+            Constant.EVENT_END_CALL -> {
+                if (messageEvent.getMessage() is String) {
+                    val str = messageEvent.getMessage() as String
+                    if (str.equals("cancel")) {
+                        cancelCall(Constant.DEVICE_ID, Constant.targetDeviceId, Constant.interactionId)
+                        callEnd(false)
+                    } else {
+                        if (!inVisiting) {
+                            callEnd(true)
+                        }
+                    }
+                }
+            }
+
+            Constant.EVENT_V_HOOK_OFF -> {
+                if (!onlyAudio) {
+                    //视频接听
+                    RingPlayHelper.stopRingTone()
+                    SpeechUtil.getInstance().stopSpeak(true)
+                    val callTcp = VoiceUtil.voiceAccept(tid, Constant.DEVICE_ID, fromId, interactionVO?.id)
+                    TcpClient.getInstance().sendMsg(callTcp.toJson())
+
+                    janusClient!!.connect(-1, false)
+                }
+            }
+        }
+    }
+
+}

+ 136 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/DormThemeFragment.kt

@@ -0,0 +1,136 @@
+package com.wdkl.ncs.android.component.nursehome.dorm
+
+import com.alibaba.android.vlayout.DelegateAdapter
+import com.alibaba.android.vlayout.VirtualLayoutManager
+import com.enation.javashop.net.engine.model.NetState
+import com.wdkl.ncs.android.component.nursehome.R
+import com.wdkl.ncs.android.component.nursehome.activity.NurseHome2Activity
+import com.wdkl.ncs.android.component.nursehome.databinding.DormThemeLayoutBinding
+import com.wdkl.ncs.android.component.nursehome.dorm.adapter.DormThemeAdapter
+import com.wdkl.ncs.android.component.nursehome.launch.NurseHomeLaunch
+import com.wdkl.ncs.android.component.nursehome.settingconfig.SettingConfig
+
+import com.wdkl.ncs.android.lib.base.BaseApplication
+import com.wdkl.ncs.android.lib.base.BaseFragment
+import com.wdkl.ncs.android.lib.vo.filter
+import com.wdkl.ncs.android.middleware.logic.contract.callingbed.BedMomMianFragmentContract
+import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.BedMomMianFragmentPresenter
+import com.wdkl.ncs.android.middleware.model.dos.EventDO
+import com.wdkl.ncs.android.middleware.model.dos.PartSettingDO
+import com.wdkl.ncs.android.middleware.model.dos.RoleDO
+import com.wdkl.ncs.android.middleware.model.vo.*
+import kotlinx.android.synthetic.main.dorm_theme_layout.*
+import java.util.*
+import kotlin.collections.ArrayList
+
+/**
+ * 更换背景
+ * */
+class DormThemeFragment : BaseFragment<BedMomMianFragmentPresenter, DormThemeLayoutBinding>(), BedMomMianFragmentContract.View,
+    DormThemeAdapter.OnItemClickListener {
+
+    val TAG = "DormThemeFragment"
+
+    private var adapter: DormThemeAdapter? = null
+    private var themeBgId: Int = 0
+
+    override fun getLayId(): Int {
+        return R.layout.dorm_theme_layout
+    }
+
+    override fun bindDagger() {
+        NurseHomeLaunch.component.inject(this)
+    }
+
+    //数据绑定
+    override fun init() {
+        themeBgId = SettingConfig.getDormThemeBgId(BaseApplication.appContext)
+
+        /**初始化LayoutMannager*/
+        val virtualLayoutManager = VirtualLayoutManager(this.activity)
+        /**初始化适配器*/
+        val delegateAdapter = DelegateAdapter(virtualLayoutManager)
+
+        val themeList = ArrayList<Int>()
+        themeList.add(R.mipmap.theme_1)
+        themeList.add(R.mipmap.theme_2)
+        themeList.add(R.mipmap.theme_3)
+        themeList.add(R.mipmap.theme_4)
+        themeList.add(R.mipmap.theme_5)
+        themeList.add(R.mipmap.theme_6)
+        themeList.add(R.mipmap.theme_7)
+        themeList.add(R.mipmap.theme_8)
+        themeList.add(R.mipmap.theme_9)
+
+        adapter = DormThemeAdapter(themeList)
+        adapter?.setSelectThemeId(themeBgId)
+        delegateAdapter.addAdapter(adapter)
+        recycler_theme.layoutManager = virtualLayoutManager
+        recycler_theme.adapter = delegateAdapter
+
+        adapter?.setOnItemClickListener(this)
+    }
+
+    override fun bindEvent() {
+
+    }
+
+
+    /**执行其他销毁操作*/
+    override fun destory() {
+
+    }
+
+    override fun showCustomInfo(customInfo: CustomerInfoVO) {
+
+    }
+
+    override fun showRelativeInfo(bedRelativeVO: ArrayList<BedRelativeVO>) {
+
+    }
+
+    override fun showEvents(data: ArrayList<EventDO>) {
+
+    }
+
+
+    override fun loadRoles(roles: List<RoleDO>) {
+
+    }
+
+    override fun showRoleData(data: InteractionVO) {
+
+    }
+
+    override fun setPartSettings(partSetting: PartSettingDO) {
+
+    }
+
+    override fun onError(message: String, type: Int) {
+
+    }
+
+    override fun complete(message: String, type: Int) {
+
+    }
+
+    override fun start() {
+
+    }
+
+    override fun networkMonitor(state: NetState) {
+        state.filter(onWifi = {
+
+        }, onMobile = {
+
+        }, offline = {
+
+        })
+    }
+
+    override fun onItemClick(resId: Int) {
+        //选定主题背景
+        (activity as NurseHome2Activity).setThemeBg(resId)
+        adapter?.notifyDataSetChanged()
+    }
+}

+ 212 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/DromMianFragment.kt

@@ -0,0 +1,212 @@
+package com.wdkl.ncs.android.component.nursehome.dorm
+
+import android.app.zhyl.ZhylManager
+import android.content.Intent
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import com.enation.javashop.net.engine.model.NetState
+import com.wdkl.ncs.android.component.nursehome.R
+import com.wdkl.ncs.android.component.nursehome.activity.NurseHome2Activity
+import com.wdkl.ncs.android.component.nursehome.databinding.MainView4LayoutBinding
+import com.wdkl.ncs.android.component.nursehome.dialog.SystemDialogHelper
+import com.wdkl.ncs.android.component.nursehome.fragment.SignGraphOfCurveFragment
+import com.wdkl.ncs.android.component.nursehome.launch.NurseHomeLaunch
+
+import com.wdkl.ncs.android.lib.base.BaseApplication
+import com.wdkl.ncs.android.lib.base.BaseFragment
+import com.wdkl.ncs.android.lib.utils.showMessage
+import com.wdkl.ncs.android.lib.vo.filter
+import com.wdkl.ncs.android.middleware.common.Constant
+import com.wdkl.ncs.android.middleware.common.MessageEvent
+import com.wdkl.ncs.android.middleware.logic.contract.callingbed.BedMomMianFragmentContract
+import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.BedMomMianFragmentPresenter
+import com.wdkl.ncs.android.middleware.model.dos.EventDO
+import com.wdkl.ncs.android.middleware.model.dos.PartSettingDO
+import com.wdkl.ncs.android.middleware.model.dos.RoleDO
+import com.wdkl.ncs.android.middleware.model.vo.BedRelativeVO
+import com.wdkl.ncs.android.middleware.model.vo.CustomerInfoVO
+import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
+import kotlinx.android.synthetic.main.main_view4_layout.*
+import org.greenrobot.eventbus.EventBus
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+
+/**
+ * 宿舍首页
+ * */
+class DromMianFragment: BaseFragment<BedMomMianFragmentPresenter, MainView4LayoutBinding>(), BedMomMianFragmentContract.View {
+    val TAG = "DromMianFragment"
+
+    private var clickBtnTime: Long = 0
+    private var infoFragment: Fragment? = null
+
+    private var clickTime: Long = 0
+    private var clickTimes: Int = 1
+    override fun getLayId(): Int {
+        return R.layout.main_view4_layout
+    }
+
+    override fun bindDagger() {
+        NurseHomeLaunch.component.inject(this)
+    }
+
+    override fun init() {
+        presenter.getRoleList()
+
+        updateInfo()
+        val fragment = DormCallRecordsFragment()
+        addCallFragment(fragment)
+    }
+
+    override fun bindEvent() {
+//        main_view4_name.setOnClickListener {
+//            SystemDialogHelper.showDialog(activity,1)
+//        }
+//
+//        main_view4_time.setOnClickListener {
+//
+//            val time = System.currentTimeMillis()
+//            if (time - clickTime < 1500) {
+//                clickTimes++
+//            } else {
+//                clickTimes = 1
+//            }
+//
+//            if (clickTimes >5) {
+//                showMessage(R.string.showMessage_2)
+//                (activity as NurseHome2Activity).showSystemSettings()
+//                clickTimes = 1
+//            }
+//            clickTime = time
+//
+//        }
+
+        //设置
+//        main_view4_10_ll.setOnClickListener {
+////            SystemDialogHelper.showDialog(activity,1)
+//        }
+
+        tv_theme.setOnClickListener {
+            //背景切换
+            val time = System.currentTimeMillis()
+            if (time - clickBtnTime > 3000) {
+                clickBtnTime = time
+                (activity as NurseHome2Activity).showThemeSet()
+            } else {
+                showMessage(R.string.wait_moment)
+            }
+        }
+
+    }
+
+    override fun destory() {
+    }
+
+    override fun showCustomInfo(customInfo: CustomerInfoVO) {
+        if (customInfo.memberId != null) {
+            Constant.MEMBER_ID = customInfo.memberId
+        }
+    }
+
+    override fun showRelativeInfo(bedRelativeVO: ArrayList<BedRelativeVO>) {
+
+    }
+
+    override fun showEvents(data: ArrayList<EventDO>) {
+
+    }
+
+    override fun setPartSettings(partSetting: PartSettingDO) {
+
+    }
+
+    override fun loadRoles(roles: List<RoleDO>) {
+        Constant.ROLES = roles
+    }
+
+    override fun showRoleData(data: InteractionVO) {
+
+    }
+
+    override fun onError(message: String, type: Int) {
+        showMessage(message)
+    }
+
+    override fun complete(message: String, type: Int) {
+    }
+
+    override fun start() {
+    }
+
+    override fun networkMonitor(state: NetState) {
+        state.filter(onWifi = {
+
+        }, onMobile = {
+
+        }, offline = {
+
+        })
+    }
+    private fun addCallFragment(fragment: Fragment) {
+        requireActivity().supportFragmentManager.beginTransaction().apply {
+            infoFragment?.let {
+                remove(it)
+            }
+            infoFragment = fragment
+            add(R.id.main_view4_frame, fragment)
+            commitAllowingStateLoss()
+        }
+    }
+
+    override fun onStart() {
+        EventBus.getDefault().register(this)
+        super.onStart()
+    }
+
+    override fun onStop() {
+        EventBus.getDefault().unregister(this)
+        super.onStop()
+    }
+
+    private fun updateInfo() {
+        //科室名称
+        main_view4_name.text = Constant.partDisplay
+//        //床位名称
+//        main_view4_name_2.text = Constant.BED_NAME
+    }
+
+
+    //心率
+    var heartRate: Int=0
+    //读取呼吸率
+    var breathingRate : Int=0
+    var slepp_data: String=""
+
+    //床垫数据解析
+    private fun sleepDataParsing(data: String) {
+        /*try {
+            heartRate = BluetoothUtil.hexToDecimal(data.substring(0, 2))
+            main_view3_bed_medic_name.text = heartRate.toString()+getString(R.string.str_breathe_nuber)
+            breathingRate = BluetoothUtil.hexToDecimal(data.substring(2, 4))
+            main_view3_bed_medic_name2.text = breathingRate.toString()+getString(R.string.str_breathe_nuber)
+        } catch (e: Exception) {
+
+        }*/
+    }
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    fun onMoonEvent(messageEvent: MessageEvent) {
+        when (messageEvent.getType()) {
+            Constant.EVENT_UPDATE_CUSTOM -> {
+                updateInfo()
+            }
+
+            Constant.EVENT_SLEEP_DATA -> {
+                if (messageEvent.slepp_data!=null){
+                    slepp_data= messageEvent.slepp_data
+                    sleepDataParsing(slepp_data)
+                }
+            }
+        }
+    }
+}

+ 135 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/VolumeSetFragment.kt

@@ -0,0 +1,135 @@
+package com.wdkl.ncs.android.component.nursehome.dorm
+
+import android.view.View
+import android.widget.SeekBar
+import com.enation.javashop.net.engine.model.NetState
+import com.wdkl.ncs.android.component.nursehome.R
+import com.wdkl.ncs.android.component.nursehome.databinding.FragmentDromSetBinding
+import com.wdkl.ncs.android.component.nursehome.launch.NurseHomeLaunch
+import com.wdkl.ncs.android.component.nursehome.settingconfig.SettingConfig
+import com.wdkl.ncs.android.component.nursehome.util.ScreenManagerUtil
+import com.wdkl.ncs.android.component.nursehome.util.VoiceManagerUtil
+import com.wdkl.ncs.android.lib.base.BaseFragment
+import com.wdkl.ncs.android.lib.utils.showMessage
+import com.wdkl.ncs.android.lib.vo.filter
+import com.wdkl.ncs.android.middleware.common.Constant
+import com.wdkl.ncs.android.middleware.common.MessageEvent
+import com.wdkl.ncs.android.middleware.logic.contract.callingbed.BedQrCodeFragmentContract
+import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.BedQrCodeFragmentPresenter
+import kotlinx.android.synthetic.main.fragment_drom_set.*
+import org.greenrobot.eventbus.EventBus
+
+class VolumeSetFragment : BaseFragment<BedQrCodeFragmentPresenter, FragmentDromSetBinding>(), BedQrCodeFragmentContract.View {
+    val TAG = "VolumeSetFragment"
+
+    override fun getLayId(): Int {
+        return R.layout.fragment_drom_set
+    }
+
+    override fun bindDagger() {
+        NurseHomeLaunch.component.inject(this)
+    }
+
+    override fun init() {
+        val type = requireArguments().getInt("set_type")
+        if (type == 0) {
+            f_drom_set_ll_1.visibility = View.VISIBLE
+            f_drom_set_ll_2.visibility = View.GONE
+        } else {
+            f_drom_set_ll_1.visibility = View.GONE
+            f_drom_set_ll_2.visibility = View.VISIBLE
+        }
+
+        val volume = SettingConfig.getExtensionDaytimeSystemVolume(activity)
+        val brightness = SettingConfig.getExtensionDaytimeBrightness(activity)
+        if (volume in 0..100) {
+            volume_seek.progress = volume
+            tv_volume_value.text = "" + volume + "%"
+        }
+
+        if (brightness in 10..100) {
+            brightness_seek.progress = brightness
+            tv_brightness_value.text = "" + brightness + "%"
+        }
+    }
+
+    override fun bindEvent() {
+        volume_set_confirm.setOnClickListener {
+            EventBus.getDefault().post(MessageEvent("volume", Constant.EVENT_DORM_REMOVE_FRAGMENT))
+        }
+
+        volume_seek.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener{
+            override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
+                if (progress in 0..100) {
+                    VoiceManagerUtil.setSystemVoice(activity, progress)
+                    VoiceManagerUtil.setMusicVoice(activity, progress)
+                    tv_volume_value.text = "" + progress + "%"
+                }
+            }
+
+            override fun onStartTrackingTouch(seekBar: SeekBar) {
+                //
+            }
+
+            override fun onStopTrackingTouch(seekBar: SeekBar) {
+                if (seekBar.progress in 0..100) {
+                    SettingConfig.setExtensionDaytimeSystemVolume(activity, seekBar.progress)
+                } else {
+                    showMessage("参数错误!")
+                }
+            }
+        })
+
+        brightness_seek.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener{
+            override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
+                if (progress in 10..100) {
+                    ScreenManagerUtil().setScreenBrightness(activity, Math.ceil(2.54 * progress).toInt())
+                    tv_brightness_value.text = "" + progress + "%"
+                }
+            }
+
+            override fun onStartTrackingTouch(seekBar: SeekBar) {
+                //
+            }
+
+            override fun onStopTrackingTouch(seekBar: SeekBar) {
+                if (seekBar.progress < 10) {
+                    seekBar.progress = 10
+                    SettingConfig.setExtensionDaytimeBrightness(activity, 10)
+                } else if (seekBar.progress in 10..100) {
+                    SettingConfig.setExtensionDaytimeBrightness(activity, seekBar.progress)
+                } else {
+                    showMessage("参数错误!")
+                }
+            }
+        })
+    }
+
+    override fun destory() {
+
+    }
+
+    override fun onError(message: String, type: Int) {
+        //
+    }
+
+    override fun complete(message: String, type: Int) {
+    }
+
+    override fun start() {
+    }
+
+    override fun networkMonitor(state: NetState) {
+        state.filter(onWifi = {
+
+        },onMobile = {
+
+        },offline = {
+
+        })
+    }
+
+    override fun setUrlString(url: String) {
+        //
+    }
+}

+ 208 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/adapter/DormCallRecordsItemAdapter.kt

@@ -0,0 +1,208 @@
+package com.wdkl.ncs.android.component.nursehome.dorm.adapter
+
+import android.app.Activity
+import android.text.TextUtils
+import android.view.View
+import android.view.ViewGroup
+import com.alibaba.android.vlayout.LayoutHelper
+import com.alibaba.android.vlayout.layout.LinearLayoutHelper
+import com.alibaba.fastjson.JSON
+import com.wdkl.ncs.android.component.nursehome.R
+import com.wdkl.ncs.android.component.nursehome.databinding.AdapterDormCallRecordsItemBinding
+import com.wdkl.ncs.android.component.nursehome.util.MediaPlayHelper
+import com.wdkl.ncs.android.lib.adapter.BaseDelegateAdapter
+import com.wdkl.ncs.android.lib.utils.BaseRecyclerViewHolder
+import com.wdkl.ncs.android.lib.utils.TimeHandle
+import com.wdkl.ncs.android.lib.utils.showMessage
+import com.wdkl.ncs.android.middleware.api.ApiManager
+import com.wdkl.ncs.android.middleware.common.Constant
+import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
+import com.wdkl.ncs.android.middleware.tcp.enums.DeviceTypeEnum
+import com.wdkl.ncs.android.middleware.tcp.enums.RoleTypeEnum
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpType
+
+class DormCallRecordsItemAdapter(val activity: Activity, var data: ArrayList<InteractionVO>) : BaseDelegateAdapter<BaseRecyclerViewHolder<AdapterDormCallRecordsItemBinding>, InteractionVO>() {
+    var TAG = DormCallRecordsItemAdapter::class.java.getSimpleName()
+
+    private var actionClickListener: ActionClickListener? = null
+
+    /**
+     * 数据提供者
+     */
+    override fun dataProvider(): Any {
+        return data
+    }
+
+    /**
+     * Item坐标
+     */
+    override fun itemFilter(position: Int): Boolean {
+        return true
+    }
+
+    /**
+     * 获取Item总数
+     */
+    override fun getItemCount(): Int {
+        return data.size
+    }
+
+    //刷新数据
+    fun updateCallRecords(data: ArrayList<InteractionVO>) {
+        this.data = data
+        notifyDataSetChanged()
+    }
+
+    /**
+     * 创建LayoutHelper
+     */
+    override fun onCreateLayoutHelper(): LayoutHelper {
+        return LinearLayoutHelper(0, data.size)
+    }
+
+    /**
+     * 创建ViewHolder
+     */
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseRecyclerViewHolder<AdapterDormCallRecordsItemBinding> {
+        return BaseRecyclerViewHolder.build(parent, R.layout.adapter_dorm_call_records_item)
+    }
+
+    /**
+     * 绑定数据
+     */
+    override fun onBindViewHolder(holder: BaseRecyclerViewHolder<AdapterDormCallRecordsItemBinding>, position: Int) {
+        holder.bind { binding ->
+            val itemData = getItem(position)
+
+            try {
+                binding.imgCallType.setImageResource(R.drawable.ic_call_main)
+                binding.callRecordsItemTitle.text = "未知"
+                if (itemData.createDate != null) {
+                    binding.callRecordsItemTime.text = TimeHandle.getDateTime(itemData.createDate * 1000, "yyyy/MM/dd HH:mm:ss")
+                } else {
+                    binding.callRecordsItemTime.text = "----"
+                }
+
+                binding.btnRecordsAction.visibility = View.VISIBLE
+                binding.btnRecordsAction.text = "未知"
+                binding.btnRecordsAction.setBackgroundResource(R.drawable.records_action_bg)
+
+                if (TcpType.VOICE.name == itemData.actionType || TcpType.VIDEO.name == itemData.actionType) {
+                    var roleName = "未知"
+                    if (itemData.fromDeviceId == Constant.DEVICE_ID) {
+                        //本机呼出记录
+                        if (!TextUtils.isEmpty(itemData.data)) {
+                            val roleType = JSON.parseObject(itemData.data).getString("roleType")
+                            if (roleType == RoleTypeEnum.NURSE.name) {
+                                roleName = "管理处"
+                            } else {
+                                if (itemData.toDeviceType == DeviceTypeEnum.DOOR_DEVICE.value()
+                                    || itemData.toDeviceType == DeviceTypeEnum.DIGIT_BED_DEVICE.value()) {
+                                    roleName = itemData.toFrameFullName
+                                } else if (itemData.toDeviceType == DeviceTypeEnum.NURSE_HOST.value()) {
+                                    roleName = "管理处"
+                                } else if (!TextUtils.isEmpty(itemData.toMemberName)) {
+                                    roleName = itemData.toMemberName
+                                }
+                            }
+                        }
+
+                        if (itemData.actionEnd != null && itemData.actionAccept != null) {
+                            //呼出已接听
+                            binding.imgCallType.setImageResource(R.drawable.ic_records_call)
+                            binding.callRecordsItemTitle.text = "您邀请  " + roleName + "  语音通话,  已接听"
+                            binding.btnRecordsAction.text = "拨打"
+                        } else {
+                            //呼出未接听
+                            binding.imgCallType.setImageResource(R.drawable.ic_records_miss_call)
+                            binding.callRecordsItemTitle.text = "您邀请  " + roleName + "  语音通话,  未接听"
+                            binding.btnRecordsAction.text = "拨打"
+                        }
+                    } else {
+                        //其他设备呼入记录
+                        if (itemData.fromDeviceType == DeviceTypeEnum.DOOR_DEVICE.value()
+                            || itemData.fromDeviceType == DeviceTypeEnum.DIGIT_BED_DEVICE.value()) {
+                            roleName = itemData.fromFrameFullName
+                        } else if (itemData.fromDeviceType == DeviceTypeEnum.NURSE_HOST.value()) {
+                            roleName = "管理处"
+                        } else if (!TextUtils.isEmpty(itemData.fromMemberName)) {
+                            roleName = itemData.fromMemberName
+                        }
+
+                        if (itemData.actionEnd != null && itemData.actionAccept != null) {
+                            binding.imgCallType.setImageResource(R.drawable.ic_records_call)
+                            binding.callRecordsItemTitle.text = roleName + "  邀请您  语音通话,  已接听"
+                            binding.btnRecordsAction.text = "拨打"
+                        } else {
+                            binding.imgCallType.setImageResource(R.drawable.ic_records_miss_call)
+                            binding.callRecordsItemTitle.text = roleName + "  邀请您 语音通话,  未接听"
+                            binding.btnRecordsAction.text = "拨打"
+                        }
+                    }
+
+                } else if (TcpType.SOS.name == itemData.actionType) {
+                    binding.imgCallType.setImageResource(R.mipmap.sos)
+                    if (itemData.actionEnd != null) {
+                        if (itemData.toDeviceType == DeviceTypeEnum.NURSE_HOST.value()) {
+                            //护士主机响应即管理处
+                            binding.callRecordsItemTitle.text = "紧急呼叫  管理处  已响应"
+                        } else {
+                            binding.callRecordsItemTitle.text = "紧急呼叫  " + itemData.actionEndMemberName + "  已响应"
+                        }
+                        binding.btnRecordsAction.text = "已响应"
+                        binding.btnRecordsAction.setBackgroundResource(R.drawable.records_action_bg2)
+                    } else {
+                        binding.callRecordsItemTitle.text = "紧急呼叫"
+                        binding.btnRecordsAction.text = "未响应"
+                    }
+                } else if (TcpType.IM.name == itemData.actionType){
+                    binding.imgCallType.setImageResource(R.drawable.ic_records_voice_message)
+                    binding.callRecordsItemTitle.text = itemData.fromMemberName + "  发来语音"
+                    binding.btnRecordsAction.text = "播放"
+                }
+
+                binding.btnRecordsAction.setOnClickListener {
+                    if (TcpType.VOICE.name == itemData.actionType || TcpType.VIDEO.name == itemData.actionType) {
+                        //拨打语音
+                        if (itemData.fromDeviceId == Constant.DEVICE_ID) {
+                            //自己呼出的,再次呼出
+                            if (!TextUtils.isEmpty(itemData.data)) {
+                                val roleType = JSON.parseObject(itemData.data).getString("roleType")
+                                if (!TextUtils.isEmpty(roleType)) {
+                                    actionClickListener?.onCallRole(roleType)
+                                } else if (itemData.toDeviceId != null) {
+                                    actionClickListener?.onCallDevice(itemData.toDeviceId)
+                                } else {
+                                    showMessage("呼叫角色异常")
+                                }
+                            } else {
+                                showMessage("呼叫数据异常")
+                            }
+                        } else {
+                            //对方呼入,直接呼叫对方
+                            actionClickListener?.onCallDevice(itemData.fromDeviceId)
+                        }
+                    } else if (TcpType.IM.name == itemData.actionType) {
+                        showMessage("播放语音")
+                        MediaPlayHelper.getInstance().stopMusic(false)
+                        MediaPlayHelper.getInstance().playUrlMusic(ApiManager.urlManager.buyer + itemData.data, 1f, false)
+                        //ImPlayDialogHelper.showImPlayDialog(activity, itemData.fromMemberName, TimeTransition().stampToTime(itemData.createDate*1000))
+                    }
+                }
+
+            } catch (e: Exception) {
+                //
+            }
+        }
+    }
+
+    fun setActionClickListener(listener: ActionClickListener) {
+        actionClickListener = listener
+    }
+
+    interface ActionClickListener {
+        fun onCallRole(role: String?)
+
+        fun onCallDevice(deviceId: Int?)
+    }
+}

+ 63 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/adapter/DormDialCallSearchAdapter.kt

@@ -0,0 +1,63 @@
+package com.wdkl.ncs.android.component.nursehome.dorm.adapter
+
+import android.app.Activity
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import com.wdkl.ncs.android.component.nursehome.R
+import com.wdkl.ncs.android.component.nursehome.dorm.search.DeviceSearchItem
+import com.wdkl.ncs.android.component.nursehome.dorm.search.FuzzySearchBaseAdapter
+import com.wdkl.ncs.android.component.nursehome.dorm.search.IFuzzySearchRule
+
+
+class DormDialCallSearchAdapter: FuzzySearchBaseAdapter<DeviceSearchItem, DormDialCallSearchAdapter.ItemHolder> {
+    var TAG = DormDialCallSearchAdapter::class.java.getSimpleName()
+
+    private lateinit var activity: Activity
+    private var actionClickListener: ActionClickListener? = null
+
+    constructor() : super(null)
+
+    constructor(rule: IFuzzySearchRule) : super(rule)
+
+    constructor(data: ArrayList<DeviceSearchItem>) : super(null, data)
+
+    constructor(rule: IFuzzySearchRule?, data: ArrayList<DeviceSearchItem>, activity: Activity) : super(rule, data) {
+        this.activity = activity
+    }
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder {
+        val view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_dorm_dial_call_item, parent, false)
+        return ItemHolder(view)
+    }
+
+    override fun onBindViewHolder(holder: ItemHolder, position: Int) {
+        try {
+            val itemData = mDataList[position]
+            holder.deviceFrameName.text = itemData.frameName
+            holder.dialAction.setOnClickListener {
+                actionClickListener?.onCallDevice(itemData.deviceId)
+            }
+        } catch (e: Exception) {
+            //
+        }
+    }
+
+
+    fun setActionClickListener(listener: ActionClickListener) {
+        actionClickListener = listener
+    }
+
+    interface ActionClickListener {
+        fun onCallRole(role: String?)
+
+        fun onCallDevice(deviceId: Int?)
+    }
+
+    class ItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+        var deviceFrameName: TextView = itemView.findViewById(R.id.call_device_frame_name)
+        var dialAction: TextView = itemView.findViewById(R.id.btn_dial_action)
+    }
+}

+ 103 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/adapter/DormThemeAdapter.kt

@@ -0,0 +1,103 @@
+package com.wdkl.ncs.android.component.nursehome.dorm.adapter
+
+import android.view.View
+import android.view.ViewGroup
+import com.alibaba.android.vlayout.LayoutHelper
+import com.alibaba.android.vlayout.layout.GridLayoutHelper
+import com.wdkl.ncs.android.component.nursehome.R
+import com.wdkl.ncs.android.component.nursehome.databinding.DormThemeItemBinding
+import com.wdkl.ncs.android.lib.adapter.BaseDelegateAdapter
+import com.wdkl.ncs.android.lib.utils.BaseRecyclerViewHolder
+import com.wdkl.ncs.android.lib.utils.then
+
+class DormThemeAdapter(val data: ArrayList<Int>) : BaseDelegateAdapter<BaseRecyclerViewHolder<DormThemeItemBinding>, Int>() {
+    var TAG = DormThemeAdapter::class.java.getSimpleName()
+
+    private var onItemClickListener: OnItemClickListener? = null
+    private var selectId: Int = 0
+
+    /**
+     * 数据提供者
+     */
+    override fun dataProvider(): Any {
+        return data
+    }
+
+    /**
+     * Item坐标
+     */
+    override fun itemFilter(position: Int): Boolean {
+        return true
+    }
+
+    /**
+     * 获取Item总数
+     */
+    override fun getItemCount(): Int {
+        return data.size
+    }
+
+    /**
+     * 创建LayoutHelper
+     */
+    override fun onCreateLayoutHelper(): LayoutHelper {
+        return GridLayoutHelper(3).then { self ->
+            /**取消自动填充*/
+            self.setAutoExpand(false)
+
+            /**设置左右间距*/
+            self.hGap = 20
+
+            /**设置上下间距*/
+            self.vGap = 20
+
+            /**设置Margin*/
+            self.setMargin(0, 0, 0, 0)
+        }
+    }
+
+    /**
+     * 创建ViewHolder
+     */
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseRecyclerViewHolder<DormThemeItemBinding> {
+        return BaseRecyclerViewHolder.build(parent, R.layout.dorm_theme_item)
+    }
+
+    /**
+     * 绑定数据
+     */
+    override fun onBindViewHolder(holder: BaseRecyclerViewHolder<DormThemeItemBinding>, position: Int) {
+        holder.bind { binding ->
+            try {
+                val resId = getItem(position)
+                binding.imgThemeItem.setImageResource(resId)
+                binding.imgThemeItem.setOnClickListener {
+                    setSelectThemeId(resId)
+                    if (onItemClickListener != null) {
+                        onItemClickListener?.onItemClick(resId)
+                    }
+                }
+
+                if (selectId == resId) {
+                    binding.imgThemeItemCheck.visibility = View.VISIBLE
+                } else {
+                    binding.imgThemeItemCheck.visibility = View.GONE
+                }
+            } catch (ex: Exception) {
+                ex.printStackTrace()
+            }
+        }
+    }
+
+    fun setSelectThemeId(id: Int) {
+        selectId = id
+    }
+
+    fun setOnItemClickListener(listener: OnItemClickListener) {
+        this.onItemClickListener = listener
+    }
+
+    interface OnItemClickListener {
+        fun onItemClick(resId: Int)
+    }
+}

+ 35 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/search/DefaultFuzzySearchRule.java

@@ -0,0 +1,35 @@
+package com.wdkl.ncs.android.component.nursehome.dorm.search;
+
+import android.text.TextUtils;
+
+import java.util.List;
+
+public class DefaultFuzzySearchRule implements IFuzzySearchRule {
+
+	@Override
+	public boolean accept(CharSequence constraint, String itemSource, List<String> itemPinYinList) {
+		/**
+		 * 1. 先匹配原始的字符,比如 原始字符是 "中国"  输入 "中" 也能保证匹配到
+		 */
+		if ((itemSource != null && itemSource.toLowerCase().contains(constraint.toString().toLowerCase()))) {
+			return true;
+		}
+		/**
+		 * 2. 拼音匹配 这里咱们匹配每个拼音的首字母
+		 */
+		if (itemPinYinList != null && !itemPinYinList.isEmpty()) {
+			StringBuilder firstWord = null;
+			for (String wordPinYin : itemPinYinList) {
+				if (!TextUtils.isEmpty(wordPinYin)) {
+					if (firstWord == null) {
+						firstWord = new StringBuilder(wordPinYin.substring(0, 1));
+					} else {
+						firstWord.append(wordPinYin.substring(0, 1));
+					}
+				}
+			}
+			return firstWord != null && firstWord.toString().toLowerCase().contains(constraint.toString().toLowerCase());
+		}
+		return false;
+	}
+}

+ 45 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/search/DeviceSearchItem.java

@@ -0,0 +1,45 @@
+package com.wdkl.ncs.android.component.nursehome.dorm.search;
+
+import java.util.List;
+
+public class DeviceSearchItem implements IAZItem, IFuzzySearchItem {
+
+    private String frameName;
+    private int deviceId;
+    private String sortLetters;
+    private List<String> fuzzySearchKey;
+
+    public DeviceSearchItem(String name, int id, String sortLetters, List<String> fuzzySearchKey) {
+        this.frameName = name;
+        this.deviceId = id;
+        this.sortLetters = sortLetters;
+        this.fuzzySearchKey = fuzzySearchKey;
+    }
+
+    public String getFrameName() {
+        return frameName;
+    }
+
+    public int getDeviceId() {
+        return deviceId;
+    }
+
+    public List<String> getFuzzySearchKey() {
+        return fuzzySearchKey;
+    }
+
+    @Override
+    public String getSortLetters() {
+        return sortLetters;
+    }
+
+    @Override
+    public String getSourceKey() {
+        return frameName;
+    }
+
+    @Override
+    public List<String> getFuzzyKey() {
+        return fuzzySearchKey;
+    }
+}

+ 87 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/search/FuzzySearchBaseAdapter.java

@@ -0,0 +1,87 @@
+package com.wdkl.ncs.android.component.nursehome.dorm.search;
+
+import android.text.TextUtils;
+import android.widget.Filter;
+import android.widget.Filterable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+public abstract class FuzzySearchBaseAdapter<ITEM extends IFuzzySearchItem, VH extends RecyclerView.ViewHolder>
+	extends RecyclerView.Adapter<VH> implements Filterable {
+
+	private   FuzzySearchFilter mFilter;
+	private   List<ITEM>        mBackDataList;
+	protected List<ITEM>        mDataList;
+	private   IFuzzySearchRule  mIFuzzySearchRule;
+
+	public FuzzySearchBaseAdapter(IFuzzySearchRule rule) {
+		this(rule, null);
+	}
+
+	public FuzzySearchBaseAdapter(IFuzzySearchRule rule, List<ITEM> dataList) {
+		if (rule == null) {
+			mIFuzzySearchRule = new DefaultFuzzySearchRule();
+		}
+		mBackDataList = dataList;
+		mDataList = dataList;
+	}
+
+	public void setDataList(List<ITEM> dataList) {
+		mBackDataList = dataList;
+		mDataList = dataList;
+		notifyDataSetChanged();
+	}
+
+
+	@Override
+	public int getItemCount() {
+		return mDataList == null ? 0 : mDataList.size();
+	}
+
+	@Override
+	public Filter getFilter() {
+		if (mFilter == null) {
+			mFilter = new FuzzySearchFilter();
+		}
+		return mFilter;
+	}
+
+	private class FuzzySearchFilter extends Filter {
+
+		/**
+		 * 执行过滤操作,如果搜索的关键字为空,默认所有结果
+		 */
+		@Override
+		protected FilterResults performFiltering(CharSequence constraint) {
+			FilterResults result = new FilterResults();
+			List<ITEM> filterList;
+			if (TextUtils.isEmpty(constraint)) {
+				filterList = mBackDataList;
+			} else {
+				filterList = new ArrayList<>();
+				for (ITEM item : mBackDataList) {
+					if (mIFuzzySearchRule.accept(constraint, item.getSourceKey(), item.getFuzzyKey())) {
+						filterList.add(item);
+					}
+				}
+			}
+			result.values = filterList;
+			result.count = filterList.size();
+			return result;
+		}
+
+		/**
+		 * 得到过滤结果
+		 */
+		@SuppressWarnings("unchecked")
+		@Override
+		protected void publishResults(CharSequence constraint, FilterResults results) {
+			mDataList = (List<ITEM>) results.values;
+			notifyDataSetChanged();
+		}
+	}
+
+}

+ 12 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/search/IAZItem.java

@@ -0,0 +1,12 @@
+package com.wdkl.ncs.android.component.nursehome.dorm.search;
+
+public interface IAZItem {
+
+	/**
+	 * 获取item对应首字母
+	 *
+	 * @return 首字母
+	 */
+	String getSortLetters();
+
+}

+ 24 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/search/IFuzzySearchItem.java

@@ -0,0 +1,24 @@
+package com.wdkl.ncs.android.component.nursehome.dorm.search;
+
+import java.util.List;
+
+/**
+ * 先匹配原始数据,再匹配模糊数据
+ */
+public interface IFuzzySearchItem {
+
+	/**
+	 * 获取item原始字符串
+	 *
+	 * @return 原始item字符串
+	 */
+	String getSourceKey();
+
+	/**
+	 * 获取item模糊字符串,item对应的拼音 江西省->["jiang", "xi", "sheng"]
+	 *
+	 * @return 模糊item字符串
+	 */
+	List<String> getFuzzyKey();
+
+}

+ 20 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/search/IFuzzySearchRule.java

@@ -0,0 +1,20 @@
+package com.wdkl.ncs.android.component.nursehome.dorm.search;
+
+import java.util.List;
+
+/**
+ * 模糊搜索匹配规则接口
+ */
+public interface IFuzzySearchRule {
+
+	/**
+	 * 匹配规则
+	 *
+	 * @param constraint     匹配字符
+	 * @param itemSource     item 对应的原始字符
+	 * @param itemPinYinList item 原始字符对应的拼音列表
+	 * @return 是否匹配
+	 */
+	boolean accept(CharSequence constraint, String itemSource, List<String> itemPinYinList);
+
+}

+ 897 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/dorm/search/PinyinUtil.java

@@ -0,0 +1,897 @@
+package com.wdkl.ncs.android.component.nursehome.dorm.search;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PinyinUtil {
+
+	private static int[]    sPinYinValue = new int[]{-20319,
+												  -20317,
+												  -20304,
+												  -20295,
+												  -20292,
+												  -20283,
+												  -20265,
+												  -20257,
+												  -20242,
+												  -20230,
+												  -20051,
+												  -20036,
+												  -20032,
+												  -20026,
+												  -20002,
+												  -19990,
+												  -19986,
+												  -19982,
+												  -19976,
+												  -19805,
+												  -19784,
+												  -19775,
+												  -19774,
+												  -19763,
+												  -19756,
+												  -19751,
+												  -19746,
+												  -19741,
+												  -19739,
+												  -19728,
+												  -19725,
+												  -19715,
+												  -19540,
+												  -19531,
+												  -19525,
+												  -19515,
+												  -19500,
+												  -19484,
+												  -19479,
+												  -19467,
+												  -19289,
+												  -19288,
+												  -19281,
+												  -19275,
+												  -19270,
+												  -19263,
+												  -19261,
+												  -19249,
+												  -19243,
+												  -19242,
+												  -19238,
+												  -19235,
+												  -19227,
+												  -19224,
+												  -19218,
+												  -19212,
+												  -19038,
+												  -19023,
+												  -19018,
+												  -19006,
+												  -19003,
+												  -18996,
+												  -18977,
+												  -18961,
+												  -18952,
+												  -18783,
+												  -18774,
+												  -18773,
+												  -18763,
+												  -18756,
+												  -18741,
+												  -18735,
+												  -18731,
+												  -18722,
+												  -18710,
+												  -18697,
+												  -18696,
+												  -18526,
+												  -18518,
+												  -18501,
+												  -18490,
+												  -18478,
+												  -18463,
+												  -18448,
+												  -18447,
+												  -18446,
+												  -18239,
+												  -18237,
+												  -18231,
+												  -18220,
+												  -18211,
+												  -18201,
+												  -18184,
+												  -18183,
+												  -18181,
+												  -18012,
+												  -17997,
+												  -17988,
+												  -17970,
+												  -17964,
+												  -17961,
+												  -17950,
+												  -17947,
+												  -17931,
+												  -17928,
+												  -17922,
+												  -17759,
+												  -17752,
+												  -17733,
+												  -17730,
+												  -17721,
+												  -17703,
+												  -17701,
+												  -17697,
+												  -17692,
+												  -17683,
+												  -17676,
+												  -17496,
+												  -17487,
+												  -17482,
+												  -17468,
+												  -17454,
+												  -17433,
+												  -17427,
+												  -17417,
+												  -17202,
+												  -17185,
+												  -16983,
+												  -16970,
+												  -16942,
+												  -16915,
+												  -16733,
+												  -16708,
+												  -16706,
+												  -16689,
+												  -16664,
+												  -16657,
+												  -16647,
+												  -16474,
+												  -16470,
+												  -16465,
+												  -16459,
+												  -16452,
+												  -16448,
+												  -16433,
+												  -16429,
+												  -16427,
+												  -16423,
+												  -16419,
+												  -16412,
+												  -16407,
+												  -16403,
+												  -16401,
+												  -16393,
+												  -16220,
+												  -16216,
+												  -16212,
+												  -16205,
+												  -16202,
+												  -16187,
+												  -16180,
+												  -16171,
+												  -16169,
+												  -16158,
+												  -16155,
+												  -15959,
+												  -15958,
+												  -15944,
+												  -15933,
+												  -15920,
+												  -15915,
+												  -15903,
+												  -15889,
+												  -15878,
+												  -15707,
+												  -15701,
+												  -15681,
+												  -15667,
+												  -15661,
+												  -15659,
+												  -15652,
+												  -15640,
+												  -15631,
+												  -15625,
+												  -15454,
+												  -15448,
+												  -15436,
+												  -15435,
+												  -15419,
+												  -15416,
+												  -15408,
+												  -15394,
+												  -15385,
+												  -15377,
+												  -15375,
+												  -15369,
+												  -15363,
+												  -15362,
+												  -15183,
+												  -15180,
+												  -15165,
+												  -15158,
+												  -15153,
+												  -15150,
+												  -15149,
+												  -15144,
+												  -15143,
+												  -15141,
+												  -15140,
+												  -15139,
+												  -15128,
+												  -15121,
+												  -15119,
+												  -15117,
+												  -15110,
+												  -15109,
+												  -14941,
+												  -14937,
+												  -14933,
+												  -14930,
+												  -14929,
+												  -14928,
+												  -14926,
+												  -14922,
+												  -14921,
+												  -14914,
+												  -14908,
+												  -14902,
+												  -14894,
+												  -14889,
+												  -14882,
+												  -14873,
+												  -14871,
+												  -14857,
+												  -14678,
+												  -14674,
+												  -14670,
+												  -14668,
+												  -14663,
+												  -14654,
+												  -14645,
+												  -14630,
+												  -14594,
+												  -14429,
+												  -14407,
+												  -14399,
+												  -14384,
+												  -14379,
+												  -14368,
+												  -14355,
+												  -14353,
+												  -14345,
+												  -14170,
+												  -14159,
+												  -14151,
+												  -14149,
+												  -14145,
+												  -14140,
+												  -14137,
+												  -14135,
+												  -14125,
+												  -14123,
+												  -14122,
+												  -14112,
+												  -14109,
+												  -14099,
+												  -14097,
+												  -14094,
+												  -14092,
+												  -14090,
+												  -14087,
+												  -14083,
+												  -13917,
+												  -13914,
+												  -13910,
+												  -13907,
+												  -13906,
+												  -13905,
+												  -13896,
+												  -13894,
+												  -13878,
+												  -13870,
+												  -13859,
+												  -13847,
+												  -13831,
+												  -13658,
+												  -13611,
+												  -13601,
+												  -13406,
+												  -13404,
+												  -13400,
+												  -13398,
+												  -13395,
+												  -13391,
+												  -13387,
+												  -13383,
+												  -13367,
+												  -13359,
+												  -13356,
+												  -13343,
+												  -13340,
+												  -13329,
+												  -13326,
+												  -13318,
+												  -13147,
+												  -13138,
+												  -13120,
+												  -13107,
+												  -13096,
+												  -13095,
+												  -13091,
+												  -13076,
+												  -13068,
+												  -13063,
+												  -13060,
+												  -12888,
+												  -12875,
+												  -12871,
+												  -12860,
+												  -12858,
+												  -12852,
+												  -12849,
+												  -12838,
+												  -12831,
+												  -12829,
+												  -12812,
+												  -12802,
+												  -12607,
+												  -12597,
+												  -12594,
+												  -12585,
+												  -12556,
+												  -12359,
+												  -12346,
+												  -12320,
+												  -12300,
+												  -12120,
+												  -12099,
+												  -12089,
+												  -12074,
+												  -12067,
+												  -12058,
+												  -12039,
+												  -11867,
+												  -11861,
+												  -11847,
+												  -11831,
+												  -11798,
+												  -11781,
+												  -11604,
+												  -11589,
+												  -11536,
+												  -11358,
+												  -11340,
+												  -11339,
+												  -11324,
+												  -11303,
+												  -11097,
+												  -11077,
+												  -11067,
+												  -11055,
+												  -11052,
+												  -11045,
+												  -11041,
+												  -11038,
+												  -11024,
+												  -11020,
+												  -11019,
+												  -11018,
+												  -11014,
+												  -10838,
+												  -10832,
+												  -10815,
+												  -10800,
+												  -10790,
+												  -10780,
+												  -10764,
+												  -10587,
+												  -10544,
+												  -10533,
+												  -10519,
+												  -10331,
+												  -10329,
+												  -10328,
+												  -10322,
+												  -10315,
+												  -10309,
+												  -10307,
+												  -10296,
+												  -10281,
+												  -10274,
+												  -10270,
+												  -10262,
+												  -10260,
+												  -10256,
+												  -10254};
+	private static String[] sPinYinStr   = new String[]{"a",
+														"ai",
+														"an",
+														"ang",
+														"ao",
+														"ba",
+														"bai",
+														"ban",
+														"bang",
+														"bao",
+														"bei",
+														"ben",
+														"beng",
+														"bi",
+														"bian",
+														"biao",
+														"bie",
+														"bin",
+														"bing",
+														"bo",
+														"bu",
+														"ca",
+														"cai",
+														"can",
+														"cang",
+														"cao",
+														"ce",
+														"ceng",
+														"cha",
+														"chai",
+														"chan",
+														"chang",
+														"chao",
+														"che",
+														"chen",
+														"cheng",
+														"chi",
+														"chong",
+														"chou",
+														"chu",
+														"chuai",
+														"chuan",
+														"chuang",
+														"chui",
+														"chun",
+														"chuo",
+														"ci",
+														"cong",
+														"cou",
+														"cu",
+														"cuan",
+														"cui",
+														"cun",
+														"cuo",
+														"da",
+														"dai",
+														"dan",
+														"dang",
+														"dao",
+														"de",
+														"deng",
+														"di",
+														"dian",
+														"diao",
+														"die",
+														"ding",
+														"diu",
+														"dong",
+														"dou",
+														"du",
+														"duan",
+														"dui",
+														"dun",
+														"duo",
+														"e",
+														"en",
+														"er",
+														"fa",
+														"fan",
+														"fang",
+														"fei",
+														"fen",
+														"feng",
+														"fo",
+														"fou",
+														"fu",
+														"ga",
+														"gai",
+														"gan",
+														"gang",
+														"gao",
+														"ge",
+														"gei",
+														"gen",
+														"geng",
+														"gong",
+														"gou",
+														"gu",
+														"gua",
+														"guai",
+														"guan",
+														"guang",
+														"gui",
+														"gun",
+														"guo",
+														"ha",
+														"hai",
+														"han",
+														"hang",
+														"hao",
+														"he",
+														"hei",
+														"hen",
+														"heng",
+														"hong",
+														"hou",
+														"hu",
+														"hua",
+														"huai",
+														"huan",
+														"huang",
+														"hui",
+														"hun",
+														"huo",
+														"ji",
+														"jia",
+														"jian",
+														"jiang",
+														"jiao",
+														"jie",
+														"jin",
+														"jing",
+														"jiong",
+														"jiu",
+														"ju",
+														"juan",
+														"jue",
+														"jun",
+														"ka",
+														"kai",
+														"kan",
+														"kang",
+														"kao",
+														"ke",
+														"ken",
+														"keng",
+														"kong",
+														"kou",
+														"ku",
+														"kua",
+														"kuai",
+														"kuan",
+														"kuang",
+														"kui",
+														"kun",
+														"kuo",
+														"la",
+														"lai",
+														"lan",
+														"lang",
+														"lao",
+														"le",
+														"lei",
+														"leng",
+														"li",
+														"lia",
+														"lian",
+														"liang",
+														"liao",
+														"lie",
+														"lin",
+														"ling",
+														"liu",
+														"long",
+														"lou",
+														"lu",
+														"lv",
+														"luan",
+														"lue",
+														"lun",
+														"luo",
+														"ma",
+														"mai",
+														"man",
+														"mang",
+														"mao",
+														"me",
+														"mei",
+														"men",
+														"meng",
+														"mi",
+														"mian",
+														"miao",
+														"mie",
+														"min",
+														"ming",
+														"miu",
+														"mo",
+														"mou",
+														"mu",
+														"na",
+														"nai",
+														"nan",
+														"nang",
+														"nao",
+														"ne",
+														"nei",
+														"nen",
+														"neng",
+														"ni",
+														"nian",
+														"niang",
+														"niao",
+														"nie",
+														"nin",
+														"ning",
+														"niu",
+														"nong",
+														"nu",
+														"nv",
+														"nuan",
+														"nue",
+														"nuo",
+														"o",
+														"ou",
+														"pa",
+														"pai",
+														"pan",
+														"pang",
+														"pao",
+														"pei",
+														"pen",
+														"peng",
+														"pi",
+														"pian",
+														"piao",
+														"pie",
+														"pin",
+														"ping",
+														"po",
+														"pu",
+														"qi",
+														"qia",
+														"qian",
+														"qiang",
+														"qiao",
+														"qie",
+														"qin",
+														"qing",
+														"qiong",
+														"qiu",
+														"qu",
+														"quan",
+														"que",
+														"qun",
+														"ran",
+														"rang",
+														"rao",
+														"re",
+														"ren",
+														"reng",
+														"ri",
+														"rong",
+														"rou",
+														"ru",
+														"ruan",
+														"rui",
+														"run",
+														"ruo",
+														"sa",
+														"sai",
+														"san",
+														"sang",
+														"sao",
+														"se",
+														"sen",
+														"seng",
+														"sha",
+														"shai",
+														"shan",
+														"shang",
+														"shao",
+														"she",
+														"shen",
+														"sheng",
+														"shi",
+														"shou",
+														"shu",
+														"shua",
+														"shuai",
+														"shuan",
+														"shuang",
+														"shui",
+														"shun",
+														"shuo",
+														"si",
+														"song",
+														"sou",
+														"su",
+														"suan",
+														"sui",
+														"sun",
+														"suo",
+														"ta",
+														"tai",
+														"tan",
+														"tang",
+														"tao",
+														"te",
+														"teng",
+														"ti",
+														"tian",
+														"tiao",
+														"tie",
+														"ting",
+														"tong",
+														"tou",
+														"tu",
+														"tuan",
+														"tui",
+														"tun",
+														"tuo",
+														"wa",
+														"wai",
+														"wan",
+														"wang",
+														"wei",
+														"wen",
+														"weng",
+														"wo",
+														"wu",
+														"xi",
+														"xia",
+														"xian",
+														"xiang",
+														"xiao",
+														"xie",
+														"xin",
+														"xing",
+														"xiong",
+														"xiu",
+														"xu",
+														"xuan",
+														"xue",
+														"xun",
+														"ya",
+														"yan",
+														"yang",
+														"yao",
+														"ye",
+														"yi",
+														"yin",
+														"ying",
+														"yo",
+														"yong",
+														"you",
+														"yu",
+														"yuan",
+														"yue",
+														"yun",
+														"za",
+														"zai",
+														"zan",
+														"zang",
+														"zao",
+														"ze",
+														"zei",
+														"zen",
+														"zeng",
+														"zha",
+														"zhai",
+														"zhan",
+														"zhang",
+														"zhao",
+														"zhe",
+														"zhen",
+														"zheng",
+														"zhi",
+														"zhong",
+														"zhou",
+														"zhu",
+														"zhua",
+														"zhuai",
+														"zhuan",
+														"zhuang",
+														"zhui",
+														"zhun",
+														"zhuo",
+														"zi",
+														"zong",
+														"zou",
+														"zu",
+														"zuan",
+														"zui",
+														"zun",
+														"zuo"};
+
+	/**
+	 * 单个汉字转成ASCII码
+	 */
+	private static int getAscii(String chs) {
+		int asc = 0;
+		try {
+			byte[] bytes = chs.getBytes("gb2312");
+			if (bytes.length > 2 || bytes.length <= 0) {
+				throw new RuntimeException("illegal resource string");
+			}
+			if (bytes.length == 1) {
+				asc = bytes[0];
+			}
+			if (bytes.length == 2) {
+				int heightByte = 256 + bytes[0];
+				int lowByte = 256 + bytes[1];
+				asc = (256 * heightByte + lowByte) - 256 * 256;
+			}
+		} catch (Exception e) {
+			System.out.println("ERROR:ChineseSpelling.class-char2Ascii(String chs)" + e);
+		}
+		return asc;
+	}
+
+	/**
+	 * 单个汉字转换成拼音
+	 **/
+	private static String getSinglePinYin(String str) {
+		String result = null;
+		int ascii = getAscii(str);
+		if (ascii > 0 && ascii < 160) {
+			result = String.valueOf((char) ascii);
+		} else {
+			for (int i = (sPinYinValue.length - 1); i >= 0; i--) {
+				if (sPinYinValue[i] <= ascii) {
+					result = sPinYinStr[i];
+					break;
+				}
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * 中文转换成拼音,返回结果是list
+	 *
+	 * @param source 原始字符
+	 * @return 中国->["zhong", "guo"]
+	 */
+	public static List<String> getPinYinList(String source) {
+		if (source == null || source.isEmpty()) {
+			return null;
+		}
+		List<String> pinyinList = new ArrayList<>();
+		for (int i = 0; i < source.length(); i++) {
+			String item = source.substring(i, i + 1);
+			if (item.getBytes().length >= 2) {
+				String pinyin = getSinglePinYin(item);
+				if (pinyin == null) {
+					pinyin = item;
+				}
+				pinyinList.add(pinyin);
+			} else {
+				pinyinList.add(item);
+			}
+		}
+		return pinyinList;
+	}
+
+	/**
+	 * 中文转换成拼音
+	 *
+	 * @param source 原始字符
+	 * @return 中国->"zhongguo"
+	 */
+	public static String getPinYin(String source) {
+		if (source == null || source.isEmpty()) {
+			return null;
+		}
+		StringBuilder pinyinList = new StringBuilder();
+		for (int i = 0; i < source.length(); i++) {
+			String item = source.substring(i, i + 1);
+			if (item.getBytes().length >= 2) {
+				String pinyin = getSinglePinYin(item);
+				if (pinyin == null) {
+					pinyin = item;
+				}
+				pinyinList.append(pinyin);
+			} else {
+				pinyinList.append(item);
+			}
+		}
+		return pinyinList.toString();
+	}
+
+
+}

+ 1 - 1
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/fragment/BedinfoFragment.kt

@@ -32,7 +32,7 @@ import kotlinx.android.synthetic.main.fragment_info_layout.*
 /**
  * 基础信息界面
  */
-class  BedinfoFragment : BaseFragment<BedAdviceFragmentPresenter, FragmentInfoLayoutBinding>(), BedAdviceFragmentContract.View {
+class   BedinfoFragment : BaseFragment<BedAdviceFragmentPresenter, FragmentInfoLayoutBinding>(), BedAdviceFragmentContract.View {
 
     val TAG = "BedinfoFragment"
     var isconfirm = true

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

@@ -266,7 +266,6 @@ class CallRecordsFragment: BaseFragment<CallRecordsFragmentPresenter, FragmentCa
         mViewDataBinding.callingLinlyout.setOnClickListener(this)
         mViewDataBinding.callFLView.setOnClickListener(this)
         mViewDataBinding.callRK.setOnClickListener(this)
-
         configRefresh()
     }
 

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

@@ -5,6 +5,7 @@ import com.alibaba.android.vlayout.DelegateAdapter
 import com.alibaba.android.vlayout.VirtualLayoutManager
 import com.enation.javashop.net.engine.model.NetState
 import com.scwang.smartrefresh.layout.footer.ClassicsFooter
+import com.wdkl.ncs.android.component.nursehome.BuildConfig
 import com.wdkl.ncs.android.component.nursehome.R
 import com.wdkl.ncs.android.component.nursehome.adapter.IotDeviceAdapter
 import com.wdkl.ncs.android.component.nursehome.databinding.FragmentNbIotDeviceBinding
@@ -19,6 +20,7 @@ import com.wdkl.ncs.android.middleware.logic.presenter.nursehome.IotDevicePresen
 import com.wdkl.ncs.android.middleware.model.vo.DeviceVO
 import kotlinx.android.synthetic.main.fragment_message.*
 import kotlinx.android.synthetic.main.fragment_nb_iot_device.*
+import kotlinx.android.synthetic.main.work_lay.*
 import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
 
@@ -52,7 +54,20 @@ class IotDeviceFragment : BaseFragment<IotDevicePresenter, FragmentNbIotDeviceBi
      *初始化操作
      */
     override fun init() {
+        if (BuildConfig.device_type.equals("4")){//宿舍
+            iot_ll_r.setBackgroundResource(R.drawable.shape_dorm_call_item_bg)
+            rv_nb_iot_device.setBackgroundResource(R.drawable.shape_dorm_call_item_bg)
+            iot_refresh_ll_r.setBackgroundResource(R.drawable.shape_dorm_call_item_bg)
+            rb_offline_device.setTextColor(resources.getColor(R.color.white))
+            rb_low_battery_device.setTextColor(resources.getColor(R.color.white))
+            group_voice_tit.setTextColor(resources.getColor(R.color.white))
+            rb_voice_warning_on.setTextColor(resources.getColor(R.color.white))
+            rb_voice_warning_off.setTextColor(resources.getColor(R.color.white))
 
+        }else{
+            iot_ll_r.setBackgroundResource(R.color.color_no_d_work)
+            rv_nb_iot_device.setBackgroundResource(R.color.color_no_d_work)
+        }
         /**初始化LayoutMannager*/
         virtualLayoutManager = VirtualLayoutManager(this.activity)
         /**初始化适配器*/

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

@@ -23,7 +23,19 @@ 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.dorm_sky_voice_call_layout.*
 import kotlinx.android.synthetic.main.sky_voice_call_layout.*
+import kotlinx.android.synthetic.main.sky_voice_call_layout.call_volume_bar
+import kotlinx.android.synthetic.main.sky_voice_call_layout.fullscreen_video_frame
+import kotlinx.android.synthetic.main.sky_voice_call_layout.ll_voice_call
+import kotlinx.android.synthetic.main.sky_voice_call_layout.ll_voice_volume_bar
+import kotlinx.android.synthetic.main.sky_voice_call_layout.pip_video_frame
+import kotlinx.android.synthetic.main.sky_voice_call_layout.sky_voice_call_calling_text
+import kotlinx.android.synthetic.main.sky_voice_call_layout.sky_voice_call_hangup
+import kotlinx.android.synthetic.main.sky_voice_call_layout.sky_voice_call_mute
+import kotlinx.android.synthetic.main.sky_voice_call_layout.sky_voice_call_outgoing
+import kotlinx.android.synthetic.main.sky_voice_call_layout.sky_voice_call_timer
+import kotlinx.android.synthetic.main.sky_voice_call_layout.tv_volume
 import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
 import org.linphone.core.Core
@@ -50,7 +62,7 @@ class SipCallFragment: BaseCallFragment() {
 
     override fun init() {
         initCountDownTimer()
-
+        showui()
         linphoneManager = LinphoneManager.getInstance(BaseApplication.appContext)
         linphoneManager?.setMicGainDb(0f)
 
@@ -109,7 +121,43 @@ class SipCallFragment: BaseCallFragment() {
             }
         }
     }
+    private fun showui(){
+        //网络图标
+        if ( Constant.network_state == 1){
+            title_layout_iv_hl_wifi.visibility = View.VISIBLE
+            title_layout_iv_hl_ethernet.visibility = View.GONE
+            title_layout_iv_hl_wifi.setImageResource(R.mipmap.ic_wifi_fail)
+        }else if ( Constant.network_state == 2){
+            title_layout_iv_hl_wifi.visibility = View.GONE
+            title_layout_iv_hl_ethernet.visibility = View.VISIBLE
+            title_layout_iv_hl_ethernet.setImageResource(R.mipmap.ic_ethernet_success_w)
+        }else{
+            title_layout_iv_hl_wifi.visibility = View.GONE
+            title_layout_iv_hl_ethernet.visibility = View.VISIBLE
+            title_layout_iv_hl_ethernet.setImageResource(R.mipmap.ic_ethernet_fail)
+        }
+
+        if (SettingConfig.getSipEnabled(activity)) {
+            title_layout_tv_hl_point.visibility = View.VISIBLE
+        } else {
+            title_layout_tv_hl_point.visibility = View.GONE
+        }
 
+        //蓝牙图标
+        if (Constant.BT_state == 0) {
+            title_layout_iv_hl_bt.visibility = View.VISIBLE
+            title_layout_iv_hl_bt.setImageResource(R.mipmap.lanya_b)
+        } else {
+            title_layout_iv_hl_bt.visibility = View.GONE
+        }
+
+        //白天/黑夜
+        if (Constant.day_state == 0){
+            title_layout_iv_day_hl_night.setImageResource(R.mipmap.ic_daylight_w)
+        }else{
+            title_layout_iv_day_hl_night.setImageResource(R.mipmap.ic_night_w)
+        }
+    }
     override fun bindEvent() {
         //通话挂断
         sky_voice_call_hangup.setOnClickListener {

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

@@ -8,8 +8,10 @@ import android.util.Log
 import android.view.View
 import androidx.recyclerview.widget.GridLayoutManager
 import com.enation.javashop.net.engine.model.NetState
+import com.wdkl.ncs.android.component.nursehome.BuildConfig
 
 import com.wdkl.ncs.android.component.nursehome.R
+import com.wdkl.ncs.android.component.nursehome.activity.NurseHome2Activity
 import com.wdkl.ncs.android.component.nursehome.activity.NurseHomeActivity
 import com.wdkl.ncs.android.component.nursehome.activity.SystemActivity
 import com.wdkl.ncs.android.component.nursehome.activity.WebviewActivity
@@ -57,6 +59,11 @@ class WorkFragment : BaseFragment<BedNursingWorkFragmentPresenter, WorkLayBindin
     }
     //数据绑定
     override fun init() {
+        if (!BuildConfig.device_type.equals("4")){//不等于宿舍
+            recycler.setBackgroundResource(R.color.color_no_d_work)
+        }
+
+
         recycler.setVisibility(View.VISIBLE)
         val layoutManager = GridLayoutManager(getActivity(), 3)
         recycler.setLayoutManager(layoutManager)
@@ -186,13 +193,19 @@ class WorkFragment : BaseFragment<BedNursingWorkFragmentPresenter, WorkLayBindin
                     activity.startActivity(intent)
                 }else if (allOrders.get(keyId).act_name.equals("LedSettingsFragment")){
                         //led设置
+
                     val mainActivity = activity as? NurseHomeActivity
                     mainActivity?.showMiddleFragment(LedSettingsFragment(),false)
                 }
                 else if (allOrders.get(keyId).act_name.equals("SystemSettingsFragment")){
                     //科室设置
-                    val mainActivity = activity as? NurseHomeActivity
-                    mainActivity?.showMiddleFragment(SystemSettingsFragment(),false)
+                    if (BuildConfig.device_type.equals("4")){//宿舍
+                        (activity as NurseHome2Activity).showSystemSettings()
+                    }else{
+                        val mainActivity = activity as? NurseHomeActivity
+                        mainActivity?.showMiddleFragment(SystemSettingsFragment(),false)
+                    }
+
                 } else if (allOrders.get(keyId).act_name.equals("MessageFragment")){
                     //留言
                     val mainActivity = activity as? NurseHomeActivity

+ 1 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/helper/SoundPoolManager.java

@@ -54,6 +54,7 @@ public class SoundPoolManager {
         soundID.put(4, soundPool.load(BaseApplication.appContext, R.raw.test_start, 1));
         soundID.put(5, soundPool.load(BaseApplication.appContext, R.raw.err, 1));
         soundID.put(6, soundPool.load(BaseApplication.appContext, R.raw.ts_call_sk, 1));
+        soundID.put(7, soundPool.load(BaseApplication.appContext, R.raw.reinforce_notify,  1));
         soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
             @Override
             public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {

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

@@ -181,6 +181,42 @@ public class SettingConfig {
     private static final String KEY_SP_OFFLINE_MODE_RUNNING = "KEY_SP_OFFLINE_MODE_RUNNING";
     private static final String KEY_SP_OFFLINE_DEVICE_SIZE = "KEY_SP_OFFLINE_DEVICE_SIZE";
 
+    //主题背景id
+    private static final String KEY_SP_DORM_THEME_BG_ID = "KEY_SP_DORM_THEME_BG_ID";
+
+    //呼叫超时时间
+    private static final String KEY_SP_SIP_OVERTIME = "KEY_SP_SIP_OVERTIME";
+    private static final int sip_over_time = 30;
+
+    //息屏超时时间
+    private static final String KEY_SP_SLEEP_TIME = "KEY_SP_SLEEP_TIME";
+    private static final int sleep_time = 30;
+    /**
+     * 设置呼叫超时时间
+     *
+     * @param value
+     */
+    public static void setSipOverTime(Context context, int value) {
+        getEditor(context).putInt(KEY_SP_SIP_OVERTIME, value).apply();
+    }
+
+    /**
+     * 获取呼叫超时时间
+     *
+     * @return
+     */
+    public static int getSipOverTime(Context context) {
+        return getSP(context).getInt(KEY_SP_SIP_OVERTIME, sip_over_time);
+    }
+    public static void setDormThemeBgId(Context context, int themeId) {
+        getEditor(context).putInt(KEY_SP_DORM_THEME_BG_ID, themeId).apply();
+    }
+
+    public static int getDormThemeBgId(Context context) {
+        return getSP(context).getInt(KEY_SP_DORM_THEME_BG_ID, 0);
+    }
+
+
     public static void setBoolTransfer(Context context, int mode) {
         getEditor(context).putInt(KEY_SP_BoolTransfer, mode).apply();
     }

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

@@ -6,6 +6,7 @@ import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Message;
 
+import com.wdkl.ncs.android.component.nursehome.window.ImPlayDialogHelper;
 import com.wdkl.ncs.android.lib.base.BaseApplication;
 
 import java.util.ArrayList;
@@ -128,6 +129,13 @@ public class MediaPlayHelper {
     public void stopMusic() {
         playHandler.sendEmptyMessage(STOP);
     }
+    public void stopMusic(boolean dismiss) {
+        playHandler.sendEmptyMessage(STOP);
+        if (dismiss) {
+            ImPlayDialogHelper.dismissIMDialog();
+        }
+    }
+
 
     public void releaseMusic() {
         playHandler.sendEmptyMessage(RELEASE);

+ 83 - 0
android_host/src/main/java/com/wdkl/ncs/android/component/nursehome/window/ImPlayDialogHelper.java

@@ -0,0 +1,83 @@
+package com.wdkl.ncs.android.component.nursehome.window;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.os.SystemClock;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.Chronometer;
+import android.widget.TextView;
+
+import com.wdkl.ncs.android.component.nursehome.R;
+import com.wdkl.ncs.android.component.nursehome.util.MediaPlayHelper;
+
+
+public class ImPlayDialogHelper {
+
+    private static AlertDialog imPlayDialog;
+
+    public static void showImPlayDialog(Activity activity, String text, String time) {
+        if (imPlayDialog != null && imPlayDialog.isShowing()) {
+            return;
+        }
+
+        View contentView = LayoutInflater.from(activity).inflate(R.layout.im_play_dialog_lay, null);
+        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+        builder.setView(contentView);
+
+        Button confirm = contentView.findViewById(R.id.btn_im_stop);
+        confirm.setOnClickListener(v -> {
+            MediaPlayHelper.getInstance().stopMusic();
+            dismissIMDialog();
+        });
+        TextView textView = contentView.findViewById(R.id.tv_im_play_name);
+        textView.setText(text);
+        TextView timeView = contentView.findViewById(R.id.tv_im_time);
+        timeView.setText(time);
+        Chronometer chronometer = contentView.findViewById(R.id.im_play_time);
+        chronometer.setBase(SystemClock.elapsedRealtime());
+        chronometer.start();
+
+
+        imPlayDialog = builder.create();
+        imPlayDialog.setCanceledOnTouchOutside(false);
+        imPlayDialog.setCancelable(false);
+        imPlayDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+            @Override
+            public void onDismiss(DialogInterface dialog) {
+                if (chronometer != null) {
+                    chronometer.stop();
+                }
+            }
+        });
+
+        //设置dialog宽高及位置
+        try {
+            Window window = imPlayDialog.getWindow();
+            window.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
+            imPlayDialog.show();
+            WindowManager.LayoutParams lp = window.getAttributes();
+            lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
+            lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
+            lp.gravity = Gravity.CENTER;
+            //lp.alpha = 0.8f;//设置透明度
+            window.setAttributes(lp);
+
+            window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void dismissIMDialog() {
+        if (imPlayDialog != null) {
+            imPlayDialog.dismiss();
+            imPlayDialog = null;
+        }
+    }
+}

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


+ 5 - 0
android_host/src/main/res/drawable/ic_baseline_backspace.xml

@@ -0,0 +1,5 @@
+<vector android:height="64dp" android:tint="#FF0000"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="64dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M22,3L7,3c-0.69,0 -1.23,0.35 -1.59,0.88L0,12l5.41,8.11c0.36,0.53 0.9,0.89 1.59,0.89h15c1.1,0 2,-0.9 2,-2L24,5c0,-1.1 -0.9,-2 -2,-2zM19,15.59L17.59,17 14,13.41 10.41,17 9,15.59 12.59,12 9,8.41 10.41,7 14,10.59 17.59,7 19,8.41 15.41,12 19,15.59z"/>
+</vector>

+ 5 - 0
android_host/src/main/res/drawable/ic_baseline_cancel.xml

@@ -0,0 +1,5 @@
+<vector android:height="64dp" android:tint="#FF0000"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="64dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM17,15.59L15.59,17 12,13.41 8.41,17 7,15.59 10.59,12 7,8.41 8.41,7 12,10.59 15.59,7 17,8.41 13.41,12 17,15.59z"/>
+</vector>

+ 5 - 0
android_host/src/main/res/drawable/ic_baseline_pause.xml

@@ -0,0 +1,5 @@
+<vector android:height="64dp" android:tint="#E84C02"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="64dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM11,16L9,16L9,8h2v8zM15,16h-2L13,8h2v8z"/>
+</vector>

+ 5 - 0
android_host/src/main/res/drawable/ic_baseline_play.xml

@@ -0,0 +1,5 @@
+<vector android:height="64dp" android:tint="#E84C02"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="64dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM10,16.5v-9l6,4.5 -6,4.5z"/>
+</vector>

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


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


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


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


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


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


+ 5 - 0
android_host/src/main/res/drawable/ic_search_48.xml

@@ -0,0 +1,5 @@
+<vector android:height="48dp" android:tint="#6685FF"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
+</vector>

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


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


+ 12 - 0
android_host/src/main/res/drawable/records_action_bg.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+        android:type="linear"
+        android:startColor="#6685FF"
+        android:endColor="#123BDC"
+        android:angle="270" />
+
+    <corners
+        android:radius="40dp" />
+
+</shape>

+ 12 - 0
android_host/src/main/res/drawable/records_action_bg2.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+        android:type="linear"
+        android:startColor="#56E95B"
+        android:endColor="#1C9E20"
+        android:angle="270" />
+
+    <corners
+        android:radius="40dp" />
+
+</shape>

+ 12 - 0
android_host/src/main/res/drawable/records_bg_1.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+        android:type="linear"
+        android:startColor="#ff6685ff"
+        android:endColor="#ff123bdc"
+        android:angle="0" />
+
+    <corners
+        android:radius="60dp" />
+
+</shape>

+ 12 - 0
android_host/src/main/res/drawable/records_bg_2.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+        android:type="linear"
+        android:startColor="#D30707"
+        android:endColor="#FF5656"
+        android:angle="180" />
+
+    <corners
+        android:radius="60dp" />
+
+</shape>

+ 12 - 0
android_host/src/main/res/drawable/records_bg_3.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+        android:type="linear"
+        android:startColor="#FFCF5A"
+        android:endColor="#F8B003"
+        android:angle="180" />
+
+    <corners
+        android:radius="60dp" />
+
+</shape>

+ 12 - 0
android_host/src/main/res/drawable/records_bg_4.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+        android:type="linear"
+        android:startColor="#56E95B"
+        android:endColor="#1C9E20"
+        android:angle="180" />
+
+    <corners
+        android:radius="60dp" />
+
+</shape>

+ 12 - 0
android_host/src/main/res/drawable/records_bg_5.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+        android:type="linear"
+        android:startColor="#8F51EF"
+        android:endColor="#6117C0"
+        android:angle="180" />
+
+    <corners
+        android:radius="60dp" />
+
+</shape>

+ 5 - 0
android_host/src/main/res/drawable/selector_dial_num_bg.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/shape_dial_num_press" android:state_pressed="true"/>
+    <item android:drawable="@drawable/shape_dial_num"/>
+</selector>

+ 14 - 0
android_host/src/main/res/drawable/shape_accept_call.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle" >
+
+    <gradient
+        android:type="linear"
+        android:startColor="#ff56e95b"
+        android:endColor="#ff1c9e20"
+        android:angle="180" />
+
+    <corners
+        android:radius="@dimen/d60" />
+
+</shape>

+ 12 - 0
android_host/src/main/res/drawable/shape_dial_num.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle" >
+
+    <stroke android:width="1dp"
+        android:color="#ffffffff" />
+
+    <solid android:color="#1affffff" />
+
+    <corners
+        android:radius="10dp" />
+</shape>

+ 12 - 0
android_host/src/main/res/drawable/shape_dial_num_press.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle" >
+
+    <stroke android:width="1dp"
+        android:color="#ffffffff" />
+
+    <solid android:color="#aa6685ff" />
+
+    <corners
+        android:radius="10dp" />
+</shape>

+ 11 - 0
android_host/src/main/res/drawable/shape_dorm_bg.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+
+    <gradient
+        android:type="linear"
+        android:startColor="#8F000000"
+        android:endColor="#DF000000"
+        android:angle="270" />
+
+</shape>

+ 13 - 0
android_host/src/main/res/drawable/shape_dorm_call_item_bg.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+
+    <gradient android:type="linear"
+        android:startColor="#1affffff"
+        android:endColor="#5fffffff"
+        android:angle="90" />
+
+    <corners
+        android:radius="20dp" />
+
+</shape>

+ 7 - 0
android_host/src/main/res/drawable/shape_drom_curtain_bg.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+
+    <solid android:color="#1affffff" />
+    <corners android:radius="@dimen/d60" />
+</shape>

+ 13 - 0
android_host/src/main/res/drawable/shape_end_call.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle" >
+    <gradient
+        android:type="linear"
+        android:startColor="#ffff5656"
+        android:endColor="#ffd30707"
+        android:angle="180" />
+
+    <corners
+        android:radius="@dimen/d60" />
+
+</shape>

+ 11 - 0
android_host/src/main/res/drawable/shape_main_drom_bg.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+
+    <gradient
+        android:type="linear"
+        android:startColor="#6F000000"
+        android:endColor="#8F000000"
+        android:angle="270"/>
+
+</shape>

+ 10 - 0
android_host/src/main/res/drawable/shape_main_drom_f_bg.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <corners android:topLeftRadius="40dp"/> <!-- 左上角圆角,可根据需要调整大小 -->
+    <gradient
+    android:startColor="#0DFFFFFF"
+    android:endColor="#00FFFFFF"
+    android:angle="0"/>
+</shape>
+

+ 12 - 0
android_host/src/main/res/drawable/shape_main_drom_f_bg2.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <corners android:topLeftRadius="40dp"
+        android:bottomLeftRadius="40dp"/>
+    <!-- 左上角圆角,可根据需要调整大小 -->
+    <gradient
+    android:startColor="#0DFFFFFF"
+    android:endColor="#00FFFFFF"
+    android:angle="0"/>
+</shape>
+

+ 11 - 0
android_host/src/main/res/drawable/theme_button_bg.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+        android:type="linear"
+        android:startColor="#20ffffff"
+        android:endColor="#40ffffff"
+        android:angle="90" />
+
+    <corners
+        android:radius="40dp" />
+</shape>

+ 8 - 0
android_host/src/main/res/layout/activity_calling.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout>
+    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/frame_calling_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+    </FrameLayout>
+</layout>

+ 55 - 0
android_host/src/main/res/layout/adapter_dorm_call_records_item.xml

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout>
+
+    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="100dp"
+        android:background="@drawable/shape_dorm_call_item_bg"
+        android:layout_marginBottom="10dp">
+
+        <ImageView
+            android:id="@+id/img_call_type"
+            android:layout_width="@dimen/d60"
+            android:layout_height="@dimen/d60"
+            android:layout_marginLeft="20dp"
+            android:layout_centerVertical="true"
+            android:src="@drawable/ic_call_main" />
+
+        <TextView
+            android:id="@+id/call_records_item_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toRightOf="@+id/img_call_type"
+            android:layout_centerVertical="true"
+            android:text="--"
+            android:textStyle="bold"
+            android:textColor="@color/white"
+            android:textSize="@dimen/font_size_22"
+            android:layout_marginLeft="@dimen/d20" />
+
+        <TextView
+            android:id="@+id/call_records_item_time"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toRightOf="@+id/call_records_item_title"
+            android:layout_centerVertical="true"
+            android:text="2023/05/04 14:04"
+            android:textColor="#C3C3C3"
+            android:textSize="@dimen/font_size_20"
+            android:layout_marginLeft="@dimen/d20" />
+
+        <TextView
+            android:id="@+id/btn_records_action"
+            android:layout_width="120dp"
+            android:layout_height="60dp"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true"
+            android:gravity="center"
+            android:layout_marginRight="20dp"
+            android:background="@drawable/records_action_bg"
+            android:textStyle="bold"
+            android:textColor="@color/white"
+            android:textSize="@dimen/font_size_22"/>
+
+    </RelativeLayout>
+</layout>

+ 84 - 0
android_host/src/main/res/layout/adapter_dorm_calling_item.xml

@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="100dp"
+    android:background="@drawable/shape_dorm_call_item_bg"
+    android:paddingBottom="10dp">
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_weight="4"
+        android:orientation="horizontal">
+
+        <ImageView
+            android:layout_width="@dimen/d60"
+            android:layout_height="@dimen/d60"
+            android:layout_marginLeft="20dp"
+            android:layout_gravity="center_vertical"
+            android:src="@drawable/ic_call_main" />
+
+        <TextView
+            android:id="@+id/dorm_tv_calling_bed_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="8dp"
+            android:paddingTop="8dp"
+            android:textSize="24sp"
+            android:text="--"
+            android:textColor="@color/white"
+            android:singleLine="true"
+            android:layout_marginLeft="@dimen/d25"
+            android:layout_gravity="center_vertical"
+            android:ellipsize="end"/>
+
+        <TextView
+            android:id="@+id/dorm_tv_calling_custom_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="8dp"
+            android:paddingTop="8dp"
+            android:textSize="22sp"
+            android:text="--"
+            android:textColor="@color/white"
+            android:singleLine="true"
+            android:layout_marginLeft="@dimen/d25"
+            android:layout_gravity="center_vertical"
+            android:ellipsize="end"/>
+
+        <TextView
+            android:id="@+id/dorm_tv_calling_time"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="8dp"
+            android:paddingTop="4dp"
+            android:textColor="#C3C3C3"
+            android:textSize="18sp"
+            android:layout_marginLeft="@dimen/d25"
+            android:layout_gravity="center_vertical"
+            android:text="--:--"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:orientation="vertical"
+        android:gravity="center">
+
+        <ImageView
+            android:id="@+id/dorm_btn_call_accept"
+            android:layout_width="68dp"
+            android:layout_height="68dp"
+            android:padding="4dp"
+            android:src="@drawable/ic_answer_normal" />
+
+        <ImageView
+            android:id="@+id/dorm_btn_call_reject"
+            android:layout_width="68dp"
+            android:layout_height="68dp"
+            android:src="@drawable/ic_hangup_normal"
+            android:visibility="gone"/>
+    </LinearLayout>
+
+</LinearLayout>

+ 45 - 0
android_host/src/main/res/layout/adapter_dorm_dial_call_item.xml

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout>
+
+    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="90dp"
+        android:background="@drawable/shape_dorm_call_item_bg"
+        android:layout_marginBottom="10dp">
+
+        <ImageView
+            android:id="@+id/img_header"
+            android:layout_width="@dimen/d40"
+            android:layout_height="@dimen/d40"
+            android:layout_marginLeft="20dp"
+            android:layout_centerVertical="true"
+            android:src="@mipmap/d_mf_img" />
+
+        <TextView
+            android:id="@+id/call_device_frame_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toRightOf="@+id/img_header"
+            android:layout_centerVertical="true"
+            android:text="--"
+            android:textStyle="bold"
+            android:textColor="@color/white"
+            android:textSize="@dimen/font_size_22"
+            android:layout_marginLeft="@dimen/d20" />
+
+        <TextView
+            android:id="@+id/btn_dial_action"
+            android:layout_width="120dp"
+            android:layout_height="60dp"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true"
+            android:gravity="center"
+            android:layout_marginRight="20dp"
+            android:background="@drawable/records_action_bg"
+            android:text="拨打"
+            android:textStyle="bold"
+            android:textColor="@color/white"
+            android:textSize="@dimen/font_size_22"/>
+
+    </RelativeLayout>
+</layout>

+ 2 - 0
android_host/src/main/res/layout/callingbed_setting_main.xml

@@ -126,6 +126,8 @@
                           android:background="@drawable/shape_n_login_ed_bg"
                           />
                   </LinearLayout>
+
+
                   <LinearLayout
                       android:id="@+id/settings_main_3_ll"
                       android:layout_width="@dimen/d165"

+ 50 - 0
android_host/src/main/res/layout/dorm_call_records.xml

@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:bind="http://schemas.android.com/apk/res-auto">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+     >
+
+        <com.scwang.smartrefresh.layout.SmartRefreshLayout
+            android:id="@+id/call_records_refresh"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginLeft="20dp"
+            android:layout_marginRight="20dp"
+            android:layout_marginTop="10dp"
+            android:layout_marginBottom="10dp"
+            bind:srlEnableLoadMore="true"
+            bind:srlEnableRefresh="true">
+
+            <androidx.recyclerview.widget.RecyclerView
+                android:id="@+id/call_records_rv"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                />
+
+        </com.scwang.smartrefresh.layout.SmartRefreshLayout>
+        <!--呼叫列表-->
+        <LinearLayout
+            android:id="@+id/dorm_ll_call_list"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_below="@+id/button_linlyout"
+            android:layout_toRightOf="@+id/call_f_l_view"
+            android:layout_marginLeft="6px"
+            android:layout_marginRight="8px"
+            android:visibility="gone">
+
+            <androidx.recyclerview.widget.RecyclerView
+                android:id="@+id/dorm_rv_calling_list"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:scrollbars="vertical"
+                android:fadeScrollbars="true"
+                android:scrollbarSize="4dp"
+                android:scrollbarThumbVertical="@color/colorPrimaryDark">
+            </androidx.recyclerview.widget.RecyclerView>
+        </LinearLayout>
+    </RelativeLayout>
+</layout>

+ 275 - 0
android_host/src/main/res/layout/dorm_dial_call.xml

@@ -0,0 +1,275 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:bind="http://schemas.android.com/apk/res-auto">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:paddingTop="10dp"
+        android:paddingBottom="10dp"
+        android:paddingLeft="20dp"
+        android:paddingRight="20dp"
+        android:orientation="horizontal">
+
+        <com.scwang.smartrefresh.layout.SmartRefreshLayout
+            android:id="@+id/dial_call_refresh"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1.4"
+            bind:srlEnableLoadMore="false"
+            bind:srlEnableRefresh="true">
+
+            <androidx.recyclerview.widget.RecyclerView
+                android:id="@+id/frame_device_rv"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:paddingTop="4dp"/>
+
+        </com.scwang.smartrefresh.layout.SmartRefreshLayout>
+
+        <RelativeLayout
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:layout_marginLeft="20dp"
+            android:layout_marginTop="4dp"
+            android:layout_marginBottom="6dp"
+            android:paddingLeft="20dp"
+            android:paddingRight="20dp"
+            android:background="@drawable/shape_dorm_call_item_bg">
+
+            <TextView
+                android:id="@+id/dial_call_search"
+                android:layout_width="match_parent"
+                android:layout_height="68dp"
+                android:drawableLeft="@drawable/ic_search_48"
+                android:drawablePadding="@dimen/d10"
+                android:gravity="center_vertical"
+                android:text="房号搜索"
+                android:textColor="@color/white"
+                android:textSize="@dimen/font_size_24" />
+
+            <View
+                android:id="@+id/line_view"
+                android:layout_width="match_parent"
+                android:layout_height="1dp"
+                android:layout_below="@id/dial_call_search"
+                android:background="#C3C3C3"/>
+
+            <TextView
+                android:id="@+id/tv_search_num_1"
+                android:layout_width="94dp"
+                android:layout_height="60dp"
+                android:layout_below="@id/line_view"
+                android:layout_marginTop="10dp"
+                android:background="@drawable/selector_dial_num_bg"
+                android:gravity="center"
+                android:text="1"
+                android:textStyle="bold"
+                android:textColor="@color/white"
+                android:textSize="32sp"/>
+
+            <TextView
+                android:id="@+id/tv_search_num_2"
+                android:layout_width="94dp"
+                android:layout_height="60dp"
+                android:layout_below="@id/line_view"
+                android:layout_toRightOf="@id/tv_search_num_1"
+                android:layout_marginLeft="14dp"
+                android:layout_marginTop="10dp"
+                android:background="@drawable/selector_dial_num_bg"
+                android:gravity="center"
+                android:text="2"
+                android:textStyle="bold"
+                android:textColor="@color/white"
+                android:textSize="32sp"/>
+
+            <TextView
+                android:id="@+id/tv_search_num_3"
+                android:layout_width="94dp"
+                android:layout_height="60dp"
+                android:layout_below="@id/line_view"
+                android:layout_toRightOf="@id/tv_search_num_2"
+                android:layout_marginLeft="14dp"
+                android:layout_marginTop="10dp"
+                android:background="@drawable/selector_dial_num_bg"
+                android:gravity="center"
+                android:text="3"
+                android:textStyle="bold"
+                android:textColor="@color/white"
+                android:textSize="32sp"/>
+
+            <TextView
+                android:id="@+id/tv_search_num_4"
+                android:layout_width="94dp"
+                android:layout_height="60dp"
+                android:layout_below="@id/tv_search_num_1"
+                android:layout_marginTop="10dp"
+                android:background="@drawable/selector_dial_num_bg"
+                android:gravity="center"
+                android:text="4"
+                android:textStyle="bold"
+                android:textColor="@color/white"
+                android:textSize="32sp"/>
+
+            <TextView
+                android:id="@+id/tv_search_num_5"
+                android:layout_width="94dp"
+                android:layout_height="60dp"
+                android:layout_below="@id/tv_search_num_1"
+                android:layout_toRightOf="@id/tv_search_num_4"
+                android:layout_marginLeft="14dp"
+                android:layout_marginTop="10dp"
+                android:background="@drawable/selector_dial_num_bg"
+                android:gravity="center"
+                android:text="5"
+                android:textStyle="bold"
+                android:textColor="@color/white"
+                android:textSize="32sp"/>
+
+            <TextView
+                android:id="@+id/tv_search_num_6"
+                android:layout_width="94dp"
+                android:layout_height="60dp"
+                android:layout_below="@id/tv_search_num_1"
+                android:layout_toRightOf="@id/tv_search_num_5"
+                android:layout_marginLeft="14dp"
+                android:layout_marginTop="10dp"
+                android:background="@drawable/selector_dial_num_bg"
+                android:gravity="center"
+                android:text="6"
+                android:textStyle="bold"
+                android:textColor="@color/white"
+                android:textSize="32sp"/>
+
+            <TextView
+                android:id="@+id/tv_search_num_7"
+                android:layout_width="94dp"
+                android:layout_height="60dp"
+                android:layout_below="@id/tv_search_num_4"
+                android:layout_marginTop="10dp"
+                android:background="@drawable/selector_dial_num_bg"
+                android:gravity="center"
+                android:text="7"
+                android:textStyle="bold"
+                android:textColor="@color/white"
+                android:textSize="32sp"/>
+
+            <TextView
+                android:id="@+id/tv_search_num_8"
+                android:layout_width="94dp"
+                android:layout_height="60dp"
+                android:layout_below="@id/tv_search_num_4"
+                android:layout_toRightOf="@id/tv_search_num_7"
+                android:layout_marginLeft="14dp"
+                android:layout_marginTop="10dp"
+                android:background="@drawable/selector_dial_num_bg"
+                android:gravity="center"
+                android:text="8"
+                android:textStyle="bold"
+                android:textColor="@color/white"
+                android:textSize="32sp"/>
+
+            <TextView
+                android:id="@+id/tv_search_num_9"
+                android:layout_width="94dp"
+                android:layout_height="60dp"
+                android:layout_below="@id/tv_search_num_4"
+                android:layout_toRightOf="@id/tv_search_num_8"
+                android:layout_marginLeft="14dp"
+                android:layout_marginTop="10dp"
+                android:background="@drawable/selector_dial_num_bg"
+                android:gravity="center"
+                android:text="9"
+                android:textStyle="bold"
+                android:textColor="@color/white"
+                android:textSize="32sp"/>
+
+            <TextView
+                android:id="@+id/tv_search_num_0"
+                android:layout_width="202dp"
+                android:layout_height="60dp"
+                android:layout_below="@id/tv_search_num_7"
+                android:layout_marginTop="10dp"
+                android:background="@drawable/selector_dial_num_bg"
+                android:gravity="center"
+                android:text="0"
+                android:textStyle="bold"
+                android:textColor="@color/white"
+                android:textSize="32sp"/>
+
+            <TextView
+                android:id="@+id/tv_search_num_del"
+                android:layout_width="94dp"
+                android:layout_height="60dp"
+                android:layout_below="@id/tv_search_num_7"
+                android:layout_toRightOf="@id/tv_search_num_0"
+                android:layout_marginLeft="14dp"
+                android:layout_marginTop="10dp"
+                android:background="@drawable/selector_dial_num_bg"
+                android:gravity="center"
+                android:text="DEL"
+                android:textStyle="bold"
+                android:textColor="@color/white"
+                android:textSize="24sp"/>
+
+            <TextView
+                android:id="@+id/dial_call_1"
+                android:layout_width="144dp"
+                android:layout_height="60dp"
+                android:layout_below="@id/tv_search_num_0"
+                android:layout_marginTop="28dp"
+                android:background="@drawable/records_bg_1"
+                android:gravity="center"
+                android:text="拨打管理处"
+                android:visibility="gone"
+                android:textColor="@color/white"
+                android:textSize="@dimen/font_size_20" />
+
+            <TextView
+                android:id="@+id/dial_call_2"
+                android:layout_width="144dp"
+                android:layout_height="60dp"
+                android:layout_below="@id/tv_search_num_0"
+                android:layout_toRightOf="@id/dial_call_1"
+                android:layout_marginLeft="20dp"
+                android:layout_marginTop="28dp"
+                android:background="@drawable/records_bg_3"
+                android:gravity="center"
+                android:text="拨打门卫"
+                android:visibility="gone"
+                android:textColor="@color/white"
+                android:textSize="@dimen/font_size_20" />
+
+            <TextView
+                android:id="@+id/dial_call_3"
+                android:layout_width="144dp"
+                android:layout_height="60dp"
+                android:layout_below="@id/dial_call_1"
+                android:layout_marginTop="20dp"
+                android:background="@drawable/records_bg_4"
+                android:gravity="center"
+                android:text="拨打点餐"
+                android:visibility="gone"
+                android:textColor="@color/white"
+                android:textSize="@dimen/font_size_20" />
+
+            <TextView
+                android:id="@+id/dial_call_4"
+                android:layout_width="144dp"
+                android:layout_height="60dp"
+                android:layout_below="@id/dial_call_1"
+                android:layout_toRightOf="@id/dial_call_3"
+                android:layout_marginLeft="20dp"
+                android:layout_marginTop="20dp"
+                android:background="@drawable/records_bg_5"
+                android:gravity="center"
+                android:text="拨打维修"
+                android:visibility="gone"
+                android:textColor="@color/white"
+                android:textSize="@dimen/font_size_20" />
+
+        </RelativeLayout>
+
+    </LinearLayout>
+</layout>

+ 339 - 0
android_host/src/main/res/layout/dorm_sky_voice_call_layout.xml

@@ -0,0 +1,339 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+    <RelativeLayout
+        android:id="@+id/dorm_calling_bed_layout_call_main"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@mipmap/theme_4">
+
+        <RelativeLayout
+            android:id="@+id/main_rl_1"
+            android:layout_width="120dp"
+            android:layout_height="match_parent"
+            android:background="@drawable/shape_main_drom_bg"
+            android:orientation="vertical">
+
+            <ImageButton
+                android:id="@+id/dorm_main_but"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:background="@mipmap/d_main_m" />
+
+            <!--<ImageButton
+                android:id="@+id/dorm_call_but"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_above="@+id/dorm_sos_but"
+                android:layout_centerInParent="true"
+                android:background="@mipmap/d_main_call" />-->
+
+            <ImageButton
+                android:id="@+id/dorm_sos_but"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentBottom="true"
+                android:layout_centerInParent="true"
+                android:layout_marginTop="@dimen/d30"
+                android:layout_marginBottom="@dimen/d30"
+                android:background="@mipmap/d_main_sos" />
+
+        </RelativeLayout>
+
+        <!--全屏视频画面-->
+        <FrameLayout
+            android:id="@+id/fullscreen_video_frame"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_gravity="center"
+            android:visibility="gone"/>
+
+        <!--小窗视频画面-->
+        <FrameLayout
+            android:id="@+id/pip_video_frame"
+            android:layout_width="200dp"
+            android:layout_height="240dp"
+            android:layout_gravity="top|end"
+            android:layout_marginHorizontal="10dp"
+            android:layout_marginTop="10dp"
+            android:visibility="gone"/>
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_toRightOf="@+id/main_rl_1"
+            android:background="@drawable/shape_dorm_bg">
+
+            <RelativeLayout
+                android:id="@+id/calling_bed_layout_title"
+                android:layout_width="match_parent"
+                android:layout_height="42dp">
+                <!--状态图标-->
+                <LinearLayout
+                    android:id="@+id/title_layout_ll_hl_right"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_alignParentRight="true"
+                    android:layout_centerVertical="true"
+                    android:layout_marginRight="10dp"
+                    android:orientation="horizontal">
+
+                    <!--SIP状态图标-->
+                    <ImageView
+                        android:id="@+id/title_layout_tv_hl_point"
+                        android:layout_width="24dp"
+                        android:layout_height="24dp"
+                        android:layout_gravity="center_vertical"
+                        android:layout_marginLeft="4dp"
+                        android:layout_marginRight="4dp"
+                        android:src="@mipmap/sip_w"
+                        android:visibility="gone" />
+
+                    <ImageView
+                        android:id="@+id/title_layout_iv_hl_bt"
+                        android:layout_width="24dp"
+                        android:layout_height="24dp"
+                        android:layout_gravity="center_vertical"
+                        android:layout_marginLeft="4dp"
+                        android:layout_marginRight="4dp"
+                        android:visibility="gone" />
+
+                    <ImageView
+                        android:id="@+id/title_layout_iv_hl_wifi"
+                        android:layout_width="24dp"
+                        android:layout_height="24dp"
+                        android:layout_gravity="center_vertical"
+                        android:layout_marginLeft="4dp"
+                        android:layout_marginRight="4dp"
+                        android:visibility="gone" />
+
+                    <ImageView
+                        android:id="@+id/title_layout_iv_hl_tcp"
+                        android:layout_width="24dp"
+                        android:layout_height="24dp"
+                        android:layout_gravity="center_vertical"
+                        android:layout_marginLeft="4dp"
+                        android:layout_marginRight="4dp"
+                        android:src="@mipmap/ic_tcp_fail" />
+
+                    <ImageView
+                        android:id="@+id/title_layout_iv_hl_ethernet"
+                        android:layout_width="24dp"
+                        android:layout_height="24dp"
+                        android:layout_gravity="center_vertical"
+                        android:layout_marginLeft="4dp"
+                        android:layout_marginRight="4dp"
+                        android:visibility="gone" />
+
+                    <ImageView
+                        android:id="@+id/title_layout_iv_day_hl_night"
+                        android:layout_width="24dp"
+                        android:layout_height="24dp"
+                        android:layout_gravity="center_vertical"
+                        android:layout_marginLeft="4dp"
+                        android:layout_marginRight="4dp"
+                        android:src="@mipmap/ic_daylight_w" />
+
+                </LinearLayout>
+
+            </RelativeLayout>
+
+            <!--呼出-->
+            <LinearLayout
+                android:id="@+id/ll_voice_call"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_below="@+id/calling_bed_layout_title"
+                android:gravity="center_horizontal"
+                android:orientation="vertical">
+
+                <ImageView
+                    android:id="@+id/sky_voice_call_head_img"
+                    android:layout_width="100dp"
+                    android:layout_height="100dp"
+                    android:layout_marginTop="80dp"
+                    android:scaleType="centerInside"
+                    android:src="@drawable/ic_call_main" />
+
+                <TextView
+                    android:id="@+id/dorm_sky_call_name"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:gravity="center"
+                    android:text=""
+                    android:textColor="@color/white"
+                    android:textSize="32sp" />
+
+                <TextView
+                    android:id="@+id/sky_voice_call_calling_text"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="20dp"
+                    android:gravity="center"
+                    android:text="正在呼叫..."
+                    android:textColor="@color/white"
+                    android:textSize="32sp" />
+
+                <TextView
+                    android:id="@+id/sky_voice_call_timeout"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="20dp"
+                    android:gravity="center"
+                    android:text=""
+                    android:textColor="@color/white"
+                    android:textSize="24sp" />
+            </LinearLayout>
+
+            <LinearLayout
+                android:id="@+id/sky_voice_call_outgoing"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_centerHorizontal="true"
+                android:layout_alignParentBottom="true"
+                android:layout_marginBottom="132dp"
+                android:orientation="vertical">
+
+                <Chronometer
+                    android:id="@+id/sky_voice_call_timer"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center"
+                    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="20dp">
+
+                    <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" />
+
+                    <TextView
+                        android:id="@+id/sky_voice_call_hangup"
+                        android:layout_width="200dp"
+                        android:layout_height="68dp"
+                        android:background="@drawable/shape_end_call"
+                        android:drawableLeft="@drawable/ic_end_call"
+                        android:drawablePadding="@dimen/d10"
+                        android:gravity="center_vertical"
+                        android:paddingLeft="32dp"
+                        android:text="取消呼叫"
+                        android:textColor="@color/white"
+                        android:textSize="@dimen/font_size_24"/>
+
+                    <ImageView
+                        android:id="@+id/sky_voice_call_speaker"
+                        android:layout_width="100dp"
+                        android:layout_height="100dp"
+                        android:layout_marginLeft="40dp"
+                        android:src="@drawable/av_speaker_selector"
+                        android:visibility="gone" />
+
+                </LinearLayout>
+
+            </LinearLayout>
+
+            <!--来电-->
+            <LinearLayout
+                android:id="@+id/sky_voice_call_incoming"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_centerHorizontal="true"
+                android:layout_alignParentBottom="true"
+                android:layout_marginBottom="132dp"
+                android:gravity="bottom"
+                android:orientation="horizontal"
+                android:visibility="gone">
+
+                <View
+                    android:layout_width="0dp"
+                    android:layout_height="1dp"
+                    android:layout_weight="2" />
+
+                <TextView
+                    android:id="@+id/sky_voice_call_ring_reject"
+                    android:layout_width="200dp"
+                    android:layout_height="68dp"
+                    android:background="@drawable/shape_end_call"
+                    android:drawableLeft="@drawable/ic_end_call"
+                    android:drawablePadding="@dimen/d10"
+                    android:gravity="center_vertical"
+                    android:paddingLeft="54dp"
+                    android:text="挂断"
+                    android:textColor="@color/white"
+                    android:textSize="@dimen/font_size_24" />
+
+                <View
+                    android:layout_width="0dp"
+                    android:layout_height="1dp"
+                    android:layout_weight="1" />
+
+                <TextView
+                    android:id="@+id/sky_voice_call_ring_pickup_audio"
+                    android:layout_width="200dp"
+                    android:layout_height="68dp"
+                    android:background="@drawable/shape_accept_call"
+                    android:drawableLeft="@drawable/ic_accept_call"
+                    android:drawablePadding="@dimen/d10"
+                    android:gravity="center_vertical"
+                    android:paddingLeft="54dp"
+                    android:text="接听"
+                    android:textColor="@color/white"
+                    android:textSize="@dimen/font_size_24" />
+
+                <View
+                    android:layout_width="0dp"
+                    android:layout_height="1dp"
+                    android:layout_weight="2" />
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:id="@+id/ll_voice_volume_bar"
+                android:layout_width="48dp"
+                android:layout_height="match_parent"
+                android:layout_alignParentRight="true"
+                android:layout_marginTop="100dp"
+                android:layout_marginRight="100dp"
+                android:layout_marginBottom="100dp"
+                android:clipChildren="true"
+                android:gravity="center"
+                android:orientation="vertical"
+                android:visibility="gone">
+
+                <TextView
+                    android:id="@+id/tv_volume"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center"
+                    android:textColor="@color/title_text"
+                    android:textSize="24sp" />
+
+                <com.wdkl.ncs.android.lib.widget.VerticalSeekBarWrapper
+                    android:layout_width="24dp"
+                    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:max="10"
+                        android:padding="8dp"
+                        android:progress="6"
+                        android:progressDrawable="@drawable/seek_bar_bg"
+                        android:splitTrack="false"
+                        android:thumb="@drawable/seek_bar_thumb"
+                        app:seekBarRotation="CW270" /> <!-- Rotation: CW90 or CW270 -->
+                </com.wdkl.ncs.android.lib.widget.VerticalSeekBarWrapper>
+            </LinearLayout>
+        </RelativeLayout>
+    </RelativeLayout>
+</layout>

+ 22 - 0
android_host/src/main/res/layout/dorm_theme_item.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout>
+    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="200dp"
+        android:layout_height="132dp">
+        <ImageView
+            android:id="@+id/img_theme_item"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:scaleType="fitXY">
+        </ImageView>
+
+        <ImageView
+            android:id="@+id/img_theme_item_check"
+            android:layout_width="60dp"
+            android:layout_height="60dp"
+            android:layout_gravity="center"
+            android:src="@drawable/ic_theme_check"
+            android:visibility="gone"/>
+    </FrameLayout>
+
+</layout>

+ 0 - 0
android_host/src/main/res/layout/dorm_theme_layout.xml


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است