Jelajahi Sumber

增加rk3128 5寸分机版本

weizhengliang 2 tahun lalu
induk
melakukan
ca493dc645
100 mengubah file dengan 8572 tambahan dan 18 penghapusan
  1. 5 1
      android_bed/build.gradle
  2. 33 0
      android_bed/src/main/h5_3128/AndroidManifest.xml
  3. 130 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/activity/AppUpdateActivity.kt
  4. 1670 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/activity/CallingbedActivity.kt
  5. 2 2
      android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/adapter/CostItemAdapter.kt
  6. 2 2
      android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/adapter/NumAdapter.java
  7. 69 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/adapter/NurseConfigAdpter.kt
  8. 9 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/agreement/CallingbedAgreement.kt
  9. 22 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/di/CallingbedComponent.kt
  10. 132 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/fragment/BaseCallFragment.kt
  11. 83 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/fragment/CostFragment.kt
  12. 196 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/fragment/MainFragment.kt
  13. 131 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/fragment/QrCodeFragment.kt
  14. 508 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/fragment/SkyCallFragment.kt
  15. 245 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/fragment/TestFragment.kt
  16. 270 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/AnrFcExceptionUtil.java.bak
  17. 188 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/AppUpdateHelper.java
  18. 94 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/AppUtil.java
  19. 1 1
      android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/AsyncPlayer.java
  20. 1 1
      android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/DoorLightHelper.java
  21. 160 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/HttpHelper.java
  22. 3 3
      android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/LanguageSetDialogHelper.java
  23. 79 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/LocaleMangerUtils.java
  24. 1 1
      android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/MediaPlayHelper.java
  25. 487 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/NetHelper.java
  26. 1 1
      android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/RecordHelper.java
  27. 30 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/ReflectHelper.java
  28. 1 1
      android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/RingPlayHelper.java
  29. 45 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/SOSHelper.java
  30. 1 1
      android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/ScreenManagerUtil.kt
  31. 195 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/SerialPortHelper.java
  32. 159 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/ServerConfigDialogHelper.java
  33. 70 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/SoundPoolHelper.java
  34. 2 2
      android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/SoundPoolManager.java
  35. 17 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/Utils.java
  36. 1 2
      android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/VoiceManagerUtil.java
  37. 51 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/WarningDialogHelper.java
  38. 237 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/XCrashUtils.java
  39. 20 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/launch/CallingbedLaunch.kt
  40. 384 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/settings/SettingConfig.java
  41. 581 0
      android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/sip/SipHelper.java.bak
  42. 7 0
      android_bed/src/main/h5_3128/res/anim/slide_down_in.xml
  43. 7 0
      android_bed/src/main/h5_3128/res/anim/slide_left_in.xml
  44. 7 0
      android_bed/src/main/h5_3128/res/anim/slide_right_out.xml
  45. 7 0
      android_bed/src/main/h5_3128/res/anim/slide_up_out.xml
  46. 34 0
      android_bed/src/main/h5_3128/res/drawable-v24/ic_launcher_foreground.xml
  47. TEMPAT SAMPAH
      android_bed/src/main/h5_3128/res/drawable/ic_answer_normal.png
  48. TEMPAT SAMPAH
      android_bed/src/main/h5_3128/res/drawable/ic_answer_press.png
  49. TEMPAT SAMPAH
      android_bed/src/main/h5_3128/res/drawable/ic_hangup_normal.png
  50. TEMPAT SAMPAH
      android_bed/src/main/h5_3128/res/drawable/ic_hangup_press.png
  51. 170 0
      android_bed/src/main/h5_3128/res/drawable/ic_launcher_background.xml
  52. TEMPAT SAMPAH
      android_bed/src/main/h5_3128/res/drawable/ic_nurse.png
  53. 5 0
      android_bed/src/main/h5_3128/res/drawable/selector_bottom_btn_text_color.xml
  54. 5 0
      android_bed/src/main/h5_3128/res/drawable/selector_call.xml
  55. 5 0
      android_bed/src/main/h5_3128/res/drawable/selector_call_answer.xml
  56. 5 0
      android_bed/src/main/h5_3128/res/drawable/selector_call_end.xml
  57. 5 0
      android_bed/src/main/h5_3128/res/drawable/selector_call_hangup.xml
  58. 5 0
      android_bed/src/main/h5_3128/res/drawable/selector_cost.xml
  59. 5 0
      android_bed/src/main/h5_3128/res/drawable/selector_doctor.xml
  60. 5 0
      android_bed/src/main/h5_3128/res/drawable/selector_main.xml
  61. 5 0
      android_bed/src/main/h5_3128/res/drawable/selector_qr_code.xml
  62. 5 0
      android_bed/src/main/h5_3128/res/drawable/selector_support.xml
  63. 7 0
      android_bed/src/main/h5_3128/res/drawable/shape_bed_name_bg.xml
  64. 7 0
      android_bed/src/main/h5_3128/res/drawable/shape_bed_num_bg.xml
  65. 7 0
      android_bed/src/main/h5_3128/res/drawable/shape_circle_bg.xml
  66. 7 0
      android_bed/src/main/h5_3128/res/drawable/shape_circle_bg_age.xml
  67. 8 0
      android_bed/src/main/h5_3128/res/drawable/shape_cost_bg.xml
  68. 7 0
      android_bed/src/main/h5_3128/res/drawable/shape_cost_list_title_bg.xml
  69. 7 0
      android_bed/src/main/h5_3128/res/drawable/shape_mai_bg_doctor_title.xml
  70. 14 0
      android_bed/src/main/h5_3128/res/drawable/shape_main_bg_admission.xml
  71. 6 0
      android_bed/src/main/h5_3128/res/drawable/shape_main_bg_bottom_broadcasting.xml
  72. 7 0
      android_bed/src/main/h5_3128/res/drawable/shape_main_bg_doctor_bottom.xml
  73. 42 0
      android_bed/src/main/h5_3128/res/layout/call_care_view.xml
  74. 40 0
      android_bed/src/main/h5_3128/res/layout/call_nurse_view.xml
  75. 253 0
      android_bed/src/main/h5_3128/res/layout/callingbed_main_lay.xml
  76. 14 0
      android_bed/src/main/h5_3128/res/layout/cost_view.xml
  77. 17 0
      android_bed/src/main/h5_3128/res/layout/digital_item.xml
  78. 75 0
      android_bed/src/main/h5_3128/res/layout/doctor_order_view.xml
  79. 36 0
      android_bed/src/main/h5_3128/res/layout/init_lay.xml
  80. 39 0
      android_bed/src/main/h5_3128/res/layout/item_cost_detail.xml
  81. 38 0
      android_bed/src/main/h5_3128/res/layout/item_cost_main_view.xml
  82. 44 0
      android_bed/src/main/h5_3128/res/layout/item_nurse_config.xml
  83. 83 0
      android_bed/src/main/h5_3128/res/layout/language_set_dialog.xml
  84. 318 0
      android_bed/src/main/h5_3128/res/layout/main_view.xml
  85. 67 0
      android_bed/src/main/h5_3128/res/layout/main_view_layout.xml
  86. 162 0
      android_bed/src/main/h5_3128/res/layout/qrcode_view.xml
  87. 189 0
      android_bed/src/main/h5_3128/res/layout/server_config_dialog_lay.xml
  88. 136 0
      android_bed/src/main/h5_3128/res/layout/sky_voice_call_layout.xml
  89. 10 0
      android_bed/src/main/h5_3128/res/layout/spinner_item.xml
  90. 41 0
      android_bed/src/main/h5_3128/res/layout/support_view.xml
  91. 39 0
      android_bed/src/main/h5_3128/res/layout/test_fragment_lay.xml
  92. 35 0
      android_bed/src/main/h5_3128/res/layout/update_lay.xml
  93. 29 0
      android_bed/src/main/h5_3128/res/layout/view_bed_name.xml
  94. 51 0
      android_bed/src/main/h5_3128/res/layout/view_message_layout.xml
  95. 102 0
      android_bed/src/main/h5_3128/res/layout/view_title_layout.xml
  96. 27 0
      android_bed/src/main/h5_3128/res/layout/warning_dialog_lay.xml
  97. 5 0
      android_bed/src/main/h5_3128/res/mipmap-anydpi-v26/ic_launcher.xml
  98. 5 0
      android_bed/src/main/h5_3128/res/mipmap-anydpi-v26/ic_launcher_round.xml
  99. TEMPAT SAMPAH
      android_bed/src/main/h5_3128/res/mipmap-hdpi/bg_main.png
  100. 0 0
      android_bed/src/main/h5_3128/res/mipmap-hdpi/bg_right.png

+ 5 - 1
android_bed/build.gradle

@@ -33,7 +33,11 @@ android {
 
     sourceSets {
         println 'config app_device_type ===== ' + app_device_type
-        if ("fj_h7_z_3128_1" == app_device_type) {
+        if ("fj_h5_z_3128_1" == app_device_type) {
+            main.java.srcDirs += 'src/main/h5_3128/java'
+            main.res.srcDirs += 'src/main/h5_3128/res'
+            main.manifest.srcFile 'src/main/h5_3128/AndroidManifest.xml'
+        } else if ("fj_h7_z_3128_1" == app_device_type) {
             main.java.srcDirs += 'src/main/h7_3128/java'
             main.res.srcDirs += 'src/main/h7_3128/res'
             main.manifest.srcFile 'src/main/h7_3128/AndroidManifest.xml'

+ 33 - 0
android_bed/src/main/h5_3128/AndroidManifest.xml

@@ -0,0 +1,33 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.wdkl.app.ncs.callingbed">
+
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.BLUETOOTH"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+
+    <application
+        android:allowBackup="true"
+        android:label="@string/app_name"
+        android:supportsRtl="true" >
+
+        <meta-data
+            android:name="com.enation.javashop.imagepluin.cache.MyGlideModule"
+            android:value="GlideModule" />
+        <meta-data
+            android:name="design_width_in_dp"
+            android:value="800"/>
+        <meta-data
+            android:name="design_height_in_dp"
+            android:value="480"/>
+
+        <activity android:name=".activity.CallingbedActivity"
+            android:screenOrientation="landscape"
+            android:launchMode="singleTask"/>
+
+        <activity android:name=".activity.AppUpdateActivity"
+            android:screenOrientation="landscape"
+            android:launchMode="singleTask"/>
+    </application>
+</manifest>

+ 130 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/activity/AppUpdateActivity.kt

@@ -0,0 +1,130 @@
+package com.wdkl.app.ncs.callingbed.activity
+
+import android.text.TextUtils
+import android.util.Log
+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.UpdateLayBinding
+import com.wdkl.app.ncs.callingbed.helper.AppUpdateHelper
+import com.wdkl.app.ncs.callingbed.helper.HttpHelper
+import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
+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.api.UrlManager
+import com.wdkl.ncs.android.middleware.common.Constant
+import com.wdkl.ncs.android.middleware.logic.contract.callingbed.AppUpdateContract
+import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.AppUpdatePresenter
+import com.wdkl.ncs.android.middleware.utils.StringUtil
+import kotlinx.android.synthetic.main.update_lay.*
+
+@Router(path = "/callingbed/update")
+class AppUpdateActivity :BaseActivity<AppUpdatePresenter, UpdateLayBinding>(), AppUpdateContract.View {
+    private val TAG = "AppUpdateActivity"
+
+    private val urlManager = UrlManager.build()
+
+    override fun getLayId(): Int {
+        return R.layout.update_lay
+    }
+
+    override fun bindDagger() {
+        CallingbedLaunch.component.inject(this)
+    }
+
+    override fun init() {
+        if (!TextUtils.isEmpty(Constant.APP_PATH)) {
+            val downloadPath = urlManager.base + Constant.APP_PATH
+            Log.e(TAG, "start download: $downloadPath")
+            downLoadAPK(downloadPath)
+        } else {
+            showMessage(R.string.download_error)
+            finish()
+        }
+    }
+
+    /**
+     * 下载APK包
+     */
+    fun downLoadAPK(url: String) {
+        Log.d(TAG, "downLoadAPK  url==$url")
+        activity_appupdate_dialog_progressview.setCurProgress(0)
+        HttpHelper.download(url, object : HttpHelper.DownloadListener {
+            override fun onDownloadSuccess() {
+                Log.d("download", "onDownloadSuccess==" + "成功")
+                runOnUiThread {
+                    activity_calling_bed_text_download.text = StringUtil.getResString(R.string.updating)
+                }
+                startInstallApk()
+            }
+
+            override fun onDownloading(progress: Int) {
+                runOnUiThread {
+                    activity_appupdate_dialog_progressview.setCurProgress(progress)
+                }
+            }
+
+            override fun onDownloadFailed() {
+                Log.d("download", "onDownloadFailed==" + "失败")
+                finish()
+            }
+        })
+    }
+
+    fun startInstallApk() {
+        Thread{
+            AppUpdateHelper.updateApp(this, object : AppUpdateHelper.UpdateCallBack {
+                override fun onFailed() {
+                    runOnUiThread {
+                        showMessage(R.string.update_fail)
+                        finish()
+                    }
+                }
+
+                override fun onSuccess() {
+                    runOnUiThread {
+                        showMessage(R.string.update_success)
+                        //finish()
+                        android.os.Process.killProcess(android.os.Process.myPid())
+                        System.exit(0)
+                    }
+                }
+            })
+        }.start()
+    }
+
+    override fun bindEvent() {
+        //
+    }
+
+    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(onMobile = {
+
+        },onWifi = {
+
+        },offline = {
+
+        })
+    }
+}

File diff ditekan karena terlalu besar
+ 1670 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/activity/CallingbedActivity.kt


+ 2 - 2
android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/adapter/CostItemAdapter.kt

@@ -1,4 +1,4 @@
-package com.wdkl.app.ncs.callingbed2.adapter
+package com.wdkl.app.ncs.callingbed.adapter
 
 import android.content.Context
 import android.support.v7.widget.LinearLayoutManager
@@ -7,7 +7,7 @@ import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.TextView
-import com.wdkl.app.ncs.callingbed2.R
+import com.wdkl.app.ncs.callingbed.R
 import com.wdkl.ncs.android.middleware.model.vo.CustomerFeeConfigByGroupNameVO
 import com.wdkl.ncs.android.middleware.model.vo.CustomerFeeConfigVO
 import com.wdkl.ncs.android.middleware.utils.StringUtil

+ 2 - 2
android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/adapter/NumAdapter.java

@@ -1,4 +1,4 @@
-package com.wdkl.app.ncs.callingbed2.adapter;
+package com.wdkl.app.ncs.callingbed.adapter;
 
 import android.content.Context;
 import android.view.LayoutInflater;
@@ -7,7 +7,7 @@ import android.view.ViewGroup;
 import android.widget.BaseAdapter;
 import android.widget.TextView;
 
-import com.wdkl.app.ncs.callingbed2.R;
+import com.wdkl.app.ncs.callingbed.R;
 
 public class NumAdapter extends BaseAdapter {
     private String[] num;

+ 69 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/adapter/NurseConfigAdpter.kt

@@ -0,0 +1,69 @@
+package com.wdkl.app.ncs.callingbed.adapter
+
+import android.content.Context
+import android.graphics.Color
+import android.support.v7.widget.RecyclerView
+import android.text.TextUtils
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.LinearLayout
+import android.widget.TextView
+import com.wdkl.app.ncs.callingbed.R
+import com.wdkl.ncs.android.middleware.model.dto.NurseConfigDto
+import java.lang.Exception
+
+class NurseConfigAdpter : RecyclerView.Adapter<NurseConfigAdpter.ViewHolder> {
+    private var context: Context
+    private var data: ArrayList<NurseConfigDto>
+
+    constructor(context: Context, data: ArrayList<NurseConfigDto>) {
+        this.context = context
+        this.data = data
+    }
+
+    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
+        val view = LayoutInflater.from(parent?.context).inflate(R.layout.item_nurse_config, parent, false)
+        val viewHolder = ViewHolder(view)
+
+        return viewHolder
+    }
+
+    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+        try {
+            val color = data[position].nurseColorRbg
+            if (TextUtils.isEmpty(color)) {
+                holder.nurseItem.setBackgroundColor(Color.parseColor("#E7E7E7"))
+            } else {
+                holder.nurseItem.setBackgroundColor(Color.parseColor("#$color"))
+            }
+            holder.nurseName.setText(data.get(position).nurseConfigName)
+            holder.nurseValue.setText(data.get(position).nurseOptionName)
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+    }
+
+    override fun getItemCount(): Int {
+        return data.size
+    }
+
+    fun updateData(data: ArrayList<NurseConfigDto>) {
+        this.data = data
+        notifyDataSetChanged()
+    }
+
+    class ViewHolder: RecyclerView.ViewHolder {
+        //var nurseColor : TextView
+        var nurseName : TextView
+        var nurseValue : TextView
+        var nurseItem : LinearLayout
+
+        constructor(itemView: View): super(itemView) {
+            //nurseColor = itemView.findViewById(R.id.tv_nurse_color)
+            nurseName = itemView.findViewById(R.id.tv_nurse_config_name)
+            nurseValue = itemView.findViewById(R.id.tv_nurse_config_value)
+            nurseItem = itemView.findViewById(R.id.ll_nurse_item)
+        }
+    }
+}

+ 9 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/agreement/CallingbedAgreement.kt

@@ -0,0 +1,9 @@
+package com.wdkl.app.ncs.callingbed.agreement
+
+import com.wdkl.ncs.android.middleware.model.dto.NurseConfigDto
+
+interface CallingbedAgreement {
+
+    //更新护理数据
+    fun updateNurseConfig(list: List<NurseConfigDto>)
+}

+ 22 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/di/CallingbedComponent.kt

@@ -0,0 +1,22 @@
+package com.wdkl.app.ncs.callingbed.di
+
+import com.wdkl.app.ncs.callingbed.activity.AppUpdateActivity
+import com.wdkl.app.ncs.callingbed.activity.CallingbedActivity
+import com.wdkl.app.ncs.callingbed.fragment.*
+import com.wdkl.ncs.android.middleware.di.ApplicationComponent
+import dagger.Component
+
+@Component(dependencies = arrayOf(ApplicationComponent::class))
+interface CallingbedComponent {
+    fun inject(activity: CallingbedActivity)
+
+    fun inject(activity: AppUpdateActivity)
+
+    fun inject(activity: MainFragment)
+
+    fun inject(activity: CostFragment)
+
+    fun inject(activity: QrCodeFragment)
+
+    fun inject(activity: TestFragment)
+}

+ 132 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/fragment/BaseCallFragment.kt

@@ -0,0 +1,132 @@
+package com.wdkl.app.ncs.callingbed.fragment
+
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.support.v4.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import com.enation.javashop.utils.base.tool.BaseToolActivity
+import com.wdkl.app.ncs.callingbed.R
+import com.wdkl.app.ncs.callingbed.helper.RingPlayHelper
+import com.wdkl.app.ncs.callingbed.settings.SettingConfig
+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.tcp.channel.VoiceUtil
+import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel
+import org.greenrobot.eventbus.EventBus
+
+abstract class BaseCallFragment: Fragment() {
+
+    private var layout: View? = null
+
+    protected lateinit var baseActivity: BaseToolActivity
+
+    //通话状态:0-去电, 1-来电, 2-探视
+    protected var callState : Int = 0
+    protected var tcpModel: TcpModel? = null
+    protected var bcPlay: Boolean = false
+
+    //计时器
+    lateinit var countDownTimer: CountDownTimer
+
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        retainInstance = true
+        callState = arguments.getInt("call_state")
+        bcPlay = arguments.getBoolean("bc_play")
+        if (arguments.getSerializable("tcp_model") != null) {
+            tcpModel = arguments.getSerializable("tcp_model") as TcpModel
+        }
+    }
+
+    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+        if (layout == null) {
+            layout = inflater.inflate(getLayId(), null)
+        }
+
+        /**初始化宿主Activity*/
+        baseActivity = getActivity() as BaseToolActivity
+
+        return layout
+    }
+
+    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        init()
+        bindEvent()
+    }
+
+    override fun onDestroyView() {
+        super.onDestroyView()
+        destroy()
+    }
+
+    override fun onStart() {
+        EventBus.getDefault().register(this)
+        super.onStart()
+    }
+
+    override fun onStop() {
+        EventBus.getDefault().unregister(this)
+        super.onStop()
+    }
+
+    protected abstract fun getLayId(): Int
+
+    protected abstract fun init()
+
+    protected abstract fun bindEvent()
+
+    protected abstract fun destroy()
+
+    protected abstract fun callEnd(handoff: Boolean)
+
+    //初始化计时器
+    protected fun initCountDownTimer(view: TextView) {
+        val overTime = SettingConfig.getSipOverTime(baseActivity) * 1000L
+        countDownTimer = object: CountDownTimer(overTime, 1000) {
+            override fun onTick(millisUntilFinished: Long) {
+                if (view != null) {
+                    val time = millisUntilFinished/1000
+                    view.setText(BaseApplication.appContext.getString(R.string.countdown_time, time))
+                }
+            }
+
+            override fun onFinish() {
+                //呼叫超时,返回到主界面
+                RingPlayHelper.stopRingTone()
+                showMessage(R.string.no_response)
+                Constant.CALL_STATE = Constant.CALL_STANDBY
+                VoiceUtil.cancelAudioCall(Constant.DEVICE_ID)
+                //backToMain()
+                callEnd(false)
+            }
+        }
+    }
+
+    //开始计时
+    protected fun startTimer() {
+        if (countDownTimer != null) {
+            countDownTimer.start()
+        }
+    }
+
+    //取消计时器
+    protected fun cancelTimer() {
+        if (countDownTimer != null) {
+            countDownTimer.cancel()
+        }
+    }
+
+    //返回主界面
+    protected fun backToMain() {
+        EventBus.getDefault().post(MessageEvent("BackCall", Constant.EVENT_REMOVE_CALL_FRAGMENT))
+    }
+
+}

+ 83 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/fragment/CostFragment.kt

@@ -0,0 +1,83 @@
+package com.wdkl.app.ncs.callingbed.fragment
+
+import android.support.v7.widget.LinearLayoutManager
+import com.enation.javashop.net.engine.model.NetState
+import com.wdkl.app.ncs.callingbed.R
+import com.wdkl.app.ncs.callingbed.adapter.CostItemAdapter
+import com.wdkl.app.ncs.callingbed.databinding.CostViewBinding
+import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
+import com.wdkl.ncs.android.lib.base.BaseFragment
+import com.wdkl.ncs.android.lib.utils.debugLog
+import com.wdkl.ncs.android.lib.utils.errorLog
+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.CostFragmentContract
+import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.CostFragmentPresenter
+import com.wdkl.ncs.android.middleware.model.vo.CustomerFeeConfigByGroupNameVO
+import com.wdkl.ncs.android.middleware.model.vo.CustomerFeeConfigVO
+import kotlinx.android.synthetic.main.cost_view.*
+
+class CostFragment : BaseFragment<CostFragmentPresenter, CostViewBinding>(), CostFragmentContract.View {
+    val TAG = "CostFragment"
+
+    override fun getLayId(): Int {
+        return R.layout.cost_view
+    }
+
+    override fun bindDagger() {
+        CallingbedLaunch.component.inject(this)
+    }
+
+    override fun init() {
+        if (Constant.CUSTOM_ID != -1) {
+            presenter.loadCustomCost(Constant.CUSTOM_ID)
+        } else {
+            showMessage("No custom id")
+        }
+    }
+
+    override fun bindEvent() {
+        //
+    }
+
+    override fun destory() {
+        //
+    }
+
+    override fun showCustomCost(cost: ArrayList<CustomerFeeConfigByGroupNameVO>) {
+        val layoutManager = LinearLayoutManager(activity)
+        rv_cost_main_view.layoutManager = layoutManager
+        rv_cost_main_view.adapter = CostItemAdapter(activity, cost)
+    }
+
+    override fun showCustomCost2(customFees: ArrayList<CustomerFeeConfigVO>) {
+        //
+    }
+
+    override fun onError(message: String, type: Int) {
+        showMessage(message)
+    }
+
+    override fun complete(message: String, type: Int) {
+        //
+    }
+
+    override fun start() {
+        //
+    }
+
+    override fun onNoNet() {
+        showMessage("No network")
+    }
+
+    override fun networkMonitor(state: NetState) {
+        state.filter(onWifi = {
+
+        },onMobile = {
+
+        },offline = {
+
+        })
+    }
+}

+ 196 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/fragment/MainFragment.kt

