Bladeren bron

亿莱顿10寸探视机

weizhengliang 2 jaren geleden
bovenliggende
commit
0c73a66615
100 gewijzigde bestanden met toevoegingen van 5746 en 0 verwijderingen
  1. 4 0
      android_visiting/build.gradle
  2. BIN
      android_visiting/src/main/assets/wd_update_plugin.apk
  3. BIN
      android_visiting/src/main/assets/yunpai_launch_app.apk
  4. 76 0
      android_visiting/src/main/h10_yld_1h/AndroidManifest.xml
  5. 222 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/activity/AppUpdateActivity.kt
  6. 631 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/activity/HomeActivity.kt
  7. 56 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/adapter/NumAdapter.java
  8. 43 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/broadcast/BatteryBroadcastReceiver.java
  9. 22 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/broadcast/NetworkBroadcastReceiver.kt
  10. 21 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/broadcast/WdBootReceiver.java
  11. 13 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/common/Constants.kt
  12. 19 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/di/HomeComponent.kt
  13. 138 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/fragment/BaseCallFragment.kt
  14. 437 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/fragment/SkyCallFragment.kt
  15. 230 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/helper/AppUpdateHelper.java
  16. 192 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/helper/AsyncPlayer.java
  17. 161 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/helper/HttpHelper.java
  18. 64 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/helper/SerialPortHelper.java
  19. 27 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/launch/HomeLaunch.kt
  20. 113 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/service/TcpHandleService.kt
  21. 75 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/service/WdKeepAliveService.kt
  22. 61 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/settingconfig/SettingConfig.java
  23. 235 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/AnrFcExceptionUtil.java
  24. 123 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/AppUtils.java
  25. 89 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/CallDialogHelper.java
  26. 14 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/EthernetWifiCallBack.java
  27. 283 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/MediaPlayHelper.java
  28. 115 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/MediaPlayer.kt
  29. 638 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/NetHelper.java
  30. 27 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/RingPlayHelper.java
  31. 159 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/ServerConfigDialogHelper.java
  32. 203 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/SpeechUtil.java
  33. 30 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/TimeTransition.kt
  34. 159 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/Util.kt
  35. 184 0
      android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/VoiceManagerUtil.java
  36. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-hdpi/hu_jiao.png
  37. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-hdpi/hu_jiao_bg.png
  38. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-hdpi/wei_chu_li_bg.png
  39. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-hdpi/yi_chu_li_bg.png
  40. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-hdpi/yu_yin_wei_chu_li.png
  41. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/bao_ma_tou_xiang.png
  42. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/dian_liang.png
  43. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/geng_duo.png
  44. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/gu_ke_lie_biao.png
  45. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/hu_chu_wei_jie.png
  46. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/hu_chu_yi_jie.png
  47. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/hu_jiao.png
  48. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/hu_jiao_bg.png
  49. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/hu_ru_wei_jie.png
  50. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/hu_ru_yi_jie.png
  51. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/hu_shi_to_xiang.png
  52. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/ju_jie.png
  53. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/sip_lian_jie.png
  54. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/tong_hu_ji_lu.png
  55. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/wei_bo_fang.png
  56. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/wei_chu_li.png
  57. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/wei_chu_li_bg.png
  58. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/wifi_lian_jie.png
  59. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/yi_bo_fang.png
  60. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/yi_chu_li.png
  61. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/yi_chu_li_bg.png
  62. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/yu_yin_gua_duan.png
  63. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/yu_yin_jie_ting.png
  64. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/yu_yin_wei_chu_li.png
  65. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/zhe_die.png
  66. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable/av_handfree_hover.png
  67. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable/btn_back.png
  68. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable/ic_answer_normal.png
  69. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable/ic_answer_press.png
  70. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable/ic_hangup_normal.png
  71. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable/ic_hangup_press.png
  72. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable/ic_nurse.png
  73. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable/icon_hd_live.png
  74. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable/icon_hd_live_item.png
  75. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable/icon_switch_off.png
  76. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable/icon_switch_on.png
  77. 5 0
      android_visiting/src/main/h10_yld_1h/res/drawable/item_selector.xml
  78. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable/main_bg.png
  79. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable/main_bg_1280x800.jpg
  80. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable/main_bg_1920x1080.jpg
  81. BIN
      android_visiting/src/main/h10_yld_1h/res/drawable/main_bg_800x1280.png
  82. 6 0
      android_visiting/src/main/h10_yld_1h/res/drawable/round_button_100dp.xml
  83. 6 0
      android_visiting/src/main/h10_yld_1h/res/drawable/round_button_80dp.xml
  84. 5 0
      android_visiting/src/main/h10_yld_1h/res/drawable/selector_button_text_color.xml
  85. 5 0
      android_visiting/src/main/h10_yld_1h/res/drawable/selector_call_answer.xml
  86. 5 0
      android_visiting/src/main/h10_yld_1h/res/drawable/selector_call_hangup.xml
  87. 5 0
      android_visiting/src/main/h10_yld_1h/res/drawable/shape_untreated_quantity.xml
  88. 5 0
      android_visiting/src/main/h10_yld_1h/res/drawable/sp_event_handled.xml
  89. 8 0
      android_visiting/src/main/h10_yld_1h/res/drawable/sp_event_unhandled_bg.xml
  90. 36 0
      android_visiting/src/main/h10_yld_1h/res/layout/activity_app_update.xml
  91. 75 0
      android_visiting/src/main/h10_yld_1h/res/layout/activity_dialing_voice.xml
  92. 77 0
      android_visiting/src/main/h10_yld_1h/res/layout/activity_home.xml
  93. 92 0
      android_visiting/src/main/h10_yld_1h/res/layout/activity_register.xml
  94. 76 0
      android_visiting/src/main/h10_yld_1h/res/layout/activity_sip_voip_audio.xml
  95. 105 0
      android_visiting/src/main/h10_yld_1h/res/layout/activity_sip_voip_audio_ringing.xml
  96. 69 0
      android_visiting/src/main/h10_yld_1h/res/layout/activity_video.xml
  97. 104 0
      android_visiting/src/main/h10_yld_1h/res/layout/activity_voice_calls.xml
  98. 92 0
      android_visiting/src/main/h10_yld_1h/res/layout/activity_web_rtc_voip_audio.xml
  99. 106 0
      android_visiting/src/main/h10_yld_1h/res/layout/activity_web_rtc_voip_audio_ringing.xml
  100. 0 0
      android_visiting/src/main/h10_yld_1h/res/layout/call_dialog_lay.xml

+ 4 - 0
android_visiting/build.gradle

@@ -51,6 +51,10 @@ android {
             main.java.srcDirs += 'src/main/h8_ke_1h/java'
             main.res.srcDirs += 'src/main/h8_ke_1h/res'
             main.manifest.srcFile 'src/main/h8_ke_1h/AndroidManifest.xml'
+        } else if ("v_h10_yld_1h" == app_device_type) {
+            main.java.srcDirs += 'src/main/h10_yld_1h/java'
+            main.res.srcDirs += 'src/main/h10_yld_1h/res'
+            main.manifest.srcFile 'src/main/h10_yld_1h/AndroidManifest.xml'
         }
     }
 }

BIN
android_visiting/src/main/assets/wd_update_plugin.apk


BIN
android_visiting/src/main/assets/yunpai_launch_app.apk


+ 76 - 0
android_visiting/src/main/h10_yld_1h/AndroidManifest.xml

@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    package="com.wdkl.ncs.android.component.home">
+
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
+
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <!-- 悬浮窗显示 -->
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT"/>
+
+    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+
+    <application
+        android:allowBackup="true"
+        android:supportsRtl="true">
+
+        <activity android:name=".activity.HomeActivity"
+            android:screenOrientation="nosensor"
+            android:launchMode="singleInstance">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".activity.AppUpdateActivity" />
+
+        <service android:name=".service.TcpHandleService">
+            <intent-filter>
+                <action android:name="com.wdkl.ncs.android.component.home.service.TcpHandleService" />
+            </intent-filter>
+        </service>
+
+        <receiver
+            android:name=".broadcast.WdBootReceiver"
+            android:enabled="true"
+            android:exported="true">
+            <intent-filter android:priority="1000">
+                <action android:name="android.intent.action.BOOT_COMPLETED"/>
+            </intent-filter>
+        </receiver>
+
+        <!--<service android:name="com.wdkl.ncs.android.component.home.service.WdKeepAliveService">
+            <intent-filter>
+                <action android:name="com.wdkl.app.ncs.service.WdKeepAliveService"/>
+            </intent-filter>
+        </service>-->
+
+        <provider
+            android:name="android.support.v4.content.FileProvider"
+            android:authorities="${applicationId}.provider"
+            tools:replace="android:authorities"
+            android:grantUriPermissions="true"
+            android:exported="false">
+            <meta-data
+                android:name="android.support.FILE_PROVIDER_PATHS"
+                android:resource="@xml/file_paths" />
+        </provider>
+
+    </application>
+
+</manifest>

+ 222 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/activity/AppUpdateActivity.kt

@@ -0,0 +1,222 @@
+package com.wdkl.ncs.android.component.home.activity
+
+import android.content.Intent
+import android.os.Build
+import android.text.TextUtils
+import android.util.Log
+import android.view.View
+import com.enation.javashop.android.jrouter.external.annotation.Router
+import com.enation.javashop.net.engine.model.NetState
+import com.wdkl.ncs.android.component.home.BuildConfig
+import com.wdkl.ncs.android.component.home.R
+import com.wdkl.ncs.android.component.home.databinding.ActivityAppUpdateBinding
+import com.wdkl.ncs.android.component.home.helper.AppUpdateHelper
+import com.wdkl.ncs.android.component.home.helper.HttpHelper
+import com.wdkl.ncs.android.component.home.launch.HomeLaunch
+import com.wdkl.ncs.android.component.home.service.TcpHandleService
+import com.wdkl.ncs.android.component.nursehome.common.Constants
+import com.wdkl.ncs.android.lib.base.BaseActivity
+import com.wdkl.ncs.android.lib.utils.AppTool
+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.logic.contract.home.AppUpdateContract
+import com.wdkl.ncs.android.middleware.logic.presenter.home.AppUpdatePresenter
+import com.wdkl.ncs.android.middleware.model.dos.AppVersionDO
+import com.wdkl.ncs.android.middleware.utils.MessageEvent
+import kotlinx.android.synthetic.main.activity_app_update.*
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+import java.io.File
+
+@Router(path = "/app/update")
+class AppUpdateActivity :BaseActivity<AppUpdatePresenter, ActivityAppUpdateBinding>(), AppUpdateContract.View {
+    private val TAG = "AppUpdateActivity"
+
+    private val urlManager = UrlManager.build()
+
+    override fun getLayId(): Int {
+        return R.layout.activity_app_update
+    }
+
+    override fun bindDagger() {
+        HomeLaunch.component.inject(this)
+    }
+
+    override fun init() {
+        checkAppVersion()
+    }
+
+    override fun handleAppVersion(appInfo: AppVersionDO) {
+        //if ("YUNPAI_H6".equals(Build.MODEL)) {
+            try {
+                //启动云派app升级监听服务
+                val intent = Intent()
+                intent.setClassName("com.wd.app", "com.wd.app.MyService")
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                    //android8.0以上通过startForegroundService启动service
+                    startForegroundService(intent)
+                } else {
+                    startService(intent)
+                }
+                Constants.yunpai_plugin = true
+            } catch (e: Exception) {
+                e.printStackTrace()
+            }
+        //}
+
+        showMessage("获取版本 ==> 当前版本: " + BuildConfig.VERSION_NAME + "_" + BuildConfig.VERSION_CODE + ", 服务器版本: " + appInfo.versionCode + "_" + appInfo.versionNo)
+        if (BuildConfig.VERSION_CODE < appInfo.versionNo){
+            if (!TextUtils.isEmpty(appInfo.appPath)) {
+                downLoadAPK(urlManager.device_url + appInfo.appPath)
+            } else {
+                showMessage("下载路径异常")
+                finish()
+            }
+        } else {
+            //showMessage("本机已经是最新版本")
+            activity_calling_bed_text_download.text = "本机已经是最新版本"
+            activity_appupdate_dialog_progressview.visibility = View.GONE
+            TcpHandleService.updateLastTime = System.currentTimeMillis() / 1000
+            AppTool.Time.delay(1000){
+                finish()
+            }
+        }
+    }
+
+    fun checkAppVersion() {
+        if (Constants.partId != null) {
+            presenter.getAppVersion(Constants.partId, 19)
+        }
+    }
+
+    /**
+     * 下载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 = "正在安装,请稍后..."
+                }
+
+                startInstallApk()
+
+                /*if ("rk3288".equals(Build.MODEL)) {
+                    installApkForRk3288()
+                } else if ("YUNPAI_H6".equals(Build.MODEL)) {
+                    startInstallAppYunPai()
+                } else {
+                    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("升级失败")
+                        finish()
+                    }
+                }
+
+                override fun onSuccess() {
+                    runOnUiThread {
+                        //showMessage("升级成功")
+                        finish()
+                        //有root权限用这个
+//                        android.os.Process.killProcess(android.os.Process.myPid())
+//                        System.exit(0)
+                    }
+                }
+            })
+        }.start()
+    }
+
+    //云派8寸机app静默升级
+    fun startInstallAppYunPai() {
+        val apkAbsolutePath = AppUpdateHelper.FILE_APK_PATH + "/" + AppUpdateHelper.FILE_APK_NAME
+        val action = "com.miki.slient.INSTALL_CUSTOMER_PACKAGES"
+        val intent = Intent(action)
+        intent.putExtra("apkPath", apkAbsolutePath)
+        intent.putExtra("packageName", "com.miki.sensortest")
+        sendBroadcast(intent)
+    }
+
+    fun installApkForRk3288() {
+        val path = AppUpdateHelper.FILE_APK_PATH + "/" + AppUpdateHelper.FILE_APK_NAME
+        if (File(path).exists()) {
+            val intent = Intent("com.android.yf_slient_install")
+            intent.putExtra("path", path)  //要静默安装的apk路径
+            intent.putExtra("isboot", true)  //安装完成后是否启动
+            sendBroadcast(intent)
+        } else {
+            showMessage("安装文件不存在,升级失败!")
+            finish()
+        }
+    }
+
+    override fun bindEvent() {
+        //
+    }
+
+    override fun destory() {
+        //
+    }
+
+    //数据加载错误
+    override fun onError(message: String, type: Int) {
+        showMessage("获取版本失败,请检查网络或服务器版本!")
+        finish()
+    }
+
+    override fun onNoneNet() {
+        showMessage("没有网络!")
+        finish()
+    }
+
+    //数据加载完成
+    override fun complete(message: String, type: Int) {
+        //
+    }
+
+    //开始获取数据
+    override fun start() {
+        //
+    }
+
+    //网络监听
+    override fun networkMonitor(state: NetState) {
+        state.filter(onMobile = {
+
+        },onWifi = {
+
+        },offline = {
+
+        })
+    }
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    fun onMoonEvent(messageEvent: MessageEvent) {
+
+    }
+
+
+}

+ 631 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/activity/HomeActivity.kt

@@ -0,0 +1,631 @@
+package com.wdkl.ncs.android.component.home.activity
+
+import android.Manifest
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.content.pm.PackageManager
+import android.graphics.Color
+import android.media.AudioManager
+import android.net.ConnectivityManager
+import android.os.Build
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.os.Environment
+import android.provider.Settings
+import android.support.v4.app.ActivityCompat
+import android.support.v4.app.Fragment
+import android.support.v4.content.ContextCompat
+import android.telephony.PhoneStateListener
+import android.telephony.SignalStrength
+import android.telephony.TelephonyManager
+import android.text.TextUtils
+import android.util.Log
+import android.view.KeyEvent
+import android.view.View
+import com.alibaba.fastjson.JSON
+import com.enation.javashop.net.engine.model.NetState
+import com.enation.javashop.net.engine.plugin.permission.RxPermissions
+import com.enation.javashop.utils.base.tool.CommonTool
+import com.enation.javashop.utils.base.widget.LoadingDialog
+import com.google.gson.Gson
+import com.wdkl.ncs.android.component.home.BuildConfig
+import com.wdkl.ncs.android.component.home.R
+import com.wdkl.ncs.android.component.home.broadcast.BatteryBroadcastReceiver
+import com.wdkl.ncs.android.component.home.databinding.ActivityHomeBinding
+import com.wdkl.ncs.android.component.home.fragment.SkyCallFragment
+import com.wdkl.ncs.android.component.home.helper.AppUpdateHelper
+import com.wdkl.ncs.android.component.home.launch.HomeLaunch
+import com.wdkl.ncs.android.component.home.service.TcpHandleService
+import com.wdkl.ncs.android.component.home.service.TcpHandleService.instance.updateLastTime
+import com.wdkl.ncs.android.component.home.settingconfig.SettingConfig
+import com.wdkl.ncs.android.component.home.util.*
+//import com.wdkl.ncs.android.component.home.service.WdKeepAliveService
+import com.wdkl.ncs.android.component.nursehome.common.Constants
+import com.wdkl.ncs.android.lib.base.BaseActivity
+import com.wdkl.ncs.android.lib.base.BaseApplication
+import com.wdkl.ncs.android.lib.utils.AppTool
+import com.wdkl.ncs.android.lib.utils.TimeHandle
+import com.wdkl.ncs.android.lib.utils.joinManager
+import com.wdkl.ncs.android.lib.utils.showMessage
+import com.wdkl.ncs.android.middleware.logic.contract.home.HomeActivityContract
+import com.wdkl.ncs.android.middleware.logic.presenter.home.HomeActivityPresenter
+import com.wdkl.ncs.android.middleware.model.ServerIpInfo
+import com.wdkl.ncs.android.middleware.model.dos.PartSettingDO
+import com.wdkl.ncs.android.middleware.model.dto.TcpSeverDTO
+import com.wdkl.ncs.android.middleware.model.vo.DeviceVO
+import com.wdkl.ncs.android.middleware.model.vo.DeviceWatchInfoVO
+import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
+import com.wdkl.ncs.android.middleware.tcp.TcpClient
+import com.wdkl.ncs.android.middleware.tcp.TcpClientHandler
+import com.wdkl.ncs.android.middleware.tcp.channel.DeviceChannel
+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.utils.CommonUtils
+import com.wdkl.ncs.android.middleware.utils.MessageEvent
+import com.wdkl.ncs.janus.util.JanusConstant
+import io.reactivex.Observable
+import kotlinx.android.synthetic.main.activity_home.*
+import kotlinx.android.synthetic.main.activity_register.*
+import org.greenrobot.eventbus.EventBus
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+import java.io.File
+import java.io.FileOutputStream
+import java.io.InputStream
+
+class HomeActivity : BaseActivity<HomeActivityPresenter, ActivityHomeBinding>(), HomeActivityContract.View {
+
+    var TAG = HomeActivity::class.java.getSimpleName()
+
+    //监听网络变化
+    lateinit var teleManager: TelephonyManager
+    private var netType: Int = -1
+
+    lateinit var batteryBroadcastReceiver: BatteryBroadcastReceiver
+    private var isRegister = true
+    private var inited = false
+
+    var currentFragment: Fragment? = null
+
+    private var clickTimes: Int = 1
+    private var clickTime: Long = 0
+
+    var netAvailable: Boolean = false
+
+    private lateinit var receiver: TimeReceiver
+
+    override fun getLayId(): Int {
+        return R.layout.activity_home
+    }
+
+    override fun bindDagger() {
+        HomeLaunch.component.inject(this)
+    }
+
+    //初始化
+    override fun init() {
+        AppUtils.hideStatusBar(activity, false)
+
+        requestPermissions()
+
+        //保活守护进程
+        //DaemonEnv.init(this)
+        //請求用戶忽略电池优化
+//        val reason = "轨迹跟踪服务的持续运行"
+//        DaemonEnv.whiteListMatters(this, reason)
+        //启动work服务
+        //DaemonEnv.startServiceSafelyWithData(this, WdKeepAliveService::class.java)
+
+        //系统设置按钮
+        btn_system_setting0.setOnClickListener {
+            val intent = Intent(Settings.ACTION_SETTINGS)
+            startActivity(intent)
+        }
+
+        btn_restart_app.setOnClickListener {
+            AppUtils.restartApp()
+        }
+
+        btn_server_config.setOnClickListener {
+            ServerConfigDialogHelper.showPasswordDialog(activity)
+        }
+
+        //APP版本
+        tv_version_name.setText("version: " + BuildConfig.VERSION_NAME)
+
+        //网络强度监听
+        teleManager = (applicationContext.getSystemService(Context.TELEPHONY_SERVICE)) as TelephonyManager
+        netType = NetHelper.getInstance().getNetworkState(applicationContext)
+        Log.i(TAG, "网络类型:" + netType)
+        /*if (netType == NetHelper.NETWORK_2G || netType == NetHelper.NETWORK_3G || netType == NetHelper.NETWORK_4G) {
+            if (teleManager != null) {
+                teleManager.listen(object : PhoneStateListener() {
+                    override fun onSignalStrengthsChanged(signalStrength: SignalStrength) {
+                        super.onSignalStrengthsChanged(signalStrength)
+                        val asu = signalStrength.gsmSignalStrength
+                        val lastSignal = -113 + 2 * asu;
+                        if (lastSignal > 0) {
+                            var mobileNetworkSignal = lastSignal
+                        }
+                    }
+                }, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
+            }
+        }*/
+
+        //if ("YUNPAI_H6".equals(Build.MODEL)) {
+            startYunpaiPlugin()
+        //}
+
+        //默认使用面板mic
+        setMainMic(true)
+    }
+
+    private fun startYunpaiPlugin() {
+        try {
+            val packageInfos = packageManager.getInstalledPackages(
+                PackageManager.GET_ACTIVITIES or
+                        PackageManager.GET_SERVICES
+            )
+            var needInstall = false
+            for (info in packageInfos) {
+                val pkg = info.packageName
+                if (pkg.equals("com.wd.app")) {
+                    //启动云派app升级监听服务
+                    val intent = Intent()
+                    intent.setClassName("com.wd.app", "com.wd.app.MyService")
+                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                        //android8.0以上通过startForegroundService启动service
+                        startForegroundService(intent)
+                    } else {
+                        startService(intent)
+                    }
+                    Constants.yunpai_plugin = true
+                    needInstall = false
+                    break
+                } else {
+                    needInstall = true
+                }
+            }
+
+            if (needInstall) {
+                //拷贝并安装云派app升级服务apk
+                Log.d(TAG,"准备安装升级服务apk")
+                Thread{
+                    try {
+                        val fileName = "wd_update_plugin.apk"
+                        val dstPath = Environment.getExternalStorageDirectory().path + "/Download"
+                        val file = File(dstPath)
+                        if (!file.exists()) {
+                            file.mkdirs()
+                        }
+                        val filePath = dstPath + "/" + fileName
+                        val outFile = File(filePath)
+                        if (outFile.exists()) {
+                            outFile.delete()
+                        }
+                        val inputStream: InputStream = getAssets().open(fileName)
+                        val fos = FileOutputStream(outFile)
+                        val buffer = ByteArray(1024)
+                        var byteCount = 0
+                        while (inputStream.read(buffer).also { byteCount = it } != -1) {
+                            fos.write(buffer, 0, byteCount)
+                        }
+                        fos.flush()
+                        inputStream.close()
+                        fos.close()
+
+                        //apk拷贝完成,即将安装
+                        AppUpdateHelper.rootSilenceInstall(filePath)
+
+                        runOnUiThread {
+                            showMessage("app升级服务正在安装,请稍后重启设备以完成升级服务启动")
+                        }
+                    } catch (e: java.lang.Exception) {
+                        e.printStackTrace()
+                    }
+                }.start()
+            }
+        } catch (t: Throwable) {
+            t.printStackTrace()
+            showMessage("启动升级插件服务失败: " + t.message)
+        }
+
+
+        if (Constants.yunpai_plugin) {
+            tv_version_name.setText("升级服务已启动 version: " + BuildConfig.VERSION_NAME)
+        } else {
+            tv_version_name.setText("升级服务未启动 version: " + BuildConfig.VERSION_NAME)
+        }
+    }
+
+    private fun permissionGranted() {
+        Constants.imei = NetHelper.getInstance().imei
+        //Constants.imei = "860475031573358"
+        Log.i(TAG, "IMEI " + Constants.imei)
+        Log.i(TAG, "mac " + Constants.mac)
+        tv_device_imei.text = Constants.imei
+        tv_server_ip.text = NetHelper.getInstance().localIP + "/" + CommonUtils.getUrl(BaseApplication.appContext)
+
+        //获取TCP服务器IP和端口
+        Thread{
+            while (isRegister) {
+                Log.i(TAG, "获取TCP服务器IP和端口")
+                presenter.getServerInfo()
+                try {
+                    Thread.sleep(25000)
+                } catch (e: Exception) {
+                    //
+                }
+            }
+        }.start()
+
+        regReceiver()
+    }
+
+    private fun regReceiver() {
+        receiver = TimeReceiver()
+        var intentFilter = IntentFilter()
+        intentFilter.addAction(Intent.ACTION_TIME_TICK)
+        registerReceiver(receiver, intentFilter)
+
+        //手柄状态监听
+        intentFilter.addAction(Constants.HOOK_OFF)
+        intentFilter.addAction(Constants.HOOK_ON)
+        intentFilter.addAction(Constants.KEY_CALL_UP)
+        intentFilter.addAction(Constants.KEY_HOME_UP)
+        registerReceiver(receiver, intentFilter)
+    }
+
+    private fun releaseReceiver(){
+        unregisterReceiver(receiver)
+    }
+
+    /**
+     * 返回的tcp信息
+     */
+    override fun setTcpServerHost(tcpSeverDTO: TcpSeverDTO) {
+        /*isRegister = false
+        if(tcpSeverDTO.publicIp!= null && tcpSeverDTO.tcpPort != null && tcpSeverDTO.readerIdleTime != null){
+            Constants.tcpServer = tcpSeverDTO.publicIp
+            Constants.tcpPort = tcpSeverDTO.tcpPort
+            Constants.heartBeat = tcpSeverDTO.readerIdleTime
+            //tv_server_ip.text = tcpSeverDTO.publicIp
+
+            Thread {
+                //启动tcp连接
+                TcpClient.getInstance().init(Constants.tcpServer, Constants.tcpPort, Constants.heartBeat)
+
+                //获取设备数据
+                while (!inited) {
+                    Log.i(TAG, "获取设备数据")
+                    if (!TextUtils.isEmpty(Constants.imei)) {
+                        presenter.getDeviceVO(Constants.imei)
+                    }
+
+                    try {
+                        Thread.sleep(15000)
+                    } catch (e: Exception) {
+                        //
+                    }
+                }
+            }.start()
+        }*/
+    }
+
+    override fun setServerInfo(serverIpInfo: ServerIpInfo) {
+        isRegister = false
+        if(serverIpInfo.tcpLocalIp!= null && serverIpInfo.tcpPort != null && serverIpInfo.tcpIdleSeconds != null){
+            Constants.tcpServer = serverIpInfo.tcpLocalIp
+            Constants.tcpPort = serverIpInfo.tcpPort
+            Constants.heartBeat = serverIpInfo.tcpIdleSeconds
+            tv_server_ip.text = NetHelper.getInstance().localIP + "/" + serverIpInfo.tcpLocalIp
+
+            JanusConstant.JANUS_URL = "ws://" + serverIpInfo.rtcLocalIp + ":" + serverIpInfo.rtcPort
+            JanusConstant.STUN_SERVER = arrayOf<String>(serverIpInfo.stunServer)
+            //JanusConstant.TURN_SERVER = data.turnServer
+
+            Thread {
+                //启动tcp连接
+                TcpClient.getInstance().init(Constants.tcpServer, Constants.tcpPort, Constants.heartBeat)
+
+                //获取设备数据
+                while (!inited) {
+                    Log.i(TAG, "获取设备数据")
+                    if (!TextUtils.isEmpty(Constants.imei)) {
+                        presenter.getDeviceVO(Constants.imei)
+                    }
+
+                    try {
+                        Thread.sleep(15000)
+                    } catch (e: Exception) {
+                        //
+                    }
+                }
+            }.start()
+        }
+    }
+
+    private fun requestPermissions() {
+        Observable.just("").compose(RxPermissions(this).ensure(Manifest.permission.CAMERA,
+            Manifest.permission.READ_EXTERNAL_STORAGE,
+            Manifest.permission.WRITE_EXTERNAL_STORAGE,
+            Manifest.permission.ACCESS_WIFI_STATE,
+            Manifest.permission.BLUETOOTH,
+            Manifest.permission.RECORD_AUDIO,
+            Manifest.permission.READ_PHONE_STATE)).subscribe {
+            if (it) {
+                permissionGranted()
+            } else {
+                showMessage("请重新授权,进入App")
+                requestPermissions()
+            }
+        }.joinManager(disposableManager)
+    }
+
+    /**
+     * 返回的设备信息
+     */
+    override fun setDeviceDo(data: DeviceWatchInfoVO) {
+        Log.i(TAG, "收到返回的设备信息 ")
+        try {
+            Constants.partId = data.partId
+            Constants.deviceId = data.id
+            Constants.sipId = data.sipId
+            Constants.ethIp = data.ethIp
+            Constants.sipIp = data.sipIp
+            Constants.sipPassword = data.sipPassword
+            Constants.userName = data.memberName
+            Constants.userRoleName = data.roleName
+
+            if (Constants.deviceId == -1 || TextUtils.isEmpty(Constants.sipId)) {
+                showMessage("初始化数据不全,请联系管理员")
+                tv_status.text = "初始化数据不全,请联系管理员"
+                return
+            } else if (TextUtils.isEmpty(Constants.tcpServer)) {
+                showMessage("初始化tcp连接数据为null")
+                tv_status.text = "初始化tcp连接数据为null"
+                return
+            } else if (data.status != null && data.status == 0) {
+                showMessage("设备未启用")
+                tv_status.text = "设备未启用"
+                return
+            }
+
+            inited = true
+            activity_register_layout.visibility = View.GONE
+            watch_activity_home_linyout.visibility = View.VISIBLE
+
+            watch_activity_home_linyout.setBackgroundResource(R.drawable.main_bg_1280x800)
+            btn_callout.setBackgroundResource(R.drawable.round_button_100dp)
+            btn_callout.textSize = 36f
+
+            initSDK()
+            presenter.getDeviceSettingData(Constants.partId)
+
+            //tv_part_name.setText(data.hospitalName + data.partName)
+            tv_part_name.text = data.partDisplay
+
+            showMessage("初始化完成")
+
+            AppTool.Time.delay(1500) {
+                AppUtils.hideStatusBar(activity, true)
+            }
+
+            startCheckUpdate()
+        } catch (e: java.lang.Exception) {
+            showMessage("设备数据异常:" + e.message)
+        }
+    }
+
+    private fun initSDK() {
+        val intent = Intent(this, TcpHandleService::class.java)
+        startService(intent)
+    }
+
+    //开始呼叫
+    private fun startVideoCall() {
+        currentFragment = SkyCallFragment()
+        var bundle = Bundle()
+        bundle.putInt("call_state", 0)
+        bundle.putBoolean("audio_only", false)
+        currentFragment?.arguments = bundle
+        supportFragmentManager.beginTransaction()
+            .add(R.id.frame_visit, currentFragment)
+            .commit()
+        watch_activity_home_linyout.visibility = View.GONE
+    }
+
+    /**
+     * 设置设备数据
+     */
+    override fun setDeviceSettingData(partSettingDO: PartSettingDO) {
+        try {
+            //分机通话音量  没做白昼区分
+            SettingConfig.setExtensionCallVolume(this, partSettingDO.dayBedVol)
+
+            VoiceManagerUtil.setCallVoice(activity, partSettingDO.dayBedVol)
+
+            VoiceManagerUtil.setSystemVoice(activity, partSettingDO.dayBedVol)
+            VoiceManagerUtil.setMusicVoice(activity, partSettingDO.dayBedVol)
+        } catch (ex: Exception) {
+            ex.printStackTrace()
+        }
+    }
+
+    override fun onError(message: String, type: Int) {
+    }
+
+    override fun complete(message: String, type: Int) {
+    }
+
+    override fun start() {
+    }
+
+    override fun networkMonitor(state: NetState) {
+    }
+
+    override fun destory() {
+        releaseReceiver()
+    }
+
+    override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
+        Log.i(TAG, "keyup keyCode " + keyCode)
+        return if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) {
+            //不执行父类点击事件
+            true
+        } else super.onKeyUp(keyCode, event)
+        //继续执行父类其他点击事件
+    }
+
+    override fun bindEvent() {
+        //长按检测升级
+        tv_version_name.setOnLongClickListener {
+            if (System.currentTimeMillis() / 1000 - updateLastTime > 10) {
+                showMessage("检查新版本")
+                updateLastTime = System.currentTimeMillis() / 1000
+                startCheckUpdate()
+            } else {
+                showMessage("请10秒后再尝试")
+            }
+            return@setOnLongClickListener true
+        }
+
+        tv_version_name.setOnClickListener {
+            val time = System.currentTimeMillis()
+            if (time - clickTime < 1500) {
+                clickTimes++
+            } else {
+                clickTimes = 1
+            }
+
+            if (clickTimes > 9) {
+                val intent = Intent(Settings.ACTION_SETTINGS)
+                startActivity(intent)
+                clickTimes = 1
+            }
+            clickTime = time
+        }
+
+        btn_callout.setOnClickListener {
+            if (System.currentTimeMillis() - clickTime > 3000) {
+                if (TcpClientHandler.getConnected() && netAvailable) {
+                    startVideoCall()
+                } else {
+                    showMessage("通话服务或网络未连接,请检查网络稍后再试")
+                }
+            } else {
+                showMessage("点击太频繁")
+            }
+            clickTime = System.currentTimeMillis()
+        }
+    }
+
+    private fun startCheckUpdate() {
+        val intent = Intent()
+        intent.setClass(this, AppUpdateActivity::class.java)
+        startActivity(intent)
+    }
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    fun onMoonEvent(messageEvent: MessageEvent) {
+        if (messageEvent.tag == Constants.BACK_TO_MAIN_MSG) {
+            if (currentFragment != null) {
+                supportFragmentManager.beginTransaction()
+                    .remove(currentFragment)
+                    .commit()
+                currentFragment = null
+            }
+            watch_activity_home_linyout.visibility = View.VISIBLE
+            AppUtils.setAudioMode(BaseApplication.appContext, AudioManager.MODE_NORMAL)
+        } else if (messageEvent.tag == Constants.EVENT_TCP_BREAK) {
+            if (TcpClientHandler.getConnected()) {
+                netAvailable = true
+                tv_rtc_status.setBackgroundColor(Color.GREEN)
+            } else {
+                netAvailable = false
+                tv_rtc_status.setBackgroundColor(Color.RED)
+            }
+        } else if (messageEvent.tag == Constants.TCP_MSG) {
+            val tcp = messageEvent.getMessage() as TcpModel
+            if (tcp.action == TcpAction.DataAction.REFRESH) {
+                if (!TextUtils.isEmpty(Constants.imei)) {
+                    presenter.getDeviceVO(Constants.imei)
+                }
+            } else if (tcp.action == TcpAction.TimeAction.SYNC) {
+                var time = 0L
+                var timeZone="Asia/Shanghai"
+                if (canParseJson(tcp.data.toString())) {
+                    val json = JSON.parseObject(tcp.data.toString())
+                    time = json.getLong("time")*1000
+                    timeZone = json.getString("time_zone")
+                } else {
+                    time = tcp.data.toString().toLong() * 1000
+                }
+
+                try {
+                    AppUtils.setSystemTime(BaseApplication.appContext, time, timeZone)
+                    Log.d("setTime", "set sys time1: $time, $timeZone")
+                } catch (e: Exception) {
+                    //"20211213:092314"
+                    val timeStr = TimeHandle.getDateTime(time, "yyyyMMdd.HHmmss")
+                    AppUtils.setSysTime(timeStr, timeZone)
+                    Log.d("setTime", "set sys time2: $timeStr, $timeZone")
+                }
+            }
+        }
+    }
+
+    private fun canParseJson(str:String) : Boolean {
+        var result = false
+        try {
+            JSON.parseObject(str)
+            result=true
+        }catch (e:java.lang.Exception){
+            result=false
+        }
+        return result
+    }
+
+    private fun setMainMic(mainMic: Boolean) {
+        if (mainMic) {
+            val intent = Intent("com.mic.mic1")
+            sendBroadcast(intent)
+        } else {
+            val intent = Intent("com.mic.mic2")
+            sendBroadcast(intent)
+        }
+    }
+
+
+    inner class TimeReceiver: BroadcastReceiver() {
+        override fun onReceive(context: Context, intent: Intent) {
+            if (intent.action == Intent.ACTION_TIME_TICK) {
+                if (inited) {
+                    if (TcpClientHandler.getConnected()) {
+                        tv_rtc_status.setBackgroundColor(Color.GREEN)
+                    } else {
+                        tv_rtc_status.setBackgroundColor(Color.RED)
+                    }
+                }
+            } else if (intent.action == Constants.HOOK_ON) {
+                Log.e(TAG,"手柄放下 ")
+                Constants.hookOn = true
+                AppUtils.switchAudioMode(activity, true)
+            } else if (intent.action == Constants.HOOK_OFF) {
+                Log.e(TAG,"手柄拿起 ")
+                Constants.hookOn = false
+                AppUtils.switchAudioMode(activity, false)
+            } else if (intent.action == Constants.KEY_CALL_UP) {
+                //手柄按键抬起
+                setMainMic(false)
+            } else if (intent.action == Constants.KEY_HOME_UP) {
+                //主板按键抬起
+                setMainMic(true)
+            }
+        }
+    }
+}