@@ -0,0 +1,196 @@
+package com.wdkl.app.ncs.callingbed.fragment
+
+import android.content.Intent
+import android.graphics.Color
+import android.text.TextUtils
+import android.util.Log
+import android.view.View
+import com.enation.javashop.net.engine.model.NetState
+import com.wdkl.app.ncs.callingbed.BuildConfig
+import com.wdkl.app.ncs.callingbed.R
+import com.wdkl.app.ncs.callingbed.activity.CallingbedActivity
+import com.wdkl.app.ncs.callingbed.databinding.MainViewLayoutBinding
+import com.wdkl.app.ncs.callingbed.helper.SerialPortHelper
+import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
+import com.wdkl.ncs.android.lib.base.BaseFragment
+import com.wdkl.ncs.android.lib.utils.*
+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.MainFragmentContract
+import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.MainFragmentPresenter
+import com.wdkl.ncs.android.middleware.model.dto.NurseConfigDto
+import com.wdkl.ncs.android.middleware.model.vo.CustomerInfoVO
+import com.wdkl.ncs.android.middleware.utils.StringUtil
+import kotlinx.android.synthetic.main.main_view.*
+import kotlinx.android.synthetic.main.view_bed_name.*
+import org.greenrobot.eventbus.EventBus
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+
+class MainFragment: BaseFragment<MainFragmentPresenter, MainViewLayoutBinding>(), MainFragmentContract.View{
+    val TAG = "MainFragment"
+
+    override fun getLayId(): Int {
+        return R.layout.main_view
+    }
+
+    override fun bindDagger() {
+        CallingbedLaunch.component.inject(this)
+    }
+
+    override fun init() {
+        updateInfo()
+    }
+
+    override fun bindEvent() {
+        //
+    }
+
+    override fun onStart() {
+        EventBus.getDefault().register(this)
+        super.onStart()
+    }
+
+    override fun onStop() {
+        EventBus.getDefault().unregister(this)
+        super.onStop()
+    }
+
+    override fun destory() {
+        //
+    }
+
+    override fun showCustomInfo(customInfo: CustomerInfoVO) {
+        //隐藏空页面并展示入住信息
+        ll_empty.visibility = View.GONE
+        ll_custom_view.visibility = View.VISIBLE
+
+        //显示入住信息
+        tv_custom_name.text = customInfo.named
+        if (customInfo.sex == 0) {
+            tv_custom_gender.setBackgroundResource(R.mipmap.ic_gender_female)
+        } else if (customInfo.sex == 1) {
+            tv_custom_gender.setBackgroundResource(R.mipmap.ic_gender_male)
+        }
+        tv_custom_age.text = "" + customInfo.age + customInfo.ageUnit
+        if (customInfo.inDate != null) {
+            tv_custom_indate.text = StringUtil.getResString(R.string.indate) + TimeHandle.getDateTime(customInfo.inDate * 1000, "yyyy.MM.dd")
+        }
+        if (TextUtils.isEmpty(customInfo.advice)) {
+            tv_order_content.text = StringUtil.getResString(R.string.str_empty)
+        } else {
+            tv_order_content.text = customInfo.advice
+        }
+
+        if (Constant.doctorValid == 1) {
+            ll_doctor_view.visibility = View.VISIBLE
+            tv_doctor_title.text = Constant.doctorTitle
+        } else {
+            ll_doctor_view.visibility = View.GONE
+        }
+
+        if (Constant.nurseValid == 1) {
+            ll_nurse_view.visibility = View.VISIBLE
+            tv_nurse_title.text = Constant.nurseTitle
+        } else {
+            ll_nurse_view.visibility = View.GONE
+        }
+
+        tv_doctor_name.text = customInfo.doctorName
+        tv_nurse_name.text = customInfo.nurseName
+
+        //更新护理项
+        if (customInfo.list != null) {
+            AppTool.Time.delay(1800) {
+                if (activity != null) {
+                    (activity as CallingbedActivity).updateNurseConfig(customInfo.list)
+                }
+            }
+
+            updateMoreConfigs(customInfo.list)
+        }
+    }
+
+    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 = {
+
+        })
+    }
+
+    override fun onNoNet() {
+        showMessage("No network")
+    }
+
+    private fun updateInfo() {
+        if (Constant.DEVICE_STATUS == 0) {
+            tv_bed_name.text = StringUtil.getResString(R.string.device_disable)
+            tv_bed_name.setTextColor(resources.getColor(R.color.red_color))
+        } else {
+            tv_bed_name.text = Constant.BED_NAME
+            tv_bed_name.setTextColor(resources.getColor(R.color.main_color))
+        }
+
+        if (Constant.CUSTOM_ID != -1) {
+            ll_empty.visibility = View.GONE
+            presenter.loadCustomInfo(Constant.CUSTOM_ID)
+        }
+
+        tv_version.text = "V"+BuildConfig.VERSION_NAME+"_"+BuildConfig.VERSION_CODE
+    }
+
+    private fun updateMoreConfigs(data: List<NurseConfigDto>) {
+        if (data.size > 5) {
+            ll_nurse_more.visibility = View.VISIBLE
+            if (data.size == 6) {
+                ll_nurse_item6.setBackgroundColor(Color.parseColor("#"+data[5].nurseColorRbg))
+                tv_nurse_name6.text = data[5].nurseConfigName
+                tv_nurse_value6.text = data[5].nurseOptionName
+            } else if (data.size == 7) {
+                ll_nurse_item6.setBackgroundColor(Color.parseColor("#"+data[5].nurseColorRbg))
+                tv_nurse_name6.text = data[5].nurseConfigName
+                tv_nurse_value6.text = data[5].nurseOptionName
+                ll_nurse_item7.setBackgroundColor(Color.parseColor("#"+data[6].nurseColorRbg))
+                tv_nurse_name7.text = data[6].nurseConfigName
+                tv_nurse_value7.text = data[6].nurseOptionName
+            } else if (data.size >= 8) {
+                ll_nurse_item6.setBackgroundColor(Color.parseColor("#"+data[5].nurseColorRbg))
+                tv_nurse_name6.text = data[5].nurseConfigName
+                tv_nurse_value6.text = data[5].nurseOptionName
+                ll_nurse_item7.setBackgroundColor(Color.parseColor("#"+data[6].nurseColorRbg))
+                tv_nurse_name7.text = data[6].nurseConfigName
+                tv_nurse_value7.text = data[6].nurseOptionName
+                ll_nurse_item8.setBackgroundColor(Color.parseColor("#"+data[7].nurseColorRbg))
+                tv_nurse_name8.text = data[7].nurseConfigName
+                tv_nurse_value8.text = data[7].nurseOptionName
+            }
+        } else {
+            ll_nurse_more.visibility = View.GONE
+        }
+    }
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    fun onMoonEvent(messageEvent: MessageEvent) {
+        when (messageEvent.getType()) {
+            Constant.EVENT_UPDATE_CUSTOM -> {
+                updateInfo()
+            }
+        }
+    }
+}

+ 131 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/fragment/QrCodeFragment.kt

@@ -0,0 +1,131 @@
+package com.wdkl.app.ncs.callingbed.fragment
+
+import com.enation.javashop.net.engine.model.NetState
+import com.wdkl.app.ncs.callingbed.BuildConfig
+import com.wdkl.app.ncs.callingbed.R
+import com.wdkl.app.ncs.callingbed.activity.CallingbedActivity
+import com.wdkl.app.ncs.callingbed.databinding.QrcodeViewBinding
+import com.wdkl.app.ncs.callingbed.helper.AppUpdateHelper
+import com.wdkl.app.ncs.callingbed.helper.LanguageSetDialogHelper
+import com.wdkl.app.ncs.callingbed.helper.NetHelper
+import com.wdkl.app.ncs.callingbed.helper.ServerConfigDialogHelper
+import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
+import com.wdkl.ncs.android.lib.base.BaseFragment
+import com.wdkl.ncs.android.lib.utils.EcodeHelper
+import com.wdkl.ncs.android.lib.vo.filter
+import com.wdkl.ncs.android.middleware.api.UrlManager
+import com.wdkl.ncs.android.middleware.common.Constant
+import com.wdkl.ncs.android.middleware.logic.contract.callingbed.QrCodeFragmentContract
+import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.QrCodeFragmentPresenter
+import com.wdkl.ncs.android.middleware.utils.StringUtil
+import kotlinx.android.synthetic.main.qrcode_view.*
+import kotlinx.android.synthetic.main.view_bed_name.*
+
+class QrCodeFragment : BaseFragment<QrCodeFragmentPresenter, QrcodeViewBinding>(), QrCodeFragmentContract.View {
+    val TAG = "QrCodeFragment"
+    val QR_CODE_PATH = "http://m.wdklian.com/care/apk/care.user?type=NCS_DEVICE"
+
+    override fun getLayId(): Int {
+        return R.layout.qrcode_view
+    }
+
+    override fun bindDagger() {
+        CallingbedLaunch.component.inject(this)
+    }
+
+    override fun init() {
+        if (Constant.DEVICE_STATUS == 0) {
+            tv_bed_name.text = StringUtil.getResString(R.string.device_disable)
+            tv_bed_name.setTextColor(resources.getColor(R.color.red_color))
+        } else {
+            tv_bed_name.text = Constant.BED_NAME
+            tv_bed_name.setTextColor(resources.getColor(R.color.main_color))
+        }
+
+        tv_version.text = "V"+BuildConfig.VERSION_NAME+"_"+BuildConfig.VERSION_CODE
+
+        Thread{
+            //val logoBitmap = BitmapFactory.decodeResource(resources, R.mipmap.erlogo)
+            var builder = StringBuilder()
+            builder.append(QR_CODE_PATH)
+            builder.append("&code=")
+            builder.append(Constant.DEVICE_CODE)
+            builder.append("&mac=")
+            builder.append(Constant.LOCAL_MAC)
+            builder.append("&model=")
+            builder.append(Constant.DEVICE_MODEL)
+            builder.append("&hard_ver=")
+            builder.append(Constant.DEVICE_HARD_VER)
+            builder.append("&soft_ver=")
+            builder.append(Constant.DEVICE_SOFT_VER)
+            builder.append("&device_type=")
+            builder.append(Constant.DEVICE_TYPE)
+            builder.append("&device_name=")
+            builder.append(Constant.DEVICE_NAME)
+            val code = EcodeHelper().createQRImage(builder.toString(),180, null)
+            activity.runOnUiThread {
+                view_qr_code?.setImageBitmap(code)
+            }
+        }.start()
+
+        val macAddr = NetHelper.getInstance().macAddress
+        val ipAddr = NetHelper.getInstance().localIP
+        if (Constant.DEVICE_STATUS == 0) {
+            tv_device_id.text = "Device ID: " + Constant.DEVICE_ID + " - " + StringUtil.getResString(R.string.str_disable)
+        } else if (Constant.DEVICE_STATUS == 1) {
+            tv_device_id.text = "Device ID: " + Constant.DEVICE_ID + " - " + StringUtil.getResString(R.string.str_enable)
+        } else {
+            tv_device_id.text = "Device ID: " + Constant.DEVICE_ID
+        }
+
+        val serverIp =  UrlManager.build().base.substringAfterLast("//").substringBefore(":")
+        tv_local_ip.text = "IP: " + ipAddr + " - " + serverIp
+        tv_local_mac.text = "MAC: " + macAddr
+        tv_app_version.text = "Version: V" + BuildConfig.VERSION_NAME + "_" + BuildConfig.VERSION_CODE
+        tv_mcu_version.text = "MCU: " + Constant.MCU_VERSION_NUMBER
+    }
+
+    override fun bindEvent() {
+        tv_btn_update_app.setOnClickListener {
+            (activity as CallingbedActivity).checkAppVersion()
+        }
+
+        tv_btn_reboot.setOnClickListener {
+            AppUpdateHelper.reboot(context)
+        }
+
+        tv_btn_server_config.setOnClickListener {
+            ServerConfigDialogHelper.showPasswordDialog(activity)
+        }
+
+        tv_btn_language_setting.setOnClickListener {
+            LanguageSetDialogHelper.showDialog(activity)
+        }
+    }
+
+    override fun setUrlString(url: String) {
+        //
+    }
+
+    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 = {
+
+        })
+    }
+}

+ 508 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/fragment/SkyCallFragment.kt

@@ -0,0 +1,508 @@
+package com.wdkl.app.ncs.callingbed.fragment
+
+import android.os.Handler
+import android.os.Looper
+import android.os.SystemClock
+import android.text.TextUtils
+import android.util.Log
+import android.view.View
+import com.google.gson.Gson
+import com.wdkl.app.ncs.callingbed.R
+import com.wdkl.app.ncs.callingbed.helper.RingPlayHelper
+import com.wdkl.app.ncs.callingbed.settings.SettingConfig
+import com.wdkl.ncs.android.lib.utils.AppTool
+import com.wdkl.ncs.android.lib.utils.showMessage
+import com.wdkl.ncs.android.middleware.common.Constant
+import com.wdkl.ncs.android.middleware.common.MessageEvent
+import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
+import com.wdkl.ncs.android.middleware.tcp.channel.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.TcpAction
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpType
+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.sky_voice_call_layout.*
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+import org.webrtc.SurfaceViewRenderer
+import java.math.BigInteger
+
+class SkyCallFragment: BaseCallFragment(), CallSessionCallback {
+    private val TAG = "SkyCallFragment"
+
+    //来电设备id
+    var fromId: Int = -1
+
+    private var interactionVO: InteractionVO? = null
+
+    private var localSurfaceView: SurfaceViewRenderer? = null
+    private var remoteSurfaceView: SurfaceViewRenderer? = null
+
+    private var janusClient: JanusClient? = null
+    private var room: Room?=null
+    private var videoRoomCallback: VideoRoomCallback? = null
+
+    private val handler = Handler(Looper.getMainLooper())
+
+    private var visiting: Boolean = false
+    private var audioCall: Boolean = true
+    private var callEnded: Boolean = false
+    private var outGoing: Boolean = false
+    private var callSuccess: Boolean = false
+
+    private var janusInit = false
+
+    override fun getLayId(): Int {
+        return R.layout.sky_voice_call_layout
+    }
+
+    override fun init() {
+        //初始化计时器
+        initCountDownTimer(sky_voice_call_timeout)
+        //tcp参数
+        if (tcpModel != null) {
+            fromId = tcpModel!!.fromId
+            interactionVO = Gson().fromJson(tcpModel!!.data.toString(), InteractionVO::class.java)
+        }
+
+
+        //判断是否有广播在播放
+        if (bcPlay && callState == 1) {
+            handler.postDelayed({
+                janusInit()
+            }, 2000)
+        } else {
+            janusInit()
+        }
+    }
+
+    private fun janusInit() {
+        //初始化 engine
+        WebRTCEngine.getInstance().init(true, this.context)
+        //初始化 janusClient
+        janusClient = JanusClient(JanusConstant.JANUS_URL, Constant.SIP_ID.toBigInteger())
+
+        when (callState) {
+            0 -> {
+                //去电
+                outGoing = true
+                startOutgoing()
+                RingPlayHelper.playRingTone(baseActivity, R.raw.ring_back2, true)
+
+                janusClient!!.callState = EnumType.CallState.Outgoing
+                room = Room(Constant.SIP_ID.toBigInteger())
+            }
+
+            1 -> {
+                //来电
+                outGoing = false
+                showIncomingCall()
+
+                janusClient!!.callState = EnumType.CallState.Incoming
+                room = Room(Constant.TARGET_SIP.toBigInteger())
+
+                if (SettingConfig.getAutoAnswer(activity)) {
+                    //自动接听
+                    handler.postDelayed({
+                        if (!callEnded && Constant.CALL_STATE != Constant.CALL_CALLING) {
+                            RingPlayHelper.stopRingTone()
+                            VoiceUtil.acceptAudioCall(Constant.DEVICE_ID, fromId, interactionVO?.id)
+                            acceptCall()
+                            janusClient!!.connect(-1, false)
+                        }
+                    }, 1500)
+                } else {
+                    RingPlayHelper.playRingTone(baseActivity, R.raw.ring_tone, true)
+                }
+            }
+
+            /*2 -> {
+                //探视
+                outGoing = true
+                visiting = true
+                acceptCall()
+                //因为探视请求是由探视机发起的,所以在每一条的探视交互记录中的from为探视机
+                startVisiting(interactionVO!!.fromSipId)
+            }*/
+        }
+
+        videoRoomCallback = VideoRoomCallback(janusClient, room, Constant.SIP_ID.toBigInteger())
+        videoRoomCallback!!.callSessionCallback = this
+        janusClient!!.setJanusCallback(videoRoomCallback)
+
+        janusInit = true
+    }
+
+    override fun bindEvent() {
+        //去电取消或通话挂断
+        /*sky_voice_call_hangup.setOnClickListener {
+            RingPlayHelper.stopRingTone()
+            if (Constant.CALL_STATE == Constant.CALL_CALLING) {
+                //结束sip通话
+                Constant.CALL_STATE = Constant.CALL_STANDBY
+                sky_voice_call_timer.stop()
+                callEnd(true)
+            } else {
+                Constant.CALL_STATE = Constant.CALL_STANDBY
+                VoiceUtil.cancelAudioCall(Constant.DEVICE_ID)
+                cancelCall()
+            }
+        }
+
+        //来电拒绝
+        sky_voice_call_ring_reject.setOnClickListener {
+            RingPlayHelper.stopRingTone()
+            Constant.CALL_STATE = Constant.CALL_STANDBY
+            VoiceUtil.rejectAudioCall(Constant.DEVICE_ID, fromId, interactionVO?.id)
+            callEnd(false)
+        }
+
+        //来电接听
+        sky_voice_call_ring_pickup_audio.setOnClickListener {
+            RingPlayHelper.stopRingTone()
+            Constant.CALL_STATE = Constant.CALL_INCOMING
+            VoiceUtil.acceptAudioCall(Constant.DEVICE_ID, fromId, interactionVO?.id)
+            acceptCall()
+            janusClient!!.connect()
+        }*/
+    }
+
+    override fun destroy() {
+        cancelTimer()
+        Constant.CALL_STATE = Constant.CALL_STANDBY
+        if (sky_voice_call_timer != null) {
+            sky_voice_call_timer.stop()
+        }
+        RingPlayHelper.stopRingTone()
+        handler.removeCallbacksAndMessages(null)
+    }
+
+    private fun startOutgoing() {
+        callSuccess = false
+        sky_voice_call_hangup.isEnabled = false
+        VoiceUtil.startAudioCall(Constant.DEVICE_ID)
+        Constant.CALL_STATE = Constant.CALL_OUTGOING
+        sky_voice_call_timeout.visibility = View.VISIBLE
+        sky_voice_call_timer.visibility = View.GONE
+        startTimer()
+
+        AppTool.Time.delay(5000) {
+            Log.d("tcp", "call success: $callSuccess")
+            if (!callSuccess) {
+                //呼叫失败
+                showMessage(R.string.call_fail)
+                RingPlayHelper.stopRingTone()
+                cancelCall()
+            }
+        }
+    }
+
+    //去电界面
+    private fun showOutgoingCall() {
+        Constant.CALL_STATE = Constant.CALL_OUTGOING
+        sky_voice_call_calling_text.text = StringUtil.getResString(R.string.call_success)
+        sky_voice_call_outgoing.visibility = View.VISIBLE
+        sky_voice_call_incoming.visibility = View.GONE
+        sky_voice_call_timeout.visibility = View.VISIBLE
+        sky_voice_call_timer.visibility = View.GONE
+        startTimer()
+    }
+
+    //来电界面
+    private fun showIncomingCall() {
+        Constant.CALL_STATE = Constant.CALL_INCOMING
+        sky_voice_call_calling_text.text = StringUtil.getResString(R.string.call_incoming)
+        sky_voice_call_outgoing.visibility = View.GONE
+        if (SettingConfig.getAutoAnswer(activity)) {
+            sky_voice_call_incoming.visibility = View.GONE
+        } else {
+            sky_voice_call_incoming.visibility = View.VISIBLE
+        }
+
+        sky_voice_call_timeout.visibility = View.GONE
+        sky_voice_call_timer.visibility = View.GONE
+    }
+
+    //开始接听
+    private fun acceptCall() {
+        sky_voice_call_calling_text.text = StringUtil.getResString(R.string.call_connecting)
+        sky_voice_call_outgoing.visibility = View.VISIBLE
+        sky_voice_call_incoming.visibility = View.GONE
+        sky_voice_call_timeout.visibility = View.GONE
+        sky_voice_call_timer.visibility = View.GONE
+        cancelTimer()
+    }
+
+    //呼叫取消
+    private fun cancelCall() {
+        cancelTimer()
+        Constant.CALL_STATE = Constant.CALL_STANDBY
+        callEnd(false)
+    }
+
+    private fun showCalling(audioOnly: Boolean) {
+        if (callEnded) {
+            return
+        }
+
+        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
+        }
+
+        Constant.CALL_STATE = Constant.CALL_CALLING
+        sky_voice_call_calling_text.text = StringUtil.getResString(R.string.call_in_call)
+        sky_voice_call_timeout.visibility = View.GONE
+        cancelTimer()
+        sky_voice_call_timer.visibility = View.VISIBLE
+        sky_voice_call_timer.base = SystemClock.elapsedRealtime()
+        sky_voice_call_timer.start()
+    }
+
+    //通话结束
+    override fun callEnd(handoff: Boolean) {
+        synchronized(this) {
+            if (callEnded) {
+                return
+            }
+            callEnded = true
+            Constant.CALL_STATE = Constant.CALL_STANDBY
+            if (sky_voice_call_timer != null) {
+                sky_voice_call_timer.stop()
+            }
+
+            Log.e(TAG, "call end !!!!!!!!!!!!!!!!!!")
+            if (handoff) {
+                if (visiting) {
+                    VideoUtil.handoffVideoCall(Constant.DEVICE_ID, fromId, interactionVO?.id)
+                } else {
+                    VoiceUtil.handoffAudioCall(Constant.DEVICE_ID, fromId, interactionVO?.id)
+                }
+            }
+
+            if (janusInit) {
+                if (janusClient!!.webSocketChannel != null) {
+                    janusClient!!.callState = EnumType.CallState.Idle
+                    if (callState == 0) {
+                        janusClient!!.destroyRoom(janusClient!!.currentHandleId, null)
+                    } else {
+                        janusClient!!.leaveRoom()
+                    }
+
+                    janusClient!!.disConnect()
+                }
+            }
+
+            backToMain()
+        }
+    }
+
+    //探视
+/*    private fun startVisiting(targetId: String) {
+        //如果设备没有摄像头则只能语音通话
+        if (!startCall(targetId, !Constant.supportCamera)) {
+            //通话失败,重置并返回主界面
+            Constant.CALL_STATE = Constant.CALL_STANDBY
+            VideoUtil.rejectVideoCall(Constant.DEVICE_ID, fromId, interactionVO!!.id)
+            if (sky_voice_call_timer != null) {
+                sky_voice_call_timer.stop()
+            }
+            backToMain()
+        }
+    }*/
+
+
+    /********************************************************
+     ********************* 通话回调 ********************
+     * 注意: 如涉及到UI更新的需要在主线程处理,务必注意
+     ********************************************************/
+    override fun didChangeState(var1: EnumType.CallState?) {
+        if (var1 == EnumType.CallState.Connected) {
+            handler.post {
+                RingPlayHelper.stopRingTone()
+                //更新界面显示
+                showCalling(audioCall)
+            }
+        }
+    }
+
+    override fun didDisconnected(userId: String?) {
+        Log.i(TAG, "disconnected user:" + userId + ",call user:" + Constant.TARGET_SIP)
+        if (userId.equals(Constant.TARGET_SIP)) {
+            Log.w(TAG, "didDisconnected: $userId")
+            handler.post {
+                showMessage("$userId disconnect")
+                callEnd(true)
+            }
+        }
+    }
+
+    override fun didCreateLocalVideoTrack() {
+
+    }
+
+    override fun didError(error: String?) {
+        Log.e(TAG, "didError: $error")
+        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 didReceiveRemoteVideoTrack(userId: BigInteger?) {
+        // TODO("Not yet implemented")
+    }
+
+
+    override fun didCallEndWithReason(var1: EnumType.CallEndReason?) {
+        handler.post {
+            callEnd(true)
+        }
+    }
+
+    override fun didChangeMode(isAudioOnly: Boolean) {
+
+    }
+
+    override fun didUserLeave(userId: BigInteger?) {
+        Log.w(TAG, "didUserLeave:"+userId)
+        handler.post {
+            callEnd(true)
+        }
+    }
+
+
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    fun onMoonEvent(messageEvent: MessageEvent) {
+        when (messageEvent.type) {
+            Constant.EVENT_TCP_MSG -> {
+                if (messageEvent.message is TcpModel) {
+                    val curTcpModel = messageEvent.message as TcpModel
+                    if (curTcpModel.getType() == TcpType.VOICE) {
+                        if (curTcpModel.action == TcpAction.VoiceAction.CANCEL_BY_DOOR) {
+                            //如果当前正在通话中则不做取消处理
+                            if (Constant.CALL_STATE == Constant.CALL_CALLING) {
+                                return
+                            }
+
+                            Constant.CALL_STATE = Constant.CALL_STANDBY
+                            VoiceUtil.cancelAudioCall(Constant.DEVICE_ID)
+                            cancelCall()
+                            return
+                        }
+
+                        if (curTcpModel.data != null) {
+                            val curInteractionVO = Gson().fromJson(curTcpModel.data.toString(), InteractionVO::class.java)
+                            if (curTcpModel.getAction() == TcpAction.VoiceAction.ACCEPT) {
+                                //我方呼出,对方接受
+                                RingPlayHelper.stopRingTone()
+                                Constant.interactionId = curInteractionVO.id
+                                fromId = curTcpModel.fromId
+                                acceptCall()
+                                /*if (TextUtils.isEmpty(curInteractionVO.toSipId)) {
+                                    //通话失败,重置并返回主界面
+                                    showMessage("targetSipId empty!")
+                                    Constant.CALL_STATE = Constant.CALL_STANDBY
+                                    callEnd(true)
+                                }*/
+                            } else if (curTcpModel.getAction() == TcpAction.VoiceAction.REJECT) {
+                                //我方呼出,对方拒绝
+                                showMessage(R.string.call_reject)
+                                RingPlayHelper.stopRingTone()
+                                cancelCall()
+                            } else if (curTcpModel.getAction() == TcpAction.VoiceAction.CALLING) {
+                                //我方呼出,对方通话中
+                                showMessage(R.string.call_busy)
+                                /*AppTool.Time.delay(1000) {
+                                RingPlayHelper.stopRingTone()
+                                cancelCall()
+                            }*/
+                            } else if (curTcpModel.getAction() == TcpAction.VoiceAction.SUCCESS) {
+                                //呼叫成功
+                                //本机呼叫的时候tcpModel为空,只有呼叫成功的时候才能获得对应tcp相关数据
+                                callSuccess = true
+                                sky_voice_call_hangup.isEnabled = true
+                                interactionVO = curInteractionVO
+                                Constant.interactionId = curInteractionVO.id
+                                showOutgoingCall()
+                                janusClient!!.connect(-1, false)
+                            } else if (curTcpModel.getAction() == TcpAction.VoiceAction.FAILED) {
+                                //我方呼出,对方不在线,设备离线或其它错误
+                                callSuccess = true
+                                showMessage(R.string.call_failed)
+                                AppTool.Time.delay(1500) {
+                                    RingPlayHelper.stopRingTone()
+                                    cancelCall()
+                                }
+                            } else if (curTcpModel.getAction() == TcpAction.VoiceAction.HANDOFF) {
+                                //对方挂断,不论我方呼出或呼入
+                                if (Constant.interactionId == curInteractionVO.id) {
+                                    RingPlayHelper.stopRingTone()
+                                    cancelCall()
+                                }
+                            } else if (curTcpModel.getAction() == TcpAction.VoiceAction.CANCEL) {
+                                //对方呼叫时取消
+                                if (Constant.interactionId == curInteractionVO.id) {
+                                    RingPlayHelper.stopRingTone()
+                                    cancelCall()
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            //外部呼叫按键
+            Constant.EVENT_SERIAL_EVENT -> {
+                if (!janusInit) {
+                    return
+                }
+
+                if (messageEvent.message is String) {
+                    val serialAction = messageEvent.message as String
+                    if (serialAction.equals("cancel")) {
+                        RingPlayHelper.stopRingTone()
+                        Constant.CALL_STATE = Constant.CALL_STANDBY
+                        VoiceUtil.cancelAudioCall(Constant.DEVICE_ID)
+                        cancelCall()
+                    } else if (serialAction.equals("accept")) {
+                        RingPlayHelper.stopRingTone()
+                        //Constant.CALL_STATE = Constant.CALL_CALLING
+                        VoiceUtil.acceptAudioCall(Constant.DEVICE_ID, fromId, interactionVO?.id)
+                        acceptCall()
+                        janusClient!!.connect(-1, false)
+                    } else if (serialAction.equals("handoff")) {
+                        Constant.CALL_STATE = Constant.CALL_STANDBY
+                        callEnd(true)
+                    } else if (serialAction.equals("reject")) {
+                        RingPlayHelper.stopRingTone()
+                        Constant.CALL_STATE = Constant.CALL_STANDBY
+                        VoiceUtil.rejectAudioCall(Constant.DEVICE_ID, fromId, interactionVO?.id)
+                        callEnd(false)
+                    }
+                }
+            }
+        }
+    }
+
+}

+ 245 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/fragment/TestFragment.kt

@@ -0,0 +1,245 @@
+package com.wdkl.app.ncs.callingbed.fragment
+
+import android.os.Handler
+import android.os.Looper
+import com.enation.javashop.net.engine.model.NetState
+import com.wdkl.app.ncs.callingbed.R
+import com.wdkl.app.ncs.callingbed.databinding.TestFragmentLayBinding
+import com.wdkl.app.ncs.callingbed.helper.MediaPlayHelper
+import com.wdkl.app.ncs.callingbed.helper.RecordHelper
+import com.wdkl.app.ncs.callingbed.helper.SoundPoolManager
+import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
+import com.wdkl.ncs.android.lib.base.BaseFragment
+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.QrCodeFragmentContract
+import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.QrCodeFragmentPresenter
+import kotlinx.android.synthetic.main.test_fragment_lay.*
+import org.greenrobot.eventbus.EventBus
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+import serialporttest.utils.SerialPortUtil
+
+class TestFragment : BaseFragment<QrCodeFragmentPresenter, TestFragmentLayBinding>(), QrCodeFragmentContract.View {
+    val TAG = "TestFragment"
+
+    var info = ""
+    var buttonTest = false
+    var testButton1 = false
+    var testButton2 = false
+    var testButton3 = false
+    var testButton4 = false
+    var testButton5 = false
+    var testButton6 = false
+    var testButton7 = false
+
+    //private var mCamera: Camera? = null
+
+    private val handler = Handler(Looper.getMainLooper())
+
+    override fun getLayId(): Int {
+        return R.layout.test_fragment_lay
+    }
+
+    override fun bindDagger() {
+        CallingbedLaunch.component.inject(this)
+    }
+
+    override fun init() {
+        RecordHelper.getInstance().init()
+        SoundPoolManager.getInstance().playSound(4, 1.0f, 1.0f, 0)
+
+        //startCameraPreview()
+
+        //2分钟后没有测试完直接退出
+        handler.postDelayed({
+            EventBus.getDefault().post(MessageEvent("BackToMain", Constant.EVENT_BACK_MAIN))
+        }, 150000)
+    }
+
+    override fun bindEvent() {
+    }
+
+    private fun startTest() {
+        Thread {
+            info += "--> 麦克风测试:\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)
+            SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + "0", "000000", "F")
+            Thread.sleep(300)
+            SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + "0", "999999", "F")
+            Thread.sleep(500)
+            SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + "1", "000000", "F")
+            Thread.sleep(300)
+            SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + "1", "999999", "F")
+            Thread.sleep(500)
+            SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + "2", "000000", "F")
+            Thread.sleep(300)
+            SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + "2", "999999", "F")
+            Thread.sleep(500)
+            SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + "3", "000000", "F")
+            Thread.sleep(300)
+            SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + "3", "999999", "F")
+            Thread.sleep(500)
+            SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + "4", "000000", "F")
+            Thread.sleep(300)
+            SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + "4", "999999", "F")
+            Thread.sleep(1000)
+
+            info += "测试结束,即将退出!"
+            showInfo(info)
+
+            Thread.sleep(6000)
+            EventBus.getDefault().post(MessageEvent("BackToMain", Constant.EVENT_BACK_MAIN))
+        }.start()
+    }
+
+    private fun showInfo(text: String) {
+        activity.runOnUiThread {
+            if (tv_test_info != null) {
+                tv_test_info.text = text
+            }
+        }
+    }
+
+    override fun setUrlString(url: String) {
+        //
+    }
+
+    /*private fun startCameraPreview() {
+        val num = Camera.getNumberOfCameras()
+        if (num > 0) {
+            try {
+                mCamera = Camera.open()
+            } catch (e: Exception) {
+                tv_camera.visibility = View.VISIBLE
+                tv_camera.text = "摄像头打开失败"
+                e.printStackTrace()
+                return
+            }
+
+            camera_preview_surface.getHolder().addCallback(object : SurfaceHolder.Callback {
+                override fun surfaceCreated(holder: SurfaceHolder?) {
+
+                    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 {
+            tv_camera.visibility = View.VISIBLE
+            tv_camera.text = "没有摄像头"
+        }
+    }*/
+
+    override fun onStart() {
+        EventBus.getDefault().register(this)
+        super.onStart()
+    }
+
+    override fun onStop() {
+        EventBus.getDefault().unregister(this)
+        super.onStop()
+    }
+
+    override fun destory() {
+        /*if (mCamera != null) {
+            mCamera!!.stopPreview()
+            mCamera!!.release()
+            mCamera = null
+        }*/
+        handler.removeCallbacksAndMessages(null)
+    }
+
+    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) {
+        if (Constant.EVENT_SERIAL_TEST == messageEvent.type) {
+            if (!buttonTest) {
+                val message = messageEvent.message as String
+                if (message == "call1" && !testButton1) {
+                    info += "##面板呼叫键## \r\n"
+                    testButton1 = true
+                } else if (message == "call2" && !testButton2) {
+                    info += "##手柄按键## \r\n"
+                    testButton2 = true
+                } else if (message == "btn1" && !testButton3) {
+                    info += "##面板触摸键1## \r\n"
+                    testButton3 = true
+                } else if (message == "btn2" && !testButton4) {
+                    info += "##面板触摸键2## \r\n"
+                    testButton4 = true
+                } else if (message == "btn3" && !testButton5) {
+                    info += "##面板触摸键3## \r\n"
+                    testButton5 = true
+                } else if (message == "btn4" && !testButton6) {
+                    info += "##面板触摸键4## \r\n"
+                    testButton6 = true
+                } else if (message == "btn5" && !testButton7) {
+                    info += "##面板触摸键5## \r\n"
+                    testButton7 = true
+                }
+
+                showInfo(info)
+
+                if (testButton1 && testButton2 && testButton3 && testButton4 && testButton5 && testButton6 && testButton7) {
+                    buttonTest = true
+                    startTest()
+                }
+            }
+        }
+    }
+}