+ 56 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/adapter/NumAdapter.java

@@ -0,0 +1,56 @@
+package com.wdkl.ncs.android.component.home.adapter;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+import com.wdkl.ncs.android.component.home.R;
+
+public class NumAdapter extends BaseAdapter {
+    private String[] num;
+    private Context context;
+
+    public NumAdapter(String[] numbers, Context context) {
+        this.num = numbers;
+        this.context = context;
+    }
+
+
+    @Override
+    public int getCount() {
+        return num.length;
+    }
+
+    @Override
+    public Object getItem(int position) {
+        return num[position];
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return position;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        ViewHolder viewHolder;
+        if (convertView == null) {
+            convertView = LayoutInflater.from(context).inflate(R.layout.digital_item, null);
+            viewHolder = new ViewHolder();
+            viewHolder.numTv = convertView.findViewById(R.id.tv_number);
+            convertView.setTag(viewHolder);
+        } else {
+            viewHolder = (ViewHolder) convertView.getTag();
+        }
+        viewHolder.numTv.setText(num[position]);
+
+        return convertView;
+    }
+
+    static class ViewHolder {
+        TextView numTv;
+    }
+}

+ 43 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/broadcast/BatteryBroadcastReceiver.java

@@ -0,0 +1,43 @@
+package com.wdkl.ncs.android.component.home.broadcast;
+
+import android.annotation.SuppressLint;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.widget.TextView;
+
+import com.wdkl.ncs.android.component.home.util.SpeechUtil;
+import com.wdkl.ncs.android.component.nursehome.common.Constants;
+import com.wdkl.ncs.android.middleware.utils.MessageEvent;
+
+import org.greenrobot.eventbus.EventBus;
+
+
+public class BatteryBroadcastReceiver extends BroadcastReceiver {
+    private String TAG = BatteryBroadcastReceiver.class.getSimpleName();
+
+    private TextView mBatteryView;
+
+    public BatteryBroadcastReceiver(TextView mBatteryView) {
+        this.mBatteryView = mBatteryView;
+    }
+
+    @SuppressLint("LongLogTag")
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
+            int level = intent.getIntExtra("level", 0);
+            int scale = intent.getIntExtra("scale", 100);
+            int power = level * 100 / scale;
+            if (power<15){
+                if (Constants.Companion.getEVENT_BATTERY_ALARM()) {
+                    SpeechUtil.getInstance().newSpeech("电池电量低,请注意!电池电量低,请注意!电池电量低,请注意!", false);
+                    Constants.Companion.setEVENT_BATTERY_ALARM(false);
+                }
+            } else {
+                Constants.Companion.setEVENT_BATTERY_ALARM(true);
+            }
+            EventBus.getDefault().post(new MessageEvent(power, Constants.EVENT_BATTERY_PERCENT));
+        }
+    }
+}

+ 22 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/broadcast/NetworkBroadcastReceiver.kt

@@ -0,0 +1,22 @@
+package com.wdkl.ncs.android.component.home.broadcast
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.net.ConnectivityManager
+import com.wdkl.ncs.android.component.home.util.NetHelper
+import com.wdkl.ncs.android.component.home.util.Util.getCpuWakeLock
+import com.wdkl.ncs.android.lib.utils.AppTool
+
+class NetworkBroadcastReceiver: BroadcastReceiver() {
+    override fun onReceive(context: Context?, intent: Intent?) {
+        if (ConnectivityManager.CONNECTIVITY_ACTION == intent!!.action) {
+            val netState = NetHelper.getInstance().getNetworkState(context)
+            if (netState == NetHelper.NETWORK_NONE) {
+                val cpuWakeLock = getCpuWakeLock(context!!)
+                cpuWakeLock.acquire(3000)
+            }
+        }
+    }
+
+}

+ 21 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/broadcast/WdBootReceiver.java

@@ -0,0 +1,21 @@
+package com.wdkl.ncs.android.component.home.broadcast;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import com.wdkl.ncs.android.component.home.activity.HomeActivity;
+
+public class WdBootReceiver extends BroadcastReceiver {
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
+            Log.d("wdBoot", "收到开机广播,启动app");
+            Intent startIntent= new Intent(context, HomeActivity.class);
+            startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            context.startActivity(startIntent);
+        }
+    }
+}

+ 13 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/common/Constants.kt

@@ -0,0 +1,13 @@
+//package com.wdkl.ncs.android.component.nursehome.common
+//
+//class Constants {
+//    companion object {
+//        var frame_id: String =""//医院结构ID
+//        var eth_ip: String ="" //当前设备的IP
+//        var ids: String =""//当前设备的ID
+//        var sip_id: String =""//sip
+//
+//    }
+//
+//
+//}

+ 19 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/di/HomeComponent.kt

@@ -0,0 +1,19 @@
+package com.wdkl.ncs.android.component.home.di
+
+import com.wdkl.ncs.android.component.home.activity.*
+import com.wdkl.ncs.android.middleware.di.ApplicationComponent
+import dagger.Component
+
+/**
+ * @author LDD
+ * @Date   2018/1/22 下午2:43
+ * @From   com.wdkl.ncs.android.component.home.di
+ * @Note   依赖注入入口
+ */
+@Component(dependencies = arrayOf(ApplicationComponent::class))
+interface HomeComponent {
+
+    fun inject(activity: HomeActivity)
+
+    fun inject(activity: AppUpdateActivity)
+}

+ 138 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/fragment/BaseCallFragment.kt

@@ -0,0 +1,138 @@
+package com.wdkl.ncs.android.component.home.fragment
+
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.support.v4.app.Fragment
+import android.view.LayoutInflater
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import com.enation.javashop.utils.base.tool.BaseToolActivity
+import com.wdkl.ncs.android.component.home.util.RingPlayHelper
+import com.wdkl.ncs.android.component.nursehome.common.Constants
+import com.wdkl.ncs.android.lib.utils.showMessage
+import com.wdkl.ncs.android.middleware.tcp.channel.DeviceChannel
+import com.wdkl.ncs.android.middleware.tcp.channel.VideoUtil
+import com.wdkl.ncs.android.middleware.tcp.channel.VoiceUtil
+import com.wdkl.ncs.android.middleware.utils.MessageEvent
+import org.greenrobot.eventbus.EventBus
+
+abstract class BaseCallFragment: Fragment(), View.OnTouchListener {
+
+    private var layout: View? = null
+
+    protected lateinit var baseActivity: BaseToolActivity
+
+    //通话状态:0-去电, 1-来电
+    protected var callState : Int = 0
+    protected var onlyAudio: Boolean = false
+    //来电设备id
+    protected var fromId: Int = -1
+    protected var interactionId: Int? = -1
+    protected var targetId: String? = null
+
+    //计时器
+    lateinit var countDownTimer: CountDownTimer
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        retainInstance = true
+        callState = arguments.getInt("call_state")
+        onlyAudio = arguments.getBoolean("audio_only")
+        fromId = arguments.getInt("fromId")
+        interactionId = arguments.getInt("interactionId")
+        targetId = arguments.getString("targetId")
+    }
+
+    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()
+
+        view!!.setOnTouchListener(this)
+    }
+
+    override fun onDestroyView() {
+        super.onDestroyView()
+        destroy()
+    }
+
+    override fun onStart() {
+        EventBus.getDefault().register(this)
+        super.onStart()
+    }
+
+    override fun onStop() {
+        EventBus.getDefault().unregister(this)
+        super.onStop()
+    }
+
+    override fun onTouch(v: View?, event: MotionEvent?): Boolean {
+        return true
+    }
+
+    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) {
+        countDownTimer = object: CountDownTimer(30000, 1000) {
+            override fun onTick(millisUntilFinished: Long) {
+                if (view != null) {
+                    val time = millisUntilFinished/1000
+                    view.setText("倒计时: " + time + "秒")
+                }
+            }
+
+            override fun onFinish() {
+                //呼叫超时,返回到主界面
+                RingPlayHelper.stopRingTone()
+                showMessage("无人应答...")
+                DeviceChannel.calling = false
+                Constants.CALL_STATE = Constants.CALL_STANDBY
+                VideoUtil.cancelVideoCall(Constants.deviceId, Constants.interactionId)
+                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("back_to_main", Constants.BACK_TO_MAIN_MSG))
+    }
+
+}

+ 437 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/fragment/SkyCallFragment.kt

@@ -0,0 +1,437 @@
+package com.wdkl.ncs.android.component.home.fragment
+
+import android.media.AudioManager
+import android.os.Build
+import android.os.Handler
+import android.os.Looper
+import android.os.SystemClock
+import android.util.Log
+import android.view.View
+import android.view.ViewGroup
+import com.google.gson.Gson
+import com.wdkl.ncs.android.component.home.R
+import com.wdkl.ncs.android.component.home.settingconfig.SettingConfig
+import com.wdkl.ncs.android.component.home.util.AppUtils
+import com.wdkl.ncs.android.component.home.util.RingPlayHelper
+import com.wdkl.ncs.android.component.home.util.Util
+import com.wdkl.ncs.android.component.home.util.VoiceManagerUtil
+import com.wdkl.ncs.android.component.nursehome.common.Constants
+import com.wdkl.ncs.android.lib.base.BaseApplication
+import com.wdkl.ncs.android.lib.utils.AppTool
+import com.wdkl.ncs.android.lib.utils.showMessage
+import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
+import com.wdkl.ncs.android.middleware.tcp.channel.DeviceChannel
+import com.wdkl.ncs.android.middleware.tcp.channel.VideoUtil
+import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpAction
+import com.wdkl.ncs.android.middleware.utils.MessageEvent
+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"
+
+    private var localSurfaceView: SurfaceViewRenderer? = null
+    private var remoteSurfaceView: SurfaceViewRenderer? = null
+
+    private val handler = Handler(Looper.getMainLooper())
+
+    private var callEnded: Boolean = false
+
+    private var outGoing: Boolean = false
+
+
+    private var janusClient: JanusClient? = null
+    private var room: Room?=null
+    private var videoRoomCallback: VideoRoomCallback? = null
+
+    private var callSuccess: Boolean = false
+
+    override fun getLayId(): Int {
+        if ("YUNPAI_H6".equals(Build.MODEL, true) || "rk3288".equals(Build.MODEL, true)) {
+            return R.layout.sky_voice_call_layout_land
+        } else {
+            return R.layout.sky_voice_call_layout
+        }
+    }
+
+    override fun init() {
+        //初始化计时器
+        initCountDownTimer(sky_voice_call_timeout)
+
+        //初始化 engine
+        WebRTCEngine.getInstance().init(false, this.context)
+
+        VoiceManagerUtil.setCallVoice(activity, SettingConfig.getExtensionCallVolume(activity))
+
+        //初始化 janusClient
+        janusClient = JanusClient(JanusConstant.JANUS_URL, Constants.sipId!!.toBigInteger())
+
+        when (callState) {
+            0 -> {
+                //发起通话
+                outGoing = true
+                startOutgoing()
+                RingPlayHelper.playRingTone(baseActivity, R.raw.ring_back2, true)
+
+                janusClient!!.callState = EnumType.CallState.Outgoing
+                room = Room(Constants.sipId!!.toBigInteger())
+            }
+
+            1 -> {
+                //接受通话
+            }
+        }
+
+
+        videoRoomCallback = VideoRoomCallback(janusClient, room, Constants.sipId!!.toBigInteger())
+        videoRoomCallback!!.callSessionCallback = this
+        janusClient!!.setJanusCallback(videoRoomCallback)
+    }
+
+    override fun bindEvent() {
+        //通话挂断
+        sky_voice_call_hangup.setOnClickListener {
+            RingPlayHelper.stopRingTone()
+            if (Constants.CALL_STATE == Constants.CALL_CALLING) {
+                //结束sip通话
+                Constants.CALL_STATE = Constants.CALL_STANDBY
+                if (sky_voice_call_timer != null) {
+                    sky_voice_call_timer.stop()
+                }
+
+                callEnd(true)
+            } else {
+                Constants.CALL_STATE = Constants.CALL_STANDBY
+                DeviceChannel.calling = false
+                VideoUtil.cancelVideoCall(Constants.deviceId, Constants.interactionId)
+                cancelCall()
+            }
+        }
+    }
+
+    override fun destroy() {
+        DeviceChannel.calling = false
+        cancelTimer()
+        Constants.CALL_STATE = Constants.CALL_STANDBY
+        if (sky_voice_call_timer != null) {
+            sky_voice_call_timer.stop()
+        }
+        RingPlayHelper.stopRingTone()
+        AppUtils.setAudioMode(BaseApplication.appContext, AudioManager.MODE_NORMAL)
+    }
+
+    private fun startOutgoing() {
+        callSuccess = false
+        sky_voice_call_hangup.isEnabled = false
+        VideoUtil.startVideoOutCall(Constants.deviceId)
+
+        DeviceChannel.calling = true
+        Constants.CALL_STATE = Constants.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 && !callEnded) {
+                //呼叫失败
+                showMessage("呼叫失败,服务器无响应或网络故障!")
+                RingPlayHelper.stopRingTone()
+                cancelCall()
+            }
+        }
+    }
+
+    //去电界面
+    private fun showOutgoingCall() {
+        Constants.CALL_STATE = Constants.CALL_OUTGOING
+        sky_voice_call_calling_text.text = "正在呼叫,等待接听..."
+        sky_voice_call_outgoing.visibility = View.VISIBLE
+        sky_voice_call_incoming.visibility = View.GONE
+
+        fullscreen_video_frame.visibility = View.VISIBLE
+        pip_video_frame.visibility = View.VISIBLE
+    }
+
+    //呼叫取消
+    private fun cancelCall() {
+        cancelTimer()
+        DeviceChannel.calling = false
+        Constants.CALL_STATE = Constants.CALL_STANDBY
+        callEnd(false)
+    }
+
+    private fun showCalling(audioOnly: Boolean) {
+        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
+        }
+
+        cancelTimer()
+        sky_voice_call_calling_text.text = "通话中..."
+        sky_voice_call_timer.visibility = View.VISIBLE
+        sky_voice_call_timer.base = SystemClock.elapsedRealtime()
+        sky_voice_call_timer.start()
+
+        if (Constants.hookOn) {
+            //手柄放下,免提模式
+            AppUtils.switchAudioMode(activity, true)
+        } else {
+            //手柄拿起,听筒模式
+            AppUtils.switchAudioMode(activity, false)
+        }
+    }
+
+    //通话结束
+    override fun callEnd(handoff: Boolean) {
+        synchronized(this) {
+            if (callEnded) {
+                return
+            }
+            callEnded = true
+            DeviceChannel.calling = false
+            Constants.CALL_STATE = Constants.CALL_STANDBY
+            if (sky_voice_call_timer != null) {
+                sky_voice_call_timer.stop()
+            }
+
+            Log.e(TAG, "call end !!!!!!!!!!!!!!!!!!")
+            if (handoff) {
+                VideoUtil.handoffVideoCall(Constants.deviceId, Constants.visitHostId, Constants.interactionId)
+            }
+
+            if (janusClient!!.webSocketChannel != null) {
+                janusClient!!.callState = EnumType.CallState.Idle
+                if (outGoing) {
+                    janusClient!!.destroyRoom(janusClient!!.currentHandleId, null)
+                } else {
+                    janusClient!!.leaveRoom()
+                }
+
+                janusClient!!.setJanusCallback(null)
+                janusClient!!.disConnect()
+            }
+
+            backToMain()
+        }
+    }
+
+
+    /********************************************************
+     ********************* webrtc通话回调 ********************
+     * 注意: 如涉及到UI更新的需要在主线程处理,务必注意
+     *******************************************************/
+    override fun didChangeState(var1: EnumType.CallState?) {
+        Log.e(TAG, "didChangeState: $var1")
+        if (var1 == EnumType.CallState.Connected) {
+            handler.post {
+                RingPlayHelper.stopRingTone()
+                //更新界面显示
+                showCalling(false)
+            }
+        }
+    }
+
+    override fun didDisconnected(userId: String?) {
+        Log.w(TAG, "didDisconnected: $userId")
+        handler.post {
+            showMessage("$userId 失去连接")
+            callEnd(true)
+        }
+    }
+
+    override fun didError(error: String?) {
+        Log.e(TAG, "didError: $error")
+        handler.post {
+            showMessage("通话错误")
+            callEnd(true)
+        }
+    }
+
+    override fun didHangUp(handlerId: BigInteger?) {
+        Log.e("hangup", "socket hangup")
+        handler.post {
+            callEnd(true)
+        }
+    }
+
+    //处理本地视频画面
+    override fun didCreateLocalVideoTrack() {
+        Log.e(TAG, "didCreateLocalVideoTrack")
+        handler.post {
+            if (!callEnded) {
+                if (localSurfaceView == null) {
+                    val surfaceView = WebRTCEngine.getInstance().startPreview(true)
+                    Log.e(TAG, "didCreateLocalVideoTrack surfaceView: $surfaceView")
+                    if (surfaceView != null) {
+                        localSurfaceView = surfaceView as SurfaceViewRenderer
+                    } else {
+                        callEnd(true)
+                    }
+                } else {
+                    localSurfaceView!!.setZOrderMediaOverlay(true)
+                }
+
+                if (localSurfaceView!!.parent != null) {
+                    (localSurfaceView!!.parent as ViewGroup).removeView(localSurfaceView)
+                }
+
+                if (fullscreen_video_frame != null) {
+                    if (fullscreen_video_frame.getChildCount() != 0) {
+                        fullscreen_video_frame.removeAllViews()
+                    }
+                    fullscreen_video_frame.addView(localSurfaceView)
+                }
+            }
+        }
+    }
+
+    override fun didReceiveRemoteVideoTrack(userId: BigInteger?) {
+        Log.e(TAG, "didReceiveRemoteVideoTrack==  userId: $userId, hostSip: ${Constants.hostSipId}")
+        handler.post {
+            if (!callEnded) {
+                if (Constants.hostSipId!!.toBigInteger() != userId) {
+                    //本地画面
+                    Log.e(TAG, "didReceiveRemoteVideoTrack, local surfaceView = $localSurfaceView")
+                    if (localSurfaceView != null) {
+                        localSurfaceView!!.setZOrderMediaOverlay(true)
+                        if (outGoing) {
+                            if (localSurfaceView!!.parent != null) {
+                                (localSurfaceView!!.parent as ViewGroup).removeView(localSurfaceView)
+                            }
+                            if (pip_video_frame != null) {
+                                pip_video_frame.addView(localSurfaceView)
+                            }
+                        }
+                    }
+
+                    //远端画面
+                    val surfaceView = WebRTCEngine.getInstance().setupRemoteVideo(userId, false)
+                    Log.e(TAG, "didReceiveRemoteVideoTrack, remote surfaceView = $surfaceView")
+                    if (surfaceView != null && fullscreen_video_frame != null) {
+                        remoteSurfaceView = surfaceView as SurfaceViewRenderer
+                        fullscreen_video_frame.removeAllViews()
+                        if (remoteSurfaceView!!.parent != null) {
+                            (remoteSurfaceView!!.parent as ViewGroup).removeView(remoteSurfaceView)
+                        }
+                        fullscreen_video_frame.addView(remoteSurfaceView)
+                    }
+                } else {
+                    showMessage("主机已接听")
+                }
+            }
+        }
+    }
+
+    override fun didCallEndWithReason(callEndReason: EnumType.CallEndReason?) {
+        handler.post {
+            callEnd(true)
+        }
+    }
+
+    override fun didChangeMode(isAudioOnly: Boolean) {
+        handler.post {
+            //
+        }
+    }
+
+    override fun didUserLeave(userId: BigInteger?) {
+        Log.w(TAG, "didUserLeave: $userId")
+        handler.post {
+            callEnd(true)
+        }
+    }
+
+
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    fun onMoonEvent(messageEvent: MessageEvent) {
+        if (messageEvent.tag == Constants.VIDEO_MSG){
+            val tcpModel = messageEvent.getMessage() as TcpModel
+            var interactionVO: InteractionVO? = null
+            if (tcpModel.data != null) {
+                interactionVO = Gson().fromJson(tcpModel.data.toString(), InteractionVO::class.java)
+            }
+            Log.e(TAG, "收到tcp消息: " + tcpModel.getType() + " " + tcpModel.getAction())
+            when (tcpModel.action){
+                TcpAction.VideoAction.CALLING->{
+                    //我方呼出,对方通话中
+                    AppTool.Time.delay(3000) {
+                        RingPlayHelper.stopRingTone()
+                        cancelCall()
+                        showMessage("对方忙线中!")
+                    }
+                }
+
+                TcpAction.VideoAction.FAILED->{
+                    //我方呼出,对方不在线,设备离线或其它错误
+                    callSuccess = true
+                    AppTool.Time.delay(3000) {
+                        RingPlayHelper.stopRingTone()
+                        cancelCall()
+                        showMessage("呼叫失败,找不到设备或对方不在线!")
+                    }
+                }
+
+                TcpAction.VideoAction.SUCCESS->{
+                    callSuccess = true
+                    DeviceChannel.calling = true
+                    if (interactionVO != null) {
+                        Constants.interactionId = interactionVO.id
+                    }
+                    Constants.visitHostId = tcpModel.fromId
+                    Util.wakeUpAndUnlock(activity)
+                    sky_voice_call_hangup.isEnabled = true
+                    showOutgoingCall()
+                    janusClient!!.connect()
+                }
+
+                TcpAction.VideoAction.ACCEPT-> {
+                   //
+                }
+
+                //主机接听
+                TcpAction.VideoAction.VIDEO_IN_CALL-> {
+                    if (interactionVO != null) {
+                        Constants.hostSipId = interactionVO.toSipId
+                    }
+                }
+
+                TcpAction.VideoAction.VIDEO_ON -> {
+                    //
+                }
+
+                TcpAction.VideoAction.REJECT->{
+                    //我方呼出,对方拒绝
+                    AppTool.Time.delay(1000) {
+                        RingPlayHelper.stopRingTone()
+                        cancelCall()
+                        showMessage("对方拒绝!")
+                    }
+                }
+
+                TcpAction.VideoAction.HANDOFF -> {
+                    if (interactionVO != null && Constants.interactionId == interactionVO.id) {
+                        callEnd(false)
+                    }
+                }
+            }
+        }
+    }
+
+}