+ 270 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/AnrFcExceptionUtil.java.bak

@@ -0,0 +1,270 @@
+package com.wdkl.app.ncs.callingbed.helper;
+
+import android.app.AlarmManager;
+import android.app.Application;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Environment;
+import android.util.Log;
+
+import com.github.anrwatchdog.ANRError;
+import com.github.anrwatchdog.ANRWatchDog;
+import com.wdkl.ncs.android.component.welcome.activity.WelcomeActivity;
+import com.wdkl.ncs.android.middleware.api.UrlManager;
+import com.wdkl.ncs.android.middleware.common.Constant;
+import com.wdkl.skywebrtc.CallSession;
+import com.wdkl.skywebrtc.EnumType;
+import com.wdkl.skywebrtc.SkyEngineKit;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TimeZone;
+
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.FormBody;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+
+/**
+ * Created by dengzhe on 2018/4/2.
+ * //=========================FC&ANR异常处理类=========================//
+ */
+
+public class AnrFcExceptionUtil implements Thread.UncaughtExceptionHandler {
+
+    private static ANRWatchDog mANRWatchDog;
+    private Thread.UncaughtExceptionHandler mDefaultHandler;
+    public static final String TAG = "MyApplication";
+    private static Application application;
+
+    private static AnrFcExceptionUtil mAnrFcExceptionUtil;
+
+    private OkHttpClient okHttpClient;
+    private UrlManager urlManager = UrlManager.Companion.build();
+
+    /**
+     * 存储异常和参数信息
+     */
+    private Map<String, String> paramsMap = new HashMap<>();
+    /**
+     * 格式化时间
+     */
+    private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
+
+
+    public static AnrFcExceptionUtil getInstance(Application application) {
+        if (mAnrFcExceptionUtil == null) {
+            mAnrFcExceptionUtil = new AnrFcExceptionUtil(application);
+        }
+        return mAnrFcExceptionUtil;
+    }
+
+    private AnrFcExceptionUtil(Application application) {
+        //获取系统默认的UncaughtException处理器
+        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
+        this.application = application;
+    }
+
+    @Override
+    public void uncaughtException(Thread thread, Throwable ex) {
+        if (!handleException(ex) && mDefaultHandler != null) {
+            //如果用户没有处理则让系统默认的异常处理器来处理
+            mDefaultHandler.uncaughtException(thread, ex);
+        } else {
+            try {
+                Thread.sleep(2000);
+            } catch (InterruptedException e) {
+                Log.e(TAG, "error : ", e);
+            }
+
+            restartApp();
+        }
+    }
+
+    private void restartApp() {
+        Constant.CALL_STATE = Constant.CALL_STANDBY;
+        CallSession session= SkyEngineKit.Instance().getCurrentSession();
+        if(session!=null&&session.getState()!= EnumType.CallState.Idle){
+            SkyEngineKit.Instance().endCall();
+        }
+
+        //重新启动app
+        Intent mStartActivity = new Intent(application.getApplicationContext(), WelcomeActivity.class);
+        mStartActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        int mPendingIntentId = 123456;
+        PendingIntent mPendingIntent = PendingIntent.getActivity(application.getApplicationContext(), mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
+        AlarmManager mgr = (AlarmManager) application.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
+        mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1500, mPendingIntent);
+
+        android.os.Process.killProcess(android.os.Process.myPid());
+        System.exit(0);
+    }
+
+    /**
+     * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
+     *
+     * @param ex
+     * @return true:如果处理了该异常信息;否则返回false.
+     */
+    private boolean handleException(Throwable ex) {
+        if (ex == null) {
+            return false;
+        }
+        //使用Toast来显示异常信息
+        /*new Thread() {
+            @Override
+            public void run() {
+                Looper.prepare();
+//                Toast.makeText(application.getApplicationContext(), "很抱歉,程序出现异常,即将重新启动.",
+//                        Toast.LENGTH_SHORT).show();
+                Looper.loop();
+            }
+        }.start();*/
+        saveCrashInfo2File(ex);
+        return true;
+    }
+
+    /**
+     * 保存错误信息到文件中
+     *
+     * @param ex
+     * @return 返回文件名称
+     */
+    private String saveCrashInfo2File(Throwable ex) {
+        StringBuffer sb = new StringBuffer();
+        for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
+            String key = entry.getKey();
+            String value = entry.getValue();
+            sb.append(key + "=" + value + "\n");
+        }
+
+        Writer writer = new StringWriter();
+        PrintWriter printWriter = new PrintWriter(writer);
+        ex.printStackTrace(printWriter);
+        Throwable cause = ex.getCause();
+        while (cause != null) {
+            cause.printStackTrace(printWriter);
+            cause = cause.getCause();
+        }
+        printWriter.close();
+        String result = writer.toString();
+        sb.append(result);
+
+        try {
+            long timestamp = System.currentTimeMillis();
+            format.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+            String time = format.format(new Date());
+            String fileName = "crash-" + time + "-" + timestamp + ".txt";
+            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+                String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/crash/";
+                File dir = new File(path);
+                if (!dir.exists()) {
+                    dir.mkdirs();
+                }
+                FileOutputStream fos = new FileOutputStream(path + fileName);
+                fos.write(sb.toString().getBytes());
+                Log.i(TAG, "saveCrashInfo2File: "+sb.toString());
+                fos.close();
+            }
+
+            //上传错误日志
+            uploadingErrorLog(application.getPackageName(), "crash", "crash", "", sb.toString());
+
+            return fileName;
+        } catch (Exception e) {
+            Log.e(TAG, "an error occured while writing file...", e);
+        }
+        return null;
+    }
+
+    private void uploadingErrorLog(String class_name, String err_msg, String exception_name, String method_name, String stack_trace) {
+        if(okHttpClient == null){
+            okHttpClient = new OkHttpClient();
+        }
+
+        FormBody.Builder formBody = new FormBody.Builder();
+        formBody.add("class_name",class_name);
+        formBody.add("method_name",method_name);
+        formBody.add("exception_name",exception_name);
+        formBody.add("err_msg",err_msg);
+        formBody.add("stack_trace",stack_trace);
+
+        Request request  = new Request.Builder()
+                .url(urlManager.getBase() + "device/error_log")
+                .post(formBody.build())
+                .build();
+
+        okHttpClient.newCall(request).enqueue(new Callback() {
+            @Override
+            public void onFailure(Call call, IOException e) {
+                Log.e(TAG,"错误日志上传失败"+e.getMessage());
+            }
+
+            @Override
+            public void onResponse(Call call, Response response) throws IOException {
+                Log.d(TAG,"错误日志上传成功");
+                String data = response.body().string();
+                Log.d(TAG,"错误日志数据 data "+data);
+            }
+        });
+    }
+
+    /**
+     * ===================================================崩溃异常处理===================================================
+     */
+    public void initFCException() {
+        //设置该CrashHandler为程序的默认处理器
+        AnrFcExceptionUtil catchExcep = AnrFcExceptionUtil.getInstance(application);
+        Thread.setDefaultUncaughtExceptionHandler(catchExcep);
+        mANRWatchDog = new ANRWatchDog(8000);
+        mANRWatchDog.setInterruptionListener(new ANRWatchDog.InterruptionListener() {
+            @Override
+            public void onInterrupted(InterruptedException exception) {
+            }
+        }).setIgnoreDebugger(true).setANRListener(new ANRWatchDog.ANRListener() {
+            @Override
+            public void onAppNotResponding(ANRError error) {
+                /*Intent mStartActivity = new Intent(application.getApplicationContext(), Constants.ANR_FC);
+                int mPendingIntentId = 123456;
+                PendingIntent mPendingIntent = PendingIntent.getActivity(application.getApplicationContext(), mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
+                AlarmManager mgr = (AlarmManager) application.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
+                mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1500, mPendingIntent);
+                android.os.Process.killProcess(android.os.Process.myPid());*/
+
+                //记录anr
+                /*try {
+                    long timestamp = System.currentTimeMillis();
+                    String time = format.format(new Date());
+                    format.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+                    String fileName = "anr-" + time + "-" + timestamp + ".txt";
+                    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+                        String path = Environment.getExternalStorageDirectory() + "/anr/";
+                        File dir = new File(path);
+                        if (!dir.exists()) {
+                            dir.mkdirs();
+                        }
+                        FileOutputStream fos = new FileOutputStream(path + fileName);
+                        fos.write(fileName.getBytes());
+                        fos.close();
+                    }
+                } catch (Exception e) {
+                }*/
+
+                Log.d("anr", "Anr restart app...");
+                AppUpdateHelper.reboot(application);
+            }
+        }).start();
+
+    }
+}

+ 188 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/AppUpdateHelper.java