+ 230 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/helper/AppUpdateHelper.java

@@ -0,0 +1,230 @@
+package com.wdkl.ncs.android.component.home.helper;
+
+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.support.v4.BuildConfig;
+import android.support.v4.content.FileProvider;
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+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() + "/IcuVisit";
+    /**
+     * 下载的APK文件的文件名
+     */
+    public static final String FILE_APK_NAME = "IcuVisitApp.apk";
+
+    public static Context mContext;
+
+    public static void updateApp(Context context, UpdateCallBack callBack) {
+        mContext = context;
+        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 (!checkApkAvailable(context, path)) {
+//            Log.d(TAG, "安装失败");
+//            return;
+//        }
+
+
+//        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();
+//            }
+//        }
+
+        /*if (installAPP(path)) {
+            Log.d(TAG, "安装成功");
+            if (callBack != null) {
+                callBack.onSuccess();
+            }
+        }*/
+    }
+
+
+    public static boolean installAPP(String path) {
+
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+        File apkFile = new File(path);
+        // 由于没有在Activity环境下启动Activity,设置下面的标签
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        //Android 7.0以上要使用FileProvider
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            //参数1 上下文, 参数2 Provider主机地址 和配置文件中保持一致   参数3  共享的文件
+            Uri uri = FileProvider.getUriForFile(mContext, mContext.getPackageName()+".provider", apkFile);
+            //添加这一句表示对目标应用临时授权该Uri所代表的文件
+//                    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            intent.setDataAndType(uri, "application/vnd.android.package-archive");
+        } else {
+            intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
+        }
+        mContext.startActivity(intent);
+        return true;
+    }
+
+
+    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) {
+                Log.d(TAG, "apk path: " + apkPath);
+                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 installApp(String packageName, String apkPath) {
+        Process process = null;
+        BufferedReader successResult = null;
+        BufferedReader errorResult = null;
+        StringBuilder successMsg = new StringBuilder();
+        StringBuilder errorMsg = new StringBuilder();
+        Log.e(TAG, "install package: " + packageName + ", apkPath: " + apkPath);
+        try {
+            process = new ProcessBuilder("pm", "install", "-i", packageName, "-r", apkPath).start();
+            successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
+            errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
+            String s;
+            while ((s = successResult.readLine()) != null) {
+                successMsg.append(s);
+            }
+            while ((s = errorResult.readLine()) != null) {
+                errorMsg.append(s);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (successResult != null) {
+                    successResult.close();
+                }
+                if (errorResult != null) {
+                    errorResult.close();
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            if (process != null) {
+                process.destroy();
+            }
+        }
+        Log.e(TAG, "" + errorMsg.toString());
+        //如果含有“success”认为安装成功
+        return successMsg.toString().equalsIgnoreCase("success");
+    }
+
+    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) {
+        Intent intent = new Intent(Intent.ACTION_REBOOT);
+        intent.putExtra("nowait", 1);
+        intent.putExtra("interval", 1);
+        intent.putExtra("window", 0);
+        context.sendBroadcast(intent);
+    }
+
+    public interface UpdateCallBack {
+        void onFailed();
+
+        void onSuccess();
+    }
+}

+ 192 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/helper/AsyncPlayer.java

@@ -0,0 +1,192 @@
+package com.wdkl.ncs.android.component.home.helper;
+
+import android.content.Context;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.LinkedList;
+
+/**
+ * 响铃相关类
+ */
+public class AsyncPlayer {
+    private static final int PLAY = 1;
+    private static final int STOP = 2;
+    private AudioManager audioManager;
+
+    private static final class Command {
+        int code;
+        Context context;
+        int resId;
+        boolean looping;
+        int stream;
+        long requestTime;
+
+        public String toString() {
+            return "{ code=" + code + " looping=" + looping + " stream=" + stream + " resId=" + resId + " }";
+        }
+    }
+
+    private final LinkedList mCmdQueue = new LinkedList();
+
+    private void startSound(Command cmd) {
+
+        try {
+            //MediaPlayer player = new MediaPlayer();
+            MediaPlayer player = MediaPlayer.create(cmd.context, cmd.resId);
+            player.setAudioStreamType(cmd.stream);
+            //player.setDataSource(cmd.context, cmd.uri);
+            player.setLooping(cmd.looping);
+            player.setVolume(1.0f, 1.0f);
+            //player.prepare();
+            player.start();
+            if (mPlayer != null) {
+                mPlayer.release();
+            }
+            mPlayer = player;
+            Log.w(mTag, "start sound " + cmd.resId);
+        } catch (Exception e) {
+            Log.w(mTag, "error loading sound for " + cmd.resId, e);
+        }
+    }
+
+    private final class PlayThread extends Thread {
+        PlayThread() {
+            super("AsyncPlayer-" + mTag);
+        }
+
+        public void run() {
+            while (true) {
+                Command cmd = null;
+
+                synchronized (mCmdQueue) {
+
+                    cmd = (Command) mCmdQueue.removeFirst();
+                }
+
+                switch (cmd.code) {
+                    case PLAY:
+                        startSound(cmd);
+                        break;
+                    case STOP:
+                        if (mPlayer != null) {
+                            mPlayer.stop();
+                            mPlayer.reset();
+                            mPlayer.release();
+                            mPlayer = null;
+                        } else {
+                            Log.w(mTag, "STOP command without a player");
+                        }
+                        break;
+                }
+
+                synchronized (mCmdQueue) {
+                    if (mCmdQueue.size() == 0) {
+
+                        mThread = null;
+                        releaseWakeLock();
+                        return;
+                    }
+                }
+            }
+        }
+    }
+
+    private String mTag;
+    private Thread mThread;
+    private MediaPlayer mPlayer;
+    private PowerManager.WakeLock mWakeLock;
+
+    private int mState = STOP;
+
+    public AsyncPlayer(String tag) {
+        if (tag != null) {
+            mTag = tag;
+        } else {
+            mTag = "AsyncPlayer";
+        }
+    }
+
+    public void play(Context context, int res, boolean looping, int stream) {
+        Command cmd = new Command();
+        cmd.requestTime = SystemClock.uptimeMillis();
+        cmd.code = PLAY;
+        cmd.context = context;
+        cmd.resId = res;
+        cmd.looping = looping;
+        cmd.stream = stream;
+        synchronized (mCmdQueue) {
+            enqueueLocked(cmd);
+            mState = PLAY;
+        }
+    }
+
+    public void stop() {
+        synchronized (mCmdQueue) {
+            if (mState != STOP) {
+                Command cmd = new Command();
+                cmd.requestTime = SystemClock.uptimeMillis();
+                cmd.code = STOP;
+                enqueueLocked(cmd);
+                mState = STOP;
+            }
+        }
+    }
+
+    public boolean isPlay() {
+        return mState == PLAY;
+    }
+
+    private void enqueueLocked(Command cmd) {
+        mCmdQueue.add(cmd);
+        if (mThread == null) {
+            acquireWakeLock();
+            mThread = new PlayThread();
+            mThread.start();
+        }
+    }
+
+    public void setUsesWakeLock(Context context) {
+        if (mWakeLock != null || mThread != null) {
+            throw new RuntimeException("assertion failed mWakeLock=" + mWakeLock + " mThread=" + mThread);
+        }
+        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, mTag);
+    }
+
+    private void acquireWakeLock() {
+        if (mWakeLock != null) {
+            mWakeLock.acquire();
+        }
+    }
+
+    private void releaseWakeLock() {
+        if (mWakeLock != null) {
+            mWakeLock.release();
+        }
+    }
+
+    private boolean isHeadphonesPlugged(Context context) {
+        if (audioManager == null) {
+            audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        }
+        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
+            AudioDeviceInfo[] audioDevices = audioManager.getDevices(AudioManager.GET_DEVICES_ALL);
+            for (AudioDeviceInfo deviceInfo : audioDevices) {
+                if (deviceInfo.getType() == AudioDeviceInfo.TYPE_WIRED_HEADPHONES
+                        || deviceInfo.getType() == AudioDeviceInfo.TYPE_WIRED_HEADSET) {
+                    return true;
+                }
+            }
+            return false;
+        } else {
+            return audioManager.isWiredHeadsetOn();
+        }
+    }
+}

+ 161 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/helper/HttpHelper.java

@@ -0,0 +1,161 @@
+package com.wdkl.ncs.android.component.home.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.ncs.android.component.home.helper.AppUpdateHelper.FILE_APK_NAME;
+import static com.wdkl.ncs.android.component.home.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();
+    }
+}

+ 64 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/helper/SerialPortHelper.java

@@ -0,0 +1,64 @@
+//package com.wdkl.ncs.android.component.home.helper;
+//
+//import android.content.Context;
+//
+//import com.wdkl.ncs.android.component.nursehome.util.VoiceManagerUtil;
+//
+//import serialporttest.utils.SerialPortUtil;
+//
+//public class SerialPortHelper {
+//
+//    //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");
+//        }
+//    }
+//
+//    /**
+//     * 设置免提
+//     */
+//    public static void setHandsFree(boolean isHandsFree) {
+////        LogUtil.d(LogUtil.getTag(null), "是否需要免提==" + isHandsFree);
+//        if (isHandsFree) {
+//            if (null != SerialPortUtil.getInstance()) {
+//                SerialPortUtil.getInstance().sendCommand(SerialPortUtil.AUDIO, "0", "F");
+//            }
+//        } else {
+//            if (null != SerialPortUtil.getInstance()) {
+//                SerialPortUtil.getInstance().sendCommand(SerialPortUtil.AUDIO, "1", "F");
+//            }
+//        }
+//    }
+//    public static void setCallVoice(Context context, int type) { //0为外喇叭 1为 手柄
+////        int sb = SharedPreferencesUtil.getIntSp(getActivity(), Constants.MSG_SP, SharedPreferencesUtil.SbCallingVoice);
+////        int sbing = SharedPreferencesUtil.getIntSp(getActivity(), Constants.MSG_SP, SharedPreferencesUtil.SbingCallingVoice);
+//        int sb = 60;
+//        int sbing = 70;
+//        if (0 == type) {
+//            if (sb < 0) {
+//                VoiceManagerUtil.setCallVoice(context, 90);
+//            } else {
+//                VoiceManagerUtil.setCallVoice(context, sb);
+//            }
+//        }
+//
+//        if (1 == type) {
+//            if (sbing < 0) {
+//                VoiceManagerUtil.setCallVoice(context, 90);
+//            } else {
+//                VoiceManagerUtil.setCallVoice(context, sbing);
+//            }
+//        }
+//
+//    }
+//
+//
+//
+//
+//
+//}

+ 27 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/launch/HomeLaunch.kt

@@ -0,0 +1,27 @@
+package com.wdkl.ncs.android.component.home.launch
+
+import com.wdkl.ncs.android.component.home.di.DaggerHomeComponent
+import com.wdkl.ncs.android.component.home.di.HomeComponent
+import com.enation.javashop.android.jrouter.external.annotation.Router
+import com.wdkl.ncs.android.lib.base.BaseLaunch
+import com.wdkl.ncs.android.middleware.di.DaggerManager
+
+/**
+ * @author LDD
+ * @Date   2018/1/22 下午2:44
+ * @From   com.wdkl.ncs.android.component.home.launch
+ * @Note   home模块启动类 代替Application 在壳工程Application中反射调用
+ */
+@Router(path = "/home/launch")
+class HomeLaunch : BaseLaunch() {
+    companion object {
+        lateinit var component:HomeComponent
+    }
+
+    override fun moduleInit() {
+        component = DaggerHomeComponent.builder()
+                .applicationComponent(DaggerManager.APPLICATION_COMPONENT)
+                .build()
+    }
+
+}

+ 113 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/service/TcpHandleService.kt

@@ -0,0 +1,113 @@
+package com.wdkl.ncs.android.component.home.service
+
+import android.app.Service
+import android.content.Intent
+import android.os.Binder
+import android.os.IBinder
+import android.util.Log
+import com.alibaba.fastjson.JSONObject
+import com.google.gson.Gson
+import com.wdkl.ncs.android.component.home.activity.*
+import com.wdkl.ncs.android.component.home.util.AppUtils
+import com.wdkl.ncs.android.component.home.util.Util
+import com.wdkl.ncs.android.component.nursehome.common.Constants
+import com.wdkl.ncs.android.lib.base.BaseApplication
+import com.wdkl.ncs.android.lib.utils.AppTool
+import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
+import com.wdkl.ncs.android.middleware.tcp.channel.DeviceChannel
+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.CommonUtils
+import com.wdkl.ncs.android.middleware.utils.MessageEvent
+import org.greenrobot.eventbus.EventBus
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+
+
+class TcpHandleService : Service(){
+    val TAG = TcpHandleService.javaClass.canonicalName
+    companion object instance {
+        var updateLastTime : Long = System.currentTimeMillis() / 1000
+    }
+
+    override fun onBind(intent: Intent?): IBinder? {
+        return ServiceBinder()
+    }
+
+    inner class ServiceBinder : Binder() {
+        fun doThings() {
+        }
+    }
+
+    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+        Log.i("TcpHandleService", "已经启动")
+
+        return super.onStartCommand(intent, flags, startId)
+    }
+
+    override fun onCreate() {
+        super.onCreate()
+        EventBus.getDefault().register(this)
+    }
+
+    override fun onDestroy() {
+        EventBus.getDefault().unregister(this)
+        super.onDestroy()
+    }
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    fun onMoonEvent(messageEvent: MessageEvent) {
+        when(messageEvent.tag){
+            //APP升级
+            Constants.EVENT_APP_UPDATE->{
+                while (DeviceChannel.calling) {    //通话中不处理,一直等待至结束
+                    Thread.sleep(3000)
+                }
+
+                DeviceChannel.calling = true    //置于通话状态中,不可呼叫
+                Util.wakeUpAndUnlock(this)
+                var tcpModel = messageEvent.getMessage() as TcpModel
+                if (tcpModel.action == TcpAction.DeviceAction.APP_UPDATE) {
+                    if ((System.currentTimeMillis() / 1000) - updateLastTime > 10){   //大于10秒可继续升级
+                        updateLastTime = System.currentTimeMillis() / 1000
+                        var intent = Intent()
+                        intent.setClass(this, AppUpdateActivity::class.java)
+                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                        startActivity(intent)
+                    }
+                }
+            }
+
+            Constants.EVENT_RESTART_APP -> {
+                AppUtils.restartApp()
+            }
+
+            //服务器IP地址切换
+            Constants.EVENT_SERVER_CHANGE -> {
+                val tcpModel = messageEvent.getMessage() as TcpModel
+                if (tcpModel.data != null) {
+                    val json = JSONObject.parseObject(tcpModel.data.toString())
+                    val serverIp = json.getString("server_ip")
+                    val serverPort = json.getString("server_port")
+                    //Log.e(TAG, "change server ip:$serverIp, server port:$serverPort")
+                    CommonUtils.setUrl(BaseApplication.appContext, serverIp)
+                    CommonUtils.setUrlPort(BaseApplication.appContext, serverPort)
+                    AppTool.Time.delay(2000) {
+                        AppUtils.restartApp()
+                    }
+                }
+            }
+
+            //网络断开,1000ms重连
+            /*Constants.EVENT_TCP_BREAK->{
+                var wakeLock = Util.wakeUpAndUnlock(this)
+                Thread(Runnable {
+                    Thread.sleep(1000)
+                    wakeLock?.release()
+                }).start()
+                Log.w(TAG, "EVENT TCP BREAK")
+            }*/
+        }
+    }
+}

+ 75 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/service/WdKeepAliveService.kt

@@ -0,0 +1,75 @@
+/*
+package com.wdkl.ncs.android.component.home.service
+
+import android.content.Intent
+import android.os.Handler
+import android.os.IBinder
+import android.os.Messenger
+import android.util.Log
+import com.wdkl.ncs.keepbackground.work.AbsWorkService
+import com.wdkl.ncs.android.component.home.util.NetHelper
+import com.wdkl.ncs.android.component.home.util.Util
+import com.wdkl.ncs.android.component.nursehome.common.Constants
+import com.wdkl.ncs.android.lib.utils.AppTool
+import com.wdkl.ncs.android.middleware.tcp.TcpClient
+import com.wdkl.ncs.android.middleware.tcp.TcpClientHandler
+import java.util.*
+
+class WdKeepAliveService : AbsWorkService() {
+    val TAG = "WdKeepAliveService"
+
+    private var mIsRunning = false
+
+    override fun startWork() {
+        checkNetState()
+    }
+
+    override fun isWorkRunning(): Boolean {
+        return mIsRunning
+    }
+
+    override fun needStartWorkService(): Boolean {
+        return true
+    }
+
+    override fun stopWork() {
+    }
+
+    override fun onBindService(p0: Intent?, p1: Void?): IBinder {
+        return Messenger(Handler()).binder
+    }
+
+    override fun onServiceKilled() {
+    }
+
+    var checkNetStateTimer: Timer? = null
+    var checkNetStateTimerTask: TimerTask? = null
+
+    */
+/**
+     * 重连wdklRTC
+     *//*
+
+    private fun checkNetState() {
+        if (!mIsRunning) {
+            mIsRunning = true
+            if (checkNetStateTimer != null) checkNetStateTimer!!.purge()
+            if (checkNetStateTimerTask != null) checkNetStateTimerTask!!.cancel()
+            checkNetStateTimer = Timer()
+            checkNetStateTimerTask = object : TimerTask() {
+                override fun run() {
+                    TcpClient.getInstance().sendMsg("0")
+                    if (NetHelper.getInstance().getNetworkState(this@WdKeepAliveService) == NetHelper.NETWORK_NONE || !TcpClientHandler.getConnected()) {
+                        Log.w(TAG, "断网唤醒CPU")
+                        var wakeLock = Util.wakeUpAndUnlock(this@WdKeepAliveService)
+                        Thread(Runnable {
+                            Thread.sleep(1000)
+                            wakeLock?.release()
+                        })
+                    }
+                }
+            }
+            checkNetStateTimer!!.schedule(checkNetStateTimerTask, 18000, Constants.heartBeat * 1000L)
+        }
+    }
+}*/

+ 61 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/settingconfig/SettingConfig.java

@@ -0,0 +1,61 @@
+package com.wdkl.ncs.android.component.home.settingconfig;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+public class SettingConfig {
+
+    private static final String SP_NAME = "SP_FUNCTION";
+
+    //呼叫转接时间设置
+    private static final String KEY_SP_COUNTDOWN_TIME = "KEY_SP_COUNTDOWN_TIME";
+    private static final int CountdownTime = 15;
+
+    //分机通话音量
+    private static final String KEY_SP_EXTENSION_CALL_VOLUME = "KEY_SP_EXTENSION_CALL_VOLUME";
+    private static final int extension_call_volume = 80;
+
+    /**
+     * 获取转发时间
+     *
+     * @return
+     */
+    public static int getCountdownTime(Context context) {
+        return getSP(context).getInt(KEY_SP_COUNTDOWN_TIME, CountdownTime);
+    }
+
+    /**
+     * 设置转发时间
+     *
+     * @param value
+     */
+    public static void setCountdownTime(Context context, int value) {
+        getEditor(context).putInt(KEY_SP_COUNTDOWN_TIME, 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();
+    }
+
+    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();
+    }
+}

+ 235 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/AnrFcExceptionUtil.java

@@ -0,0 +1,235 @@
+package com.wdkl.ncs.android.component.home.util;
+
+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.home.activity.HomeActivity;
+import com.wdkl.ncs.android.middleware.api.UrlManager;
+import com.wdkl.ncs.android.middleware.tcp.channel.DeviceChannel;
+
+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 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 = "AnrFcExceptionUtil";
+    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(3000);
+            } catch (InterruptedException e) {
+                Log.e(TAG, "error : ", e);
+            }
+
+            restartApp();
+        }
+    }
+
+    private void restartApp() {
+        DeviceChannel.calling = false;
+
+        //重新启动app
+        Intent mStartActivity = new Intent(application.getApplicationContext(), HomeActivity.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;
+        }
+
+        saveCrashInfo2File(ex);
+        return true;
+    }
+
+    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.getDevice_url() + "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);
+            }
+        });
+    }
+
+    /**
+     * 保存错误信息到文件中
+     *
+     * @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();
+            String time = format.format(new Date());
+            String fileName = "crash-" + time + "-" + timestamp + ".txt";
+            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+                String path = Environment.getExternalStorageDirectory() + "/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;
+    }
+
+    /**
+     * ===================================================崩溃异常处理===================================================
+     */
+    public void initFCException() {
+        //设置该CrashHandler为程序的默认处理器
+        AnrFcExceptionUtil catchExcep = AnrFcExceptionUtil.getInstance(application);
+        Thread.setDefaultUncaughtExceptionHandler(catchExcep);
+        mANRWatchDog = new ANRWatchDog(10000);
+        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());*/
+
+                Log.d("anr", "Anr restart app...");
+                restartApp();
+            }
+        }).start();
+
+    }
+}

+ 123 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/AppUtils.java

@@ -0,0 +1,123 @@
+package com.wdkl.ncs.android.component.home.util;
+
+import android.annotation.SuppressLint;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.media.AudioManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.wdkl.ncs.android.component.home.activity.HomeActivity;
+import com.wdkl.ncs.android.lib.base.BaseApplication;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class AppUtils {
+
+    public static void restartApp() {
+        try {
+            Log.i("AppUtil", "restartApp ======================");
+            //重新启动app
+            Intent mStartActivity = new Intent(BaseApplication.appContext, HomeActivity.class);
+            mStartActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+            int mPendingIntentId = 123456;
+            PendingIntent mPendingIntent = PendingIntent.getActivity(BaseApplication.appContext, mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
+            AlarmManager mgr = (AlarmManager) BaseApplication.appContext.getSystemService(Context.ALARM_SERVICE);
+            mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1500, mPendingIntent);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        android.os.Process.killProcess(android.os.Process.myPid());
+        System.exit(0);
+    }
+
+    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);
+    }
+
+    /**
+     * 设置系统时间
+     *
+     * @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";
+        }
+    }
+
+    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 switchAudioMode(Context context, boolean speakerOn) {
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        audioManager.setSpeakerphoneOn(speakerOn);
+        /*if (speakerOn) {
+            audioManager.setMode(AudioManager.MODE_NORMAL);
+        } else {
+            audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
+        }*/
+    }
+
+    public static void setAudioMode(Context context, int mode) {
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        audioManager.setMode(mode);
+    }
+
+    //是否隐藏系统栏
+    public static void hideStatusBar(Context context, boolean hide) {
+        Intent intent = new Intent();
+        if (hide) {
+            intent.setAction("com.elclcd.hidebar");
+        } else {
+            intent.setAction("com.elclcd.unhidebar");
+        }
+        context.sendBroadcast(intent);
+    }
+}

+ 89 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/CallDialogHelper.java

@@ -0,0 +1,89 @@
+package com.wdkl.ncs.android.component.home.util;
+
+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.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.wdkl.ncs.android.component.home.R;
+
+
+public class CallDialogHelper {
+
+    private static AlertDialog callDialog;
+
+    public static void showCallDialog(Activity activity, int callType, String callText, View.OnClickListener hangupCall, View.OnClickListener acceptCall, View.OnClickListener rejectCall) {
+        View contentView = LayoutInflater.from(activity).inflate(R.layout.call_dialog_lay, null);
+        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+        builder.setView(contentView);
+
+        LinearLayout outCall = contentView.findViewById(R.id.ll_call_outgoing);
+        ImageView hangup = contentView.findViewById(R.id.iv_hangup_call);
+
+        RelativeLayout inCall = contentView.findViewById(R.id.rl_call_incoming);
+        ImageView accept = contentView.findViewById(R.id.iv_accept_call);
+        ImageView reject = contentView.findViewById(R.id.iv_reject_call);
+        TextView inText = contentView.findViewById(R.id.tv_incoming_call_text);
+        TextView outText = contentView.findViewById(R.id.tv_out_call_text);
+
+        if (callType == 0) {
+            //去电
+            outCall.setVisibility(View.VISIBLE);
+            inCall.setVisibility(View.GONE);
+            outText.setText(callText);
+            RingPlayHelper.playRingTone(activity, R.raw.ring_back2, true);
+        } else {
+            //来电
+            outCall.setVisibility(View.GONE);
+            inCall.setVisibility(View.VISIBLE);
+            inText.setText(callText);
+            RingPlayHelper.playRingTone(activity, R.raw.incoming_call, false);
+
+        }
+
+        hangup.setOnClickListener(hangupCall);
+        accept.setOnClickListener(acceptCall);
+        reject.setOnClickListener(rejectCall);
+
+        callDialog = builder.create();
+        callDialog.setCanceledOnTouchOutside(false);
+        callDialog.setCancelable(false);
+
+        //设置dialog宽高及位置
+        try {
+            Window window = callDialog.getWindow();
+            window.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
+            callDialog.show();
+            WindowManager.LayoutParams lp = window.getAttributes();
+            lp.width = 800;
+            lp.height = 600;
+            lp.gravity = Gravity.CENTER;
+            //lp.alpha = 0.8f;//设置透明度
+            window.setAttributes(lp);
+
+            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+                    | View.SYSTEM_UI_FLAG_FULLSCREEN);
+            window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void dismissCallDialog() {
+        if (callDialog != null && callDialog.isShowing()) {
+            callDialog.dismiss();
+            RingPlayHelper.stopRingTone();
+        }
+    }
+}

+ 14 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/EthernetWifiCallBack.java

@@ -0,0 +1,14 @@
+package com.wdkl.ncs.android.component.home.util;
+
+/**
+ * ======================以太网和wifi状态接口=====================
+ * Created by dengzhe on 2018/2/7.
+ */
+
+public interface EthernetWifiCallBack {
+
+    boolean ethernetStatus(boolean status);//以太网状态
+
+    boolean wifiStatus(boolean status);//wifi状态
+
+}

+ 283 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/MediaPlayHelper.java

@@ -0,0 +1,283 @@
+package com.wdkl.ncs.android.component.home.util;
+
+import android.content.Intent;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Message;
+import android.support.v4.media.session.MediaSessionCompat;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.KeyEvent;
+
+import com.wdkl.ncs.android.component.nursehome.common.Constants;
+import com.wdkl.ncs.android.lib.base.BaseApplication;
+import com.wdkl.ncs.android.middleware.utils.MessageEvent;
+import com.wdkl.ncs.janus.rtc.AudioFocusManager;
+
+import org.greenrobot.eventbus.EventBus;
+
+public class MediaPlayHelper {
+    private static String TAG = MediaPlayHelper.class.getCanonicalName();
+
+    private static MediaPlayHelper sInstance = null;
+    private MediaPlayer mediaPlayer;
+    private HandlerThread playHandlerThread;
+    private Handler playHandler;
+    private MediaSessionCompat mediaSessionCompat;
+    private AudioFocusManager audioFocusManager;
+
+    private int mResId;
+    private String mUrl;
+    private float mVolume;
+    private boolean mLoop;
+
+    /**
+     * 播放res资源
+     */
+    public static final int PLAY_RES = 100;
+    /**
+     * 播放url资源
+     */
+    public static final int PLAY_URL = 101;
+    /**
+     * 停止
+     */
+    public static final int STOP = 102;
+    /**
+     * 释放
+     */
+    public static final int RELEASE = 103;
+
+
+    private MediaPlayHelper() {
+        createHandlerThread();
+        audioFocusManager = new AudioFocusManager(BaseApplication.appContext);
+    }
+
+    public static MediaPlayHelper getInstance() {
+        if (sInstance == null) {
+            synchronized (MediaPlayHelper.class) {
+                if (sInstance == null) {
+                    sInstance = new MediaPlayHelper();
+                }
+            }
+        }
+        return sInstance;
+    }
+
+    private void createHandlerThread() {
+        if (playHandlerThread == null) {
+            playHandlerThread = new HandlerThread("playHandlerThread");
+            playHandlerThread.start();
+        }
+
+        if (playHandler == null) {
+            playHandler = new Handler(playHandlerThread.getLooper()) {
+                @Override
+                public void handleMessage(Message msg) {
+                    switch (msg.what) {
+                        case PLAY_RES:
+                            playResMusicNow();
+                            break;
+                        case PLAY_URL:
+                            playUrlMusicNow();
+                            break;
+                        case STOP:
+                            stopMusicNow();
+                            break;
+                        case RELEASE:
+                            releaseMediaNow();
+                            break;
+                        default:
+                            break;
+                    }
+                }
+            };
+        }
+    }
+
+    public void playResMusic(int id, float vol, boolean loop) {
+        mResId = id;
+        mVolume = vol;
+        mLoop = loop;
+        playHandler.sendEmptyMessage(PLAY_RES);
+    }
+
+    public void playUrlMusic(String url, float vol, boolean loop) {
+        mUrl = url;
+        mVolume = vol;
+        mLoop = loop;
+        playHandler.sendEmptyMessage(PLAY_URL);
+    }
+
+    public void stopMusic() {
+        playHandler.sendEmptyMessage(STOP);
+    }
+
+    public void releaseMusic() {
+        playHandler.sendEmptyMessage(RELEASE);
+    }
+
+    //播放本地res音频资源
+    private void playResMusicNow() {
+        if (mediaPlayer != null) {
+            mediaPlayer.stop();
+        }
+        mediaPlayer = MediaPlayer.create(BaseApplication.appContext, mResId);
+        try {
+            mediaPlayer.setLooping(mLoop);
+            mediaPlayer.setVolume(mVolume, mVolume);
+            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+            mediaPlayer.start();
+            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+                @Override
+                public void onCompletion(MediaPlayer player) {
+                    //playMusicComplete();
+                    //stopMusicNow();
+                }
+            });
+            mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
+                @Override
+                public boolean onError(MediaPlayer player, int what, int extra) {
+                    //playMusicError();
+                    stopMusicNow();
+                    releaseMediaSession();
+                    return false;
+                }
+            });
+            initMediaSession();
+        } catch (Exception e) {
+            //playMusicError();
+            e.printStackTrace();
+        }
+    }
+
+    //播放远程或本地存储音频资源
+    private void playUrlMusicNow() {
+        if (mediaPlayer != null) {
+            mediaPlayer.stop();
+        }
+        mediaPlayer = new MediaPlayer();
+        try {
+            mediaPlayer.reset();
+            mediaPlayer.setDataSource(mUrl);
+            mediaPlayer.setLooping(mLoop);
+            mediaPlayer.setVolume(mVolume, mVolume);
+            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
+                @Override
+                public void onPrepared(MediaPlayer player) {
+                    if (mediaPlayer != null) {
+                        mediaPlayer.start();
+                    }
+                }
+            });
+            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+                @Override
+                public void onCompletion(MediaPlayer player) {
+                    //playMusicComplete();
+                    //stopMusicNow();
+                }
+            });
+            mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
+                @Override
+                public boolean onError(MediaPlayer player, int what, int extra) {
+                    //playMusicError();
+                    stopMusicNow();
+                    return false;
+                }
+            });
+            mediaPlayer.prepareAsync();
+        } catch (Exception e) {
+            //playMusicError();
+            e.printStackTrace();
+        }
+    }
+
+    private void stopMusicNow() {
+        if (mediaPlayer != null) {
+            mediaPlayer.setOnPreparedListener(null);
+            mediaPlayer.setOnCompletionListener(null);
+            try {
+                if (mediaPlayer.isPlaying()) {
+                    mediaPlayer.stop();
+                }
+            } catch (IllegalStateException e) {
+                e.printStackTrace();
+            }
+        }
+        mediaPlayer = null;
+        releaseMediaSession();
+    }
+
+    private void releaseMediaNow() {
+        if (mediaPlayer != null) {
+            mediaPlayer.setOnPreparedListener(null);
+            mediaPlayer.setOnCompletionListener(null);
+            try {
+                mediaPlayer.stop();
+                mediaPlayer.release();
+            } catch (IllegalStateException e) {
+                e.printStackTrace();
+            }
+        }
+        mediaPlayer = null;
+        releaseMediaSession();
+    }
+
+    public boolean isMediaPlaying() {
+        if (mediaPlayer != null) {
+            return mediaPlayer.isPlaying();
+        }
+        return false;
+    }
+
+    private void initMediaSession(){
+        if (mediaSessionCompat!=null){
+            releaseMediaSession();
+        }
+
+        audioFocusManager.requestFocus();
+
+        mediaSessionCompat = new MediaSessionCompat(BaseApplication.appContext,TAG);
+        mediaSessionCompat.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS);
+        mediaSessionCompat.setActive(true);
+        mediaSessionCompat.setCallback(new MediaSessionCompat.Callback(){
+            @Override
+            public boolean onMediaButtonEvent(Intent intent) {
+                String action = intent.getAction();
+                if (action != null) {
+                    if (TextUtils.equals(action, Intent.ACTION_MEDIA_BUTTON)) {
+                        KeyEvent keyEvent = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+                        if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
+                            Integer keyCode = keyEvent.getKeyCode();
+                            Log.i(TAG, "mediasession keycode " + keyCode);
+                            switch (keyCode) {
+                                case KeyEvent.KEYCODE_MEDIA_PLAY:
+                                case KeyEvent.KEYCODE_MEDIA_PAUSE:
+                                    EventBus.getDefault().post(new MessageEvent(1, Constants.EVENT_BLUETOOTH_ACCEPT_CALL));
+                                    break;
+                                default:
+                                    break;
+                            }
+                        }
+                    }
+                }
+                return super.onMediaButtonEvent(intent);
+            }
+        });
+    }
+
+    private void releaseMediaSession(){
+        if (mediaSessionCompat!=null){
+            mediaSessionCompat.setCallback(null);
+            mediaSessionCompat.setActive(false);
+            mediaSessionCompat.release();
+            mediaSessionCompat = null;
+
+            audioFocusManager.releaseAudioFocus();
+        }
+    }
+}

+ 115 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/MediaPlayer.kt

@@ -0,0 +1,115 @@
+package com.wdkl.ncs.android.component.nursehome.util
+
+import android.media.AudioManager
+import android.media.MediaPlayer
+import android.util.Log
+import com.umeng.weixin.umengwx.e
+import java.io.IOException
+import java.lang.IllegalStateException
+
+class MediaPlayer {
+    private val TAG = MediaPlayer::class.java.getSimpleName()
+
+    var mMediaPlayer: MediaPlayer? = null
+
+    init {
+        Log.e(TAG, "初始化播放器")
+        mMediaPlayer = MediaPlayer()
+        //这样设置 不能控制本音乐的音量大小 也就是setVolume无效
+//        mMediaPlayer!!.setAudioStreamType(AudioManager.STREAM_MUSIC)
+        mMediaPlayer!!.setAudioStreamType(AudioManager.STREAM_VOICE_CALL)
+        mMediaPlayer!!.setOnCompletionListener {
+            Log.e(TAG, "播放完成")
+        }
+
+        mMediaPlayer!!.setOnPreparedListener {
+            Log.e(TAG, "加载完长")
+            mMediaPlayer!!.start()
+        }
+        mMediaPlayer!!.setOnErrorListener { mp, what, extra ->
+            Log.e(TAG, "异常")
+            false
+        }
+
+    }
+
+    //启动播放
+    fun startMediaPlayer(url: String) {
+        if ((mMediaPlayer != null && mMediaPlayer!!.isPlaying())) {
+            mMediaPlayer!!.stop()
+        }
+        mMediaPlayer!!.reset()
+        //设置音频文件到MediaPlayer对象中
+        //测试地址 "http://file.kuyinyun.com/group1/M00/90/B7/rBBGdFPXJNeAM-nhABeMElAM6bY151.mp3"
+        try {
+            mMediaPlayer!!.setDataSource(url)
+            //让MediaPlayer对象准备,用这个方法防止加载时耗时导致anr
+            mMediaPlayer!!.prepareAsync()
+        } catch (e: IOException) {
+            e.printStackTrace()
+            Log.e(TAG, "播放异常")
+        }catch (e:IllegalStateException) {
+            e.message
+            Log.e(TAG, "IllegalStateException+播放异常");
+        }
+
+    }
+
+    /**
+     * 暂停播放
+     */
+    fun pauseMediaPlayer() {
+        if (mMediaPlayer != null) {
+            mMediaPlayer!!.pause()
+        }
+
+    }
+
+    /**
+     * 继续播放
+     */
+    fun continueToPlayMediaPlayer() {
+        if (mMediaPlayer != null) {
+            mMediaPlayer!!.start()
+        }
+
+    }
+
+    /**
+     * 停止播放
+     */
+    fun stopMediaPlayer() {
+        if (mMediaPlayer != null) {
+            mMediaPlayer!!.stop()
+        }
+    }
+
+    /**
+     * 释放播放器资源
+     */
+    fun releaseMediaPlayer() {
+        if (mMediaPlayer != null) {
+            try {
+                mMediaPlayer!!.stop()
+                mMediaPlayer!!.release()
+            } catch (e: IllegalStateException) {
+
+            }
+
+        }
+        mMediaPlayer = null
+    }
+
+    /**
+     * 音量设置
+     *setDataSource()方法之后设置才有效
+     * @param volume
+     */
+    fun setVolume(volume: Float) {
+        if (mMediaPlayer != null) {
+            mMediaPlayer!!.setVolume(volume, volume)
+        }
+    }
+
+
+}

+ 638 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/NetHelper.java

@@ -0,0 +1,638 @@
+package com.wdkl.ncs.android.component.home.util;
+
+import android.Manifest;
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.os.Build;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+
+import com.wdkl.ncs.android.component.nursehome.common.Constants;
+import com.wdkl.ncs.android.lib.base.BaseApplication;
+import com.wdkl.ncs.android.middleware.utils.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;
+
+
+public class NetHelper {
+    private WifiManager wifiManager;
+    private ConnectivityManager connManager;
+    private static NetHelper sInstance = null;
+
+    private static Timer timerNetStatus = null;
+    private static final int SCHEDULE_TIME = 20000;
+    public static boolean NetConn = false;
+
+    public static final int NETWORK_NONE = -1;
+    public static final int NETWORK_WIFI = 1;
+    public static final int NETWORK_2G = 2;
+    public static final int NETWORK_3G = 3;
+    public static final int NETWORK_4G = 4;
+    public static final int NETWORK_MOBILE = 5;
+
+    /**
+     * 以太网是否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() {
+        wifiManager = (WifiManager) BaseApplication.appContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
+        connManager = (ConnectivityManager) BaseApplication.appContext.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+    }
+
+    /**
+     * 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() {
+        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N){//小于安卓7 走这里
+            String mac = "";
+            try {
+//                mac = getLocalMacAddressFromIp();
+//                if (TextUtils.isEmpty(mac)) {
+//                    mac = getNetworkMac();
+//                }
+                if (TextUtils.isEmpty(mac)) {
+                    mac = tryGetWifiMac();
+                }
+            } catch (Exception e) {
+            }
+            return mac;
+        }else {//大于等于安卓7走这里
+            List<NetworkInterface> interfaces = null;
+            try {
+                interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
+                for (NetworkInterface networkInterface : interfaces) {
+                    if (networkInterface != null && TextUtils.isEmpty(networkInterface.getName()) == false) {
+                        if ("wlan0".equalsIgnoreCase(networkInterface.getName())) {
+                            byte[] macBytes = networkInterface.getHardwareAddress();
+                            if (macBytes != null && macBytes.length > 0) {
+                                StringBuilder str = new StringBuilder();
+                                for (byte b : macBytes) {
+                                    str.append(String.format("%02X:", b));
+                                }
+                                if (str.length() > 0) {
+                                    str.deleteCharAt(str.length() - 1);
+                                }
+                                return str.toString();
+                            }
+                        }
+                    }
+                }
+            } catch (SocketException e) {
+                e.printStackTrace();
+            }
+            return "unknown";
+
+        }
+    }
+
+    /**
+     * 兼容安卓5-10 获取Mac地址
+     * @return
+     */
+    public String getMacAddress2() {
+        List<NetworkInterface> interfaces = null;
+        try {
+            interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
+            for (NetworkInterface networkInterface : interfaces) {
+                if (networkInterface != null && TextUtils.isEmpty(networkInterface.getName()) == false) {
+                    if ("wlan0".equalsIgnoreCase(networkInterface.getName())) {
+                        byte[] macBytes = networkInterface.getHardwareAddress();
+                        if (macBytes != null && macBytes.length > 0) {
+                            StringBuilder str = new StringBuilder();
+                            for (byte b : macBytes) {
+                                str.append(String.format("%02X:", b));
+                            }
+                            if (str.length() > 0) {
+                                str.deleteCharAt(str.length() - 1);
+                            }
+                            return str.toString();
+                        }
+                    }
+                }
+            }
+        } catch (SocketException e) {
+            e.printStackTrace();
+        }
+        return "unknown";
+    }
+
+
+    /**
+     * 通过WiFiManager获取mac地址
+     * 这个方法Android 7.0是获取不到的,返回的是null,其实是返回“02:00:00:00:00:00”
+     *
+     * @return
+     */
+    public String tryGetWifiMac() {
+        String mac;
+        WifiInfo wi = wifiManager.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;
+    }
+
+    public String getIMEI() {
+        //获取序列号
+        String serial = null;
+        try {
+            serial = android.os.Build.SERIAL;
+            if (serial.equalsIgnoreCase("unknown")||serial.equalsIgnoreCase("0123456789abcdef")) {
+                final TelephonyManager mTelephony = (TelephonyManager) BaseApplication.appContext.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+                    if (BaseApplication.appContext.getApplicationContext().checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
+                        serial = null;
+                    }
+                }
+                assert mTelephony != null;
+                if (mTelephony.getDeviceId() != null) {
+                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                        serial = mTelephony.getImei();
+                    } else {
+                        serial = mTelephony.getDeviceId();
+                    }
+                } else {
+                    serial = Settings.Secure.getString(BaseApplication.appContext.getApplicationContext().getContentResolver(), Settings.Secure.ANDROID_ID);
+                }
+
+            }
+        } catch (Exception e) {
+
+        }
+        return serial;
+    }
+
+
+    /**
+     * 根据IP地址获取MAC地址
+     *
+     * @return
+     */
+    @SuppressLint("NewApi")
+    public static 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;
+    }
+
+    /**
+     * 获取移动设备本地IP
+     *
+     * @return
+     */
+    public static InetAddress getLocalInetAddress() {
+        InetAddress ip = null;
+        try {
+            // 列举
+            Enumeration<NetworkInterface> en_netInterface = NetworkInterface
+                    .getNetworkInterfaces();
+            while (en_netInterface.hasMoreElements()) {// 是否还有元素
+                NetworkInterface ni = (NetworkInterface) 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;
+    }
+
+    //获取本地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 null;
+    }
+
+    public int getNetworkType() {
+        if (connManager != null && connManager.getActiveNetworkInfo() != null) {
+            return connManager.getActiveNetworkInfo().getType();
+        }
+
+        return -1;
+    }
+
+    /**
+     * 获取当前网络连接的类型
+     *
+     * @param context context
+     * @return int
+     */
+    public int getNetworkState(Context context) {
+        ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); // 获取网络服务
+        if (null == connManager) { // 为空则认为无网络
+            return NETWORK_NONE;
+        }
+        // 获取网络类型,如果为空,返回无网络
+        NetworkInfo activeNetInfo = connManager.getActiveNetworkInfo();
+        if (activeNetInfo == null || !activeNetInfo.isAvailable()) {
+            return NETWORK_NONE;
+        }
+        // 判断是否为WIFI
+        NetworkInfo wifiInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        if (null != wifiInfo) {
+            NetworkInfo.State state = wifiInfo.getState();
+            if (null != state) {
+                if (state == NetworkInfo.State.CONNECTED || state == NetworkInfo.State.CONNECTING) {
+                    return NETWORK_WIFI;
+                }
+            }
+        }
+        // 若不是WIFI,则去判断是2G、3G、4G网
+        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+        int networkType = telephonyManager.getNetworkType();
+        switch (networkType) {
+            /*
+             GPRS : 2G(2.5) General Packet Radia Service 114kbps
+             EDGE : 2G(2.75G) Enhanced Data Rate for GSM Evolution 384kbps
+             UMTS : 3G WCDMA 联通3G Universal Mobile Telecommunication System 完整的3G移动通信技术标准
+             CDMA : 2G 电信 Code Division Multiple Access 码分多址
+             EVDO_0 : 3G (EVDO 全程 CDMA2000 1xEV-DO) Evolution - Data Only (Data Optimized) 153.6kps - 2.4mbps 属于3G
+             EVDO_A : 3G 1.8mbps - 3.1mbps 属于3G过渡,3.5G
+             1xRTT : 2G CDMA2000 1xRTT (RTT - 无线电传输技术) 144kbps 2G的过渡,
+             HSDPA : 3.5G 高速下行分组接入 3.5G WCDMA High Speed Downlink Packet Access 14.4mbps
+             HSUPA : 3.5G High Speed Uplink Packet Access 高速上行链路分组接入 1.4 - 5.8 mbps
+             HSPA : 3G (分HSDPA,HSUPA) High Speed Packet Access
+             IDEN : 2G Integrated Dispatch Enhanced Networks 集成数字增强型网络 (属于2G,来自维基百科)
+             EVDO_B : 3G EV-DO Rev.B 14.7Mbps 下行 3.5G
+             LTE : 4G Long Term Evolution FDD-LTE 和 TDD-LTE , 3G过渡,升级版 LTE Advanced 才是4G
+             EHRPD : 3G CDMA2000向LTE 4G的中间产物 Evolved High Rate Packet Data HRPD的升级
+             HSPAP : 3G HSPAP 比 HSDPA 快些
+             */
+            // 2G网络
+            case TelephonyManager.NETWORK_TYPE_GPRS:
+            case TelephonyManager.NETWORK_TYPE_CDMA:
+            case TelephonyManager.NETWORK_TYPE_EDGE:
+            case TelephonyManager.NETWORK_TYPE_1xRTT:
+            case TelephonyManager.NETWORK_TYPE_IDEN:
+                return NETWORK_2G;
+            // 3G网络
+            case TelephonyManager.NETWORK_TYPE_EVDO_A:
+            case TelephonyManager.NETWORK_TYPE_UMTS:
+            case TelephonyManager.NETWORK_TYPE_EVDO_0:
+            case TelephonyManager.NETWORK_TYPE_HSDPA:
+            case TelephonyManager.NETWORK_TYPE_HSUPA:
+            case TelephonyManager.NETWORK_TYPE_HSPA:
+            case TelephonyManager.NETWORK_TYPE_EVDO_B:
+            case TelephonyManager.NETWORK_TYPE_EHRPD:
+            case TelephonyManager.NETWORK_TYPE_HSPAP:
+                return NETWORK_3G;
+            // 4G网络
+            case TelephonyManager.NETWORK_TYPE_LTE:
+                return NETWORK_4G;
+            default:
+                return NETWORK_MOBILE;
+        }
+    }
+}

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

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

+ 159 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/ServerConfigDialogHelper.java

@@ -0,0 +1,159 @@
+package com.wdkl.ncs.android.component.home.util;
+
+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.ncs.android.component.home.R;
+import com.wdkl.ncs.android.component.home.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("请输入密码");
+                }
+            }
+        });
+
+        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, "密码错误", 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("参数不能为空");
+                } else {
+                    //保存配置
+                    CommonUtils.setUrl(BaseApplication.appContext, url);
+                    CommonUtils.setUrlPort(BaseApplication.appContext, port);
+                    //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 = 480;
+            lp.height = 720;
+            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();
+        }
+    }
+}

+ 203 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/SpeechUtil.java

@@ -0,0 +1,203 @@
+package com.wdkl.ncs.android.component.home.util;
+
+import android.content.Context;
+import android.os.Build;
+import android.speech.tts.TextToSpeech;
+import android.speech.tts.UtteranceProgressListener;
+import android.text.TextUtils;
+import android.util.Log;
+
+
+import com.wdkl.ncs.android.component.nursehome.common.Constants;
+
+import java.util.ArrayList;
+import java.util.Locale;
+
+public class SpeechUtil {
+    private static final String TAG = "SpeechUtil";
+
+    private TextToSpeech textToSpeech;
+    private static SpeechUtil speech;
+    private int speakIndex = 0;
+    private int loopCount = 1;
+    private boolean isStop = true;
+    public volatile static ArrayList<String> speechTextList = new ArrayList<>();
+    private Thread speechThread;
+    private boolean isSpeechLoop = true;
+    private String speakSpeech;
+    private final Object lockObject = new Object();
+
+    public static SpeechUtil getInstance() {
+        if (speech == null) {
+            synchronized (SpeechUtil.class) {
+                if (speech == null) {
+                    speech = new SpeechUtil();
+                }
+            }
+        }
+        return speech;
+    }
+
+    public void init(Context context) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
+            textToSpeech = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
+                @Override
+                public void onInit(int status) {
+                    if (status == TextToSpeech.SUCCESS) {
+                        int supported = textToSpeech.setLanguage(Locale.CHINESE);
+                        if ((supported != TextToSpeech.LANG_AVAILABLE) && (supported != TextToSpeech.LANG_COUNTRY_AVAILABLE)) {
+                            Constants.Companion.setTtsState(1);
+                            Log.d(TAG, "onInit: 当前不支持中文");
+                        } else {
+                            Constants.Companion.setTtsState(2);
+                            Log.d(TAG, "onInit: 支持中文");
+                        }
+                        Log.d(TAG, "onInit: TTS引擎初始化成功");
+                    } else {
+                        Constants.Companion.setTtsState(0);
+                        Log.d(TAG, "onInit: TTS引擎初始化失败");
+                    }
+                }
+            }, "com.iflytek.speechcloud");
+        } else {
+            textToSpeech = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
+                @Override
+                public void onInit(int status) {
+                    if (status == TextToSpeech.SUCCESS) {
+                        int supported = textToSpeech.setLanguage(Locale.CHINESE);
+                        if ((supported != TextToSpeech.LANG_AVAILABLE) && (supported != TextToSpeech.LANG_COUNTRY_AVAILABLE)) {
+                            Constants.Companion.setTtsState(1);
+                            Log.d(TAG, "onInit: 当前不支持中文");
+                        } else {
+                            Constants.Companion.setTtsState(2);
+                            Log.d(TAG, "onInit: 支持中文");
+                        }
+                        Log.d(TAG, "onInit: TTS引擎初始化成功");
+                    } else {
+                        Constants.Companion.setTtsState(0);
+                        Log.d(TAG, "onInit: TTS引擎初始化失败");
+                    }
+                }
+            });
+        }
+        textToSpeech.setSpeechRate(1f);
+    }
+
+    public void newSpeech(String text, boolean emergency) {
+        synchronized (lockObject) {
+            if (Constants.Companion.getTtsState() == 2) {
+                if (emergency) {
+                    speechTextList.add(0, text);
+                } else {
+                    speechTextList.add(text);
+                }
+                startSpeechThread();
+            }
+        }
+    }
+
+    public synchronized void speak(final String text) {
+        isStop = false;
+        textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null, "uniqueId");
+        textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
+            @Override
+            public void onStart(String utteranceId) {
+                //LogUtil.d(TAG, "speak onStart..." + utteranceId);
+            }
+
+            @Override
+            public void onDone(String utteranceId) {
+                speakIndex++;
+                //LogUtil.d(TAG, "speak onDone...index: " + speakIndex + ", loop: " + loopCount);
+                if (speakIndex < loopCount) {
+                    //循环播报
+                    speak(text);
+                } else {
+                    //语音播报完毕
+                    speakIndex = 0;
+                    isStop = true;
+                }
+            }
+
+            @Override
+            public void onError(String utteranceId) {
+                isStop = true;
+                Log.d(TAG, "speak onError..." + utteranceId);
+            }
+        });
+    }
+
+    public void stopSpeak() {
+        if (textToSpeech.isSpeaking()) {
+            textToSpeech.stop();
+            speechTextList.clear();
+            isStop = true;
+            speakIndex = 0;
+            Log.d(TAG, "stop speak");
+        }
+    }
+
+    public void removeSpeak(String text) {
+        synchronized (lockObject) {
+            if (!TextUtils.isEmpty(text) && !TextUtils.isEmpty(speakSpeech)) {
+                if (text.equals(speakSpeech) && textToSpeech.isSpeaking()) {
+                    textToSpeech.stop();
+                    speechTextList.remove(text);
+                    isStop = true;
+                    speakIndex = 0;
+                } else {
+                    speechTextList.remove(text);
+                }
+            }
+        }
+    }
+
+    public void setSpeechLoopCount(int count) {
+        loopCount = count;
+    }
+
+    public void release() {
+        speechTextList.clear();
+        isStop = true;
+        speakIndex = 0;
+        if (textToSpeech != null) {
+            textToSpeech.stop();
+            textToSpeech.shutdown();
+            textToSpeech = null;
+        }
+    }
+
+    public void startSpeechThread() {
+        if (null == speechThread) {
+            speechThread = new Thread(new SpeechRunnable());
+            speechThread.start();
+        } else if (!speechThread.isAlive()) {
+            speechThread.start();
+        }
+    }
+
+    public class SpeechRunnable implements Runnable {
+        public void run() {
+            while (isSpeechLoop) {
+                //synchronized (lockObject) {
+                    if (speechTextList.size() > 0 && isStop) {
+                        speakSpeech = speechTextList.get(0);
+                        Log.d(TAG, "speakSpeech: " + speakSpeech);
+                        speak(speakSpeech);
+
+                        //if (speechTextList.contains(speakSpeech)) {
+                            speechTextList.remove(speakSpeech);
+                        //}
+                    }
+                //}
+
+                try {
+                    Thread.sleep(50);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+}

+ 30 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/TimeTransition.kt

@@ -0,0 +1,30 @@
+package com.wdkl.ncs.android.component.nursehome.util
+
+import com.umeng.weixin.handler.s
+import java.text.SimpleDateFormat
+import java.util.*
+
+
+class TimeTransition {
+
+    fun stampToDate(s:Long):String{
+        return TimeStampToTime(s,"MM-dd HH:mm")
+    }
+
+    fun stampToTime(s:Long):String{
+        return TimeStampToTime(s,"HH:mm:ss")
+    }
+    /**
+     * 时间戳转时间
+     */
+    fun TimeStampToTime(s:Long, timestamp:String):String{
+        val res: String
+        val simpleDateFormat = SimpleDateFormat(timestamp)
+        val lt = s
+        val date = Date(lt)
+        res = simpleDateFormat.format(date)
+        return res
+}
+
+
+}

+ 159 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/Util.kt

@@ -0,0 +1,159 @@
+package com.wdkl.ncs.android.component.home.util
+
+import android.annotation.SuppressLint
+import android.app.KeyguardManager
+import android.content.Context
+import android.content.Context.KEYGUARD_SERVICE
+import android.os.Build
+import android.os.Environment
+import android.os.PowerManager
+import android.telephony.TelephonyManager
+import android.util.Log
+import com.enation.javashop.utils.base.tool.SystemTool
+import com.google.common.base.Strings
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileOutputStream
+import java.io.IOException
+import java.lang.Exception
+import java.util.*
+
+object Util {
+
+    var IMEI = ""
+    var UUID_FILE_NAME = "wdkl_uuid.txt"
+
+    /*
+      激活获取IMEI用
+    */
+    @SuppressLint("MissingPermission", "PrivateApi")
+    fun getIMEI(context: Context): String {
+        if (Build.VERSION.SDK_INT >= 29) {
+            val UUIDStr = readSD()
+            if (UUIDStr == null || UUIDStr.isEmpty()) { //如果为空或者空字符串就生成UUID创建文件并写入UUID
+                val uuid: String = Date().getTime().toString()
+                writeSD(uuid)
+                IMEI = uuid
+            } else {
+                IMEI = UUIDStr
+            }
+            return IMEI
+        }
+
+        IMEI = SystemTool.getPhoneImei(context)
+        if (Strings.isNullOrEmpty(IMEI)) {
+            val tm = (context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager)
+            try {
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                    IMEI = tm.imei
+                } else {
+                    IMEI = tm.deviceId
+                }
+            }catch (e:Exception){
+            }
+
+            if (Strings.isNullOrEmpty(IMEI)) {
+                IMEI = SystemTool.getLocalMacAddress()
+//                IMEI = "35" + //we make this look like a valid IMEI
+//                        Build.BOARD.length % 10 + Build.BRAND.length % 10 + Build.CPU_ABI.length % 10 + Build.DEVICE.length % 10 + Build.DISPLAY.length % 10 + Build.HOST.length % 10 + Build.ID.length % 10 + Build.MANUFACTURER.length % 10 + Build.MODEL.length % 10 + Build.PRODUCT.length % 10 + Build.TAGS.length % 10 + Build.TYPE.length % 10 + Build.USER.length % 10 //13 digits
+            }
+        }
+        return IMEI
+    }
+
+    /**
+     * 亮屏并解锁
+     */
+    @SuppressLint("InvalidWakeLockTag")
+    fun wakeUpAndUnlock(context: Context): PowerManager.WakeLock? {
+        val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
+        var wakeLock: PowerManager.WakeLock? = null
+
+        val screenOn = pm.isInteractive
+        if (!screenOn) { //如果是熄灭状态
+            wakeLock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP or PowerManager.SCREEN_DIM_WAKE_LOCK, "TAG")
+            wakeLock.acquire(3000)//亮屏
+        }
+
+        // 屏幕解锁
+        val keyguardManager = context.getSystemService(KEYGUARD_SERVICE) as KeyguardManager
+        val keyguardLock = keyguardManager.newKeyguardLock("unLock")
+        // 屏幕锁定
+        keyguardLock.reenableKeyguard()
+        keyguardLock.disableKeyguard() // 解锁
+        return wakeLock
+    }
+
+    @SuppressLint("InvalidWakeLockTag")
+    fun getCpuWakeLock(context: Context): PowerManager.WakeLock {
+        val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
+        val cpuWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK or PowerManager.ON_AFTER_RELEASE,
+                context.javaClass.canonicalName)
+        return cpuWakeLock
+    }
+
+    fun appendSpace(para: String): String? {
+        val length = para.length
+        val value = CharArray(length shl 1)
+        var i = 0
+        var j = 0
+        while (i < length) {
+            value[j] = para[i]
+            value[1 + j] = ' '
+            ++i
+            j = i shl 1
+        }
+        return String(value)
+    }
+
+    fun writeSD(content: String): String? {
+        //文件输出流
+        var out: FileOutputStream? = null
+        //设置文件路径
+        val file = File(Environment.getExternalStorageDirectory(), UUID_FILE_NAME)
+        return try {
+            out = FileOutputStream(file)
+            out.write(content.toByteArray())
+            content
+        } catch (e: Exception) {
+            e.printStackTrace()
+            ""
+        } finally {
+            try {
+                if (out != null) {
+                    out.close()
+                }
+            } catch (e: IOException) {
+                e.printStackTrace()
+            }
+        }
+    }
+
+    fun readSD(): String? {
+        //文件输入流
+        var `in`: FileInputStream? = null
+        //设置文件路径
+        val file = File(Environment.getExternalStorageDirectory(), UUID_FILE_NAME)
+        return try {
+            `in` = FileInputStream(file)
+            //使用缓冲来读
+            val buf = ByteArray(1024) //每1024字节读一次
+            val builder = StringBuilder()
+            while (`in`.read(buf) !== -1) {
+                builder.append(String(buf).trim { it <= ' ' })
+            }
+            builder.toString()
+        } catch (e: java.lang.Exception) {
+            e.printStackTrace()
+            ""
+        } finally {
+            try {
+                if (`in` != null) {
+                    `in`.close()
+                }
+            } catch (e: IOException) {
+                e.printStackTrace()
+            }
+        }
+    }
+}

+ 184 - 0
android_visiting/src/main/h10_yld_1h/java/com/wdkl/ncs/android/component/home/util/VoiceManagerUtil.java

@@ -0,0 +1,184 @@
+package com.wdkl.ncs.android.component.home.util;
+
+import android.content.Context;
+import android.media.AudioManager;
+
+/**
+ * 类名称:VoiceManagerUtil <br>
+ * 类描述:声音控制工具类 <br>
+ * 创建人:Waderson Shll (TEL:15675117662)<br>
+ * 创建时间:2018-03-15 <br>
+ * 特别提醒:如有需要该类可任意创建与调用;在未通知本人的情况下该类禁止任何修改!<br>
+ */
+public class VoiceManagerUtil {
+    /**
+     * 获取提示音音量最大值
+     *
+     * @param context
+     */
+    public static int getAlarmMax(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM);
+    }
+
+    /**
+     * 获取提示音音量当前值
+     *
+     * @param context
+     */
+    public static int getAlarmNow(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamVolume(AudioManager.STREAM_ALARM);
+    }
+
+    /**
+     * 获取多媒体音量最大值
+     *
+     * @param context
+     */
+    public static int getMusicMax(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+    }
+
+    /**
+     * 获取多媒体音量当前值
+     *
+     * @param context
+     */
+    public static int getMusicNow(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
+    }
+
+    /**
+     * 获取铃声音量最大值
+     *
+     * @param context
+     */
+    public static int getRingMax(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamMaxVolume(AudioManager.STREAM_RING);
+    }
+
+    /**
+     * 获取铃声音量当前值
+     *
+     * @param context
+     */
+    public static int getRingNow(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamVolume(AudioManager.STREAM_RING);
+    }
+
+    /**
+     * 获取系统音量最大值
+     *
+     * @param context
+     */
+    public static int getSystemMax(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamMaxVolume(AudioManager.STREAM_SYSTEM);
+    }
+
+    /**
+     * 获取系统音量当前值
+     *
+     * @param context
+     */
+    public static int getSystemNow(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamVolume(AudioManager.STREAM_SYSTEM);
+    }
+
+    /**
+     * 获取通话音量最大值
+     *
+     * @param context
+     */
+    public static int getCallMax(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL);
+    }
+
+    /**
+     * 获取通话音量当前值
+     *
+     * @param context
+     */
+    public static int getCallNow(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
+    }
+
+    /**
+     * 设置提示音音量
+     *
+     * @param context
+     * @param percent (百分比;只能0--100之间)
+     */
+    public static void setAlarmVoice(Context context, int percent) {
+        float vPercent=((float)percent)/100f;
+        vPercent = vPercent < 0 ? 0 : vPercent;
+        vPercent = vPercent > 1 ? 1 : vPercent;
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        audioManager.setStreamVolume(AudioManager.STREAM_ALARM, (int) (getAlarmMax(context) * vPercent), 0);
+    }
+
+    /**
+     * 设置多媒体音量
+     *
+     * @param context
+     * @param percent (百分比;只能0--100之间)
+     */
+    public static void setMusicVoice(Context context, int percent) {
+        float vPercent=((float)percent)/100f;
+        vPercent = vPercent < 0 ? 0 : vPercent;
+        vPercent = vPercent > 1 ? 1 : vPercent;
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int) (getMusicMax(context) * vPercent), 0);
+    }
+
+    /**
+     * 设置铃声音量
+     *
+     * @param context
+     * @param percent (百分比;只能0--100之间)
+     */
+    public static void setRingVoice(Context context, int percent) {
+        float vPercent=((float)percent)/100f;
+        vPercent = vPercent < 0 ? 0 : vPercent;
+        vPercent = vPercent > 1 ? 1 : vPercent;
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        audioManager.setStreamVolume(AudioManager.STREAM_RING, (int) (getRingMax(context) * vPercent), 0);
+    }
+
+    /**
+     * 设置系统音量
+     *
+     * @param context
+     * @param percent (百分比;只能0--100之间)
+     */
+    public static void setSystemVoice(Context context, int percent) {
+        float vPercent=((float)percent)/100f;
+        vPercent = vPercent < 0 ? 0 : vPercent;
+        vPercent = vPercent > 1 ? 1 : vPercent;
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        audioManager.setStreamVolume(AudioManager.STREAM_SYSTEM, (int) (getSystemMax(context) * vPercent), 0);
+    }
+
+    /**
+     * 设置通话音量
+     *
+     * @param context
+     * @param percent (百分比;只能0--100之间)
+     */
+    public static void setCallVoice(Context context, int percent) {
+        float vPercent=((float)percent)/100f;
+        vPercent = vPercent < 0 ? 0 : vPercent;
+        vPercent = vPercent > 1 ? 1 : vPercent;
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, (int) (getCallMax(context) * vPercent), 0);
+    }
+
+}

BIN
android_visiting/src/main/h10_yld_1h/res/drawable-hdpi/hu_jiao.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-hdpi/hu_jiao_bg.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-hdpi/wei_chu_li_bg.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-hdpi/yi_chu_li_bg.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-hdpi/yu_yin_wei_chu_li.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/bao_ma_tou_xiang.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/dian_liang.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/geng_duo.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/gu_ke_lie_biao.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/hu_chu_wei_jie.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/hu_chu_yi_jie.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/hu_jiao.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/hu_jiao_bg.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/hu_ru_wei_jie.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/hu_ru_yi_jie.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/hu_shi_to_xiang.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/ju_jie.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/sip_lian_jie.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/tong_hu_ji_lu.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/wei_bo_fang.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/wei_chu_li.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/wei_chu_li_bg.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/wifi_lian_jie.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/yi_bo_fang.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/yi_chu_li.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/yi_chu_li_bg.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/yu_yin_gua_duan.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/yu_yin_jie_ting.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/yu_yin_wei_chu_li.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable-mdpi/zhe_die.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable/av_handfree_hover.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable/btn_back.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable/ic_answer_normal.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable/ic_answer_press.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable/ic_hangup_normal.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable/ic_hangup_press.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable/ic_nurse.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable/icon_hd_live.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable/icon_hd_live_item.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable/icon_switch_off.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable/icon_switch_on.png


+ 5 - 0
android_visiting/src/main/h10_yld_1h/res/drawable/item_selector.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/color_gray2" android:state_pressed="true"/>
+    <item android:drawable="@color/color_white"/>
+</selector>

BIN
android_visiting/src/main/h10_yld_1h/res/drawable/main_bg.png


BIN
android_visiting/src/main/h10_yld_1h/res/drawable/main_bg_1280x800.jpg


BIN
android_visiting/src/main/h10_yld_1h/res/drawable/main_bg_1920x1080.jpg


BIN
android_visiting/src/main/h10_yld_1h/res/drawable/main_bg_800x1280.png


+ 6 - 0
android_visiting/src/main/h10_yld_1h/res/drawable/round_button_100dp.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval">
+    <solid android:color="#0081ff"/>
+    <size android:width="100dp" android:height="100dp"/>
+</shape>

+ 6 - 0
android_visiting/src/main/h10_yld_1h/res/drawable/round_button_80dp.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval">
+    <solid android:color="#0081ff"/>
+    <size android:width="80dp" android:height="80dp"/>
+</shape>

+ 5 - 0
android_visiting/src/main/h10_yld_1h/res/drawable/selector_button_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="#202020" android:state_pressed="true"/>
+    <item android:color="#ffffff"/>
+</selector>

+ 5 - 0
android_visiting/src/main/h10_yld_1h/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_visiting/src/main/h10_yld_1h/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_visiting/src/main/h10_yld_1h/res/drawable/shape_untreated_quantity.xml

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

+ 5 - 0
android_visiting/src/main/h10_yld_1h/res/drawable/sp_event_handled.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <stroke android:color="#F78B8F" android:width="2px" />
+    <corners android:radius="2px"/>
+</shape>

+ 8 - 0
android_visiting/src/main/h10_yld_1h/res/drawable/sp_event_unhandled_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="#F78B8F"/>
+    <corners android:topLeftRadius="0px"
+        android:topRightRadius="0px"
+        android:bottomLeftRadius="0px"
+        android:bottomRightRadius="0px"/>
+</shape>

+ 36 - 0
android_visiting/src/main/h10_yld_1h/res/layout/activity_app_update.xml

@@ -0,0 +1,36 @@
+<?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="#ffffff"
+        android:keepScreenOn="true"
+        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="正在下载,请勿操作..."
+            android:textColor="#3D3D63"
+            android:textSize="18sp" />
+
+        <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="10dp"
+            android:layout_marginRight="10dp"
+            app:haveChangeColor="true"
+            app:isShowDesc="false"
+            app:max="100"
+            app:progress="0"
+            app:progressDesc="进度:"
+            app:progressRadius="10dp" />
+
+    </RelativeLayout>
+</layout>

+ 75 - 0
android_visiting/src/main/h10_yld_1h/res/layout/activity_dialing_voice.xml

@@ -0,0 +1,75 @@
+<?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"
+    android:background="#FFE6E8">
+
+    <LinearLayout
+        android:id="@+id/ll_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:gravity="center_horizontal"
+        android:layout_marginTop="11px"
+        android:orientation="vertical">
+
+        <ImageView
+            android:id="@+id/bao_mother_image_imagev"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/bao_ma_tou_xiang" />
+        <TextView
+            android:id="@+id/room_number_tv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:text="房号"
+            android:textSize="18sp" />
+        <TextView
+            android:id="@+id/bao_mother_name_tv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:text="宝妈名字"
+            android:textSize="20sp" />
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/ll_name"
+        android:layout_alignParentBottom="true"
+        android:layout_centerHorizontal="true"
+        android:layout_marginBottom="11px"
+        android:orientation="vertical">
+
+        <Chronometer
+            android:id="@+id/call_duration_tv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:text="00:00"
+            android:textSize="12sp" />
+
+        <TextView
+            android:id="@+id/voice_status"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:textSize="12sp" />
+
+        <ImageView
+            android:id="@+id/hang_up_imagev"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="13px"
+            android:src="@drawable/yu_yin_gua_duan" />
+
+    </LinearLayout>
+
+
+</RelativeLayout>

+ 77 - 0
android_visiting/src/main/h10_yld_1h/res/layout/activity_home.xml

@@ -0,0 +1,77 @@
+<?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">
+
+        <FrameLayout
+            android:id="@+id/frame_visit"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginTop="40dp" />
+
+        <include
+            android:id="@+id/activity_register_layout"
+            layout="@layout/activity_register" />
+
+        <RelativeLayout
+            android:id="@+id/watch_activity_home_linyout"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="center_horizontal"
+            android:visibility="gone">
+
+            <Button
+                android:id="@+id/btn_callout"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentBottom="true"
+                android:layout_marginBottom="60dp"
+                android:text="探视"
+                android:textColor="@drawable/selector_button_text_color" />
+
+        </RelativeLayout>
+
+        <TextView
+            android:id="@+id/tv_rtc_status"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            android:layout_marginLeft="5dp"
+            android:layout_marginTop="5dp"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentTop="true"/>
+
+        <TextView
+            android:id="@+id/tv_part_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerHorizontal="true"
+            android:layout_alignParentTop="true"
+            android:textSize="32sp"
+            android:textColor="#2F9DF1"/>
+
+        <TextClock
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentRight="true"
+            android:layout_alignParentTop="true"
+            android:layout_marginRight="5dp"
+            android:textSize="32sp"
+            android:format12Hour="HH:mm"
+            android:format24Hour="HH:mm"
+            android:textColor="#2F9DF1"/>
+
+        <TextView
+            android:id="@+id/tv_version_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textColor="@color/black"
+            android:layout_marginRight="10dp"
+            android:layout_marginBottom="20dp"
+            android:textSize="18sp"
+            android:layout_alignParentEnd="true"
+            android:layout_alignParentBottom="true"/>
+
+    </RelativeLayout>
+</layout>

+ 92 - 0
android_visiting/src/main/h10_yld_1h/res/layout/activity_register.xml

@@ -0,0 +1,92 @@
+<?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:padding="10dp"
+    android:orientation="vertical">
+
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="20dp"
+                android:text="服务器IP: "
+                android:textSize="24sp" />
+
+            <TextView
+                android:id="@+id/tv_server_ip"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="40dp"
+                android:text=""
+                android:textSize="24sp" />
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="20dp"
+                android:text="识别码: "
+                android:textSize="24sp" />
+
+            <TextView
+                android:id="@+id/tv_device_imei"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="20dp"
+                android:text=""
+                android:textSize="24sp" />
+
+            <TextView
+                android:id="@+id/tv_status"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="20dp"
+                android:gravity="center_horizontal"
+                android:text=""
+                android:textColor="@color/color_red"
+                android:textSize="24sp" />
+
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:layout_marginTop="10dp"
+                android:orientation="vertical">
+
+                <Button
+                    android:id="@+id/btn_system_setting0"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:background="@drawable/javashop_btn_balck_line_bg"
+                    android:text="系统设置" />
+
+                <Button
+                    android:id="@+id/btn_server_config"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="10dp"
+                    android:background="@drawable/javashop_btn_balck_line_bg"
+                    android:text="服务器配置" />
+
+                <Button
+                    android:id="@+id/btn_restart_app"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="10dp"
+                    android:background="@drawable/javashop_btn_balck_line_bg"
+                    android:text="重启" />
+            </LinearLayout>
+
+        </LinearLayout>
+    </ScrollView>
+</LinearLayout>
+</layout>

+ 76 - 0
android_visiting/src/main/h10_yld_1h/res/layout/activity_sip_voip_audio.xml

@@ -0,0 +1,76 @@
+<?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"
+    android:background="#FFE6E8">
+
+    <LinearLayout
+        android:id="@+id/ll_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:gravity="center_horizontal"
+        android:layout_marginTop="11px"
+        android:orientation="vertical">
+
+        <ImageView
+            android:id="@+id/bao_mother_image_imagev"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/bao_ma_tou_xiang" />
+        <TextView
+            android:id="@+id/room_number_tv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:text="房号"
+            android:textSize="18sp" />
+        <TextView
+            android:id="@+id/bao_mother_name_tv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:text="宝妈名字"
+            android:textSize="20sp" />
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/ll_name"
+        android:layout_alignParentBottom="true"
+        android:layout_centerHorizontal="true"
+        android:layout_marginBottom="11px"
+        android:orientation="vertical">
+
+        <Chronometer
+            android:id="@+id/call_duration_tv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:text="00:00"
+            android:textSize="12sp"
+            android:visibility="gone"/>
+
+        <TextView
+            android:id="@+id/voice_status"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:textSize="12sp" />
+
+        <ImageView
+            android:id="@+id/hang_up_imagev"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="13px"
+            android:src="@drawable/yu_yin_gua_duan" />
+
+    </LinearLayout>
+
+
+</RelativeLayout>

+ 105 - 0
android_visiting/src/main/h10_yld_1h/res/layout/activity_sip_voip_audio_ringing.xml

@@ -0,0 +1,105 @@
+<?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"
+    android:background="#FFE6E8">
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="11px"
+        android:gravity="center_horizontal"
+        android:orientation="vertical">
+
+        <ImageView
+            android:id="@+id/bao_mother_image_imagev"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/bao_ma_tou_xiang" />
+        <TextView
+            android:id="@+id/room_number_tv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:text="房号"
+            android:textSize="18sp" />
+        <TextView
+            android:id="@+id/bao_mother_name_tv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:text="宝妈名字"
+            android:textSize="20sp" />
+
+        <TextView
+            android:id="@+id/event_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:text=""
+            android:textSize="20sp" />
+
+    </LinearLayout>
+
+
+    <TextView
+        android:id="@+id/call_duration_tv"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_above="@+id/call_out_linlyout"
+        android:layout_centerHorizontal="true"
+        android:text=""
+        android:textSize="24sp"
+        android:visibility="gone" />
+
+    <LinearLayout
+        android:id="@+id/call_out_linlyout"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="13px"
+        android:layout_marginBottom="11px"
+        android:orientation="horizontal">
+        <RelativeLayout
+            android:id="@+id/change_over_relayout"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="100dp"
+            android:layout_gravity="center" >
+            <ImageView
+                android:id="@+id/change_over_image"
+                android:layout_width="45dp"
+                android:layout_height="45dp"
+                android:src="@drawable/yu_yin_wei_chu_li" />
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_centerInParent="true"
+                android:textSize="14dp"
+                android:textColor="#ffffff"
+                android:text="转接"/>
+
+        </RelativeLayout>
+        <ImageView
+            android:id="@+id/hang_up_imagev"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="28px"
+            android:src="@drawable/yu_yin_gua_duan"
+            android:visibility="gone"/>
+
+        <ImageView
+            android:id="@+id/call_the_voice_imagev"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/yu_yin_jie_ting" />
+
+    </LinearLayout>
+
+
+</RelativeLayout>

+ 69 - 0
android_visiting/src/main/h10_yld_1h/res/layout/activity_video.xml

@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:tools="http://schemas.android.com/tools">
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@android:color/black"
+    tools:ignore="MergeRootFrame"
+    android:keepScreenOn="true">
+
+    <FrameLayout
+        android:id="@+id/fullscreen_video_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="center" />
+
+    <FrameLayout
+        android:id="@+id/pip_video_view"
+        android:layout_width="100dp"
+        android:layout_height="140dp"
+        android:layout_gravity="top|end"
+        android:layout_marginHorizontal="10dp"
+        android:layout_marginTop="10dp" />
+
+    <RelativeLayout
+        android:id="@+id/lytParent"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@android:color/transparent">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            android:gravity="center_horizontal"
+            android:layout_marginBottom="11dp"
+            android:orientation="vertical">
+
+            <Chronometer
+                android:id="@+id/call_duration_tv"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:text="00:00"
+                android:textSize="12dp"
+                android:textColor="#FFFFFF"
+                android:visibility="gone"/>
+
+            <TextView
+                android:id="@+id/tv_connecting"
+                android:text="呼叫中"
+                android:textSize="14dp"
+                android:visibility="gone"
+                android:textColor="#FFFFFF"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"/>
+
+            <ImageView
+                android:id="@+id/iv_handoff"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="13dp"
+                android:src="@drawable/yu_yin_gua_duan" />
+
+        </LinearLayout>
+
+    </RelativeLayout>
+
+</FrameLayout>
+</layout>

+ 104 - 0
android_visiting/src/main/h10_yld_1h/res/layout/activity_voice_calls.xml

@@ -0,0 +1,104 @@
+<?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"
+    android:background="#FFE6E8">
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="11px"
+        android:gravity="center_horizontal"
+        android:orientation="vertical">
+
+        <ImageView
+            android:id="@+id/bao_mother_image_imagev"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/bao_ma_tou_xiang" />
+        <TextView
+            android:id="@+id/room_number_tv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:text="房号"
+            android:textSize="18sp" />
+        <TextView
+            android:id="@+id/bao_mother_name_tv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:text="宝妈名字"
+            android:textSize="20sp" />
+
+        <TextView
+            android:id="@+id/event_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:text=""
+            android:textSize="20sp" />
+
+    </LinearLayout>
+
+
+    <TextView
+        android:id="@+id/call_duration_tv"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_above="@+id/call_out_linlyout"
+        android:layout_centerHorizontal="true"
+        android:text=""
+        android:textSize="24sp"
+        android:visibility="gone" />
+
+    <LinearLayout
+        android:id="@+id/call_out_linlyout"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="13px"
+        android:layout_marginBottom="11px"
+        android:orientation="horizontal">
+      <RelativeLayout
+          android:id="@+id/change_over_relayout"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:layout_marginRight="28px"
+          android:layout_gravity="center" >
+        <ImageView
+            android:id="@+id/change_over_image"
+            android:layout_width="45px"
+            android:layout_height="45px"
+            android:src="@drawable/yu_yin_wei_chu_li" />
+      <TextView
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:layout_centerInParent="true"
+          android:textSize="14px"
+          android:textColor="#ffffff"
+          android:text="转接"/>
+
+      </RelativeLayout>
+        <ImageView
+            android:id="@+id/hang_up_imagev"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="28px"
+            android:src="@drawable/yu_yin_gua_duan"
+            android:visibility="gone"/>
+        <ImageView
+            android:id="@+id/call_the_voice_imagev"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/yu_yin_jie_ting" />
+
+    </LinearLayout>
+
+
+</RelativeLayout>

+ 92 - 0
android_visiting/src/main/h10_yld_1h/res/layout/activity_web_rtc_voip_audio.xml

@@ -0,0 +1,92 @@
+<?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"
+    android:keepScreenOn="true"
+    android:background="#FFE6E8">
+
+    <LinearLayout
+        android:id="@+id/ll_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:gravity="center_horizontal"
+        android:layout_marginTop="11px"
+        android:orientation="vertical">
+
+        <ImageView
+            android:id="@+id/bao_mother_image_imagev"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/bao_ma_tou_xiang" />
+        <TextView
+            android:id="@+id/room_number_tv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:text="房号"
+            android:textSize="18sp" />
+        <TextView
+            android:id="@+id/bao_mother_name_tv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:text="宝妈名字"
+            android:textSize="20sp" />
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_centerHorizontal="true"
+        android:layout_marginBottom="11px"
+        android:orientation="vertical">
+
+        <Chronometer
+            android:id="@+id/call_duration_tv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:text="00:00"
+            android:textSize="12sp"
+            android:visibility="gone"/>
+
+        <TextView
+            android:id="@+id/voice_status"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:textSize="12sp" />
+
+        <ImageView
+            android:id="@+id/hang_up_imagev"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="13px"
+            android:src="@drawable/yu_yin_gua_duan" />
+
+    </LinearLayout>
+
+    <RelativeLayout
+        android:id="@+id/hands_free_relayout"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentRight="true"
+        android:layout_marginBottom="11px"
+        android:layout_marginRight="28px"
+        android:layout_gravity="center" >
+        <ImageView
+            android:id="@+id/hands_free_image"
+            android:layout_width="55px"
+            android:layout_height="55px"
+            android:src="@drawable/av_handfree_hover" />
+
+    </RelativeLayout>
+
+</RelativeLayout>

+ 106 - 0
android_visiting/src/main/h10_yld_1h/res/layout/activity_web_rtc_voip_audio_ringing.xml

@@ -0,0 +1,106 @@
+<?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"
+    android:keepScreenOn="true"
+    android:background="#FFE6E8">
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="11px"
+        android:gravity="center_horizontal"
+        android:orientation="vertical">
+
+        <ImageView
+            android:id="@+id/bao_mother_image_imagev"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/bao_ma_tou_xiang" />
+        <TextView
+            android:id="@+id/room_number_tv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:text="房号"
+            android:textSize="18sp" />
+        <TextView
+            android:id="@+id/bao_mother_name_tv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:text="宝妈名字"
+            android:textSize="20sp" />
+
+        <TextView
+            android:id="@+id/event_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="8px"
+            android:text=""
+            android:textSize="20sp" />
+
+    </LinearLayout>
+
+
+    <TextView
+        android:id="@+id/call_duration_tv"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_above="@+id/call_out_linlyout"
+        android:layout_centerHorizontal="true"
+        android:text=""
+        android:textSize="24sp"
+        android:visibility="gone" />
+
+    <LinearLayout
+        android:id="@+id/call_out_linlyout"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="13px"
+        android:layout_marginBottom="11px"
+        android:orientation="horizontal">
+        <RelativeLayout
+            android:id="@+id/change_over_relayout"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="28dp"
+            android:layout_gravity="center" >
+            <ImageView
+                android:id="@+id/change_over_image"
+                android:layout_width="45dp"
+                android:layout_height="45dp"
+                android:src="@drawable/yu_yin_wei_chu_li" />
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_centerInParent="true"
+                android:textSize="14dp"
+                android:textColor="#ffffff"
+                android:text="转接"/>
+
+        </RelativeLayout>
+        <ImageView
+            android:id="@+id/hang_up_imagev"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="28dp"
+            android:src="@drawable/yu_yin_gua_duan"
+            android:visibility="gone"/>
+
+        <ImageView
+            android:id="@+id/call_the_voice_imagev"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/yu_yin_jie_ting" />
+
+    </LinearLayout>
+
+
+</RelativeLayout>

+ 0 - 0
android_visiting/src/main/h10_yld_1h/res/layout/call_dialog_lay.xml


Some files were not shown because too many files changed in this diff