@@ -0,0 +1,188 @@
+package com.wdkl.app.ncs.callingbed.helper;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Environment;
+import android.util.Log;
+
+import com.wdkl.ncs.android.component.welcome.activity.WelcomeActivity;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+public class AppUpdateHelper {
+    private final static String TAG = "AppUpdate";
+
+    /**
+     * 下载的APK文件绝对路径
+     */
+    public static final String FILE_APK_PATH = Environment.getExternalStorageDirectory() + "/CallingBed";
+    /**
+     * 下载的APK文件的文件名
+     */
+    public static final String FILE_APK_NAME = "CallingBedAPK.apk";
+
+    public static void updateApp(Context context, UpdateCallBack callBack) {
+        if (checkApkExit(context)) {
+            Log.d(TAG, "文件存在");
+        } else {
+            Log.d(TAG, "文件不存在");
+            if (callBack != null) {
+                callBack.onFailed();
+            }
+            return;
+        }
+
+        String path = FILE_APK_PATH + "/" + FILE_APK_NAME;
+        //if (installApp(context.getPackageName(), path)) {
+        if (rootSilenceInstall(path)) {
+            Log.d(TAG, "安装成功");
+            if (callBack != null) {
+                callBack.onSuccess();
+            }
+        } else {
+            Log.d(TAG, "安装失败");
+            if (callBack != null) {
+                callBack.onFailed();
+            }
+        }
+
+        /*if (silentInstall(context, path)) {
+            Log.d(TAG, "app 安装成功");
+            if (callBack != null) {
+                callBack.onSuccess();
+            }
+        }*/
+    }
+
+    public static void updateApp(Context context) {
+        if (checkApkExit(context)) {
+            Log.d(TAG, "文件存在");
+        } else {
+            Log.d(TAG, "文件不存在");
+            return;
+        }
+
+        /*if (!checkApkAvailable(context, DownloadUtil.FILE_APK_PATH + "/" + DownloadUtil.FILE_APK_NAME)) {
+            ToastUtil.showToast("apk文件不匹配,升级失败!");
+            return;
+        }*/
+
+
+        if (silentInstall(context, FILE_APK_PATH + "/" + FILE_APK_NAME)) {
+            Log.d(TAG, "app 安装成功");
+        }
+    }
+
+    private static boolean checkApkExit(Context context) {
+        File file = new File(FILE_APK_PATH + "/" + FILE_APK_NAME);
+        return file.exists();
+    }
+
+    private static boolean checkApkAvailable(Context context, String path) {
+        try {
+            PackageManager pm = context.getPackageManager();
+            PackageInfo info = pm.getPackageArchiveInfo(path, 0);
+            ApplicationInfo applicationInfo = info.applicationInfo;
+            String newPkg = applicationInfo.packageName;
+            String curPkg = context.getPackageName();
+            Log.d(TAG, "new package: " + newPkg + ", cur package: " + curPkg);
+            if (curPkg.equals(newPkg)) {
+                return true;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return false;
+    }
+
+    public static boolean silentInstall(Context context, String apkPath) {
+        PackageManager packageManager = context.getPackageManager();
+        Class pmClz = packageManager.getClass();
+        try {
+            if (Build.VERSION.SDK_INT >= 21) {
+                Class aClass = Class.forName("android.app.PackageInstallObserver");
+                Constructor constructor = aClass.getDeclaredConstructor();
+                constructor.setAccessible(true);
+                Object installObserver = constructor.newInstance();
+                Method method = pmClz.getDeclaredMethod("installPackage", Uri.class, aClass, int.class, String.class);
+                method.setAccessible(true);
+                method.invoke(packageManager, Uri.fromFile(new File(apkPath)), installObserver, 2, null);
+            } else {
+                Method method = pmClz.getDeclaredMethod("installPackage", Uri.class, Class.forName("android.content.pm.IPackageInstallObserver"), int.class, String.class);
+                method.setAccessible(true);
+                method.invoke(packageManager, Uri.fromFile(new File(apkPath)), null, 2, null);
+            }
+            return true;
+        } catch (Exception e) {
+            Log.e(TAG, e.toString());
+        }
+        return false;
+    }
+
+    public static boolean rootSilenceInstall(String path) {
+        Process process;
+        PrintWriter printWriter;
+        try {
+            process = Runtime.getRuntime().exec("su");
+            printWriter = new PrintWriter(process.getOutputStream());
+            printWriter.println("pm install -r " + path);
+            printWriter.flush();
+            printWriter.close();
+            int res = process.waitFor();
+            Log.e(TAG, "silent install res: " + res);
+            if (res == 0) {
+                return true;
+            } else {
+                return false;
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "rootSilenceInstall e:" + e.getMessage());
+            return false;
+        }
+    }
+
+
+    public static void reboot(Context context) {
+        try {
+            Intent intent = new Intent(Intent.ACTION_REBOOT);
+            intent.putExtra("nowait", 1);
+            intent.putExtra("interval", 1);
+            intent.putExtra("window", 0);
+            context.sendBroadcast(intent);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        SerialPortHelper.resetDevice();
+    }
+
+    public static void restartApp(Context context) {
+        //重新启动app
+        Intent mStartActivity = new Intent(context.getApplicationContext(), WelcomeActivity.class);
+        mStartActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        int mPendingIntentId = 123456;
+        PendingIntent mPendingIntent = PendingIntent.getActivity(context.getApplicationContext(), mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
+        AlarmManager mgr = (AlarmManager) context.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
+        mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1500, mPendingIntent);
+
+        android.os.Process.killProcess(android.os.Process.myPid());
+        System.exit(0);
+    }
+
+
+    public interface UpdateCallBack {
+        void onFailed();
+        void onSuccess();
+    }
+}

+ 94 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/AppUtil.java

@@ -0,0 +1,94 @@
+package com.wdkl.app.ncs.callingbed.helper;
+
+import android.app.AlarmManager;
+import android.content.Context;
+import android.text.TextUtils;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.Calendar;
+
+public class AppUtil {
+
+    /**
+     * 设置系统时间
+     *
+     * @param time
+     */
+    public static void setSysTime(String time, String timeZone) {
+        try {
+            Process process = Runtime.getRuntime().exec("su");
+            if (null == process) return;
+            DataOutputStream os = new DataOutputStream(process.getOutputStream());
+            //os.writeBytes("setprop persist.sys.timezone Asia/Shanghai\n");
+            os.writeBytes("setprop persist.sys.timezone " + timeZone + "\n");
+            if (android.os.Build.VERSION.SDK_INT >= 24) {//7.1以上的系统
+                String datetime = changeTimeForm(time); //20211213:092314  ------  051315372019.00
+                os.writeBytes("/system/bin/date " + datetime + " set\n");
+            } else {
+                os.writeBytes("/system/bin/date -s " + time + "\n");//【时间格式 yyyyMMdd.HHmmss】"20131023.112800"
+            }
+            os.writeBytes("clock -w\n");
+            os.writeBytes("exit\n");
+            os.flush();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static String changeTimeForm(String t) {
+        if (!TextUtils.isEmpty(t) && t.length() >= 15) {
+            String yyyy = substringByLengh(t, 0, 4);
+            String MMdd = substringByLengh(t, 4, 8);
+            String HHmm = substringByLengh(t, 9, 13);
+            String ss = substringByLengh(t, 13, 15);
+
+            return MMdd + HHmm + yyyy + "." + ss;
+        } else {
+            return "051315372019.00";
+        }
+    }
+
+    /**
+     * 字符串按索引截取
+     *
+     * @param str
+     * @return
+     */
+    public static String substringByLengh(String str, int start, int end) {
+        if (str == null) {
+            return "";
+        }
+        if (start > end) {
+            return "";
+        }
+        if (str.length() - 1 < start || str.length() < end) {
+            return "";
+        }
+
+        return str.substring(start, end);
+    }
+
+
+    public static void setSystemTime(Context context, int year, int month, int day, int hour, int minute, int mill) {
+        Calendar c = Calendar.getInstance();
+        c.set(Calendar.YEAR, year);
+        c.set(Calendar.MONTH, month);
+        c.set(Calendar.DAY_OF_MONTH, day);
+        c.set(Calendar.HOUR_OF_DAY, hour);
+        c.set(Calendar.MINUTE, minute);
+        c.set(Calendar.SECOND, mill);
+        c.set(Calendar.MILLISECOND, 0);
+        long when = c.getTimeInMillis();
+        if (when / 1000 < Integer.MAX_VALUE) {
+            ((AlarmManager) context.getSystemService(Context.ALARM_SERVICE)).setTime(when);
+        }
+    }
+
+    public static void setSystemTime(Context context, long timeMills, String timeZone) {
+        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+        //alarmManager.setTimeZone("Asia/Shanghai");
+        alarmManager.setTimeZone(timeZone);
+        alarmManager.setTime(timeMills);
+    }
+}

+ 1 - 1
android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/AsyncPlayer.java

@@ -1,4 +1,4 @@
-package com.wdkl.app.ncs.callingbed2.helper;
+package com.wdkl.app.ncs.callingbed.helper;
 
 import android.content.Context;
 import android.media.AudioDeviceInfo;

+ 1 - 1
android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/DoorLightHelper.java

@@ -1,4 +1,4 @@
-package com.wdkl.app.ncs.callingbed2.helper;
+package com.wdkl.app.ncs.callingbed.helper;
 
 import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel;
 import com.wdkl.ncs.android.middleware.tcp.enums.TcpAction;

+ 160 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/HttpHelper.java

@@ -0,0 +1,160 @@
+package com.wdkl.app.ncs.callingbed.helper;
+
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.MediaType;
+import okhttp3.MultipartBody;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+
+import static com.wdkl.app.ncs.callingbed.helper.AppUpdateHelper.FILE_APK_NAME;
+import static com.wdkl.app.ncs.callingbed.helper.AppUpdateHelper.FILE_APK_PATH;
+
+public class HttpHelper {
+
+    /**
+     * @param url   服务器地址
+     * @param file  所要上传的文件
+     */
+    public static void upload(String url, File file, final UploadCallback callback) {
+        OkHttpClient client = new OkHttpClient();
+        RequestBody requestBody = new MultipartBody.Builder()
+                .setType(MultipartBody.FORM)
+                .addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file))
+                .build();
+        Request request = new Request.Builder()
+                .url(url)
+                .post(requestBody)
+                .build();
+
+        client.newCall(request).enqueue(new Callback() {
+            @Override
+            public void onFailure(Call call, IOException e) {
+                if (callback != null) {
+                    callback.onFail();
+                }
+            }
+
+            @Override
+            public void onResponse(Call call, Response response) throws IOException {
+                Log.d("wzlll", "voice msg response: " + response.toString());
+               if( response.code()==200 && response.body() != null) {
+                   String data = response.body().string();
+                   //voice msg response: upload/file/202104102037715.mp3
+                   if (callback != null) {
+                       callback.onSuccess(data);
+                   }
+               } else {
+                   if (callback != null) {
+                       callback.onFail();
+                   }
+               }
+            }
+        });
+    }
+
+    public static void download(String url, final DownloadListener listener) {
+        Request request = new Request.Builder().url(url).build();
+        OkHttpClient okHttpClient = new OkHttpClient();
+        okHttpClient.newCall(request).enqueue(new Callback() {
+            @Override
+            public void onFailure(Call call, IOException e) {
+                Log.d("download", "onFailure==" + e.toString());
+                if (listener != null) {
+                    listener.onDownloadFailed(); // 下载失败
+                }
+            }
+
+            @Override
+            public void onResponse(Call call, Response response) {
+                Log.d("download", "response==" + response.body().contentLength());
+                InputStream is = null;
+                byte[] buf = new byte[2048];
+                int len;
+                FileOutputStream fos = null;
+                try {
+                    is = response.body().byteStream();
+                    long total = response.body().contentLength();
+                    File file = new File(isHaveExistDir(new File(FILE_APK_PATH), new File(FILE_APK_PATH + "/" + FILE_APK_NAME)), FILE_APK_NAME);
+                    fos = new FileOutputStream(file);
+                    long sum = 0;
+                    while ((len = is.read(buf)) != -1) {
+                        fos.write(buf, 0, len);
+                        sum = sum + (long) len;
+                        //int progress = (int) (sum * 1.0f / total * 100);
+                        float sp = (float) sum / (float) total;
+                        int progress = (int) (sp * 100);
+                        Log.d("download", "progress==" + progress);
+                        if (listener != null) {
+                            listener.onDownloading(progress);// 下载中
+                        }
+                    }
+                    fos.flush();
+                    if (listener != null) {
+                        listener.onDownloadSuccess(); // 下载完成
+                    }
+                } catch (Exception e) {
+                    Log.d("download", "Exception==");
+                    if (listener != null) {
+                        listener.onDownloadFailed();
+                    }
+                } finally {
+                    try {
+                        if (is != null)
+                            is.close();
+                        if (fos != null)
+                            fos.close();
+                    } catch (IOException e) {
+                        Log.d("download", "IOException==");
+                    }
+                }
+            }
+        });
+    }
+
+    private static String isHaveExistDir(File downloadFile, File sonFile) throws IOException {
+        Log.d("download", "downloadFile.mkdirs()==" + downloadFile.mkdirs());
+        Log.d("download", "sonFile.mkdir()==" + sonFile.mkdir());
+        if (!downloadFile.mkdirs()) {
+            downloadFile.createNewFile();
+        }
+        deleteAPKFile(sonFile);//只要文件名相同就可以自动替换(按道理此处不需要了,但为了保险起见还是先执行删除操作)。
+        return downloadFile.getAbsolutePath();
+    }
+
+    public static boolean deleteAPKFile(File downloadFile) {
+        return downloadFile.delete();
+    }
+
+
+    public interface UploadCallback{
+        void onFail();
+        void onSuccess(String data);
+    }
+
+    public interface DownloadListener {
+        /**
+         * 下载成功
+         */
+        void onDownloadSuccess();
+
+        /**
+         * @param progress 下载进度
+         */
+        void onDownloading(int progress);
+
+        /**
+         * 下载失败
+         */
+        void onDownloadFailed();
+    }
+}

+ 3 - 3
android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/LanguageSetDialogHelper.java

@@ -1,4 +1,4 @@
-package com.wdkl.app.ncs.callingbed2.helper;
+package com.wdkl.app.ncs.callingbed.helper;
 
 import android.app.Activity;
 import android.app.AlertDialog;
@@ -17,8 +17,8 @@ import android.widget.RadioGroup;
 import android.widget.Spinner;
 import android.widget.Toast;
 
-import com.wdkl.app.ncs.callingbed2.R;
-import com.wdkl.app.ncs.callingbed2.settings.SettingConfig;
+import com.wdkl.app.ncs.callingbed.R;
+import com.wdkl.app.ncs.callingbed.settings.SettingConfig;
 
 
 public class LanguageSetDialogHelper {

+ 79 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/LocaleMangerUtils.java

@@ -0,0 +1,79 @@
+package com.wdkl.app.ncs.callingbed.helper;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.os.Build;
+import android.util.DisplayMetrics;
+
+import com.wdkl.app.ncs.callingbed.R;
+import com.wdkl.app.ncs.callingbed.settings.SettingConfig;
+import com.wdkl.ncs.android.lib.base.BaseApplication;
+
+import java.util.Locale;
+
+public class LocaleMangerUtils {
+
+    public static Locale getSystemLocale() {
+        return Locale.getDefault();
+    }
+
+    //获取当前语言id: 0--auto, 1--English, 2--中文, 3--西班牙语, 4--俄语
+    public static int getCurrentLocaleIndex() {
+        int languageSize = BaseApplication.appContext.getResources().getStringArray(R.array.language_list).length;
+        int index = SettingConfig.getLanguageId(BaseApplication.appContext);
+        //Log.d("wzl", "current language index: " + index);
+        if (index >= 0 && index <languageSize) {
+            return index;
+        } else {
+            return 0;
+        }
+    }
+
+    public static void setApplicationLanguageByIndex(Context context, int index) {
+        Locale locale = Locale.getDefault();
+        switch (index) {
+            case 0:
+                //
+                break;
+            case 1:
+                locale = Locale.ENGLISH;
+                break;
+            case 2:
+                locale = Locale.CHINESE;
+                break;
+            case 3:
+                locale = new Locale("es");
+                break;
+            case 4:
+                locale = new Locale("ru");
+                break;
+        }
+
+        setApplicationLanguage(context, locale);
+    }
+
+    public static void setApplicationLanguage(Context context, Locale locale) {
+        //Log.d("wzl", "set locale language: " + locale.getLanguage());
+        Configuration configuration = context.getResources().getConfiguration();
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            configuration.setLocale(locale);
+        } else {
+            configuration.locale = locale;
+        }
+        // 更新context中的语言设置
+        Resources resources = context.getResources();
+        DisplayMetrics dm = resources.getDisplayMetrics();
+        resources.updateConfiguration(configuration, dm);
+    }
+
+    public static Locale getApplicationLocale() {
+        Configuration config = BaseApplication.appContext.getResources().getConfiguration();
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            return config.locale;
+        } else {
+            return config.getLocales().get(0);
+        }
+    }
+
+}

+ 1 - 1
android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/MediaPlayHelper.java

@@ -1,4 +1,4 @@
-package com.wdkl.app.ncs.callingbed2.helper;
+package com.wdkl.app.ncs.callingbed.helper;
 
 import android.media.AudioManager;
 import android.media.MediaPlayer;

+ 487 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/NetHelper.java

@@ -0,0 +1,487 @@
+package com.wdkl.app.ncs.callingbed.helper;
+
+import android.annotation.SuppressLint;
+import android.bluetooth.BluetoothAdapter;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.text.TextUtils;
+
+import com.wdkl.ncs.android.middleware.common.MessageEvent;
+
+import org.greenrobot.eventbus.EventBus;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import static com.wdkl.ncs.android.middleware.common.Constant.EVENT_INTERNETPING;
+
+
+public class NetHelper {
+    private Context mContext;
+    private WifiManager wifiManager;
+    private ConnectivityManager connManager;
+    private static NetHelper sInstance = null;
+
+    private static Timer timerNetStatus = null;
+    private static final int SCHEDULE_TIME = 30000;
+    public static boolean NetConn = false;
+
+    /**
+     * 以太网是否ping成功
+     */
+    public static final String ETHERNETSTATUS = "ethernetStatus";
+
+    public NetHelper() {
+    }
+
+    public static NetHelper getInstance() {
+        if (sInstance == null) {
+            synchronized (NetHelper.class) {
+                if (sInstance == null) {
+                    sInstance = new NetHelper();
+                }
+            }
+        }
+        return sInstance;
+    }
+
+    public void init(Context context) {
+        mContext = context;
+        wifiManager = (WifiManager) mContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
+        connManager = (ConnectivityManager) mContext.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+    }
+
+    public static void startNetCheck() {
+        if (timerNetStatus != null) {
+            timerNetStatus.purge();
+        }
+        timerNetStatus = new Timer();
+        timerNetStatus.schedule(new TimerTask() {
+            @Override
+            public void run() {
+                NetConn = ping(getLocalElement(3), 2, null);
+
+                EventBus.getDefault().post(new MessageEvent(ETHERNETSTATUS, EVENT_INTERNETPING));//循环检测SIP,以太网ping状态
+            }
+        }, 10, SCHEDULE_TIME);
+    }
+
+    /**
+     * ping 网络
+     *
+     * @param host
+     * @param pingCount
+     * @param stringBuffer
+     * @return
+     */
+    public static boolean ping(String host, int pingCount, StringBuffer stringBuffer) {
+        String line = null;
+        Process process = null;
+        BufferedReader successReader = null;
+        String command = "ping -c " + pingCount + " " + host;
+        boolean isSuccess = false;
+        try {
+            process = Runtime.getRuntime().exec(command);
+            if (process == null) {
+                append(stringBuffer, "ping fail:process is null.");
+                return false;
+            }
+            successReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+            while ((line = successReader.readLine()) != null) {
+                append(stringBuffer, line);
+            }
+            int status = process.waitFor();
+            if (status == 0) {
+                append(stringBuffer, "exec cmd success:" + command);
+                isSuccess = true;
+            } else {
+                append(stringBuffer, "exec cmd fail.");
+                isSuccess = false;
+            }
+            append(stringBuffer, "exec finished.");
+        } catch (IOException e) {
+        } catch (InterruptedException e) {
+        } finally {
+            if (process != null) {
+                process.destroy();
+            }
+            if (successReader != null) {
+                try {
+                    successReader.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+
+        return isSuccess;
+    }
+
+    private static void append(StringBuffer stringBuffer, String text) {
+        if (stringBuffer != null) {
+            stringBuffer.append(text + "\n");
+        }
+    }
+
+    /**
+     * 获取网关  Waderson
+     * <p>
+     * 1 WIFI情况下获取网关 2 有线网络下的DHCP模式连接 3 有线网络其他连接方式:比如静态ip、pppoe拨号、ipoe拨号等
+     */
+    public static String getLocalElement(int type) {
+        String e = "";
+        if (1 == type) {
+            //e = getLocalElementByWifi();
+        } else if (2 == type) {
+            e = getLocalElementByDhcp();
+        } else if (3 == type) {
+            e = getLocalElementByIp();
+        }
+        if (!TextUtils.isEmpty(e) && e.length() >= 11 && e.length() <= 15) {
+            return e;
+        } else {
+            return "192.168.101.1";
+        }
+    }
+
+
+    /**
+     * 有线网络下的DHCP模式连接
+     */
+    public static String getLocalElementByDhcp() {
+        BufferedReader bufferedReader = null;
+        String str2 = "";
+        String str3 = "getprop dhcp.eth0.gateway";
+        Process exec;
+        BufferedReader bufferedReader2 = null;
+        try {
+            exec = Runtime.getRuntime().exec(str3);
+            try {
+                bufferedReader2 = new BufferedReader(new InputStreamReader(exec.getInputStream()));
+            } catch (Throwable th3) {
+                if (bufferedReader != null) {
+                    bufferedReader.close();
+                }
+                if (exec != null) {
+                    exec.exitValue();
+                }
+            }
+            try {
+                str3 = bufferedReader2.readLine();
+                if (str3 != null) {
+                    TextUtils.isEmpty(str3);
+                }
+                try {
+                    bufferedReader2.close();
+                } catch (IOException iOException222) {
+                    iOException222.printStackTrace();
+                }
+                if (exec != null) {
+                    try {
+                        exec.exitValue();
+                    } catch (Exception e5) {
+                    }
+                }
+            } catch (IOException e6) {
+                str3 = str2;
+                if (bufferedReader2 != null) {
+                    bufferedReader2.close();
+                }
+                if (exec != null) {
+                    exec.exitValue();
+                }
+                return str3;
+            }
+        } catch (IOException e62) {
+            bufferedReader2 = null;
+            exec = null;
+            str3 = str2;
+            if (bufferedReader2 != null) {
+                try {
+                    bufferedReader2.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (exec != null) {
+                exec.exitValue();
+            }
+            return str3;
+        } catch (Throwable th4) {
+            exec = null;
+            if (bufferedReader != null) {
+                try {
+                    bufferedReader.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (exec != null) {
+                exec.exitValue();
+            }
+        }
+        return str3;
+    }
+
+    /**
+     * 有线网络其他连接方式:比如静态ip、pppoe拨号、ipoe拨号等
+     */
+    public static String getLocalElementByIp() {
+        BufferedReader bufferedReader = null;
+        String result = "";
+        String str2 = "";
+        String str3 = "ip route list table 0";
+        Process exec;
+        BufferedReader bufferedReader2 = null;
+        try {
+            exec = Runtime.getRuntime().exec(str3);
+            try {
+                bufferedReader2 = new BufferedReader(new InputStreamReader(exec.getInputStream()));
+            } catch (Throwable th3) {
+                if (bufferedReader != null) {
+                    bufferedReader.close();
+                }
+                if (exec != null) {
+                    exec.exitValue();
+                }
+            }
+            try {
+                str2 = bufferedReader2.readLine();
+                if (str2 != null) {
+                    str2 = str2.trim();
+                    String[] strings = str2.split("\\s+");
+                    if (strings.length > 3) {
+                        result = strings[2];
+                    }
+                }
+                try {
+                    bufferedReader2.close();
+                } catch (IOException iOException222) {
+                    iOException222.printStackTrace();
+                }
+                if (exec != null) {
+                    try {
+                        exec.exitValue();
+                    } catch (Exception e5) {
+                    }
+                }
+            } catch (IOException e6) {
+                if (bufferedReader2 != null) {
+                    bufferedReader2.close();
+                }
+                if (exec != null) {
+                    exec.exitValue();
+                }
+                return result;
+            }
+        } catch (IOException e62) {
+            bufferedReader2 = null;
+            exec = null;
+            if (bufferedReader2 != null) {
+                try {
+                    bufferedReader2.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (exec != null) {
+                exec.exitValue();
+            }
+            return result;
+        } catch (Throwable th4) {
+            exec = null;
+            if (bufferedReader != null) {
+                try {
+                    bufferedReader.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (exec != null) {
+                exec.exitValue();
+            }
+        }
+        return result;
+    }
+
+    /**
+     * 得到MAC
+     *
+     * @return String
+     */
+    public String getMacAddress() {
+        String mac = "";
+        try {
+            mac = getLocalMacAddressFromIp();
+            if (TextUtils.isEmpty(mac)) {
+                mac = getNetworkMac();
+            }
+            if (TextUtils.isEmpty(mac)) {
+                mac = tryGetWifiMac();
+            }
+        } catch (Exception e) {
+        }
+        return mac;
+    }
+
+    public String tryGetWifiMac() {
+        String mac;
+        WifiManager wm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+        WifiInfo wi = wm.getConnectionInfo();
+        if (wi == null || wi.getMacAddress() == null) {
+            mac = null;
+        }
+        if ("02:00:00:00:00:00".equals(wi.getMacAddress().trim())) {
+            mac = null;
+        } else {
+            mac = wi.getMacAddress().trim();
+        }
+        return mac;
+    }
+
+    /**
+     * 通过网络接口获取
+     *
+     * @return
+     */
+    public static String getNetworkMac() {
+        try {
+            List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
+            for (NetworkInterface nif : all) {
+                // if (!nif.getName().equalsIgnoreCase("wlan0") && !nif.getName().equalsIgnoreCase("eth0") && !nif.getName().equalsIgnoreCase("eth1"))
+                if (!nif.getName().equalsIgnoreCase("eth0") && !nif.getName().equalsIgnoreCase("eth1") && !nif.getName().equalsIgnoreCase("eth2"))
+                    continue;
+                byte[] macBytes = nif.getHardwareAddress();
+                if (macBytes == null) {
+                    return null;
+                }
+                StringBuilder res1 = new StringBuilder();
+                for (byte b : macBytes) {
+                    res1.append(String.format("%02X:", b));
+                }
+                if (res1.length() > 0) {
+                    res1.deleteCharAt(res1.length() - 1);
+                }
+                return res1.toString();
+            }
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 根据IP地址获取MAC地址
+     *
+     * @return
+     */
+    @SuppressLint("NewApi")
+    public String getLocalMacAddressFromIp() {
+        String strMacAddr = null;
+        try {
+            // 获得IpD地址
+            InetAddress ip = getLocalInetAddress();
+            byte[] b = NetworkInterface.getByInetAddress(ip)
+                    .getHardwareAddress();
+            StringBuffer buffer = new StringBuffer();
+            for (int i = 0; i < b.length; i++) {
+                if (i != 0) {
+                    buffer.append(':');
+                }
+                String str = Integer.toHexString(b[i] & 0xFF);
+                buffer.append(str.length() == 1 ? 0 + str : str);
+            }
+            strMacAddr = buffer.toString().toUpperCase();
+
+        } catch (Exception e) {
+
+        }
+
+        return strMacAddr;
+    }
+
+    public InetAddress getLocalInetAddress() {
+        InetAddress ip = null;
+        try {
+            // 列举
+            Enumeration<NetworkInterface> en_netInterface = NetworkInterface
+                    .getNetworkInterfaces();
+            while (en_netInterface.hasMoreElements()) {// 是否还有元素
+                NetworkInterface ni = en_netInterface
+                        .nextElement();// 得到下一个元素
+                Enumeration<InetAddress> en_ip = ni.getInetAddresses();// 得到一个ip地址的列举
+                while (en_ip.hasMoreElements()) {
+                    ip = en_ip.nextElement();
+                    if (!ip.isLoopbackAddress()
+                            && ip.getHostAddress().indexOf(":") == -1)
+                        break;
+                    else
+                        ip = null;
+                }
+
+                if (ip != null) {
+                    break;
+                }
+            }
+        } catch (SocketException e) {
+
+            e.printStackTrace();
+        }
+
+
+        return ip;
+    }
+
+    public String getLocalIP() {
+        try {
+            for (Enumeration<NetworkInterface> enNetI = NetworkInterface.getNetworkInterfaces(); enNetI.hasMoreElements(); ) {
+                NetworkInterface netI = enNetI.nextElement();
+                for (Enumeration<InetAddress> enumIpAddr = netI.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
+                    InetAddress inetAddress = enumIpAddr.nextElement();
+                    if (inetAddress instanceof Inet4Address && !inetAddress.isLoopbackAddress()) {
+                        return inetAddress.getHostAddress();
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return "";
+    }
+
+    public static boolean isBTConnected() {
+        BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
+        if (btAdapter != null) {
+            return btAdapter.getState() == BluetoothAdapter.STATE_ON;
+        }
+
+        return false;
+    }
+
+    public int getNetworkType() {
+        if (connManager != null && connManager.getActiveNetworkInfo() != null) {
+            return connManager.getActiveNetworkInfo().getType();
+        }
+
+        return -1;
+    }
+
+    public boolean networkAvailable() {
+        if (connManager != null && connManager.getActiveNetworkInfo() != null) {
+            return connManager.getActiveNetworkInfo().isConnected();
+        }
+
+        return false;
+    }
+}

+ 1 - 1
android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/RecordHelper.java

@@ -1,4 +1,4 @@
-package com.wdkl.app.ncs.callingbed2.helper;
+package com.wdkl.app.ncs.callingbed.helper;
 
 import android.media.MediaRecorder;
 import android.os.Environment;

+ 30 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/ReflectHelper.java

@@ -0,0 +1,30 @@
+package com.wdkl.app.ncs.callingbed.helper;
+
+import java.lang.reflect.Method;
+
+public class ReflectHelper {
+
+    public static String getProperty(String key, String defaultValue) {
+        String value = defaultValue;
+        try {
+            Class<?> c = Class.forName("android.os.SystemProperties");
+            Method get = c.getMethod("get", String.class, String.class);
+            value = (String)(get.invoke(c, key, defaultValue));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return value;
+
+    }
+
+    public static void setProperty(String key, String value) {
+        try {
+            Class<?> c = Class.forName("android.os.SystemProperties");
+            Method set = c.getMethod("set", String.class, String.class);
+            set.invoke(c, key, value);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 1 - 1
android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/RingPlayHelper.java

@@ -1,4 +1,4 @@
-package com.wdkl.app.ncs.callingbed2.helper;
+package com.wdkl.app.ncs.callingbed.helper;
 
 import android.content.Context;
 import android.media.AudioManager;

+ 45 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/SOSHelper.java

@@ -0,0 +1,45 @@
+package com.wdkl.app.ncs.callingbed.helper;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+
+import com.wdkl.ncs.android.middleware.common.Constant;
+import com.wdkl.ncs.android.middleware.tcp.channel.OtherUtil;
+
+
+/*
+ * 紧急按钮辅助类
+ */
+public class SOSHelper {
+
+    private final static Handler handler = new Handler(Looper.getMainLooper()) {
+        @Override
+        public void handleMessage(Message msg) {
+            sosStop();
+        }
+    };
+
+    public static void sosStart() {
+        SerialPortHelper.setSosLight("2");
+        //如果该床位绑定了紧急按钮则直接通过紧急按钮设备id发送sos请求
+        if (Constant.EMERGENCY_ID != -1) {
+            OtherUtil.sendSosCall(Constant.EMERGENCY_ID);
+        } else {
+            OtherUtil.sendRoomSosCall(Constant.DEVICE_ID);
+        }
+
+        //60s之后紧急按钮灯自动复位
+        handler.removeCallbacksAndMessages(null);
+        handler.sendEmptyMessageDelayed(110, 120000);
+    }
+
+    public static void sosStop() {
+        handler.removeCallbacksAndMessages(null);
+        if (Constant.day_state == 1) {
+            SerialPortHelper.setSosLight("1");
+        } else {
+            SerialPortHelper.setSosLight("0");
+        }
+    }
+}

+ 1 - 1
android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/ScreenManagerUtil.kt

@@ -1,4 +1,4 @@
-package com.wdkl.app.ncs.callingbed2.helper
+package com.wdkl.app.ncs.callingbed.helper
 
 import android.content.Context
 import android.content.Intent

+ 195 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/SerialPortHelper.java

@@ -0,0 +1,195 @@
+package com.wdkl.app.ncs.callingbed.helper;
+
+import com.wdkl.ncs.android.middleware.model.dto.NurseConfigDto;
+
+import java.util.ArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import serialporttest.utils.SerialPortUtil;
+import serialporttest.utils.StringUtils;
+
+public class SerialPortHelper {
+    private static int brightnessPercent;
+    private static ArrayList<NurseConfigDto> nurseConfigs;
+    private static boolean dismissLed;
+
+    private final static Object lockObject = new Object();
+    private final static ExecutorService threadPool = Executors.newSingleThreadExecutor();
+    private static NurseLedRunnable ledRunnable;
+
+    //MIC设置
+    public static void setHandsMIC(boolean isHandsMIC) {
+        if (isHandsMIC) {
+            //打开手柄mic
+            SerialPortUtil.getInstance().sendCommand(SerialPortUtil.MIC, "0", "F");
+        } else {
+            //打开面板mic
+            SerialPortUtil.getInstance().sendCommand(SerialPortUtil.MIC, "1", "F");
+        }
+    }
+
+    /**
+     * 设置卫生间紧急按钮灯状态: 0关闭1打开2闪烁
+     */
+    public static void setSosLight(String state) {
+        SerialPortUtil.getInstance().sendCommand(SerialPortUtil.ULED, state, "F");
+    }
+
+    //重置设备
+    public static void resetDevice() {
+        SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NET_STATUS , "1", "F");
+    }
+
+    /**
+     * 门灯控制开关
+     *
+     * @param data  0  表示灯灭   1  表示灯亮
+     * @param color 0 表示灯灭  非0表示灯的颜色
+     */
+    public static void setDoorLight(int data, String color) {
+        String command;
+        if (data == 0 || color == null) {
+            command = "000";
+        } else {
+            command = color;
+        }
+        SerialPortUtil.getInstance().sendCommand(SerialPortUtil.DOORLIGHT, command, "F");
+    }
+
+    //护理灯测试
+    public static void nurseLedLightTest() {
+
+    }
+
+    /**
+     * 设置护理灯
+     */
+    public static void setNurseLedLight(final int brightnessPercent, final String oneColor, final String twoColor, final String threeColor, final String fourColor, final String fiveColor) {
+        //需要在子线程中设置
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    float p = (float) brightnessPercent / 100;
+                    if (StringUtils.notEmpty(oneColor)) {
+                        int rr = (int) ((StringUtils.parseFloat(StringUtils.substringByLengh(oneColor, 0, 2))) * p);
+                        int gg = (int) ((StringUtils.parseFloat(StringUtils.substringByLengh(oneColor, 2, 4))) * p);
+                        int bb = (int) ((StringUtils.parseFloat(StringUtils.substringByLengh(oneColor, 4, 6))) * p);
+                        SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + "0", beComeDoubleStr(rr) + beComeDoubleStr(gg) + beComeDoubleStr(bb), "F");
+                    }
+                    Thread.sleep(300);
+                    if (StringUtils.notEmpty(twoColor)) {
+                        int rr = (int) ((StringUtils.parseFloat(StringUtils.substringByLengh(twoColor, 0, 2))) * p);
+                        int gg = (int) ((StringUtils.parseFloat(StringUtils.substringByLengh(twoColor, 2, 4))) * p);
+                        int bb = (int) ((StringUtils.parseFloat(StringUtils.substringByLengh(twoColor, 4, 6))) * p);
+                        SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + "1", beComeDoubleStr(rr) + beComeDoubleStr(gg) + beComeDoubleStr(bb), "F");
+                    }
+                    Thread.sleep(300);
+                    if (StringUtils.notEmpty(threeColor)) {
+                        int rr = (int) ((StringUtils.parseFloat(StringUtils.substringByLengh(threeColor, 0, 2))) * p);
+                        int gg = (int) ((StringUtils.parseFloat(StringUtils.substringByLengh(threeColor, 2, 4))) * p);
+                        int bb = (int) ((StringUtils.parseFloat(StringUtils.substringByLengh(threeColor, 4, 6))) * p);
+                        SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + "2", beComeDoubleStr(rr) + beComeDoubleStr(gg) + beComeDoubleStr(bb), "F");
+                    }
+                    Thread.sleep(300);
+                    if (StringUtils.notEmpty(fourColor)) {
+                        int rr = (int) ((StringUtils.parseFloat(StringUtils.substringByLengh(fourColor, 0, 2))) * p);
+                        int gg = (int) ((StringUtils.parseFloat(StringUtils.substringByLengh(fourColor, 2, 4))) * p);
+                        int bb = (int) ((StringUtils.parseFloat(StringUtils.substringByLengh(fourColor, 4, 6))) * p);
+                        SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + "3", beComeDoubleStr(rr) + beComeDoubleStr(gg) + beComeDoubleStr(bb), "F");
+                    }
+                    Thread.sleep(300);
+                    if (StringUtils.notEmpty(fiveColor)) {
+                        int rr = (int) ((StringUtils.parseFloat(StringUtils.substringByLengh(fiveColor, 0, 2))) * p);
+                        int gg = (int) ((StringUtils.parseFloat(StringUtils.substringByLengh(fiveColor, 2, 4))) * p);
+                        int bb = (int) ((StringUtils.parseFloat(StringUtils.substringByLengh(fiveColor, 4, 6))) * p);
+                        SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + "4", beComeDoubleStr(rr) + beComeDoubleStr(gg) + beComeDoubleStr(bb), "F");
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }).start();
+    }
+
+    /**
+     * 设置护理灯2
+     */
+    public static synchronized void setNurseLedLight2(final int brightness, final ArrayList<NurseConfigDto> configs) {
+        synchronized (lockObject) {
+            brightnessPercent = brightness;
+            nurseConfigs = configs;
+            dismissLed = false;
+
+            updateNurseLed();
+        }
+    }
+
+    /**
+     * 熄灭护理灯
+     */
+    public static synchronized void dismissNurseLedLight() {
+        synchronized (lockObject) {
+            dismissLed = true;
+
+            updateNurseLed();
+        }
+    }
+
+    private static String beComeDoubleStr(int b) {
+        if (b >= 0 && b < 10) {
+            return "0" + b;
+        } else if (b >= 10 && b < 100) {
+            return "" + b;
+        } else {
+            return "99";
+        }
+    }
+
+    private static void updateNurseLed() {
+        if (ledRunnable == null) {
+            ledRunnable = new NurseLedRunnable();
+        }
+        threadPool.execute(ledRunnable);
+    }
+
+    public static class NurseLedRunnable implements Runnable {
+        @Override
+        public void run() {
+            try {
+                if (dismissLed) {
+                    for (int i = 0; i < 5; i++) {
+                        SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + i, "000000", "F");
+                        Thread.sleep(300);
+                    }
+                } else {
+                    if (nurseConfigs == null) {
+                        return;
+                    }
+
+                    float p = (float) brightnessPercent / 100;
+                    int size = nurseConfigs.size();
+                    //只有5个护理灯,超出无效
+                    if (size > 5) {
+                        size = 5;
+                    }
+                    for (int i = 0; i < size; i++) {
+                        String color = nurseConfigs.get(i).getNurseColorRbg();
+                        if (StringUtils.notEmpty(color)) {
+                            int rr = (int) ((StringUtils.parseHex2Int(StringUtils.substringByLengh(color, 0, 2))) * p);
+                            int gg = (int) ((StringUtils.parseHex2Int(StringUtils.substringByLengh(color, 2, 4))) * p);
+                            int bb = (int) ((StringUtils.parseHex2Int(StringUtils.substringByLengh(color, 4, 6))) * p);
+                            SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + i, beComeDoubleStr(rr) + beComeDoubleStr(gg) + beComeDoubleStr(bb), "F");
+                        } else {
+                            SerialPortUtil.getInstance().sendCommand(SerialPortUtil.NURSELIGHT + i, "000000", "F");
+                        }
+                        Thread.sleep(300);
+                    }
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}

+ 159 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/ServerConfigDialogHelper.java

@@ -0,0 +1,159 @@
+package com.wdkl.app.ncs.callingbed.helper;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.AdapterView;
+import android.widget.EditText;
+import android.widget.GridView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.wdkl.app.ncs.callingbed.R;
+import com.wdkl.app.ncs.callingbed.adapter.NumAdapter;
+import com.wdkl.ncs.android.lib.base.BaseApplication;
+import com.wdkl.ncs.android.lib.utils.ExtendMethodsKt;
+import com.wdkl.ncs.android.middleware.utils.CommonUtils;
+
+
+public class ServerConfigDialogHelper {
+
+    private static AlertDialog callDialog;
+    private static String pwd = "";
+
+    public static void showPasswordDialog(final Activity activity) {
+        View contentView = LayoutInflater.from(activity).inflate(R.layout.server_config_dialog_lay, null);
+        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+        builder.setView(contentView);
+
+        final String[] numbers = {"1","2","3","4","5","6","7","8","9"};
+        final TextView password = contentView.findViewById(R.id.tv_psw_view);
+        final LinearLayout llPwd = contentView.findViewById(R.id.ll_password);
+        final LinearLayout llServer = contentView.findViewById(R.id.ll_server_config);
+        GridView gridView = contentView.findViewById(R.id.grid_psw);
+        NumAdapter adapter = new NumAdapter(numbers, activity);
+        gridView.setAdapter(adapter);
+        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                if (pwd.length() <= 2) {
+                    pwd = pwd + numbers[position];
+                    password.setText(pwd);
+                }
+                Log.d("serverIp", "input password len: " + pwd.length() + "--" + pwd);
+            }
+        });
+
+        TextView delete = contentView.findViewById(R.id.btn_delete);
+        TextView cancel = contentView.findViewById(R.id.btn_cancel);
+        TextView confirm = contentView.findViewById(R.id.btn_confirm);
+        delete.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Log.d("serverIp", "delete password len: " + pwd.length() + "--" + pwd);
+                if (pwd.length() > 1) {
+                    pwd = pwd.substring(0, pwd.length()-1);
+                    password.setText(pwd);
+                } else {
+                    pwd = "";
+                    password.setText(pwd);
+                    password.setHint(R.string.input_password);
+                }
+            }
+        });
+
+        cancel.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                dismissCallDialog();
+            }
+        });
+
+        confirm.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if ("666".equals(pwd)) {
+                    llPwd.setVisibility(View.GONE);
+                    llServer.setVisibility(View.VISIBLE);
+                } else {
+                    Toast.makeText(activity, R.string.invalid_password, Toast.LENGTH_SHORT).show();
+                }
+            }
+        });
+
+        final EditText editUrl = contentView.findViewById(R.id.edit_url);
+        final EditText editPort = contentView.findViewById(R.id.edit_port);
+        final EditText editSipUrl = contentView.findViewById(R.id.edit_sip_url);
+        final EditText editSipPort = contentView.findViewById(R.id.edit_sip_port);
+        TextView saveConfig = contentView.findViewById(R.id.btn_save_config);
+        TextView cancelConfig = contentView.findViewById(R.id.btn_cancel_config);
+        editUrl.setText(CommonUtils.getUrl(BaseApplication.appContext));
+        editPort.setText(CommonUtils.getUrlPort(BaseApplication.appContext));
+        //editSipUrl.setText(CommonUtils.getSipUrl(BaseApplication.appContext));
+        //editSipPort.setText(CommonUtils.getSipPort(BaseApplication.appContext));
+        saveConfig.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                String url = editUrl.getText().toString();
+                String port = editPort.getText().toString();
+                if (TextUtils.isEmpty(url) || TextUtils.isEmpty(port)) {
+                    ExtendMethodsKt.showMessage(R.string.input_empty);
+                } else {
+                    //保存配置
+                    CommonUtils.setUrl(BaseApplication.appContext, editUrl.getText().toString());
+                    CommonUtils.setUrlPort(BaseApplication.appContext, editPort.getText().toString());
+                    //CommonUtils.setSipUrl(BaseApplication.appContext, editSipUrl.getText().toString());
+                    //CommonUtils.setSipPort(BaseApplication.appContext, editSipPort.getText().toString());
+                    dismissCallDialog();
+                }
+            }
+        });
+        cancelConfig.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                dismissCallDialog();
+            }
+        });
+
+
+        callDialog = builder.create();
+        callDialog.setCanceledOnTouchOutside(false);
+        callDialog.setCancelable(false);
+        callDialog.show();
+
+        //设置dialog宽高及位置
+        try {
+            Window window = callDialog.getWindow();
+            window.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
+            WindowManager.LayoutParams lp = window.getAttributes();
+            lp.width = 400;
+            lp.height = 480;
+            lp.gravity = Gravity.CENTER;
+            window.setAttributes(lp);
+
+            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+                    | View.SYSTEM_UI_FLAG_FULLSCREEN);
+            window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void dismissCallDialog() {
+        pwd = "";
+        if (callDialog != null && callDialog.isShowing()) {
+            callDialog.dismiss();
+        }
+    }
+}

+ 70 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/SoundPoolHelper.java

@@ -0,0 +1,70 @@
+package com.wdkl.app.ncs.callingbed.helper;
+
+import android.content.Context;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.media.SoundPool;
+import android.os.Build;
+
+import com.wdkl.app.ncs.callingbed.R;
+
+import java.util.HashMap;
+
+public class SoundPoolHelper {
+
+    private static SoundPoolHelper instance;
+    private SoundPool soundPool;
+    private HashMap<Integer, Integer> soundID = new HashMap<Integer, Integer>();
+    private boolean isLoaded = false;
+
+    public static SoundPoolHelper getInstance() {
+        if (instance == null) {
+            instance = new SoundPoolHelper();
+        }
+        return instance;
+    }
+
+    public void init(Context context) {
+        if(Build.VERSION.SDK_INT > 21){
+            SoundPool.Builder builder = new SoundPool.Builder();
+            //传入音频数量
+            builder.setMaxStreams(3);
+            //AudioAttributes是一个封装音频各种属性的方法
+            AudioAttributes.Builder attrBuilder = new AudioAttributes.Builder();
+            //设置音频流的合适的属性
+            attrBuilder.setLegacyStreamType(AudioManager.STREAM_SYSTEM);//STREAM_MUSIC
+            //加载一个AudioAttributes
+            builder.setAudioAttributes(attrBuilder.build());
+            soundPool = builder.build();
+        }else{
+            soundPool = new SoundPool(3, AudioManager.STREAM_SYSTEM, 0);
+        }
+
+        //来电
+        soundID.put(1, soundPool.load(context, R.raw.incoming_call, 1));
+        //去电
+        soundID.put(2, soundPool.load(context, R.raw.outgoing_call, 1));
+        //测试音频
+        soundID.put(3, soundPool.load(context, R.raw.speaker_test, 1));
+        soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
+            @Override
+            public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
+                isLoaded = true;
+            }
+        });
+    }
+
+    public void playSound(int index) {
+        try {
+            if (isLoaded) {
+                soundPool.play(soundID.get(index), 1, 1, 0, 0, 1);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void release() {
+        soundPool.release();
+    }
+}

+ 2 - 2
android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/SoundPoolManager.java

@@ -1,11 +1,11 @@
-package com.wdkl.app.ncs.callingbed2.helper;
+package com.wdkl.app.ncs.callingbed.helper;
 
 import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.SoundPool;
 import android.os.Build;
 
-import com.wdkl.app.ncs.callingbed2.R;
+import com.wdkl.app.ncs.callingbed.R;
 import com.wdkl.ncs.android.lib.base.BaseApplication;
 
 import java.util.HashMap;

+ 17 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/Utils.java

@@ -0,0 +1,17 @@
+package com.wdkl.app.ncs.callingbed.helper;
+
+import android.hardware.Camera;
+
+import com.wdkl.ncs.android.middleware.common.Constant;
+
+public class Utils {
+
+    public static void checkCameraSupport() {
+        int num = Camera.getNumberOfCameras();
+        if (num > 0) {
+            Constant.supportCamera = true;
+        } else {
+            Constant.supportCamera = false;
+        }
+    }
+}

+ 1 - 2
android_bed/src/main/h7_3128/java/com/wdkl/app/ncs/callingbed2/helper/VoiceManagerUtil.java

@@ -1,8 +1,7 @@
-package com.wdkl.app.ncs.callingbed2.helper;
+package com.wdkl.app.ncs.callingbed.helper;
 
 import android.content.Context;
 import android.media.AudioManager;
-import android.util.Log;
 
 /**
  * 类名称:VoiceManagerUtil <br>

+ 51 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/WarningDialogHelper.java

@@ -0,0 +1,51 @@
+package com.wdkl.app.ncs.callingbed.helper;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+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 com.wdkl.app.ncs.callingbed.R;
+
+
+public class WarningDialogHelper {
+    private static AlertDialog dialog;
+
+    public static void showDialog(final Activity activity) {
+        if (dialog != null && dialog.isShowing()) {
+            return;
+        }
+
+        View contentView = LayoutInflater.from(activity).inflate(R.layout.warning_dialog_lay, null);
+        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+        builder.setView(contentView);
+        Button button = contentView.findViewById(R.id.cancel_button);
+        button.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                AppUpdateHelper.reboot(activity);
+            }
+        });
+
+        dialog = builder.create();
+        //dialog.setCanceledOnTouchOutside(false);
+        //dialog.setCancelable(false);
+        dialog.show();
+
+        //设置dialog宽高及位置
+        try {
+            Window window = dialog.getWindow();
+            WindowManager.LayoutParams lp = window.getAttributes();
+            lp.width = 600;
+            lp.height = 240;
+            lp.gravity = Gravity.CENTER;
+            window.setAttributes(lp);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 237 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/helper/XCrashUtils.java

@@ -0,0 +1,237 @@
+package com.wdkl.app.ncs.callingbed.helper;
+
+import android.app.AlarmManager;
+import android.app.Application;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import com.wdkl.app.ncs.callingbed.BuildConfig;
+import com.wdkl.ncs.android.component.welcome.activity.WelcomeActivity;
+import com.wdkl.ncs.android.middleware.api.UrlManager;
+
+import org.json.JSONObject;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.FormBody;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import xcrash.ICrashCallback;
+import xcrash.TombstoneManager;
+import xcrash.TombstoneParser;
+import xcrash.XCrash;
+
+public class XCrashUtils {
+    private final static String TAG = "XCrashUtils";
+
+    private Application app;
+    private OkHttpClient okHttpClient;
+
+    // callback for java crash, native crash and ANR
+    private final ICrashCallback callback = new ICrashCallback() {
+        @Override
+        public void onCrash(String logPath, String emergency) {
+            Log.d(TAG, "log path: " + (logPath != null ? logPath : "(null)") + ", emergency: " + (emergency != null ? emergency : "(null)"));
+
+            if (emergency != null) {
+                debug(logPath, emergency);
+
+                // Disk is exhausted, send crash report immediately.
+                //sendThenDeleteCrashLog(logPath, emergency);
+            } else {
+                // Add some expanded sections. Send crash report at the next time APP startup.
+
+                // OK
+                TombstoneManager.appendSection(logPath, "expanded_key_1", "expanded_content");
+                TombstoneManager.appendSection(logPath, "expanded_key_2", "expanded_content_row_1\nexpanded_content_row_2");
+
+                // Invalid. (Do NOT include multiple consecutive newline characters ("\n\n") in the content string.)
+                // TombstoneManager.appendSection(logPath, "expanded_key_3", "expanded_content_row_1\n\nexpanded_content_row_2");
+
+                debug(logPath, null);
+            }
+
+            // Disk is exhausted, send crash report immediately.
+            //sendThenDeleteCrashLog(logPath, emergency);
+
+            //非debug版本上传crash日志
+            if (!BuildConfig.DEBUG) {
+                uploadCrashLog(logPath);
+            } else {
+                restartApp();
+            }
+        }
+    };
+
+    //ANR Catcher
+    private final ICrashCallback anrCallback = new ICrashCallback() {
+        @Override
+        public void onCrash(String logPath, String emergency) {
+            Log.d(TAG, "log path: " + (logPath != null ? logPath : "(null)") + ", emergency: " + (emergency != null ? emergency : "(null)"));
+
+            if (emergency != null) {
+                debug(logPath, emergency);
+
+                // Disk is exhausted, send crash report immediately.
+                //sendThenDeleteCrashLog(logPath, emergency);
+            } else {
+                // Add some expanded sections. Send crash report at the next time APP startup.
+
+                // OK
+                TombstoneManager.appendSection(logPath, "expanded_key_1", "expanded_content");
+                TombstoneManager.appendSection(logPath, "expanded_key_2", "expanded_content_row_1\nexpanded_content_row_2");
+
+                // Invalid. (Do NOT include multiple consecutive newline characters ("\n\n") in the content string.)
+                // TombstoneManager.appendSection(logPath, "expanded_key_3", "expanded_content_row_1\n\nexpanded_content_row_2");
+
+                debug(logPath, null);
+            }
+
+            AppUpdateHelper.reboot(app);
+        }
+    };
+
+    public void init(Application application) {
+        Log.d(TAG, "xCrash SDK init: start");
+        app = application;
+
+        // Initialize xCrash.
+        XCrash.init(application, new XCrash.InitParameters()
+                .setAppVersion(BuildConfig.VERSION_NAME)
+                .setJavaRethrow(true)
+                .setJavaLogCountMax(10)
+                .setJavaDumpAllThreadsWhiteList(new String[]{"^main$", "^Binder:.*", ".*Finalizer.*"})
+                .setJavaDumpAllThreadsCountMax(10)
+                .setJavaCallback(callback)
+                .setNativeRethrow(true)
+                .setNativeLogCountMax(10)
+                .setNativeDumpAllThreadsWhiteList(new String[]{"^xcrash\\.sample$", "^Signal Catcher$", "^Jit thread pool$", ".*(R|r)ender.*", ".*Chrome.*"})
+                .setNativeDumpAllThreadsCountMax(10)
+                .setNativeCallback(callback)
+                .setAnrRethrow(true)
+                .setAnrLogCountMax(10)
+                .setAnrCallback(anrCallback)
+                .setPlaceholderCountMax(3)
+                .setPlaceholderSizeKb(512)
+                .setLogDir(application.getExternalFilesDir("xcrash").toString())
+                .setLogFileMaintainDelayMs(5000));
+    }
+
+    private void uploadCrashLog(String path) {
+        final File logFile = new File(path);
+        if (logFile.exists()) {
+            final UrlManager urlManager = UrlManager.Companion.build();
+            String url = urlManager.getBuyer() + "ncs/upload/file";
+            HttpHelper.upload(url, logFile, new HttpHelper.UploadCallback() {
+                @Override
+                public void onFail() {
+                    Log.e(TAG,"错误日志文件上传失败!");
+                    restartApp();
+                }
+
+                @Override
+                public void onSuccess(String data) {
+                    Log.e(TAG,"错误日志文件上传成功!" + data);
+                    sendThenDeleteCrashLog(urlManager.getBuyer() + data, null);
+                    //删除日志文件
+                    //logFile.delete();
+                }
+            });
+        }
+    }
+
+    private void sendThenDeleteCrashLog(final String logPath, String emergency) {
+        try {
+            // Parse
+            //Map<String, String> map = TombstoneParser.parse(logPath, emergency);
+            //String crashReport = new JSONObject(map).toString();
+
+            if(okHttpClient == null){
+                okHttpClient = new OkHttpClient();
+            }
+
+            FormBody.Builder formBody = new FormBody.Builder();
+            formBody.add("class_name", app.getPackageName());
+            formBody.add("method_name", "");
+            formBody.add("exception_name", "");
+            formBody.add("err_msg", "");
+            formBody.add("stack_trace", logPath);
+
+            UrlManager urlManager = UrlManager.Companion.build();
+            Request request  = new Request.Builder()
+                    .url(urlManager.getBuyer() + "device/error_log")
+                    .post(formBody.build())
+                    .build();
+
+            okHttpClient.newCall(request).enqueue(new Callback() {
+                @Override
+                public void onFailure(Call call, IOException e) {
+                    Log.e(TAG,"错误日志名称上传失败"+e.getMessage());
+                    restartApp();
+                }
+
+                @Override
+                public void onResponse(Call call, Response response) throws IOException {
+                    Log.d(TAG,"错误日志名称上传成功");
+                    TombstoneManager.deleteTombstone(logPath);
+                    //String data = response.body().string();
+                    //Log.d(TAG,"错误日志数据 data "+data);
+                    restartApp();
+                }
+            });
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        // Send the crash report to server-side.
+        // ......
+
+        // If the server-side receives successfully, delete the log file.
+        //
+        // Note: When you use the placeholder file feature,
+        //       please always use this method to delete tombstone files.
+        //
+        //TombstoneManager.deleteTombstone(logPath);
+    }
+
+    private void debug(String logPath, String emergency) {
+        // Parse and save the crash info to a JSON file for debugging.
+        FileWriter writer = null;
+        try {
+            File debug = new File(XCrash.getLogDir() + "/debug.json");
+            debug.createNewFile();
+            writer = new FileWriter(debug, false);
+            writer.write(new JSONObject(TombstoneParser.parse(logPath, emergency)).toString());
+        } catch (Exception e) {
+            Log.d(TAG, "debug failed", e);
+        } finally {
+            if (writer != null) {
+                try {
+                    writer.close();
+                } catch (Exception ignored) {
+                }
+            }
+        }
+    }
+
+    private void restartApp() {
+        //重新启动app
+        Intent mStartActivity = new Intent(app.getApplicationContext(), WelcomeActivity.class);
+        mStartActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        int mPendingIntentId = 123456;
+        PendingIntent mPendingIntent = PendingIntent.getActivity(app.getApplicationContext(), mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
+        AlarmManager mgr = (AlarmManager) app.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
+        mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 2000, mPendingIntent);
+
+        android.os.Process.killProcess(android.os.Process.myPid());
+        System.exit(0);
+    }
+
+}

+ 20 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/launch/CallingbedLaunch.kt

@@ -0,0 +1,20 @@
+package com.wdkl.app.ncs.callingbed.launch
+
+import com.enation.javashop.android.jrouter.external.annotation.Router
+import com.wdkl.app.ncs.callingbed.di.CallingbedComponent
+import com.wdkl.app.ncs.callingbed.di.DaggerCallingbedComponent
+import com.wdkl.ncs.android.lib.base.BaseLaunch
+import com.wdkl.ncs.android.middleware.di.DaggerManager
+
+@Router(path = "/callingbed/launch")
+class CallingbedLaunch :BaseLaunch() {
+    companion object {
+        lateinit var component: CallingbedComponent
+    }
+
+    override fun moduleInit() {
+        component = DaggerCallingbedComponent.builder()
+                .applicationComponent(DaggerManager.APPLICATION_COMPONENT)
+                .build()
+    }
+}

+ 384 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/settings/SettingConfig.java

@@ -0,0 +1,384 @@
+package com.wdkl.app.ncs.callingbed.settings;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+
+public class SettingConfig {
+
+
+    private static final String SP_NAME = "SP_BED_FUNCTION";
+
+    //白昼设置白天的初始时间设置
+    private static final String KEY_SP_INITIAL_DAY_TIME = "KEY_SP_INITIAL_DAY_TIME";
+    private static final String initial_day_time = "07:00";
+    private static final String KEY_SP_INITIAL_DAY_TIME_LOCATION = "KEY_SP_INITIAL_DAY_TIME_LOCATION";
+    private static final String initial_day_time_location = "12";
+
+
+    //白昼设置白天的结束时间设置
+    private static final String KEY_SP_END_OF_DAY = "KEY_SP_END_OF_DAY";
+    private static final String end_of_day = "19:00";
+    //白昼设置白天的结束时间设置
+    private static final String KEY_SP_END_OF_DAY_LOCATION = "KEY_SP_END_OF_DAY_LOCATION";
+    private static final String end_of_day_location = "38";
+
+
+    //分机白天亮度
+    private static final String KEY_SP_EXTENSION_DAYTIME_BRIGHTNESS = "KEY_SP_EXTENSION_DAYTIME_BRIGHTNESS";
+    private static final int extension_daytime_brightness = 80;
+    //分机晚上亮度
+    private static final String KEY_SP_EXTENSION_NIGHT_BRIGHTNESS = "KEY_SP_EXTENSION_NIGHT_BRIGHTNESS";
+    private static final int extension_night_brightness = 50;
+
+    //分机护理灯白天亮度
+    private static final String KEY_SP_EXTENSION_DAYTIME_LED_BRIGHTNESS = "KEY_SP_EXTENSION_DAYTIME_LED_BRIGHTNESS";
+    private static final int extension_daytime_led_brightness = 80;
+    //分机护理灯晚上亮度
+    private static final String KEY_SP_EXTENSION_NIGHT_LED_BRIGHTNESS = "KEY_SP_EXTENSION_NIGHT_LED_BRIGHTNESS";
+    private static final int extension_night_led_brightness = 50;
+
+    //分机白天系统音量
+    private static final String KEY_SP_EXTENSION_DAYTIME_SYSTEM_VOLUME = "KEY_SP_EXTENSION_DAYTIME_SYSTEM_VOLUME";
+    private static final int extension_daytime_system_volume = 100;
+    //分机晚上系统音量
+    private static final String KEY_SP_EXTENSION_NIGHT_SYSTEM_VOLUME = "KEY_SP_EXTENSION_NIGHT_SYSTEM_VOLUME";
+    private static final int extension_night_system_volume = 70;
+
+    //分机手柄录入音量
+    private static final String KEY_SP_THE_EXTENSION_HANDLR_RECORDS_THE_VOLUME = "KEY_SP_THE_EXTENSION_HANDLR_RECORDS_THE_VOLUME";
+    private static final int the_extension_handle_records_the_volume = 50;
+
+    //分机通话音量
+    private static final String KEY_SP_EXTENSION_CALL_VOLUME = "KEY_SP_EXTENSION_CALL_VOLUME";
+    private static final int extension_call_volume = 100;
+
+    //呼叫超时时间
+    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;
+
+    //网络异常重启次数
+    private static final String KEY_SP_NET_ERR_RESET_COUNT = "KEY_SP_NET_ERR_RESET_COUNT";
+
+    //默认语言
+    private static final String KEY_LANGUAGE_ID = "KEY_LANGUAGE_ID";
+    private static final String KEY_LANGUAGE_MODE = "KEY_LANGUAGE_MODE";
+    //是否自动接通
+    private static final String KEY_SP_AUTO_ANSWER = "KEY_SP_AUTO_ANSWER";
+
+    public static int getLanguageId(Context context) {
+        //0--auto, 1--English, 2--中文, 3--西班牙语, 4--俄语
+        return getSP(context).getInt(KEY_LANGUAGE_ID, 2);
+    }
+
+    public static void setLanguageId(Context context, int id) {
+        getEditor(context).putInt(KEY_LANGUAGE_ID, id).apply();
+    }
+
+    public static int getLanguageMode(Context context) {
+        return getSP(context).getInt(KEY_LANGUAGE_MODE, 0);
+    }
+
+    public static void setLanguageMode(Context context, int mode) {
+        getEditor(context).putInt(KEY_LANGUAGE_MODE, mode).apply();
+    }
+
+    /**
+     * 获取分机白天亮度
+     *
+     * @return
+     */
+    public static int getExtensionDaytimeBrightness(Context context) {
+        return getSP(context).getInt(KEY_SP_EXTENSION_DAYTIME_BRIGHTNESS, extension_daytime_brightness);
+    }
+
+    /**
+     * 设置分机白天亮度
+     *
+     * @param value
+     */
+    public static void setExtensionDaytimeBrightness(Context context, int value) {
+        getEditor(context).putInt(KEY_SP_EXTENSION_DAYTIME_BRIGHTNESS, value).apply();
+    }
+
+    /**
+     * 获取分机晚上亮度
+     *
+     * @return
+     */
+    public static int getExtensionNightBrightness(Context context) {
+        return getSP(context).getInt(KEY_SP_EXTENSION_NIGHT_BRIGHTNESS, extension_night_brightness);
+    }
+
+    /**
+     * 设置分机晚上亮度
+     *
+     * @param value
+     */
+    public static void setExtensionNightBrightness(Context context, int value) {
+        getEditor(context).putInt(KEY_SP_EXTENSION_NIGHT_BRIGHTNESS, value).apply();
+    }
+
+    /**
+     * 获取分机LED白天亮度
+     *
+     * @return
+     */
+    public static int getExtensionDaytimeLEDBrightness(Context context) {
+        return getSP(context).getInt(KEY_SP_EXTENSION_DAYTIME_LED_BRIGHTNESS, extension_daytime_led_brightness);
+    }
+
+    /**
+     * 设置分机LED白天亮度
+     *
+     * @param value
+     */
+    public static void setExtensionDaytimeLEDBrightness(Context context, int value) {
+        getEditor(context).putInt(KEY_SP_EXTENSION_DAYTIME_LED_BRIGHTNESS, value).apply();
+    }
+
+    /**
+     * 获取分机LED晚上亮度
+     *
+     * @return
+     */
+    public static int getExtensionNightLEDBrightness(Context context) {
+        return getSP(context).getInt(KEY_SP_EXTENSION_NIGHT_LED_BRIGHTNESS, extension_night_led_brightness);
+    }
+
+    /**
+     * 设置分机LED晚上亮度
+     *
+     * @param value
+     */
+    public static void setExtensionNightLEDBrightness(Context context, int value) {
+        getEditor(context).putInt(KEY_SP_EXTENSION_NIGHT_LED_BRIGHTNESS, value).apply();
+    }
+
+
+    /**
+     * 获取分机白天系统音量
+     *
+     * @return
+     */
+    public static int getExtensionDaytimeSystemVolume(Context context) {
+        return getSP(context).getInt(KEY_SP_EXTENSION_DAYTIME_SYSTEM_VOLUME, extension_daytime_system_volume);
+    }
+
+    /**
+     * 设置分机白天系统音量
+     *
+     * @param value
+     */
+    public static void setExtensionDaytimeSystemVolume(Context context, int value) {
+        getEditor(context).putInt(KEY_SP_EXTENSION_DAYTIME_SYSTEM_VOLUME, value).apply();
+    }
+
+    /**
+     * 获取分机晚上系统音量
+     *
+     * @return
+     */
+    public static int getExtensionNightSystemVolume(Context context) {
+        return getSP(context).getInt(KEY_SP_EXTENSION_NIGHT_SYSTEM_VOLUME, extension_night_system_volume);
+    }
+
+    /**
+     * 设置分机晚上系统音量
+     *
+     * @param value
+     */
+    public static void setExtensionNightSystemVolume(Context context, int value) {
+        getEditor(context).putInt(KEY_SP_EXTENSION_NIGHT_SYSTEM_VOLUME, value).apply();
+    }
+
+
+
+    /**
+     * 获取分机手柄录入音量
+     *
+     * @return
+     */
+    public static int getTheExtensionHandleRecordsTheVolume(Context context) {
+        return getSP(context).getInt(KEY_SP_THE_EXTENSION_HANDLR_RECORDS_THE_VOLUME, the_extension_handle_records_the_volume);
+    }
+
+    /**
+     * 设置分机手柄录入音量
+     *
+     * @param value
+     */
+    public static void setTheExtensionHandleRecordsTheVolume(Context context, int value) {
+        getEditor(context).putInt(KEY_SP_THE_EXTENSION_HANDLR_RECORDS_THE_VOLUME, value).apply();
+    }
+
+
+    /**
+     * 获取分机通话音量
+     *
+     * @return
+     */
+    public static int getExtensionCallVolume(Context context) {
+        return getSP(context).getInt(KEY_SP_EXTENSION_CALL_VOLUME, extension_call_volume);
+    }
+
+    /**
+     * 设置分机通话音量
+     *
+     * @param value
+     */
+    public static void setExtensionCallVolume(Context context, int value) {
+        getEditor(context).putInt(KEY_SP_EXTENSION_CALL_VOLUME, value).apply();
+    }
+
+
+    /**
+     * 获取白昼设置白天的初始时间
+     *
+     * @return
+     */
+    public static String getInitialDayTime(Context context) {
+        return getSP(context).getString(KEY_SP_INITIAL_DAY_TIME, initial_day_time);
+    }
+
+    /**
+     * 设置白昼白天的初始时间
+     *
+     * @param value
+     */
+    public static void setInitialDayTime(Context context, String value) {
+        getEditor(context).putString(KEY_SP_INITIAL_DAY_TIME, value).apply();
+    }
+
+    /**
+     * 获取白昼设置白天的初始时间位置
+     *
+     * @return
+     */
+    public static String getInitialDayTimeLocation(Context context) {
+        return getSP(context).getString(KEY_SP_INITIAL_DAY_TIME_LOCATION, initial_day_time_location);
+    }
+
+    /**
+     * 设置白昼白天的初始时间位置
+     *
+     * @param value
+     */
+    public static void setInitialDayTimeLocation(Context context, String value) {
+        getEditor(context).putString(KEY_SP_INITIAL_DAY_TIME_LOCATION, value).apply();
+    }
+
+
+
+    /**
+     * 设置白昼白天的结束时间
+     *
+     * @param value
+     */
+    public static void setEndOfDay(Context context, String value) {
+        getEditor(context).putString(KEY_SP_END_OF_DAY, value).apply();
+    }
+
+    /**
+     * 获取白昼设置白天的结束时间
+     *
+     * @return
+     */
+    public static String getEndOfDay(Context context) {
+        return getSP(context).getString(KEY_SP_END_OF_DAY, end_of_day);
+    }
+
+    /**
+     * 设置白昼白天的结束时间位置
+     *
+     * @param value
+     */
+    public static void setEndOfDayLocation(Context context, String value) {
+        getEditor(context).putString(KEY_SP_END_OF_DAY_LOCATION, value).apply();
+    }
+
+    /**
+     * 获取白昼设置白天的结束时间位置
+     *
+     * @return
+     */
+    public static String getEndOfDayLocation(Context context) {
+        return getSP(context).getString(KEY_SP_END_OF_DAY_LOCATION, end_of_day_location);
+    }
+
+    /**
+     * 设置呼叫超时时间
+     *
+     * @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);
+    }
+
+    /**
+     * 设置息屏时间
+     *
+     * @param value
+     */
+    public static void setSleepTime(Context context, int value) {
+        getEditor(context).putInt(KEY_SP_SLEEP_TIME, value).apply();
+    }
+
+    /**
+     * 获取息屏时间
+     *
+     * @return
+     */
+    public static int getSleepTime(Context context) {
+        return getSP(context).getInt(KEY_SP_SLEEP_TIME, sleep_time);
+    }
+
+    /**
+     * 获取网络异常重启次数
+     *
+     * @return
+     */
+    public static int getNetErrResetCount(Context context) {
+        return getSP(context).getInt(KEY_SP_NET_ERR_RESET_COUNT, 0);
+    }
+
+    /**
+     * 设置网络异常重启次数
+     *
+     * @param value
+     */
+    public static void setNetErrResetCount(Context context, int value) {
+        getEditor(context).putInt(KEY_SP_NET_ERR_RESET_COUNT, value).apply();
+    }
+
+    public static boolean getAutoAnswer(Context context) {
+        return getSP(context).getBoolean(KEY_SP_AUTO_ANSWER, false);
+    }
+
+    public static void setAutoAnswer(Context context, boolean value) {
+        getEditor(context).putBoolean(KEY_SP_AUTO_ANSWER, value).apply();
+    }
+
+    private static SharedPreferences getSP(Context context) {
+        return context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
+    }
+
+    private static SharedPreferences.Editor getEditor(Context context) {
+        return getSP(context).edit();
+    }
+
+
+}

+ 581 - 0
android_bed/src/main/h5_3128/java/com/wdkl/app/ncs/callingbed/sip/SipHelper.java.bak

@@ -0,0 +1,581 @@
+package com.wdkl.app.ncs.callingbed.sip;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.CountDownTimer;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.util.Log;
+
+import com.vvsip.ansip.IVvsipService;
+import com.vvsip.ansip.IVvsipServiceListener;
+import com.vvsip.ansip.VvsipCall;
+import com.vvsip.ansip.VvsipService;
+import com.vvsip.ansip.VvsipServiceBinder;
+import com.vvsip.ansip.VvsipTask;
+import com.wdkl.app.ncs.callingbed.helper.NetHelper;
+import com.wdkl.ncs.android.middleware.common.MessageEvent;
+
+
+import org.greenrobot.eventbus.EventBus;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.wdkl.app.ncs.callingbed.sip.SipStatus.REGISTERCOM;
+import static com.wdkl.app.ncs.callingbed.sip.SipStatus.REGISTERFAIL;
+import static com.wdkl.app.ncs.callingbed.sip.SipStatus.REGISTERING;
+import static com.vvsip.ansip.VvsipTask.EXOSIP_CALL_CLOSED;
+import static com.wdkl.ncs.android.middleware.common.Constant.EVENT_SIP_REGISTER_STATUS;
+
+
+public class SipHelper {
+
+    private final static String SIP_IP_END = ":5060";
+
+    private static String sipIP = "";
+    private static String sipID = "";
+    private static String sipPWD = "";
+
+    /**
+     * Sip启动注册.
+     */
+    protected int mSipRegisterTime = 5000;
+    private Handler sipRegisterHandler = null;
+    private Runnable sipRegisterRunnable = null;
+
+    /**
+     * SIP信息
+     */
+    public static final String SipInfoTag = "SipInfo";
+    /**
+     * 电话呼叫对象
+     */
+    private List<VvsipCall> mVvsipCalls = null;
+
+
+    private static SipHelper sipHelper;
+
+    public Handler getSipRegisterHandler() {
+        return sipRegisterHandler;
+    }
+
+    public Runnable getSipRegisterRunnable() {
+        return sipRegisterRunnable;
+    }
+
+    public List<VvsipCall> getmVvsipCalls() {
+        return mVvsipCalls;
+    }
+
+    private IVvsipServiceListener sipListner;
+
+
+    private Context mContext;
+
+    public static SipHelper getInstance() {
+        if (sipHelper == null) {
+            synchronized (SipHelper.class) {
+                if (sipHelper == null) {
+                    sipHelper = new SipHelper();
+                }
+            }
+        }
+        return sipHelper;
+    }
+
+    /**
+     * Instantiates a new Sip register util.
+     */
+    private SipHelper() {
+        if (mVvsipCalls == null) {
+            mVvsipCalls = new ArrayList<VvsipCall>();
+        }
+
+        // Runnable exiting the splash screen and launching the menu
+        sipRegisterRunnable = new Runnable() {
+            public void run() {
+                isSuccessRegisterSip();
+            }
+        };
+
+        // Run the exitRunnable in in mSipRegisterTime ms
+        sipRegisterHandler = new Handler();
+
+        IVvsipService sipservice = VvsipService.getService();
+        if (sipservice != null) {
+            sipRegisterHandler.postDelayed(sipRegisterRunnable, 3000);
+            return;
+        }
+        sipRegisterHandler.postDelayed(sipRegisterRunnable, mSipRegisterTime);
+    }
+
+    public void initSip(Context context, String ip, String id, String pwd) {
+        mContext = context;
+        sipIP = ip;
+        sipID = id;
+        sipPWD = pwd;
+    }
+
+    public void setSipListner(IVvsipServiceListener listner) {
+        sipListner = listner;
+    }
+
+    /*public void addSipListner(IVvsipServiceListener listner) {
+        IVvsipService sipService = VvsipService.getService();
+        if (sipService != null && listner != null) {
+            sipService.addListener(listner);
+            Log.d("sip", "add sip listner");
+        }
+    }
+
+    public void removeSipListner(IVvsipServiceListener listner) {
+        IVvsipService sipService = VvsipService.getService();
+        if (sipService != null && listner != null) {
+            sipService.removeListener(listner);
+            Log.d("sip", "remove sip listner");
+        }
+    }*/
+
+    /**
+     * 检测Sip服务是否注册成功
+     */
+    public void isSuccessRegisterSip() {
+        VvsipTask vvsipTask = VvsipTask.getVvsipTask();
+        if (vvsipTask != null && VvsipTask.global_failure != 0) {
+            /**
+             * ==================================sip服务启动失败 ================================
+             */
+        }
+    }
+
+    /**
+     * 注销Sip服务
+     */
+    public void unRegisterSip() {
+        //LogUtil.i(SipInfoTag, "lifecycle // onDestroy");
+
+        IVvsipService sipservice = VvsipService.getService();
+        if (sipservice != null) {
+            //sipservice.removeListener(sipListner);
+            sipservice.clearListener();
+        }
+
+        getSipServiceStartHandler().removeCallbacks(getSipServiceStartRunnable());
+        sipRegisterHandler.removeCallbacks(sipRegisterRunnable);
+        if (getSipServiceConnection() != null && isRegister) {
+            try {
+                mContext.unbindService(getSipServiceConnection());
+                setSipServiceConnection(null);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        if (mVvsipCalls != null) {
+            mVvsipCalls.clear();
+            mVvsipCalls = null;
+        }
+
+        //Log.i(SipInfoTag, "lifecycle // onDestroy");
+    }
+
+    public static String sipStatus = "";
+
+    /**
+     * Sip信息获取
+     */
+    public void obtainSipInfo() {
+        if (sipStatus.equals(REGISTERCOM) && NetHelper.NetConn) {//sip注册成功并且以太网连上
+            return;
+        }
+        IVvsipService sipService = VvsipService.getService();
+        if (sipService != null && sipListner != null) {
+            //sipService.addListener(sipListner);
+            sipService.setMessageHandler(messageHandler);
+        } else {
+            //LogUtil.i(SipInfoTag, "lifecycle // _service==null");
+        }
+        sipRegister();
+        failUiRefreshSip();
+    }
+
+    private void failUiRefreshSip() {
+        if (!NetHelper.NetConn) {
+            sipStatus = REGISTERFAIL;
+            EventBus.getDefault().post(new MessageEvent(REGISTERFAIL, EVENT_SIP_REGISTER_STATUS));
+            if (mSipThread != null) {
+                mSipThread.interrupt();
+                mSipThread = null;
+            }
+            //LogUtil.e(SipInfoTag, "以太网断开,SIP UI状态刷新为失败");
+        }
+    }
+
+
+    /**
+     * Sip信息
+     */
+    private String sipinfo = "";
+    private static int handleCount = 0;
+    //Sip註冊次數
+    private CountDownTimer mCountDownAutoTimer;
+    @SuppressLint("HandlerLeak")
+    private Handler messageHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            //LogUtil.i("QASE", "handleMessage==" + " msg.obj==" + msg.obj.toString() + " msg.what==" + msg.what);
+            //LogUtil.i(SipInfoTag, "#" + msg.obj);
+            sipinfo = "" + msg.obj + sipinfo;
+            //LogUtil.i(SipInfoTag, "Sip信息" + sipinfo);
+
+            if (msg.what == 22) {//释放资源
+                //EventBus.getDefault().post(new MessageEvent(msg.what, EVENT_SIP_REGISTER_STATUS));
+            }
+
+            if (sipinfo.contains("200 OK")) {//注册成功
+                sipStatus = REGISTERCOM;
+                EventBus.getDefault().post(new MessageEvent(REGISTERCOM, EVENT_SIP_REGISTER_STATUS));
+                if (mSipThread != null) {
+                    mSipThread.interrupt();
+                    mSipThread = null;
+                }
+                if (msg.obj.toString().contains("408")) {//超时
+                    sipStatus = REGISTERFAIL;
+                    EventBus.getDefault().post(new MessageEvent(REGISTERFAIL, EVENT_SIP_REGISTER_STATUS));
+                    sipRegister();
+                }
+            } else {//注册失败
+                sipStatus = REGISTERFAIL;
+                EventBus.getDefault().post(new MessageEvent(REGISTERFAIL, EVENT_SIP_REGISTER_STATUS));
+                if (mSipThread != null) {
+                    mSipThread.interrupt();
+                    mSipThread = null;
+                }
+                sipRegister();
+            }
+            failUiRefreshSip();
+
+            if (msg.obj.toString().contains("autocall")) {
+                VvsipCall pCall = null;
+                //LogUtil.e(SipInfoTag, "onClick1");
+                for (VvsipCall _pCall : mVvsipCalls) {
+                    if (_pCall.cid > 0)
+                        //LogUtil.e(SipInfoTag, "state#" + _pCall.mState);
+                        if (_pCall.cid > 0 && _pCall.mState <= 2) {
+                            pCall = _pCall;
+                            break;
+                        }
+                }
+                //LogUtil.e(SipInfoTag, "onClick2");
+                if (pCall == null)
+                    return;
+                //LogUtil.e(SipInfoTag, "onClick3#" + pCall.mState);
+                IVvsipService _service = VvsipService.getService();
+                if (_service == null)
+                    return;
+                VvsipTask _vvsipTask = _service.getVvsipTask();
+                if (_vvsipTask == null)
+                    return;
+                pCall.stop();
+                _service.setSpeakerModeOff();
+            }
+        }
+    };
+
+    /**
+     * ====================Sip注册======================
+     */
+    private Thread mSipThread;
+
+    private static class SipThread extends Thread {
+        WeakReference<Activity> mThreadCallingBedActivity;
+
+        private SipThread(Activity activity) {
+            mThreadCallingBedActivity = new WeakReference<Activity>(activity);
+        }
+
+        @Override
+        public void run() {
+            super.run();
+            if (mThreadCallingBedActivity == null)
+                return;
+            if (mThreadCallingBedActivity.get() != null) {
+                IVvsipService sipService = VvsipService.getService();
+                try {
+                    if (sipService != null && !SipHelper.getInstance().sipinfo.contains("200 OK") && NetHelper.NetConn) {
+                        sipStatus = REGISTERING;
+                        EventBus.getDefault().post(new MessageEvent(REGISTERING, EVENT_SIP_REGISTER_STATUS));
+                        sipService.register(sipIP + SIP_IP_END, sipID, sipPWD);
+                        handleCount++;
+                        Log.e(SipInfoTag, "以太网连接,SIP UI状态刷新为注册中");
+                    } else if (sipService != null && SipHelper.getInstance().sipinfo.contains("200 OK")) {
+                        sipStatus = REGISTERCOM;
+                        EventBus.getDefault().post(new MessageEvent(REGISTERCOM, EVENT_SIP_REGISTER_STATUS));
+                    }
+                } catch (NullPointerException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    private void sipRegister() {
+        synchronized (this) {
+            mSipThread = new SipThread((Activity) mContext);
+            if (handleCount < 3) {
+                if (mCountDownAutoTimer == null) {
+                    mCountDownAutoTimer = new CountDownTimer(10000, 1000) {
+                        @Override
+                        public void onTick(long l) {
+                        }
+
+                        @Override
+                        public void onFinish() {
+                            handleCount = 0;
+                            if (mSipThread != null) {
+                                mSipThread.start();
+                            }
+                            if (mCountDownAutoTimer != null) {
+                                mCountDownAutoTimer.cancel();
+                                mCountDownAutoTimer = null;
+                            }
+                        }
+                    };
+                    mCountDownAutoTimer.start();
+                }
+                return;
+            } else {
+                if (mCountDownAutoTimer != null) {
+                    mCountDownAutoTimer.cancel();
+                    mCountDownAutoTimer = null;
+                }
+            }
+            if (handleCount == 0) {
+                mSipThread.start();
+            }
+        }
+    }
+
+
+    public void setmSipThread(Thread mSipThread) {
+        this.mSipThread = mSipThread;
+    }
+
+    public Thread getmSipThread() {
+        return mSipThread;
+    }
+
+    /**
+     * 开始通话
+     */
+    public void startCall(String sipUseName) {
+        IVvsipService sipService = VvsipService.getService();
+        if (sipService == null) return;
+        //----------------------------------------------携带呼叫列表转接床头机的Mac地址--------------------------------------------------//
+        sipService.initiateOutgoingCall(sipUseName, "");
+    }
+
+    /**
+     * 结束通话
+     */
+    public void endCall() {
+        VvsipCall call = null;
+        for (VvsipCall pCall : mVvsipCalls) {
+            if (pCall.cid > 0 && pCall.mState <= 2) {
+                call = pCall;
+                break;
+            }
+        }
+        if (call == null) return;
+        IVvsipService sipService = VvsipService.getService();
+        if (sipService == null) return;
+        VvsipTask sipTask = sipService.getVvsipTask();
+        if (sipTask == null) return;
+        VvsipService.getService().mainEndCall(EXOSIP_CALL_CLOSED);
+        call.stop();
+        sipService.setSpeakerModeOff();
+        sipService.stopPlayer();
+        sipService.setAudioNormalMode();
+    }
+
+    /**
+     * 添加一个电话呼叫对象
+     *
+     * @param call
+     */
+    public void addCallObject(final VvsipCall call) {
+        try {
+            if (call == null) {
+                return;
+            }
+
+            if (mVvsipCalls == null)
+                return;
+            mVvsipCalls.add(call);
+        } catch (Exception e) {
+            //LogUtil.e(SipInfoTag, "onNewVvsipCallEvent: " + e);
+        }
+    }
+
+    /**
+     * 移除一个电话呼叫对象
+     *
+     * @param call
+     */
+    public void removeCallObject(final VvsipCall call) {
+        try {
+            if (call == null) {
+                return;
+            }
+
+            // 4 crash detected here for 4.0.9 with mVvsipCalls=NULL
+            if (mVvsipCalls == null)
+                return;
+            mVvsipCalls.remove(call);
+        } catch (Exception e) {
+            //Log.e(SipInfoTag, "onRemoveVvsipCallEvent: " + e);
+        }
+    }
+
+    /**
+     * 自动接电话
+     */
+    public void autoTalking() {
+        if (mVvsipCalls == null) {
+            mVvsipCalls = new ArrayList<VvsipCall>();
+        }
+        for (VvsipCall _pCall : mVvsipCalls) {
+            if (_pCall.cid > 0 && _pCall.mState < 2 && _pCall.mIncomingCall) {
+                // ANSWER EXISTING CALL
+                int i = _pCall.answer(200, 1);
+              //LogUtil.d(SipInfoTag, "ANSWER EXISTING CALL");
+                IVvsipService _service = VvsipService.getService();
+                if (_service != null) {
+                    if (i >= 0) {
+                        _service.stopPlayer();
+                        _service.setSpeakerModeOff();
+                        _service.setAudioInCallMode();
+                    }
+                }
+                break;
+            }
+        }
+    }
+
+    public static boolean isServiceRunning(Context context, String className) {
+        boolean isRunning = false;
+        ActivityManager activityManager = (ActivityManager) context
+                .getSystemService(Context.ACTIVITY_SERVICE);
+        List<ActivityManager.RunningServiceInfo> serviceList = activityManager
+                .getRunningServices(30);
+
+        if (!(serviceList.size() > 0)) {
+            return false;
+        }
+
+        for (int i = 0; i < serviceList.size(); i++) {
+            if (serviceList.get(i).service.getClassName().equals(className) == true) {
+                isRunning = true;
+                break;
+            }
+        }
+        return isRunning;
+    }
+
+    /**
+     * #############################
+     * <p>
+     * Sip启动服务.
+     * <p>
+     * #############################
+     */
+    private static Handler sipServiceStartHandler = null;
+    private static Runnable sipServiceStartRunnable = null;
+    private static ServiceConnection sipServiceConnection;
+
+    public static Runnable getSipServiceStartRunnable() {
+        return sipServiceStartRunnable;
+    }
+
+    public static Handler getSipServiceStartHandler() {
+        return sipServiceStartHandler;
+    }
+
+    public static ServiceConnection getSipServiceConnection() {
+        return sipServiceConnection;
+    }
+
+    public static void setSipServiceConnection(ServiceConnection sipServiceConnections) {
+        sipServiceConnection = sipServiceConnections;
+    }
+
+    /**
+     * 启动服务
+     */
+    public static Boolean isRegister = false;//是否注册
+
+    public void sipStartService() {
+        sipServiceStartHandler = new Handler();
+
+        sipServiceStartRunnable = new Runnable() {
+            public void run() {
+                if (mContext == null) {
+                    sipServiceStartHandler.postDelayed(sipServiceStartRunnable, 1000);
+                    return;
+                }
+                Intent intent = new Intent(mContext.getApplicationContext(), VvsipService.class);
+                mContext.startService(intent);
+
+                sipServiceConnection = new ServiceConnection() {
+                    public void onServiceConnected(ComponentName name, IBinder service) {
+                        IVvsipService sipservice = ((VvsipServiceBinder) service).getService();
+                        if (sipservice != null && sipListner != null) {
+                            //LogUtil.i(SipInfoTag, "Connected!");
+                            sipservice.clearListener();
+                            sipservice.addListener(sipListner);
+                            SipHelper.getInstance().obtainSipInfo();//Sip信息获取
+                        }
+                    }
+
+                    public void onServiceDisconnected(ComponentName name) {
+                        //LogUtil.i(SipInfoTag, "Disconnected!");
+                    }
+                };
+
+                isRegister = mContext.bindService(intent, sipServiceConnection, Context.BIND_AUTO_CREATE);
+            }
+        };
+
+        sipServiceStartHandler.postDelayed(sipServiceStartRunnable, 0);
+    }
+
+    /**
+     * 用来解析错误代码
+     */
+    public static String analyseErrorCode(String errorCode) {
+        switch (errorCode) {
+            case "200":
+                return "成功";
+            case "408":
+                return "请求超时";
+            case "400":
+                return "服务器不支持请求的语法";
+            case "401":
+                return "未授权";
+            case "403":
+                return "服务器禁止请求";
+            case "404":
+                return "服务器找不到";
+            default:
+                return "未知错误";
+        }
+    }
+
+}

+ 7 - 0
android_bed/src/main/h5_3128/res/anim/slide_down_in.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate
+        android:fromYDelta="100%p"
+        android:toYDelta="0%p"
+        android:duration="300"/>
+</set>

+ 7 - 0
android_bed/src/main/h5_3128/res/anim/slide_left_in.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate
+        android:fromXDelta="-100%p"
+        android:toXDelta="0%p"
+        android:duration="300"/>
+</set>

+ 7 - 0
android_bed/src/main/h5_3128/res/anim/slide_right_out.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate
+        android:fromXDelta="0%p"
+        android:toXDelta="100%p"
+        android:duration="300"/>
+</set>

+ 7 - 0
android_bed/src/main/h5_3128/res/anim/slide_up_out.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate
+        android:fromYDelta="0%p"
+        android:toYDelta="-100%p"
+        android:duration="300"/>
+</set>

File diff ditekan karena terlalu besar
+ 34 - 0
android_bed/src/main/h5_3128/res/drawable-v24/ic_launcher_foreground.xml


TEMPAT SAMPAH
android_bed/src/main/h5_3128/res/drawable/ic_answer_normal.png


TEMPAT SAMPAH
android_bed/src/main/h5_3128/res/drawable/ic_answer_press.png


TEMPAT SAMPAH
android_bed/src/main/h5_3128/res/drawable/ic_hangup_normal.png


TEMPAT SAMPAH
android_bed/src/main/h5_3128/res/drawable/ic_hangup_press.png


+ 170 - 0
android_bed/src/main/h5_3128/res/drawable/ic_launcher_background.xml

@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+    <path
+        android:fillColor="#008577"
+        android:pathData="M0,0h108v108h-108z" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M9,0L9,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,0L19,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,0L29,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,0L39,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,0L49,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,0L59,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,0L69,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,0L79,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M89,0L89,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M99,0L99,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,9L108,9"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,19L108,19"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,29L108,29"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,39L108,39"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,49L108,49"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,59L108,59"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,69L108,69"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,79L108,79"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,89L108,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,99L108,99"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,29L89,29"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,39L89,39"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,49L89,49"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,59L89,59"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,69L89,69"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,79L89,79"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,19L29,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,19L39,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,19L49,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,19L59,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,19L69,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,19L79,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+</vector>

TEMPAT SAMPAH
android_bed/src/main/h5_3128/res/drawable/ic_nurse.png


+ 5 - 0
android_bed/src/main/h5_3128/res/drawable/selector_bottom_btn_text_color.xml

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

+ 5 - 0
android_bed/src/main/h5_3128/res/drawable/selector_call.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="@mipmap/ic_call_p" android:state_pressed="true"/>
+    <item android:drawable="@mipmap/ic_call_n"/>
+</selector>

+ 5 - 0
android_bed/src/main/h5_3128/res/drawable/selector_call_answer.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/ic_answer_press" android:state_pressed="true"/>
+    <item android:drawable="@drawable/ic_answer_normal"/>
+</selector>

+ 5 - 0
android_bed/src/main/h5_3128/res/drawable/selector_call_end.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="@mipmap/ic_hangup_press" android:state_pressed="true"/>
+    <item android:drawable="@mipmap/ic_hangup_normal"/>
+</selector>

+ 5 - 0
android_bed/src/main/h5_3128/res/drawable/selector_call_hangup.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/ic_hangup_press" android:state_pressed="true"/>
+    <item android:drawable="@drawable/ic_hangup_normal"/>
+</selector>

+ 5 - 0
android_bed/src/main/h5_3128/res/drawable/selector_cost.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="@mipmap/ic_cost_p" android:state_pressed="true"/>
+    <item android:drawable="@mipmap/ic_cost_n"/>
+</selector>

+ 5 - 0
android_bed/src/main/h5_3128/res/drawable/selector_doctor.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="@mipmap/ic_doctor_p" android:state_pressed="true"/>
+    <item android:drawable="@mipmap/ic_doctor_n"/>
+</selector>

+ 5 - 0
android_bed/src/main/h5_3128/res/drawable/selector_main.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="@color/right_item_select" android:state_pressed="true"/>
+    <item android:drawable="@color/right_item_bg"/>
+</selector>

+ 5 - 0
android_bed/src/main/h5_3128/res/drawable/selector_qr_code.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="@mipmap/ic_qr_code_p" android:state_pressed="true"/>
+    <item android:drawable="@mipmap/ic_qr_code_n"/>
+</selector>

+ 5 - 0
android_bed/src/main/h5_3128/res/drawable/selector_support.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="@mipmap/ic_support_p" android:state_pressed="true"/>
+    <item android:drawable="@mipmap/ic_support_n"/>
+</selector>

+ 7 - 0
android_bed/src/main/h5_3128/res/drawable/shape_bed_name_bg.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#FFFFFF"/>
+    <corners
+        android:bottomRightRadius="10dp"
+        android:bottomLeftRadius="10dp" />
+</shape>

+ 7 - 0
android_bed/src/main/h5_3128/res/drawable/shape_bed_num_bg.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#FBE5E8"/>
+    <corners
+        android:topLeftRadius="10dp"
+        android:topRightRadius="10dp" />
+</shape>

+ 7 - 0
android_bed/src/main/h5_3128/res/drawable/shape_circle_bg.xml

@@ -0,0 +1,7 @@
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval">
+    <solid android:color="#C823BE"/>
+    <size
+        android:height="20dp"
+        android:width="20dp"/>
+</shape>

+ 7 - 0
android_bed/src/main/h5_3128/res/drawable/shape_circle_bg_age.xml

@@ -0,0 +1,7 @@
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval">
+    <solid android:color="#E85E5B"/>
+    <size
+        android:height="20dp"
+        android:width="20dp"/>
+</shape>

+ 8 - 0
android_bed/src/main/h5_3128/res/drawable/shape_cost_bg.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#FFFFFF"/>
+    <corners android:topLeftRadius="10dp"
+                android:topRightRadius="10dp"
+                android:bottomRightRadius="10dp"
+                android:bottomLeftRadius="10dp" />
+</shape>

+ 7 - 0
android_bed/src/main/h5_3128/res/drawable/shape_cost_list_title_bg.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#FBE5E8"/>
+    <corners android:topLeftRadius="10dp"
+        android:topRightRadius="10dp"
+        />
+</shape>

+ 7 - 0
android_bed/src/main/h5_3128/res/drawable/shape_mai_bg_doctor_title.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#D4676A"/>
+    <corners
+        android:topLeftRadius="5dp"
+        android:topRightRadius="5dp" />
+</shape>

+ 14 - 0
android_bed/src/main/h5_3128/res/drawable/shape_main_bg_admission.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#FBE5E8"/>
+    <corners android:topLeftRadius="3dp"
+        android:topRightRadius="3dp"
+        android:bottomRightRadius="3dp"
+        android:bottomLeftRadius="3dp"
+        />
+    <stroke
+        android:dashGap="2dp"
+        android:dashWidth="1dp"
+        android:width="1dp"
+        android:color="#8B8B8B" />
+</shape>

+ 6 - 0
android_bed/src/main/h5_3128/res/drawable/shape_main_bg_bottom_broadcasting.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/transparent"/>
+    <corners android:bottomRightRadius="2dp" />
+
+</shape>

+ 7 - 0
android_bed/src/main/h5_3128/res/drawable/shape_main_bg_doctor_bottom.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#D4676A"/>
+    <corners
+        android:bottomRightRadius="5dp"
+        android:bottomLeftRadius="5dp" />
+</shape>

+ 42 - 0
android_bed/src/main/h5_3128/res/layout/call_care_view.xml

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout>
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="#FCADB1"
+        android:orientation="vertical">
+
+
+        <ImageView
+            android:id="@+id/view_call_layout_iv_pic"
+            android:layout_width="200dp"
+            android:layout_height="200dp"
+            android:layout_gravity="center"
+            android:layout_marginTop="80dp"
+            android:gravity="center"
+            android:src="@mipmap/ic_call_calling"
+            android:textColor="@color/white"
+            android:textSize="20sp" />
+
+        <TextView
+            android:id="@+id/view_call_layout_tv_call_text"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:layout_marginTop="10dp"
+            android:gravity="center"
+            android:text="正在呼叫护工..."
+            android:textColor="@color/white"
+            android:textSize="@dimen/font_size_30" />
+
+        <TextView
+            android:id="@+id/view_call_layout_tv_call_timeout"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:layout_marginTop="10dp"
+            android:gravity="center"
+            android:text=""
+            android:textColor="@color/white"
+            android:textSize="@dimen/font_size_30" />
+
+    </LinearLayout>
+</layout>

+ 40 - 0
android_bed/src/main/h5_3128/res/layout/call_nurse_view.xml

@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout>
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="#FCADB1"
+        android:orientation="vertical">
+
+        <ImageView
+            android:id="@+id/view_nurse_layout_iv_pic"
+            android:layout_width="200dp"
+            android:layout_height="200dp"
+            android:layout_gravity="center"
+            android:layout_marginTop="80dp"
+            android:gravity="center"
+            android:src="@mipmap/ic_nurse_call"
+            android:textColor="@color/white"
+            android:textSize="20sp" />
+
+        <TextView
+            android:id="@+id/view_nurse_layout_tv_call_text"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:layout_marginTop="10dp"
+            android:gravity="center"
+            android:text="@string/call_in_calling"
+            android:textColor="@color/white"
+            android:textSize="@dimen/font_size_30" />
+
+        <TextView
+            android:id="@+id/view_nurse_layout_tv_call_timeout"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:layout_marginTop="10dp"
+            android:gravity="center"
+            android:text=""
+            android:textColor="@color/white"
+            android:textSize="@dimen/font_size_30" />
+    </LinearLayout>
+</layout>

+ 253 - 0
android_bed/src/main/h5_3128/res/layout/callingbed_main_lay.xml

@@ -0,0 +1,253 @@
+<?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:background="#EAF2F9">
+
+        <include
+            android:id="@+id/activity_calling_bed_layout_title"
+            layout="@layout/view_title_layout"/>
+
+        <LinearLayout
+            android:id="@+id/rl_left_view"
+            android:layout_width="188dp"
+            android:layout_height="match_parent"
+            android:layout_below="@id/activity_calling_bed_layout_title"
+            android:layout_marginTop="4dp"
+            android:paddingLeft="4dp"
+            android:paddingRight="4dp">
+
+            <!--左侧护理列表-->
+            <android.support.v7.widget.RecyclerView
+                android:id="@+id/rv_left_list"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent" />
+
+        </LinearLayout>
+
+        <!--右侧fragment区域-->
+        <FrameLayout
+            android:id="@+id/callingbed_main_frame"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginTop="10dp"
+            android:layout_marginBottom="2dp"
+            android:layout_marginRight="10dp"
+            android:layout_toRightOf="@id/rl_left_view"
+            android:layout_below="@id/activity_calling_bed_layout_title" />
+
+        <LinearLayout
+            android:id="@+id/ll_broadcast_view"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_toRightOf="@id/rl_left_view"
+            android:layout_alignParentBottom="true"
+            android:layout_marginRight="10dp"
+            android:layout_marginBottom="10dp"
+            android:padding="10dp"
+            android:gravity="center"
+            android:background="@color/trans_bg_color"
+            android:visibility="gone">
+
+            <com.wdkl.ncs.android.lib.widget.MarqueeTextView
+                android:layout_width="160dp"
+                android:layout_height="wrap_content"
+                android:ellipsize="marquee"
+                android:focusable="true"
+                android:focusableInTouchMode="true"
+                android:marqueeRepeatLimit="-1"
+                android:singleLine="true"
+                android:text="正在广播中......"
+                android:textSize="32sp"
+                android:textColor="@color/title_text"/>
+        </LinearLayout>
+
+        <!--通话界面-->
+        <FrameLayout
+            android:id="@+id/call_frame"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+
+        <!--呼叫状态显示-->
+        <LinearLayout
+            android:id="@+id/ll_call_view"
+            android:layout_width="match_parent"
+            android:layout_height="86dp"
+            android:layout_marginTop="10dp"
+            android:layout_marginBottom="10dp"
+            android:layout_marginRight="10dp"
+            android:layout_toRightOf="@id/rl_left_view"
+            android:layout_below="@id/activity_calling_bed_layout_title"
+            android:background="#37C127"
+            android:gravity="center_vertical"
+            android:visibility="gone">
+
+            <com.wdkl.ncs.android.lib.widget.MarqueeTextView
+                android:id="@+id/tv_call_bed_name"
+                android:layout_width="200dp"
+                android:layout_height="match_parent"
+                android:gravity="center"
+                android:ellipsize="marquee"
+                android:focusable="true"
+                android:focusableInTouchMode="true"
+                android:marqueeRepeatLimit="-1"
+                android:singleLine="true"
+                android:textColor="@color/white"
+                android:textSize="48sp"/>
+
+            <com.wdkl.ncs.android.lib.widget.MarqueeTextView
+                android:id="@+id/tv_call_state"
+                android:layout_width="200dp"
+                android:layout_height="match_parent"
+                android:paddingLeft="10dp"
+                android:paddingRight="10dp"
+                android:gravity="center"
+                android:ellipsize="marquee"
+                android:focusable="true"
+                android:focusableInTouchMode="true"
+                android:marqueeRepeatLimit="-1"
+                android:singleLine="true"
+                android:textColor="@color/red_color"
+                android:textSize="32sp" />
+
+            <Chronometer
+                android:id="@+id/voice_call_timer_view"
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:layout_marginLeft="20dp"
+                android:gravity="center"
+                android:text="00:00"
+                android:textColor="@color/white"
+                android:textSize="20sp" />
+
+            <ImageView
+                android:id="@+id/iv_call_end"
+                android:layout_width="60dp"
+                android:layout_height="60dp"
+                android:layout_marginLeft="20dp"
+                android:src="@drawable/selector_call_end"
+                android:scaleType="centerInside"/>
+        </LinearLayout>
+
+
+        <LinearLayout
+            android:id="@+id/right_menu"
+            android:layout_width="140dp"
+            android:layout_height="match_parent"
+            android:layout_alignParentRight="true"
+            android:background="@mipmap/bg_right"
+            android:orientation="vertical"
+            android:paddingTop="20dp"
+            android:paddingLeft="6dp"
+            android:paddingRight="6dp"
+            android:visibility="gone">
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1">
+
+                <TextView
+                    android:id="@+id/activity_calling_bed_layout_tv_doctor_text"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:paddingLeft="14dp"
+                    android:paddingTop="10dp"
+                    android:paddingBottom="10dp"
+                    android:background="@mipmap/bg_bottom_btn"
+                    android:drawableLeft="@mipmap/ic_home"
+                    android:drawablePadding="4dp"
+                    android:text="@string/str_home"
+                    android:textColor="@drawable/selector_bottom_btn_text_color"
+                    android:textSize="24sp"/>
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1" >
+
+                <TextView
+                    android:id="@+id/activity_calling_bed_layout_tv_cost_text"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:paddingLeft="14dp"
+                    android:paddingTop="10dp"
+                    android:paddingBottom="10dp"
+                    android:background="@mipmap/bg_bottom_btn"
+                    android:drawableLeft="@mipmap/ic_cost"
+                    android:drawablePadding="4dp"
+                    android:text="@string/str_fees"
+                    android:textColor="@drawable/selector_bottom_btn_text_color"
+                    android:textSize="24sp"/>
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1">
+
+                <TextView
+                    android:id="@+id/activity_calling_bed_layout_tv_qr_code_text"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:paddingLeft="14dp"
+                    android:paddingTop="10dp"
+                    android:paddingBottom="10dp"
+                    android:background="@mipmap/bg_bottom_btn"
+                    android:drawableLeft="@mipmap/ic_more"
+                    android:drawablePadding="4dp"
+                    android:text="@string/str_more"
+                    android:textColor="@drawable/selector_bottom_btn_text_color"
+                    android:textSize="24sp"/>
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1">
+
+                <TextView
+                    android:id="@+id/activity_calling_bed_layout_tv_support_text"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:paddingLeft="14dp"
+                    android:paddingTop="10dp"
+                    android:paddingBottom="10dp"
+                    android:background="@mipmap/bg_bottom_btn"
+                    android:drawableLeft="@mipmap/ic_support"
+                    android:drawablePadding="4dp"
+                    android:text="@string/str_support"
+                    android:textColor="@drawable/selector_bottom_btn_text_color"
+                    android:textSize="24sp"/>
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1">
+
+                <TextView
+                    android:id="@+id/activity_calling_bed_layout_tv_call_text"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:paddingLeft="14dp"
+                    android:paddingTop="10dp"
+                    android:paddingBottom="10dp"
+                    android:background="@mipmap/bg_bottom_btn"
+                    android:drawableLeft="@mipmap/ic_call"
+                    android:drawablePadding="4dp"
+                    android:text="@string/str_call"
+                    android:textColor="@drawable/selector_bottom_btn_text_color"
+                    android:textSize="24sp"/>
+
+            </LinearLayout>
+        </LinearLayout>
+
+    </RelativeLayout>
+</layout>

+ 14 - 0
android_bed/src/main/h5_3128/res/layout/cost_view.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout>
+    <LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <android.support.v7.widget.RecyclerView
+            android:id="@+id/rv_cost_main_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginBottom="6dp"/>
+    </LinearLayout>
+</layout>

+ 17 - 0
android_bed/src/main/h5_3128/res/layout/digital_item.xml

@@ -0,0 +1,17 @@
+<?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="match_parent">
+
+    <TextView
+        android:id="@+id/tv_number"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@color/color_gray"
+        android:layout_margin="4dp"
+        android:padding="10dp"
+        android:gravity="center"
+        android:textSize="32sp"
+        android:textColor="@color/main_color"/>
+
+</LinearLayout>

+ 75 - 0
android_bed/src/main/h5_3128/res/layout/doctor_order_view.xml

@@ -0,0 +1,75 @@
+<?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:background="@mipmap/bg_main"
+        android:orientation="vertical">
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginBottom="@dimen/font_size_20"
+            android:layout_marginLeft="@dimen/font_size_20"
+            android:layout_marginRight="@dimen/font_size_20"
+            android:layout_marginTop="@dimen/font_size_20"
+            android:background="@drawable/shape_cost_bg"
+            android:orientation="vertical">
+
+            <RelativeLayout
+                android:id="@+id/view_doctor_layout_rl_title"
+                android:layout_width="match_parent"
+                android:layout_height="50dp"
+                android:background="@drawable/shape_cost_list_title_bg">
+
+                <TextView
+                    android:id="@+id/view_doctor_tv_name"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_centerVertical="true"
+                    android:layout_marginLeft="20dp"
+                    android:text="--"
+                    android:textColor="#FF5963"
+                    android:textSize="@dimen/font_size_25"
+                    android:textStyle="bold" />
+
+                <TextView
+                    android:id="@+id/view_doctor_tv_inpatient_num"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_alignParentRight="true"
+                    android:layout_centerVertical="true"
+                    android:layout_marginLeft="20dp"
+                    android:layout_marginRight="50dp"
+                    android:text="--"
+                    android:textColor="#FF5963"
+                    android:textSize="@dimen/font_size_25"
+                    android:textStyle="bold" />
+            </RelativeLayout>
+
+            <android.support.v7.widget.RecyclerView
+                android:id="@+id/view_doctor_layout_rv_doctor"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_above="@+id/view_doctor_layout_tv_text"
+                android:layout_below="@+id/view_doctor_layout_rl_title"/>
+
+            <TextView
+                android:id="@+id/view_doctor_layout_tv_text"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentBottom="true"
+                android:layout_centerHorizontal="true"
+                android:layout_gravity="center"
+                android:layout_marginBottom="@dimen/margin_to_side_5"
+                android:layout_marginTop="@dimen/margin_to_side_5"
+                android:background="@drawable/shape_main_bg_admission"
+                android:padding="@dimen/margin_to_side_5"
+                android:paddingLeft="@dimen/margin_to_side_10"
+                android:paddingRight="@dimen/margin_to_side_10"
+                android:text="               更多信息请按右侧按键扫描二维码               "
+                android:textColor="#FF5963"
+                android:textSize="@dimen/font_size_20" />
+        </RelativeLayout>
+    </RelativeLayout>
+</layout>

+ 36 - 0
android_bed/src/main/h5_3128/res/layout/init_lay.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout>
+    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/activity_init_layout_rl"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <ImageView
+            android:id="@+id/iv_net_err"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:layout_centerHorizontal="true"
+            android:src="@mipmap/msg_network" />
+
+        <Button
+            android:id="@+id/btn_init_refresh"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:layout_below="@id/iv_net_err"
+            android:layout_centerHorizontal="true"
+            android:text="重新加载"/>
+
+        <TextView
+            android:id="@+id/tv_init_msg"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:layout_below="@id/btn_init_refresh"
+            android:layout_centerHorizontal="true"
+            android:text="正在初始化"
+            android:textSize="24sp" />
+
+    </RelativeLayout>
+</layout>

+ 39 - 0
android_bed/src/main/h5_3128/res/layout/item_cost_detail.xml

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_marginTop="10dp">
+
+    <TextView
+        android:id="@+id/tv_item_cost_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="20sp"
+        android:textColor="@color/black"/>
+    <TextView
+        android:id="@+id/tv_item_cost_value"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentRight="true"
+        android:textSize="20sp"
+        android:textColor="@color/black"/>
+    <TextView
+        android:id="@+id/tv_item_cost_id"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/tv_item_cost_name"
+        android:layout_marginTop="8dp"
+        android:textSize="20sp"
+        android:textColor="#A4A4A4"/>
+    <TextView
+        android:id="@+id/tv_item_cost_unit"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentRight="true"
+        android:layout_below="@id/tv_item_cost_value"
+        android:layout_marginTop="8dp"
+        android:textSize="20sp"
+        android:textColor="#A4A4A4"/>
+
+</RelativeLayout>

+ 38 - 0
android_bed/src/main/h5_3128/res/layout/item_cost_main_view.xml

@@ -0,0 +1,38 @@
+<?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="wrap_content"
+    android:padding="16dp"
+    android:layout_marginBottom="10dp"
+    android:orientation="vertical"
+    android:background="@color/white">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <TextView
+            android:id="@+id/tv_cost_group_name"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text=""
+            android:textColor="@color/main_color"
+            android:textSize="24sp"/>
+        <TextView
+            android:id="@+id/tv_cost_group_total"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:gravity="right"
+            android:text=""
+            android:textColor="@color/main_color"
+            android:textSize="24sp"/>
+    </LinearLayout>
+
+    <android.support.v7.widget.RecyclerView
+        android:id="@+id/rv_cost_detail"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"/>
+
+</LinearLayout>

+ 44 - 0
android_bed/src/main/h5_3128/res/layout/item_nurse_config.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/ll_nurse_item"
+    android:layout_width="match_parent"
+    android:layout_height="80dp"
+    android:layout_marginTop="6dp"
+    android:background="#E7E7E7"
+    android:orientation="vertical">
+
+    <!--<TextView
+        android:id="@+id/tv_nurse_color"
+        android:layout_width="8dp"
+        android:layout_height="match_parent"
+        android:background="@color/main_color"/>-->
+
+    <TextView
+        android:id="@+id/tv_nurse_config_name"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        android:paddingLeft="6dp"
+        android:paddingTop="6dp"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:text="@string/default_nurse_config_name"
+        android:textSize="20sp"
+        android:textColor="@color/white"/>
+
+    <TextView
+        android:id="@+id/tv_nurse_config_value"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        android:paddingRight="6dp"
+        android:paddingBottom="6dp"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:gravity="right|bottom"
+        android:text="@string/str_empty"
+        android:textSize="22sp"
+        android:textColor="@color/white"/>
+
+</LinearLayout>

+ 83 - 0
android_bed/src/main/h5_3128/res/layout/language_set_dialog.xml

@@ -0,0 +1,83 @@
+<?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="match_parent"
+    android:padding="20dp"
+    android:gravity="center"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/tv_language_title"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="10dp"
+        android:text="@string/language_set_mode"
+        android:textSize="24sp" />
+
+    <RadioGroup
+        android:id="@+id/group_language_mode"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="10dp"
+        android:orientation="horizontal">
+        <RadioButton
+            android:id="@+id/rb_language_yes"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/str_yes"/>
+        <RadioButton
+            android:id="@+id/rb_language_no"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="4dp"
+            android:text="@string/str_no"/>
+    </RadioGroup>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="20dp"
+        android:orientation="vertical">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:text="@string/language_set_title"
+            android:textSize="24sp" />
+
+        <Spinner
+            android:id="@+id/spinner_language_select"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="60dp"
+        android:gravity="center_horizontal">
+        <Button
+            android:id="@+id/confirm_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:background="@mipmap/bg_bottom_btn"
+            android:padding="8dp"
+            android:text="@string/str_confirm"
+            android:textSize="20sp"
+            android:textColor="@drawable/selector_bottom_btn_text_color"/>
+
+        <Button
+            android:id="@+id/cancel_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="80dp"
+            android:background="@mipmap/bg_bottom_btn"
+            android:padding="8dp"
+            android:text="@string/str_cancel"
+            android:textSize="20sp"
+            android:textColor="@drawable/selector_bottom_btn_text_color"/>
+    </LinearLayout>
+
+</LinearLayout>

+ 318 - 0
android_bed/src/main/h5_3128/res/layout/main_view.xml

@@ -0,0 +1,318 @@
+<?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">
+
+        <include android:id="@+id/lay_main_bed_name"
+            layout="@layout/view_bed_name"/>
+
+        <LinearLayout
+            android:id="@+id/ll_doctor_nurse_view"
+            android:layout_width="140dp"
+            android:layout_height="match_parent"
+            android:layout_below="@id/lay_main_bed_name"
+            android:layout_alignParentRight="true"
+            android:layout_marginTop="6dp"
+            android:layout_marginBottom="6dp"
+            android:orientation="vertical">
+            <!--责任医生-->
+            <LinearLayout
+                android:id="@+id/ll_doctor_view"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:gravity="center_horizontal"
+                android:orientation="vertical"
+                android:background="@color/white">
+                <ImageView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="12dp"
+                    android:src="@mipmap/ic_doctor_default"/>
+                <TextView
+                    android:id="@+id/tv_doctor_title"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="8dp"
+                    android:textColor="#B4B4B4"
+                    android:textSize="18sp"
+                    android:text="@string/doctor_title"/>
+                <TextView
+                    android:id="@+id/tv_doctor_name"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="4dp"
+                    android:textColor="@color/black"
+                    android:textSize="18sp"
+                    android:text="@string/str_empty"/>
+            </LinearLayout>
+
+            <!--责任护士-->
+            <LinearLayout
+                android:id="@+id/ll_nurse_view"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:layout_marginTop="10dp"
+                android:gravity="center_horizontal"
+                android:orientation="vertical"
+                android:background="@color/white">
+                <ImageView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="12dp"
+                    android:src="@mipmap/ic_nurse_default"/>
+                <TextView
+                    android:id="@+id/tv_nurse_title"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="8dp"
+                    android:textColor="#B4B4B4"
+                    android:textSize="18sp"
+                    android:text="@string/nurse_title"/>
+                <TextView
+                    android:id="@+id/tv_nurse_name"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="4dp"
+                    android:textColor="@color/black"
+                    android:textSize="18sp"
+                    android:text="@string/str_empty"/>
+            </LinearLayout>
+        </LinearLayout>
+
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_below="@id/lay_main_bed_name"
+            android:layout_toLeftOf="@id/ll_doctor_nurse_view"
+            android:layout_marginTop="6dp"
+            android:layout_marginRight="10dp"
+            android:layout_marginBottom="6dp">
+            <!--无人入住时展示-->
+            <LinearLayout
+                android:id="@+id/ll_empty"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:padding="12dp"
+                android:background="@mipmap/bg_empty_info"
+                android:orientation="vertical">
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="10dp"
+                    android:text="-"
+                    android:textSize="48sp"
+                    android:textColor="@color/main_color"
+                    android:visibility="invisible"/>
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="24dp"
+                    android:text="@string/empty_title"
+                    android:textSize="56sp"
+                    android:textColor="@color/black"/>
+            </LinearLayout>
+
+            <!--有人入住时展示-->
+            <RelativeLayout
+                android:id="@+id/ll_custom_view"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:paddingTop="10dp"
+                android:paddingLeft="12dp"
+                android:paddingRight="12dp"
+                android:background="@color/white"
+                android:orientation="vertical"
+                android:visibility="gone">
+
+                <LinearLayout
+                    android:id="@+id/ll_nurse_more"
+                    android:layout_width="match_parent"
+                    android:layout_height="80dp"
+                    android:layout_marginTop="6dp"
+                    android:layout_alignParentBottom="true"
+                    android:gravity="center_horizontal"
+                    android:visibility="gone">
+                    <LinearLayout
+                        android:id="@+id/ll_nurse_item6"
+                        android:layout_width="140dp"
+                        android:layout_height="match_parent"
+                        android:background="#E7E7E7"
+                        android:orientation="vertical">
+                        <TextView
+                            android:id="@+id/tv_nurse_name6"
+                            android:layout_width="match_parent"
+                            android:layout_height="0dp"
+                            android:layout_weight="1"
+                            android:paddingLeft="6dp"
+                            android:paddingTop="6dp"
+                            android:singleLine="true"
+                            android:ellipsize="end"
+                            android:text="@string/default_nurse_config_name"
+                            android:textSize="20sp"
+                            android:textColor="@color/white"/>
+
+                        <TextView
+                            android:id="@+id/tv_nurse_value6"
+                            android:layout_width="match_parent"
+                            android:layout_height="0dp"
+                            android:layout_weight="1"
+                            android:paddingRight="6dp"
+                            android:paddingBottom="6dp"
+                            android:singleLine="true"
+                            android:ellipsize="end"
+                            android:gravity="right|bottom"
+                            android:text="@string/str_empty"
+                            android:textSize="22sp"
+                            android:textColor="@color/white"/>
+                    </LinearLayout>
+
+                    <LinearLayout
+                        android:id="@+id/ll_nurse_item7"
+                        android:layout_width="140dp"
+                        android:layout_height="match_parent"
+                        android:layout_marginLeft="10dp"
+                        android:background="#E7E7E7"
+                        android:orientation="vertical">
+                        <TextView
+                            android:id="@+id/tv_nurse_name7"
+                            android:layout_width="match_parent"
+                            android:layout_height="0dp"
+                            android:layout_weight="1"
+                            android:paddingLeft="6dp"
+                            android:paddingTop="6dp"
+                            android:singleLine="true"
+                            android:ellipsize="end"
+                            android:text="@string/default_nurse_config_name"
+                            android:textSize="20sp"
+                            android:textColor="@color/white"/>
+
+                        <TextView
+                            android:id="@+id/tv_nurse_value7"
+                            android:layout_width="match_parent"
+                            android:layout_height="0dp"
+                            android:layout_weight="1"
+                            android:paddingRight="6dp"
+                            android:paddingBottom="6dp"
+                            android:singleLine="true"
+                            android:ellipsize="end"
+                            android:gravity="right|bottom"
+                            android:text="@string/str_empty"
+                            android:textSize="22sp"
+                            android:textColor="@color/white"/>
+                    </LinearLayout>
+
+                    <LinearLayout
+                        android:id="@+id/ll_nurse_item8"
+                        android:layout_width="140dp"
+                        android:layout_height="match_parent"
+                        android:layout_marginLeft="10dp"
+                        android:background="#E7E7E7"
+                        android:orientation="vertical">
+                        <TextView
+                            android:id="@+id/tv_nurse_name8"
+                            android:layout_width="match_parent"
+                            android:layout_height="0dp"
+                            android:layout_weight="1"
+                            android:paddingLeft="6dp"
+                            android:paddingTop="6dp"
+                            android:singleLine="true"
+                            android:ellipsize="end"
+                            android:text="@string/default_nurse_config_name"
+                            android:textSize="20sp"
+                            android:textColor="@color/white"/>
+
+                        <TextView
+                            android:id="@+id/tv_nurse_value8"
+                            android:layout_width="match_parent"
+                            android:layout_height="0dp"
+                            android:layout_weight="1"
+                            android:paddingRight="6dp"
+                            android:paddingBottom="6dp"
+                            android:singleLine="true"
+                            android:ellipsize="end"
+                            android:gravity="right|bottom"
+                            android:text="@string/str_empty"
+                            android:textSize="22sp"
+                            android:textColor="@color/white"/>
+                    </LinearLayout>
+                </LinearLayout>
+
+                <TextView
+                    android:id="@+id/tv_custom_name"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textSize="60sp"
+                    android:textColor="@color/main_color"
+                    android:text="---"/>
+                <TextView
+                    android:id="@+id/tv_custom_gender"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_toRightOf="@id/tv_custom_name"
+                    android:layout_alignBottom="@id/tv_custom_name"
+                    android:background="@mipmap/ic_gender_male"
+                    android:layout_marginLeft="20dp"
+                    android:layout_marginBottom="10dp"/>
+                <TextView
+                    android:id="@+id/tv_custom_age"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_toRightOf="@id/tv_custom_gender"
+                    android:layout_alignBottom="@id/tv_custom_name"
+                    android:layout_marginLeft="20dp"
+                    android:textSize="40sp"
+                    android:textColor="#B4B4B4"
+                    android:text="--"/>
+                <TextView
+                    android:id="@+id/tv_custom_indate"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_below="@id/tv_custom_name"
+                    android:layout_marginTop="10dp"
+                    android:textSize="28sp"
+                    android:textColor="#B4B4B4"
+                    android:text="@string/indate"/>
+                <!--<TextView
+                    android:id="@+id/tv_order_title"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_below="@id/tv_custom_indate"
+                    android:layout_marginTop="20dp"
+                    android:padding="10dp"
+                    android:background="#F3F9FE"
+                    android:drawableLeft="@mipmap/ic_order"
+                    android:drawablePadding="10dp"
+                    android:textSize="24sp"
+                    android:textColor="@color/black"
+                    android:text=""/>-->
+                <com.wdkl.ncs.android.lib.widget.MarqueeTextView
+                    android:id="@+id/tv_order_content"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:layout_below="@id/tv_custom_indate"
+                    android:layout_above="@id/ll_nurse_more"
+                    android:layout_marginTop="8dp"
+                    android:padding="10dp"
+                    android:ellipsize="marquee"
+                    android:focusable="true"
+                    android:focusableInTouchMode="true"
+                    android:marqueeRepeatLimit="marquee_forever"
+                    android:scrollHorizontally="true"
+                    android:singleLine="true"
+                    android:background="#F3F9FE"
+                    android:scrollbars="vertical"
+                    android:fadeScrollbars="true"
+                    android:textSize="24sp"
+                    android:textColor="#131313"
+                    android:text="@string/str_empty"
+                    android:lineSpacingExtra="12dp"/>
+            </RelativeLayout>
+        </FrameLayout>
+
+    </RelativeLayout>
+</layout>

+ 67 - 0
android_bed/src/main/h5_3128/res/layout/main_view_layout.xml

@@ -0,0 +1,67 @@
+<?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:padding="20dp">
+
+    <!--<TextView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        android:text="Hello"
+        android:textSize="8sp"/>-->
+
+    <LinearLayout
+        android:id="@+id/ll_sip_name"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="本机SIP账号:"/>
+        <TextView
+            android:id="@+id/my_sip_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="10dp"
+            android:text=""/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:id="@+id/ll_sip_target"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/ll_sip_name">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="被叫SIP账号:" />
+
+        <EditText
+            android:id="@+id/edit_sip_target"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="" />
+    </LinearLayout>
+
+
+    <Button
+        android:id="@+id/btn_start"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_below="@id/ll_sip_target"
+        android:text="呼叫"/>
+
+    <Button
+        android:id="@+id/btn_end"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_below="@id/btn_start"
+        android:text="挂断" />
+
+</RelativeLayout>
+</layout>

+ 162 - 0
android_bed/src/main/h5_3128/res/layout/qrcode_view.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">
+
+        <include android:id="@+id/lay_qr_bed_name"
+            layout="@layout/view_bed_name"/>
+
+        <LinearLayout
+            android:id="@+id/ll_qr_code_view"
+            android:layout_width="340dp"
+            android:layout_height="match_parent"
+            android:layout_below="@id/lay_qr_bed_name"
+            android:layout_marginTop="6dp"
+            android:layout_marginBottom="6dp"
+            android:background="@color/white"
+            android:orientation="vertical">
+            <ImageView
+                android:id="@+id/view_qr_code"
+                android:layout_width="180dp"
+                android:layout_height="180dp"
+                android:layout_gravity="center_horizontal"/>
+
+            <TextView
+                android:id="@+id/tv_device_id"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="10dp"
+                android:text="ID:"
+                android:textColor="@color/black"
+                android:textSize="20sp" />
+
+            <TextView
+                android:id="@+id/tv_local_ip"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="4dp"
+                android:layout_marginLeft="10dp"
+                android:text="IP:"
+                android:textColor="@color/black"
+                android:textSize="20sp" />
+
+            <TextView
+                android:id="@+id/tv_local_mac"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="4dp"
+                android:layout_marginLeft="10dp"
+                android:text="MAC:"
+                android:textColor="@color/black"
+                android:textSize="20sp" />
+
+            <TextView
+                android:id="@+id/tv_app_version"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="4dp"
+                android:layout_marginLeft="10dp"
+                android:text="Version:"
+                android:textColor="@color/black"
+                android:textSize="20sp" />
+
+            <TextView
+                android:id="@+id/tv_mcu_version"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="4dp"
+                android:layout_marginLeft="10dp"
+                android:text="MCU:"
+                android:textColor="@color/black"
+                android:textSize="20sp" />
+        </LinearLayout>
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:background="@color/white"
+            android:layout_toRightOf="@id/ll_qr_code_view"
+            android:layout_below="@id/lay_qr_bed_name"
+            android:layout_marginTop="6dp"
+            android:layout_marginBottom="6dp"
+            android:layout_marginLeft="10dp"
+            android:padding="10dp"
+            android:orientation="vertical">
+            <LinearLayout
+                android:id="@+id/ll_device_action"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_alignParentBottom="true"
+                android:orientation="vertical">
+                <TextView
+                    android:id="@+id/tv_btn_language_setting"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:padding="4dp"
+                    android:background="@color/main_color"
+                    android:gravity="center_horizontal"
+                    android:text="@string/language_set_title"
+                    android:textColor="@drawable/selector_bottom_btn_text_color"
+                    android:textSize="20sp" />
+
+                <TextView
+                    android:id="@+id/tv_btn_reboot"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="10dp"
+                    android:padding="4dp"
+                    android:background="@color/main_color"
+                    android:gravity="center_horizontal"
+                    android:text="@string/reboot_device"
+                    android:textColor="@drawable/selector_bottom_btn_text_color"
+                    android:textSize="20sp" />
+
+                <TextView
+                    android:id="@+id/tv_btn_update_app"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="10dp"
+                    android:padding="4dp"
+                    android:background="@color/main_color"
+                    android:gravity="center_horizontal"
+                    android:text="@string/check_update"
+                    android:textColor="@drawable/selector_bottom_btn_text_color"
+                    android:textSize="20sp" />
+
+                <TextView
+                    android:id="@+id/tv_btn_server_config"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="10dp"
+                    android:padding="4dp"
+                    android:background="@color/main_color"
+                    android:gravity="center_horizontal"
+                    android:text="@string/server_config"
+                    android:textColor="@drawable/selector_bottom_btn_text_color"
+                    android:textSize="20sp"/>
+            </LinearLayout>
+
+            <TextView
+                android:id="@+id/tv_detail_title"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/product_desc"
+                android:textColor="@color/black"
+                android:textSize="22sp" />
+
+            <TextView
+                android:id="@+id/tv_about_me"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_below="@id/tv_detail_title"
+                android:layout_above="@id/ll_device_action"
+                android:layout_marginTop="10dp"
+                android:text="@string/str_empty"
+                android:textColor="#949494"
+                android:textSize="20sp" />
+        </RelativeLayout>
+
+    </RelativeLayout>
+</layout>

+ 189 - 0
android_bed/src/main/h5_3128/res/layout/server_config_dialog_lay.xml

@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <!--密码框-->
+    <LinearLayout
+        android:id="@+id/ll_password"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/tv_psw_view"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:textSize="24sp"
+            android:hint="@string/input_password"
+            android:textColor="@color/main_color"/>
+
+        <GridView
+            android:id="@+id/grid_psw"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:verticalSpacing="5dp"
+            android:horizontalSpacing="5dp"
+            android:numColumns="3"/>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="20dp"
+            android:orientation="horizontal">
+            <TextView
+                android:id="@+id/btn_delete"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:padding="4dp"
+                android:gravity="center_horizontal"
+                android:text="@string/str_delete"
+                android:textSize="24sp"
+                android:textColor="@color/main_color"/>
+
+            <TextView
+                android:id="@+id/btn_cancel"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:padding="4dp"
+                android:gravity="center_horizontal"
+                android:text="@string/str_cancel"
+                android:textSize="24sp"
+                android:textColor="@color/main_color"/>
+            <TextView
+                android:id="@+id/btn_confirm"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:padding="4dp"
+                android:gravity="center_horizontal"
+                android:text="@string/str_confirm"
+                android:textSize="24sp"
+                android:textColor="@color/main_color"/>
+        </LinearLayout>
+    </LinearLayout>
+
+
+    <!--服务器ip配置-->
+    <LinearLayout
+        android:id="@+id/ll_server_config"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginTop="20dp"
+        android:padding="10dp"
+        android:orientation="vertical"
+        android:visibility="gone">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:text="Server IP:"
+                android:textSize="20sp"
+                android:textColor="@color/main_color"/>
+
+            <EditText
+                android:id="@+id/edit_url"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="4dp"
+                android:inputType="textUri"
+                android:textSize="20sp"/>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:text="Port:"
+                android:textSize="20sp"
+                android:textColor="@color/main_color"/>
+
+            <EditText
+                android:id="@+id/edit_port"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="4dp"
+                android:inputType="number"
+                android:textSize="20sp"/>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:visibility="gone">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:text="Sip IP:"
+                android:textSize="20sp"
+                android:textColor="@color/main_color"/>
+
+            <EditText
+                android:id="@+id/edit_sip_url"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="4dp"
+                android:inputType="textUri"
+                android:textSize="20sp"/>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:visibility="gone">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:text="Sip port:"
+                android:textSize="20sp"
+                android:textColor="@color/main_color"/>
+
+            <EditText
+                android:id="@+id/edit_sip_port"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="4dp"
+                android:inputType="number"
+                android:textSize="20sp" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="20dp">
+            <TextView
+                android:id="@+id/btn_cancel_config"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:gravity="center"
+                android:text="@string/str_cancel"
+                android:textSize="28sp"
+                android:textColor="@color/black"/>
+
+            <TextView
+                android:id="@+id/btn_save_config"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:gravity="center"
+                android:text="@string/str_save"
+                android:textSize="28sp"
+                android:textColor="@color/black" />
+        </LinearLayout>
+    </LinearLayout>
+</RelativeLayout>

+ 136 - 0
android_bed/src/main/h5_3128/res/layout/sky_voice_call_layout.xml

@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout>
+    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@color/gray_deep">
+        <!--全屏视频画面-->
+        <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="140dp"
+            android:layout_height="180dp"
+            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">
+
+            <!--语音呼叫layout-->
+            <LinearLayout
+                android:id="@+id/ll_voice_call"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                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="100dp"
+                    android:scaleType="centerInside"
+                    android:src="@drawable/ic_nurse" />
+
+                <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="#9E9E9F"
+                    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="#9E9E9F"
+                    android:textSize="24sp" />
+            </LinearLayout>
+
+            <!--呼出-->
+            <LinearLayout
+                android:id="@+id/sky_voice_call_outgoing"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentBottom="true"
+                android:layout_centerHorizontal="true"
+                android:layout_marginBottom="40dp"
+                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"
+                    android:visibility="gone"/>
+
+                <ImageView
+                    android:id="@+id/sky_voice_call_hangup"
+                    android:layout_width="100dp"
+                    android:layout_height="100dp"
+                    android:layout_marginTop="20dp"
+                    android:src="@drawable/selector_call_hangup"
+                    android:visibility="gone"/>
+            </LinearLayout>
+
+            <!--来电-->
+            <LinearLayout
+                android:id="@+id/sky_voice_call_incoming"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_alignParentBottom="true"
+                android:layout_centerHorizontal="true"
+                android:layout_marginBottom="40dp"
+                android:gravity="bottom"
+                android:orientation="horizontal"
+                android:visibility="gone">
+
+                <View
+                    android:layout_width="0dp"
+                    android:layout_height="1dp"
+                    android:layout_weight="2" />
+
+                <ImageView
+                    android:id="@+id/sky_voice_call_ring_reject"
+                    android:layout_width="100dp"
+                    android:layout_height="100dp"
+                    android:src="@drawable/selector_call_hangup" />
+
+                <View
+                    android:layout_width="0dp"
+                    android:layout_height="1dp"
+                    android:layout_weight="1" />
+
+                <ImageView
+                    android:id="@+id/sky_voice_call_ring_pickup_audio"
+                    android:layout_width="100dp"
+                    android:layout_height="100dp"
+                    android:src="@drawable/selector_call_answer" />
+
+                <View
+                    android:layout_width="0dp"
+                    android:layout_height="1dp"
+                    android:layout_weight="2" />
+            </LinearLayout>
+        </RelativeLayout>
+    </FrameLayout>
+</layout>

+ 10 - 0
android_bed/src/main/h5_3128/res/layout/spinner_item.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:singleLine="true"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:gravity="center"
+    android:padding="4dp"
+    android:ellipsize="marquee"
+    android:textAlignment="inherit"
+    android:textSize="20sp"/>

+ 41 - 0
android_bed/src/main/h5_3128/res/layout/support_view.xml

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout>
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="#FCADB1"
+        android:orientation="vertical">
+
+        <ImageView
+            android:id="@+id/view_support_layout_iv_pic"
+            android:layout_width="200dp"
+            android:layout_height="200dp"
+            android:layout_gravity="center"
+            android:layout_marginTop="80dp"
+            android:gravity="center"
+            android:src="@mipmap/ic_nurse_calling"
+            android:textColor="@color/white"
+            android:textSize="20sp" />
+
+        <TextView
+            android:id="@+id/view_support_layout_tv_call_text"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:layout_marginTop="10dp"
+            android:gravity="center"
+            android:text="请求增援..."
+            android:textColor="@color/white"
+            android:textSize="@dimen/font_size_30" />
+
+        <TextView
+            android:id="@+id/view_support_layout_tv_call_timeout"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:layout_marginTop="10dp"
+            android:gravity="center"
+            android:text=""
+            android:textColor="@color/white"
+            android:textSize="@dimen/font_size_30" />
+
+    </LinearLayout>
+</layout>

+ 39 - 0
android_bed/src/main/h5_3128/res/layout/test_fragment_lay.xml

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout>
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:padding="10dp">
+
+    <!--<SurfaceView
+        android:id="@+id/camera_preview_surface"
+        android:layout_width="160dp"
+        android:layout_height="160dp" />
+
+    <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:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="10dp"
+        android:textSize="28sp"
+        android:text="请按任意按键开始测试"
+        android:textColor="@color/red_color"/>
+
+    <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>
+</layout>

+ 35 - 0
android_bed/src/main/h5_3128/res/layout/update_lay.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout>
+    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@color/white"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/activity_calling_bed_text_download"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerInParent="true"
+            android:text="@string/updating"
+            android:textColor="#3D3D63"
+            android:textSize="30sp" />
+
+        <com.wdkl.ncs.android.lib.widget.ProgressView
+            android:id="@+id/activity_appupdate_dialog_progressview"
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:layout_alignParentBottom="true"
+            android:layout_marginBottom="30dp"
+            android:layout_marginLeft="50dp"
+            android:layout_marginRight="50dp"
+            app:haveChangeColor="true"
+            app:isShowDesc="false"
+            app:max="100"
+            app:progress="0"
+            app:progressDesc="progress:"
+            app:progressRadius="10dp" />
+
+    </RelativeLayout>
+</layout>

+ 29 - 0
android_bed/src/main/h5_3128/res/layout/view_bed_name.xml

@@ -0,0 +1,29 @@
+<?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="80dp">
+
+    <TextView
+        android:id="@+id/tv_bed_name"
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:background="@color/white"
+        android:paddingLeft="24dp"
+        android:gravity="center_vertical"
+        android:textColor="@color/main_color"
+        android:textSize="54sp"
+        android:text=""/>
+
+    <TextView
+        android:id="@+id/tv_version"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:padding="6dp"
+        android:background="@color/white"
+        android:gravity="bottom"
+        android:textColor="@color/black"
+        android:textSize="16sp"
+        android:text="v--"/>
+</LinearLayout>

+ 51 - 0
android_bed/src/main/h5_3128/res/layout/view_message_layout.xml

@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/view_main_layout_rl_message"
+    android:layout_width="match_parent"
+    android:layout_height="54dp"
+    android:layout_alignParentBottom="true"
+    android:gravity="center_vertical"
+    android:orientation="horizontal">
+
+    <ImageView
+        android:id="@+id/view_main_iv_notice_logo"
+        android:layout_width="40dp"
+        android:layout_height="40dp"
+        android:layout_centerVertical="true"
+        android:layout_marginLeft="@dimen/margin_to_side_20"
+        android:src="@mipmap/ic_notice"
+        android:visibility="invisible" />
+
+    <com.wdkl.ncs.android.lib.widget.MarqueeTextView
+        android:id="@+id/view_main_layout_tv_msg"
+        android:layout_width="200dp"
+        android:layout_height="wrap_content"
+        android:layout_centerInParent="true"
+        android:layout_centerVertical="true"
+        android:layout_marginLeft="@dimen/margin_to_side_10"
+        android:layout_marginRight="@dimen/margin_to_side_20"
+        android:layout_toLeftOf="@+id/view_main_iv_logo"
+        android:layout_toRightOf="@+id/view_main_iv_notice_logo"
+        android:ellipsize="marquee"
+        android:focusable="true"
+        android:focusableInTouchMode="true"
+        android:marqueeRepeatLimit="marquee_forever"
+        android:scrollHorizontally="true"
+        android:singleLine="true"
+        android:textColor="#FCFF16"
+        android:textSize="24sp"
+        android:visibility="invisible"/>
+
+    <ImageView
+        android:id="@+id/view_main_iv_logo"
+        android:layout_width="120dp"
+        android:layout_height="100dp"
+        android:layout_alignParentRight="true"
+        android:layout_centerVertical="true"
+        android:layout_marginLeft="10dp"
+        android:layout_marginTop="10dp"
+        android:layout_marginRight="30dp"
+        android:layout_marginBottom="10dp"
+        android:src="@mipmap/ic_logo" />
+
+</RelativeLayout>

+ 102 - 0
android_bed/src/main/h5_3128/res/layout/view_title_layout.xml

@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="42dp"
+    android:background="#FFFFFF"
+    android:orientation="vertical">
+
+    <!--SIP状态图标-->
+    <TextView
+        android:id="@+id/view_title_layout_tv_point"
+        android:layout_width="12dp"
+        android:layout_height="12dp"
+        android:layout_centerVertical="true"
+        android:layout_marginLeft="20dp"
+        android:background="@color/red_color"/>
+
+    <!--医院名称-->
+    <TextView
+        android:id="@+id/view_title_layout_tv_hospital_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerVertical="true"
+        android:layout_marginLeft="20dp"
+        android:layout_toRightOf="@+id/view_title_layout_tv_point"
+        android:text="----"
+        android:textColor="@color/main_color"
+        android:textSize="@dimen/font_size_20" />
+
+    <!--日期时间-->
+    <TextClock
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_centerVertical="true"
+        android:format12Hour="yyyy-MM-dd HH:mm EEEE"
+        android:format24Hour="yyyy-MM-dd HH:mm EEEE"
+        android:textColor="@color/main_color"
+        android:textSize="@dimen/font_size_20" />
+
+    <!--设备号-->
+    <TextView
+        android:id="@+id/view_title_layout_tv_no"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerVertical="true"
+        android:layout_marginRight="4dp"
+        android:layout_toLeftOf="@+id/view_title_layout_ll_right"
+        android:text="ID:"
+        android:textColor="@color/main_color"
+        android:textSize="16sp" />
+
+    <!--状态图标-->
+    <LinearLayout
+        android:id="@+id/view_title_layout_ll_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">
+
+        <ImageView
+            android:id="@+id/view_title_layout_iv_bt"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            android:layout_gravity="center_vertical"
+            android:layout_marginLeft="4dp"
+            android:layout_marginRight="4dp"
+            android:visibility="gone"/>
+        <ImageView
+            android:id="@+id/view_title_layout_iv_wifi"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            android:layout_gravity="center_vertical"
+            android:layout_marginLeft="4dp"
+            android:layout_marginRight="4dp" />
+        <ImageView
+            android:id="@+id/view_title_layout_iv_tcp"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            android:layout_gravity="center_vertical"
+            android:layout_marginLeft="4dp"
+            android:layout_marginRight="4dp"
+            android:src="@mipmap/ic_tcp_fail"/>
+        <ImageView
+            android:id="@+id/view_title_layout_iv_ethernet"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            android:layout_gravity="center_vertical"
+            android:layout_marginLeft="4dp"
+            android:layout_marginRight="4dp" />
+        <ImageView
+            android:id="@+id/view_title_layout_iv_day_night"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            android:layout_gravity="center_vertical"
+            android:layout_marginLeft="4dp"
+            android:layout_marginRight="4dp"
+            android:src="@mipmap/ic_daylight"/>
+
+    </LinearLayout>
+</RelativeLayout>

+ 27 - 0
android_bed/src/main/h5_3128/res/layout/warning_dialog_lay.xml

@@ -0,0 +1,27 @@
+<?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="match_parent"
+    android:gravity="center"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/warnig_text"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="20dp"
+        android:padding="8dp"
+        android:text="@string/device_error"
+        android:textColor="@color/red_color"
+        android:textSize="32sp"
+        android:gravity="center" />
+
+    <Button
+        android:id="@+id/cancel_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="20dp"
+        android:padding="8dp"
+        android:text="@string/str_confirm" />
+</LinearLayout>

+ 5 - 0
android_bed/src/main/h5_3128/res/mipmap-anydpi-v26/ic_launcher.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>

+ 5 - 0
android_bed/src/main/h5_3128/res/mipmap-anydpi-v26/ic_launcher_round.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>

TEMPAT SAMPAH
android_bed/src/main/h5_3128/res/mipmap-hdpi/bg_main.png


+ 0 - 0
android_bed/src/main/h5_3128/res/mipmap-hdpi/bg_right.png


Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini