Просмотр исходного кода

增加sip通话协议兼容,需要在断网或未连接服务器情况下手动设置选择通话协议

weizhengliang 1 год назад
Родитель
Сommit
cd0ef7b5f2
77 измененных файлов с 1162 добавлено и 299 удалено
  1. 10 2
      app/build.gradle
  2. BIN
      app/libs/linphone-sdk-android-5.2.10.aar
  3. BIN
      app/release/app-release.apk
  4. 1 0
      app/release/output.json
  5. 11 3
      app/src/main/AndroidManifest.xml
  6. 463 73
      app/src/main/java/com/wdkl/ncs/entraceguard/activity/MainActivity.kt
  7. 2 2
      app/src/main/java/com/wdkl/ncs/entraceguard/application/Application.java
  8. 2 3
      app/src/main/java/com/wdkl/ncs/entraceguard/contracts/MainActivityContract.kt
  9. 1 2
      app/src/main/java/com/wdkl/ncs/entraceguard/di/ApplicationComponent.java
  10. 1 1
      app/src/main/java/com/wdkl/ncs/entraceguard/di/PresenterComponent.java
  11. 5 5
      app/src/main/java/com/wdkl/ncs/entraceguard/helper/ServerConfigDialogHelper.java
  12. 14 13
      app/src/main/java/com/wdkl/ncs/entraceguard/presenters/MainActivityPresenter.kt
  13. 2 2
      app/src/main/java/com/wdkl/ncs/entraceguard/tcp/TcpClientHandler.java
  14. 2 3
      app/src/main/java/com/wdkl/ncs/entraceguard/tcp/channel/DeviceChannel.java
  15. 169 0
      app/src/main/java/com/wdkl/ncs/entraceguard/utils/AudioRouteUtils.kt
  16. 1 1
      app/src/main/java/com/wdkl/ncs/entraceguard/utils/LocaleMangerUtils.java
  17. 31 0
      app/src/main/java/com/wdkl/ncs/entraceguard/utils/SettingConfig.java
  18. BIN
      app/src/main/res/drawable/ic_hangup_normal.png
  19. BIN
      app/src/main/res/drawable/ic_hangup_press.png
  20. 5 0
      app/src/main/res/drawable/selector_call_hangup.xml
  21. 55 18
      app/src/main/res/layout/activity_main.xml
  22. 196 44
      app/src/main/res/layout/view_tips_layout.xml
  23. 20 0
      app/src/main/res/raw/linphonerc_default
  24. 34 0
      app/src/main/res/raw/linphonerc_factory
  25. 14 15
      build.gradle
  26. 0 9
      framework/src/main/AndroidManifest.xml
  27. 0 11
      framework/src/main/java/com/wdkl/ncs/framework/di/FrameWorkComponent.kt
  28. 0 26
      framework/src/main/java/com/wdkl/ncs/framework/utils/MessageEvent.kt
  29. 2 1
      gradle/wrapper/gradle-wrapper.properties
  30. 1 1
      janus/build.gradle
  31. 8 1
      janus/src/main/java/com/wdkl/ncs/janus/rtc/WebRTCEngine.java
  32. 2 2
      janus/src/main/java/com/wdkl/ncs/janus/util/Constant.java
  33. 0 0
      middleware/.gitignore
  34. 4 0
      framework/build.gradle
  35. 0 0
      middleware/consumer-rules.pro
  36. 0 0
      middleware/proguard-rules.pro
  37. 0 0
      middleware/src/androidTest/java/com/wdkl/ncs/framework/ExampleInstrumentedTest.java
  38. 2 0
      middleware/src/main/AndroidManifest.xml
  39. 3 3
      framework/src/main/java/com/wdkl/ncs/framework/api/ApiManager.kt
  40. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/api/DeviceApi.kt
  41. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/api/NetFactory.kt
  42. 5 5
      framework/src/main/java/com/wdkl/ncs/framework/api/UrlManager.kt
  43. 3 2
      framework/src/main/java/com/wdkl/ncs/framework/base/BaseActivity.kt
  44. 1 3
      framework/src/main/java/com/wdkl/ncs/framework/base/BaseApplication.kt
  45. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/base/BaseContract.kt
  46. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/base/BaseControl.kt
  47. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/base/DisposableManager.kt
  48. 1 3
      framework/src/main/java/com/wdkl/ncs/framework/base/RxPresenter.kt
  49. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/beans/ServerInfo.java
  50. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/common/Constants.kt
  51. 3 3
      framework/src/main/java/com/wdkl/ncs/framework/di/ApiProviders.kt
  52. 11 0
      middleware/src/main/code/com/wdkl/ncs/middleware/di/FrameWorkComponent.kt
  53. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/exception/ExceptionHandle.java
  54. 2 7
      framework/src/main/java/com/wdkl/ncs/framework/helper/NetHelper.java
  55. 2 2
      framework/src/main/java/com/wdkl/ncs/framework/helper/RingPlayHelper.java
  56. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/network/ConnectionClassManager.java
  57. 6 6
      framework/src/main/java/com/wdkl/ncs/framework/network/ConnectionObserver.kt
  58. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/network/ConnectionQuality.kt
  59. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/network/ConnectionQualityMonitor.kt
  60. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/network/DeviceBandwidthSampler.java
  61. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/network/ExponentialGeometricAverage.java
  62. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/utils/AsyncPlayer.java
  63. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/utils/CommonUtils.java
  64. 3 3
      framework/src/main/java/com/wdkl/ncs/framework/utils/ExtendMethods.kt
  65. 33 0
      middleware/src/main/code/com/wdkl/ncs/middleware/utils/MessageEvent.kt
  66. 2 2
      framework/src/main/java/com/wdkl/ncs/framework/utils/ServerInfoUtil.java
  67. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/utils/SystemTool.java
  68. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/utils/ThreadFromUtils.java
  69. 1 2
      framework/src/main/java/com/wdkl/ncs/framework/utils/Util.kt
  70. 1 1
      framework/src/main/java/com/wdkl/ncs/framework/utils/VoiNetTool.java
  71. 0 0
      middleware/src/test/java/com/wdkl/ncs/framework/ExampleUnitTest.java
  72. BIN
      release/ncs_entraceguard_V1.1.0_10_black_IP172.28.100.100.apk
  73. 2 0
      resource/src/main/res/values-es/strings.xml
  74. 2 0
      resource/src/main/res/values-ru/strings.xml
  75. 2 0
      resource/src/main/res/values-zh/strings.xml
  76. 2 0
      resource/src/main/res/values/strings.xml
  77. 2 2
      settings.gradle

+ 10 - 2
app/build.gradle

@@ -65,6 +65,11 @@ android {
         sourceCompatibility JavaVersion.VERSION_1_8
         targetCompatibility JavaVersion.VERSION_1_8
     }
+
+    packagingOptions {
+        pickFirst 'lib/arm64-v8a/libc++_shared.so'
+        pickFirst 'lib/armeabi-v7a/libc++_shared.so'
+    }
 }
 
 dependencies {
@@ -139,12 +144,12 @@ dependencies {
      */
     compile 'com.alibaba:fastjson:1.2.23'
 
-    compile 'org.mongodb:bson:3.6.3'
+    implementation 'org.mongodb:bson:3.12.10'
 
 
     compile project(':resource')
 
-    compile project(':framework')
+    compile project(':middleware')
 
     compile project(':janus')
 
@@ -165,6 +170,9 @@ dependencies {
     implementation files('libs/FacePassAndroidSDK-McvSafe-release.aar')
     implementation files('libs/mcvSafe.v1.2.2.aar')
 
+    //sip
+    implementation files('libs/linphone-sdk-android-5.2.10.aar')
+
     // 硬件 sdk
     implementation 'io.github.jimmy-j:facesdk:2.0.19'
     // todo 下面是主板依赖,需要开发人员根据更新系统类型切换,rk 表示 rk 主板,well 表示三星主板,如果依赖错误会 crash

BIN
app/libs/linphone-sdk-android-5.2.10.aar


BIN
app/release/app-release.apk


+ 1 - 0
app/release/output.json

@@ -0,0 +1 @@
+[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":10,"versionName":"1.1.0_black","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]

+ 11 - 3
app/src/main/AndroidManifest.xml

@@ -2,14 +2,16 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     android:sharedUserId="android.uid.system"
-    package="iot.facereco.smart.terminal"
-  >
+    package="iot.facereco.smart.terminal">
 
     <uses-permission android:name="android.permission.CAMERA"/>
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
     <uses-permission android:name="android.permission.RECORD_AUDIO"/>
 
-
+    <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_NUMBERS" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 
     <uses-feature
         android:name="android.hardware.com.camera.front"
@@ -41,6 +43,11 @@
     <uses-permission android:name="android.permission.WRITE_SETTINGS"
         tools:ignore="ProtectedPermissions" />
     <uses-sdk tools:overrideLibrary="com.q_zheng" />
+
+    <uses-feature
+        android:name="android.hardware.sip.voip"
+        android:required="true" />
+
     <application
         android:name="com.wdkl.ncs.entraceguard.application.Application"
         android:allowBackup="true"
@@ -50,6 +57,7 @@
         android:roundIcon="@mipmap/ic_launcher_round"
         android:supportsRtl="true"
         android:theme="@style/Theme.AppCompat.NoActionBar"
+        android:hardwareAccelerated="true"
         tools:remove="android:requestLegacyExternalStorage"
         tools:replace="android:label,android:icon,android:theme">
 

+ 463 - 73
app/src/main/java/com/wdkl/ncs/entraceguard/activity/MainActivity.kt

@@ -3,6 +3,7 @@ package com.wdkl.ncs.entraceguard.activity
 import android.app.AlarmManager
 import android.content.Context
 import android.content.Intent
+import android.content.pm.PackageInfo
 import android.content.pm.PackageManager
 import android.media.AudioAttributes
 import android.media.SoundPool
@@ -10,18 +11,17 @@ import android.os.Build
 import android.os.CountDownTimer
 import android.os.Handler
 import android.os.Looper
+import android.text.TextUtils
 import android.util.Log
 import android.view.View
-import android.widget.Button
-import android.widget.ImageView
-import android.widget.TextView
+import android.widget.*
 import androidx.annotation.RequiresApi
 import com.alibaba.fastjson.JSON
 import com.google.common.base.Strings
 import com.szeasco.facesdk.helper.GpioHelper
+import com.wdkl.ncs.entraceguard.adapter.NumAdapter
 import com.wdkl.ncs.entraceguard.contracts.MainActivityContract
 import com.wdkl.ncs.entraceguard.di.DaggerApplicationComponent
-import com.wdkl.ncs.entraceguard.helper.ServerConfigDialogHelper
 import com.wdkl.ncs.entraceguard.model.dos.DeviceDO
 import com.wdkl.ncs.entraceguard.model.dto.TcpSeverDTO
 import com.wdkl.ncs.entraceguard.model.vo.InteractionVO
@@ -31,16 +31,9 @@ import com.wdkl.ncs.entraceguard.tcp.channel.EntraceGuardUtil
 import com.wdkl.ncs.entraceguard.tcp.dto.TcpModel
 import com.wdkl.ncs.entraceguard.tcp.enums.TcpAction
 import com.wdkl.ncs.entraceguard.tcp.enums.TcpType
+import com.wdkl.ncs.entraceguard.utils.AudioRouteUtils
 import com.wdkl.ncs.entraceguard.utils.LocaleMangerUtils
-import com.wdkl.ncs.framework.base.BaseActivity
-import com.wdkl.ncs.framework.beans.ServerInfo
-import com.wdkl.ncs.framework.common.Constants
-import com.wdkl.ncs.framework.di.ApiProviders
-import com.wdkl.ncs.framework.di.DaggerFrameWorkComponent
-import com.wdkl.ncs.framework.helper.NetHelper
-import com.wdkl.ncs.framework.helper.RingPlayHelper
-import com.wdkl.ncs.framework.utils.MessageEvent
-import com.wdkl.ncs.framework.utils.Util
+import com.wdkl.ncs.entraceguard.utils.SettingConfig
 import com.wdkl.ncs.janus.client.CallSessionCallback
 import com.wdkl.ncs.janus.client.JanusClient
 import com.wdkl.ncs.janus.client.VideoRoomCallback
@@ -48,6 +41,18 @@ import com.wdkl.ncs.janus.entity.Room
 import com.wdkl.ncs.janus.rtc.WebRTCEngine
 import com.wdkl.ncs.janus.util.Constant
 import com.wdkl.ncs.janus.util.EnumType
+import com.wdkl.ncs.middleware.base.BaseActivity
+import com.wdkl.ncs.middleware.base.BaseApplication
+import com.wdkl.ncs.middleware.beans.ServerInfo
+import com.wdkl.ncs.middleware.common.Constants
+import com.wdkl.ncs.middleware.di.ApiProviders
+import com.wdkl.ncs.middleware.di.DaggerFrameWorkComponent
+import com.wdkl.ncs.middleware.helper.NetHelper
+import com.wdkl.ncs.middleware.helper.RingPlayHelper
+import com.wdkl.ncs.middleware.utils.CommonUtils
+import com.wdkl.ncs.middleware.utils.MessageEvent
+import com.wdkl.ncs.middleware.utils.Util
+import com.wdkl.ncs.middleware.utils.showMessage
 import iot.facereco.smart.terminal.BuildConfig
 import iot.facereco.smart.terminal.R
 import iot.facereco.smart.terminal.databinding.ActivityMainBinding
@@ -55,11 +60,16 @@ import kotlinx.android.synthetic.main.activity_main.*
 import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
+import org.linphone.core.*
+import org.linphone.mediastream.Version
 import org.webrtc.SurfaceViewRenderer
+import java.io.File
+import java.io.IOException
 import java.math.BigInteger
 import java.util.*
 
 class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(), MainActivityContract.View, CallSessionCallback /*IUserState, CallSession.CallSessionCallback*/ {
+    val TAG = MainActivity::class.java.getSimpleName()
 
     private val mSoundPool: SoundPool by lazy {
         val audioAttributes = AudioAttributes.Builder()
@@ -90,6 +100,15 @@ class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(),
 
     private var language = "zh"
 
+    //sip
+    private val START_SIPPHONE_LOGS = " ==== Device information dump ===="
+    private var sipHandler: Handler? = null
+    private var sipTimer: Timer? = null
+
+    private var mCore: Core? = null
+    private var mCoreListener: CoreListenerStub? = null
+    private var mAccountCreator: AccountCreator? = null
+
     override fun getLayId(): Int {
         return R.layout.activity_main
     }
@@ -103,18 +122,24 @@ class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(),
 
     @RequiresApi(Build.VERSION_CODES.N)
     override fun init() {
+        if (SettingConfig.getSipEnabled(activity)) {
+            initSip()
+            tv_voice_type.text = "SIP"
+        } else {
+            tv_voice_type.text = "RTC"
+        }
+
+        Constants.imei = Build.SERIAL
+        passSoundID = mSoundPool.load(this, R.raw.pass, 1)
+        strangerSoundID = mSoundPool.load(this, R.raw.not_allow, 1)
+        // 门禁SDK
+        gpioHelper = GpioHelper.getInstance()
 
         if(!NetHelper.getInstance().netAvailable){
             showTipView(R.drawable.net_inavailable,R.string.no_network, true, 5000)
             //exitApp(5000)
         }else {
-            Constants.imei = Build.SERIAL
-            passSoundID = mSoundPool.load(this, R.raw.pass, 1)
-            strangerSoundID = mSoundPool.load(this, R.raw.not_allow, 1)
-            // 门禁SDK
-            gpioHelper = GpioHelper.getInstance()
             //获取tcp服务器信息
-            //presenter.getTcpServerInfo()
             presenter.getServerInfo()
 
             initResponseCountDownTimer()
@@ -125,12 +150,109 @@ class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(),
         language = LocaleMangerUtils.getApplicationLocale().language
     }
 
+    private fun initSip() {
+        //首次调用必须使用 Factory相关方法
+        //这里开户调试日志及设置路径
+        val basePath = filesDir.absolutePath
+        Factory.instance().setLogCollectionPath(basePath)
+        Factory.instance().enableLogCollection(LogCollectionState.Disabled)
+        Factory.instance().setDebugMode(false, getString(R.string.app_name))
+
+        //收集一些设备信息
+        Log.i("sipCall", START_SIPPHONE_LOGS)
+        dumpDeviceInformation()
+        dumpInstalledLinphoneInformation()
+
+        sipHandler = Handler()
+        //主监听器,根据事件调用界面
+        mCoreListener = object : CoreListenerStub() {
+            override fun onCallStateChanged(
+                core: Core,
+                call: Call,
+                state: Call.State,
+                message: String
+            ) {
+                if (!SettingConfig.getSipEnabled(BaseApplication.appContext)) {
+                    return
+                }
+
+                Log.d("sipCall", ">>>>>>>>>>>> call state: " + state + ", " + call.remoteAddress.asString())
+                if (state == Call.State.IncomingReceived || state == Call.State.IncomingEarlyMedia) {
+                    //无需处理来电
+                } else if (state == Call.State.Connected) {
+                    runOnUiThread {
+                        showMessage(message)
+                    }
+                } else if (state == Call.State.End || state == Call.State.Released) {
+                    runOnUiThread {
+                        showMessage(message)
+                    }
+                }
+            }
+
+            override fun onRegistrationStateChanged(
+                core: Core,
+                cfg: ProxyConfig,
+                state: RegistrationState,
+                message: String
+            ) {
+                if (!SettingConfig.getSipEnabled(BaseApplication.appContext)) {
+                    return
+                }
+            }
+        }
+
+        try {
+            //复制一些源资源
+            //默认配置只能在首次时安装一次
+            copyIfNotExist(R.raw.linphonerc_default, "$basePath/.wdkl_sip_rc")
+            //用户配置,每次复制
+            copyFromPackage(R.raw.linphonerc_factory, "wdkl_sip_rc")
+        } catch (ioe: IOException) {
+            Log.e("sipCall", ioe.message)
+        }
+
+        //创建SIP核心并加载监听器
+        mCore = Factory.instance().createCore("$basePath/.wdkl_sip_rc", "$basePath/wdkl_sip_rc", this)
+        mCore?.addListener(mCoreListener)
+        mCore?.nativePreviewWindowId = sip_video_surface
+        sip_video_surface.visibility = View.VISIBLE
+
+        //SIP核心配置完成
+        configureCore()
+
+        //SIP核心在创建和配置完成后,开启
+        mCore!!.start()
+        //必须定时运行 SIP核心 iterate()
+        val lTask: TimerTask = object : TimerTask() {
+            override fun run() {
+                sipHandler?.post {
+                    if (mCore != null) {
+                        mCore!!.iterate()
+                    }
+                }
+            }
+        }
+        sipTimer = Timer("wdkl sip scheduler")
+        sipTimer?.schedule(lTask, 0, 20)
+    }
+
     override fun bindEvent() {
+        call_hangup.setOnClickListener {
+            //呼叫挂断
+            callFinish()
 
+            exitApp(1000)
+        }
     }
 
     override fun destory() {
-
+        mCore?.removeListener(mCoreListener)
+        sipTimer?.cancel()
+        mCore?.stop()
+        // A stopped Core can be started again
+        // To ensure resources are freed, we must ensure it will be garbage collected
+        mCore = null
     }
 
     override fun showTcpServerInfo(tcpSeverDTO: TcpSeverDTO) {
@@ -143,6 +265,8 @@ class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(),
         Constant.JANUS_URL = "ws://" + serverInfo.rtcLocalIp + ":" + serverInfo.rtcPort
         Constant.STUN_SERVER = arrayOf<String>(serverInfo.stunServer)
 
+        Constants.sipIp = serverInfo.sipIp
+
         Thread {
             TcpClient.getInstance().init(serverInfo.tcpLocalIp, serverInfo.tcpPort, serverInfo.tcpIdleSeconds)
         }.start()
@@ -156,19 +280,45 @@ class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(),
             Constants.sipId = deviceDO.sipId
             Constants.sipPassword = deviceDO.sipPassword
             Constants.deviceId = deviceDO.id
-            //初始化 engine
-            WebRTCEngine.getInstance().init(false, this)
-
 
-            //初始化 janusClient
-            Log.d("janus", "janus url: " + Constant.JANUS_URL + ", id: " + Constants.sipId)
-            janusClient = JanusClient(Constant.JANUS_URL, Constants.sipId!!.toBigInteger())
-            janusClient!!.callState = EnumType.CallState.Outgoing
-            room = Room(Constants.sipId!!.toBigInteger())
-            videoRoomCallback = VideoRoomCallback(janusClient, room,  Constants.sipId!!.toBigInteger())
-            videoRoomCallback!!.callSessionCallback = this
-            janusClient!!.setJanusCallback(videoRoomCallback)
-            janusClient!!.connect()
+            if (SettingConfig.getSipEnabled(activity)) {
+                //配置sip账户
+                if (mCore != null) {
+                    mAccountCreator = mCore?.createAccountCreator(null)
+                    // 以下三项必须
+                    if (!TextUtils.isEmpty(Constants.sipIp)) {
+                        Log.e(TAG, "sip connect: ${Constants.sipId} @ ${Constants.sipIp}")
+                        mAccountCreator?.setDomain(Constants.sipIp)
+                        mAccountCreator?.setUsername(Constants.sipId)
+                        mAccountCreator?.setPassword(Constants.sipId)
+                        //默认使用udp
+                        mAccountCreator?.transport = TransportType.Udp
+
+                        // 这里会自动创建代理配置、认证信息到 SIP核心
+                        val cfg = mAccountCreator?.createProxyConfig()
+                        // 确保新创建的是最新
+                        mCore?.defaultProxyConfig = cfg
+
+                        //初始化时静音,等主机端允许通话后才打开mic
+                        mCore?.isMicEnabled = false
+                    } else {
+                        showMessage("SIP empty")
+                    }
+                }
+            } else {
+                //初始化 engine
+                WebRTCEngine.getInstance().init(false, this)
+
+                //初始化 janusClient
+                Log.d("janus", "janus url: " + Constant.JANUS_URL + ", id: " + Constants.sipId)
+                janusClient = JanusClient(Constant.JANUS_URL, Constants.sipId!!.toBigInteger())
+                janusClient!!.callState = EnumType.CallState.Outgoing
+                room = Room(Constants.sipId!!.toBigInteger())
+                videoRoomCallback = VideoRoomCallback(janusClient, room, Constants.sipId!!.toBigInteger())
+                videoRoomCallback!!.callSessionCallback = this
+                janusClient!!.setJanusCallback(videoRoomCallback)
+                janusClient!!.connect()
+            }
 
             initCountDownTimer()
             countDownTimer.start()
@@ -195,12 +345,27 @@ class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(),
 
     @Subscribe(threadMode = ThreadMode.MAIN)
     fun onMoonEvent(messageEvent: MessageEvent) {
-        when (messageEvent.tag) {
+        when (messageEvent.getType()) {
             Constants.ENTRACEGUARD -> {
-                Log.i("收到tcp消息:", JSON.toJSONString(messageEvent.tcpModel))
-                val tcpModel = messageEvent.tcpModel as TcpModel
+                Log.i("收到tcp消息:", JSON.toJSONString(messageEvent.getMessage()))
+                val tcpModel = messageEvent.getMessage() as TcpModel
                 if (tcpModel.type.equals(TcpType.ENTRACEGUARD)) {
                     when (tcpModel.action) {
+                        TcpAction.EntraceGuardAction.SUCCESS -> {
+                            //呼叫请求成功
+                            interactionVO = JSON.parseObject(tcpModel.data.toString(), InteractionVO::class.java)
+                            if (mCore != null) {
+                                val addressToCall = mCore!!.interpretUrl(interactionVO!!.toSipId)
+                                val params = mCore!!.createCallParams(null)
+                                params?.isVideoEnabled = true
+
+                                if (addressToCall != null) {
+                                    mCore!!.inviteAddressWithParams(addressToCall, params!!)
+                                    Log.d(TAG, ">>>>>>>>>>> invite address: " + addressToCall.asString())
+                                }
+                            }
+                        }
+
                         TcpAction.EntraceGuardAction.ACCEPT -> { //接通视频
                             //取消响应计时
                             responseCountDownTimer.cancel()
@@ -225,8 +390,12 @@ class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(),
                             gpioHelper!!.setPassStatus(true)
                             gpioHelper!!.setWhiteLedStatus(true)
                             //结束通话
-                            janusClient!!.destroyRoom(janusClient!!.currentHandleId, null)
-                            janusClient!!.disConnect()
+                            if (SettingConfig.getSipEnabled(activity)) {
+                                sipCallTerminate()
+                            } else {
+                                janusClient!!.destroyRoom(janusClient!!.currentHandleId, null)
+                                janusClient!!.disConnect()
+                            }
 
                             showTipView(R.drawable.allow_in,R.string.door_opened, false, 10000)
                             play(passSoundID!!)
@@ -240,11 +409,16 @@ class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(),
                             //停止等待音乐,停止倒计时
                             cancelCountDownTimer()
 
-                            play(strangerSoundID!!)
+                            if (SettingConfig.getSipEnabled(activity)) {
+                                sipCallTerminate()
+                            } else {
+                                janusClient!!.destroyRoom(janusClient!!.currentHandleId, null)
+                                janusClient!!.disConnect()
+                            }
+
                             showTipView(R.drawable.busyline,R.string.call_busy, false, 3000)
+                            play(strangerSoundID!!)
 
-                            janusClient!!.destroyRoom(janusClient!!.currentHandleId, null)
-                            janusClient!!.disConnect()
                             //3秒后退出程序
                             //exitApp(3000)
 
@@ -259,24 +433,41 @@ class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(),
                             //停止等待音乐,停止倒计时
                             cancelCountDownTimer()
 
-                            WebRTCEngine.getInstance().toggleSpeaker(true)
-                            WebRTCEngine.getInstance().muteAudio(false)
+                            if (SettingConfig.getSipEnabled(activity)) {
+                                mCore?.isMicEnabled = true
+                                toggleSpeaker(true)
+                            } else {
+                                WebRTCEngine.getInstance().toggleSpeaker(true)
+                                WebRTCEngine.getInstance().muteAudio(false)
+                            }
                         }
 
                         TcpAction.EntraceGuardAction.CLOSESPEAKER -> { //关闭音频
                             //停止等待音乐,停止倒计时
                             cancelCountDownTimer()
-                            WebRTCEngine.getInstance().toggleSpeaker(false)
-                            WebRTCEngine.getInstance().muteAudio(true)
+
+                            if (SettingConfig.getSipEnabled(activity)) {
+                                mCore?.isMicEnabled = false
+                                toggleSpeaker(false)
+                            } else {
+                                WebRTCEngine.getInstance().toggleSpeaker(false)
+                                WebRTCEngine.getInstance().muteAudio(true)
+                            }
                         }
 
                         TcpAction.EntraceGuardAction.HANGUP -> { //主机直接挂断,不开门显示
                             //停止等待音乐,停止倒计时
                             cancelCountDownTimer()
+
+                            if (SettingConfig.getSipEnabled(activity)) {
+                                sipCallTerminate()
+                            } else {
+                                janusClient!!.destroyRoom(janusClient!!.currentHandleId, null)
+                                janusClient!!.disConnect()
+                            }
+
                             play(strangerSoundID!!)
                             showTipView(R.drawable.not_allow,R.string.not_allowed, false, 3000)
-                            janusClient!!.destroyRoom(janusClient!!.currentHandleId, null)
-                            janusClient!!.disConnect()
 
                             //3秒后退出程序
                             //exitApp(3000)
@@ -288,14 +479,15 @@ class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(),
 
             }
             Constants.EVENT_TCP_BREAK -> {
-                if (messageEvent.tcpModel.equals("net on")) {
+                val msg = messageEvent.getMessage() as String
+                if (msg.equals("net on")) {
                     //获取设备信息
                     presenter.getDeviceInfo()
 
                 }
             }
             Constants.TIME->{
-                var tcpModel = messageEvent.tcpModel as TcpModel
+                var tcpModel = messageEvent.getMessage() as TcpModel
                 if(tcpModel.type.equals(TcpType.TIME)&&tcpModel.action.equals(TcpAction.TimeAction.SYNC)){
                     var time = 0L
                     var timeZone = "Asia/Shanghai"
@@ -351,6 +543,21 @@ class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(),
         }
     }
 
+    fun callFinish() {
+        RingPlayHelper.stopRingTone()
+
+        if (SettingConfig.getSipEnabled(activity)) {
+            sipCallTerminate()
+        } else {
+            janusClient!!.destroyRoom(janusClient!!.currentHandleId, null)
+            janusClient!!.disConnect()
+        }
+
+        if (interactionVO != null) {
+            TcpClient.getInstance().sendMsg(EntraceGuardUtil.timeOut(interactionVO, tid).toJson())
+        }
+    }
+
     fun initCountDownTimer() {
         countDownTimer = object : CountDownTimer(100 * 1000L, 1000) {
 
@@ -362,13 +569,8 @@ class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(),
 
             override fun onFinish() {
                 //呼叫超时,返回到主界面
-                janusClient!!.destroyRoom(janusClient!!.currentHandleId, null)
-                janusClient!!.disConnect()
-                RingPlayHelper.stopRingTone()
+                callFinish()
 
-                if (interactionVO != null) {
-                    TcpClient.getInstance().sendMsg(EntraceGuardUtil.timeOut(interactionVO, tid).toJson())
-                }
                 showTipView(R.drawable.no_reponse,R.string.call_no_response, false, 3000)
                 //exitApp(3000)
             }
@@ -377,7 +579,7 @@ class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(),
 
     fun cancelCountDownTimer(){
         countDownTimer.cancel()
-        counter_down_wrap.visibility=View.GONE
+        counter_down.visibility=View.GONE
         RingPlayHelper.stopRingTone()
     }
 
@@ -399,35 +601,116 @@ class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(),
     }
 
     fun showTipView(imageId: Int, message: String, serverConfig: Boolean, delayExit: Long){
-        counter_down_wrap.visibility=View.GONE
-        surface_view.removeAllViews()
+        counter_down.visibility=View.GONE
+        tips_view.removeAllViews()
+        tips_view.setOnClickListener {
+            return@setOnClickListener
+        }
         val view = layoutInflater.inflate(R.layout.view_tips_layout, null)
-        val imageView = view.findViewById<ImageView>(R.id.tips_image)
-        imageView.setImageResource(imageId)
-        val messageView = view.findViewById<TextView>(R.id.tips_message)
-        val serverBtn = view.findViewById<Button>(R.id.btn_server_config)
-        val exitBtn = view.findViewById<Button>(R.id.btn_exit)
-        val tvVersion = view.findViewById<TextView>(R.id.tv_version)
-        tvVersion.setText("V" + BuildConfig.VERSION_NAME)
-        messageView.setText(message)
-        surface_view.addView(view)
 
         if (serverConfig) {
             exitApp(60000)
 
-            tvVersion.visibility = View.VISIBLE
-            serverBtn.visibility = View.VISIBLE
-            serverBtn.setOnClickListener {
-                //服务器IP配置
-                ServerConfigDialogHelper.showPasswordDialog(activity)
+            var pwd = ""
+            val numbers = arrayOf("1", "2", "3", "4", "5", "6", "7", "8", "9")
+            val password: TextView = view.findViewById(R.id.tv_password_view)
+            val llPwd: LinearLayout = view.findViewById(R.id.ll_password_view)
+            val rlConfig: RelativeLayout = view.findViewById(R.id.rl_config)
+            val gridView: GridView = view.findViewById(R.id.grid_password)
+            val delete: TextView = view.findViewById(R.id.bn_delete)
+            val cancel: TextView = view.findViewById(R.id.bn_cancel)
+            val confirm: TextView = view.findViewById(R.id.bn_confirm)
+
+            llPwd.visibility = View.VISIBLE
+            val adapter = NumAdapter(numbers, activity)
+            gridView.adapter = adapter
+            gridView.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->
+                if (pwd.length <= 2) {
+                    pwd = pwd + numbers[position]
+                    password.text = pwd
+                }
+
+                Log.d(TAG, "input password len: " + pwd.length + "--" + pwd)
+            }
+
+            cancel.setOnClickListener {
+                //退出
+                handler.removeCallbacksAndMessages(null)
+                exitApp(0)
+            }
+
+            delete.setOnClickListener {
+                Log.d(TAG, "delete password len: " + pwd.length + "--" + pwd)
+                if (pwd.length > 1) {
+                    pwd = pwd.substring(0, pwd.length - 1)
+                    password.text = pwd
+                } else {
+                    pwd = ""
+                    password.text = pwd
+                    password.setHint(R.string.input_password)
+                }
+            }
+
+            confirm.setOnClickListener {
+                if ("666" == pwd) {
+                    llPwd.visibility = View.GONE
+                    rlConfig.visibility = View.VISIBLE
+                } else {
+                    Toast.makeText(activity, R.string.invalid_password, Toast.LENGTH_SHORT).show()
+                }
+            }
+
+
+            val groupSip = view.findViewById<RadioGroup>(R.id.group_sip)
+            val sipOn = view.findViewById<RadioButton>(R.id.radio_sip_on)
+            val sipOff = view.findViewById<RadioButton>(R.id.radio_sip_off)
+            val saveIp = view.findViewById<Button>(R.id.btn_save)
+            val exitBtn = view.findViewById<Button>(R.id.btn_exit)
+            val editIp = view.findViewById<EditText>(R.id.edit_url)
+            val tvVersion = view.findViewById<TextView>(R.id.tv_version)
+            tvVersion.setText("V" + BuildConfig.VERSION_NAME)
+            editIp.setText(CommonUtils.getUrl(BaseApplication.appContext))
+
+            if (SettingConfig.getSipEnabled(activity)) {
+                sipOn.isChecked = true
+            } else {
+                sipOff.isChecked = true
+            }
+
+            saveIp.setOnClickListener {
+                val url: String = editIp.getText().toString()
+                if (TextUtils.isEmpty(url)) {
+                    Toast.makeText(activity, R.string.input_empty, Toast.LENGTH_SHORT).show()
+                } else {
+                    //保存配置
+                    CommonUtils.setUrl(BaseApplication.appContext, url)
+
+                    Toast.makeText(activity, R.string.str_save, Toast.LENGTH_SHORT).show()
+                }
+            }
+
+            groupSip.setOnCheckedChangeListener { group, checkedId ->
+                if (checkedId == R.id.radio_sip_on) {
+                    SettingConfig.setSipEnable(activity, true)
+                } else {
+                    SettingConfig.setSipEnable(activity, false)
+                }
             }
 
-            exitBtn.visibility = View.VISIBLE
             exitBtn.setOnClickListener {
+                //退出
                 handler.removeCallbacksAndMessages(null)
                 exitApp(0)
             }
+
+            tips_view.addView(view)
         } else {
+            val imageView = view.findViewById<ImageView>(R.id.tips_image)
+            imageView.setImageResource(imageId)
+            val messageView = view.findViewById<TextView>(R.id.tips_message)
+            messageView.setText(message)
+            tips_view.addView(view)
+
             exitApp(delayExit)
         }
     }
@@ -436,6 +719,7 @@ class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(),
 
         when (var1) {
             EnumType.CallState.Connected -> { // 订阅对方流媒体成功,开始通话计时
+                //刚连接上时静音,等主机端允许通话后才打开mic
                 WebRTCEngine.getInstance().muteAudio(true)
             }
         }
@@ -461,7 +745,10 @@ class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(),
             } else {
                 localSurfaceView!!.setZOrderMediaOverlay(true)
             }
-            surface_view!!.addView(localSurfaceView)
+            if (surface_view != null) {
+                surface_view.visibility = View.VISIBLE
+                surface_view!!.addView(localSurfaceView)
+            }
         }
     }
 
@@ -488,4 +775,107 @@ class MainActivity : BaseActivity<MainActivityPresenter, ActivityMainBinding>(),
     override fun didUserLeave(userId: BigInteger?) {
 
     }
+
+
+    private fun toggleSpeaker(enable: Boolean) {
+        if (mCore == null) {
+            return
+        }
+
+        if (enable) {
+            AudioRouteUtils.routeAudioToSpeaker(mCore!!)
+        } else {
+            AudioRouteUtils.routeAudioToEarpiece(mCore!!)
+        }
+    }
+
+    private fun sipCallTerminate() {
+        if (mCore != null && mCore!!.callsNb > 0) {
+            var call = mCore!!.currentCall
+            if (call == null) {
+                call = mCore!!.calls[0]
+            }
+            call?.terminate()
+        }
+    }
+
+    /**************sip core config******************/
+    private fun configureCore() {
+        // We will create a directory for user signed certificates if needed
+        val basePath = filesDir.absolutePath
+        val userCerts = "$basePath/user-certs"
+        val f = File(userCerts)
+        if (!f.exists()) {
+            if (!f.mkdir()) {
+                Log.e("sipCall", "$userCerts can't be created.")
+            }
+        }
+        mCore?.userCertificatesPath = userCerts
+
+        //音频部分, 这里增加了一个遍历, 用于设置指定的音频格式.
+        val payloads = mCore!!.audioPayloadTypes
+        for (i in payloads.indices) {
+            val pt = payloads[i]
+            //Log.i("sipCall", ">>>>>>>>>>>>>>>>>1 " + pt.getMimeType() + " = " + pt.enabled());
+            if (pt.mimeType == "PCMU") {
+                pt.enable(true)
+            } else {
+                pt.enable(false)
+            }
+        }
+        mCore?.setAudioPayloadTypes(payloads)
+    }
+
+    private fun dumpDeviceInformation() {
+        val sb = StringBuilder()
+        sb.append("DEVICE=").append(Build.DEVICE).append("\n")
+        sb.append("MODEL=").append(Build.MODEL).append("\n")
+        sb.append("MANUFACTURER=").append(Build.MANUFACTURER).append("\n")
+        sb.append("SDK=").append(Build.VERSION.SDK_INT).append("\n")
+        sb.append("Supported ABIs=")
+        for (abi in Version.getCpuAbis()) {
+            sb.append(abi).append(", ")
+        }
+        sb.append("\n")
+        Log.i("sipCall", sb.toString())
+    }
+
+    private fun dumpInstalledLinphoneInformation() {
+        var info: PackageInfo? = null
+        try {
+            info = packageManager.getPackageInfo(packageName, 0)
+        } catch (nnfe: PackageManager.NameNotFoundException) {
+            Log.e("sipCall", nnfe.message)
+        }
+        if (info != null) {
+            Log.i(TAG,
+                "[Service] sipphone version is " +
+                info.versionName + " (" + info.versionCode + ")"
+            )
+        } else {
+            Log.i(TAG, "[Service] sipphone version is unknown")
+        }
+    }
+
+    @Throws(IOException::class)
+    private fun copyIfNotExist(ressourceId: Int, target: String) {
+        val lFileToCopy = File(target)
+        if (!lFileToCopy.exists()) {
+            copyFromPackage(ressourceId, lFileToCopy.name)
+        }
+    }
+
+    @Throws(IOException::class)
+    private fun copyFromPackage(ressourceId: Int, target: String) {
+        val lOutputStream = openFileOutput(target, 0)
+        val lInputStream = resources.openRawResource(ressourceId)
+        var readByte: Int
+        val buff = ByteArray(8048)
+        while (lInputStream.read(buff).also { readByte = it } != -1) {
+            lOutputStream.write(buff, 0, readByte)
+        }
+        lOutputStream.flush()
+        lOutputStream.close()
+        lInputStream.close()
+    }
 }

+ 2 - 2
app/src/main/java/com/wdkl/ncs/entraceguard/application/Application.java

@@ -2,8 +2,8 @@ package com.wdkl.ncs.entraceguard.application;
 
 import com.szeasco.facesdk.FaceSdkApplication;
 import com.szeasco.facesdk.config.FaceSdkConfig;
-import com.wdkl.ncs.framework.base.BaseApplication;
-import com.wdkl.ncs.framework.helper.NetHelper;
+import com.wdkl.ncs.middleware.base.BaseApplication;
+import com.wdkl.ncs.middleware.helper.NetHelper;
 
 public class Application extends BaseApplication {
     @Override

+ 2 - 3
app/src/main/java/com/wdkl/ncs/entraceguard/contracts/MainActivityContract.kt

@@ -2,9 +2,8 @@ package com.wdkl.ncs.entraceguard.contracts
 
 import com.wdkl.ncs.entraceguard.model.dos.DeviceDO
 import com.wdkl.ncs.entraceguard.model.dto.TcpSeverDTO
-import com.wdkl.ncs.entraceguard.model.vo.DeviceVO
-import com.wdkl.ncs.framework.base.BaseContract
-import com.wdkl.ncs.framework.beans.ServerInfo
+import com.wdkl.ncs.middleware.base.BaseContract
+import com.wdkl.ncs.middleware.beans.ServerInfo
 
 interface MainActivityContract{
     interface View : BaseContract.BaseView{

+ 1 - 2
app/src/main/java/com/wdkl/ncs/entraceguard/di/ApplicationComponent.java

@@ -1,10 +1,9 @@
 package com.wdkl.ncs.entraceguard.di;
 
 import com.wdkl.ncs.entraceguard.activity.MainActivity;
-import com.wdkl.ncs.framework.di.FrameWorkComponent;
+import com.wdkl.ncs.middleware.di.FrameWorkComponent;
 
 import dagger.Component;
-import dagger.Subcomponent;
 
 @Component(dependencies = {FrameWorkComponent.class})
 public interface ApplicationComponent {

+ 1 - 1
app/src/main/java/com/wdkl/ncs/entraceguard/di/PresenterComponent.java

@@ -1,7 +1,7 @@
 package com.wdkl.ncs.entraceguard.di;
 
 import com.wdkl.ncs.entraceguard.presenters.MainActivityPresenter;
-import com.wdkl.ncs.framework.di.FrameWorkComponent;
+import com.wdkl.ncs.middleware.di.FrameWorkComponent;
 
 import dagger.Component;
 

+ 5 - 5
app/src/main/java/com/wdkl/ncs/entraceguard/helper/ServerConfigDialogHelper.java

@@ -17,8 +17,8 @@ import android.widget.TextView;
 import android.widget.Toast;
 
 import com.wdkl.ncs.entraceguard.adapter.NumAdapter;
-import com.wdkl.ncs.framework.base.BaseApplication;
-import com.wdkl.ncs.framework.utils.CommonUtils;
+import com.wdkl.ncs.middleware.base.BaseApplication;
+import com.wdkl.ncs.middleware.utils.CommonUtils;
 
 import iot.facereco.smart.terminal.R;
 
@@ -64,7 +64,7 @@ public class ServerConfigDialogHelper {
                 } else {
                     pwd = "";
                     password.setText(pwd);
-                    password.setHint("请输密码");
+                    password.setHint(R.string.input_password);
                 }
             }
         });
@@ -83,7 +83,7 @@ public class ServerConfigDialogHelper {
                     llPwd.setVisibility(View.GONE);
                     llServer.setVisibility(View.VISIBLE);
                 } else {
-                    Toast.makeText(activity, "密码错误", Toast.LENGTH_SHORT).show();
+                    Toast.makeText(activity, R.string.invalid_password, Toast.LENGTH_SHORT).show();
                 }
             }
         });
@@ -104,7 +104,7 @@ public class ServerConfigDialogHelper {
                 String url = editUrl.getText().toString();
                 String port = editPort.getText().toString();
                 if (TextUtils.isEmpty(url) || TextUtils.isEmpty(port)) {
-                    Toast.makeText(activity, "数据为空", Toast.LENGTH_SHORT).show();
+                    Toast.makeText(activity, R.string.input_empty, Toast.LENGTH_SHORT).show();
                 } else {
                     //保存配置
                     CommonUtils.setUrl(BaseApplication.appContext, editUrl.getText().toString());

+ 14 - 13
app/src/main/java/com/wdkl/ncs/entraceguard/presenters/MainActivityPresenter.kt

@@ -7,18 +7,17 @@ import com.wdkl.ncs.entraceguard.contracts.MainActivityContract
 import com.wdkl.ncs.entraceguard.di.DaggerPresenterComponent
 import com.wdkl.ncs.entraceguard.model.dos.DeviceDO
 import com.wdkl.ncs.entraceguard.model.dto.TcpSeverDTO
-import com.wdkl.ncs.framework.api.DeviceApi
-import com.wdkl.ncs.framework.base.RxPresenter
-import com.wdkl.ncs.framework.beans.ServerInfo
-import com.wdkl.ncs.framework.common.Constants
-import com.wdkl.ncs.framework.di.ApiProviders
-import com.wdkl.ncs.framework.di.DaggerFrameWorkComponent
-import com.wdkl.ncs.framework.di.FrameWorkComponent
-import com.wdkl.ncs.framework.exception.ExceptionHandle
-import com.wdkl.ncs.framework.network.ConnectionObserver
-import com.wdkl.ncs.framework.network.ConnectionQuality
-import com.wdkl.ncs.framework.utils.ThreadFromUtils
-import com.wdkl.ncs.framework.utils.getJsonString
+import com.wdkl.ncs.middleware.api.DeviceApi
+import com.wdkl.ncs.middleware.base.RxPresenter
+import com.wdkl.ncs.middleware.beans.ServerInfo
+import com.wdkl.ncs.middleware.common.Constants
+import com.wdkl.ncs.middleware.di.ApiProviders
+import com.wdkl.ncs.middleware.di.DaggerFrameWorkComponent
+import com.wdkl.ncs.middleware.exception.ExceptionHandle
+import com.wdkl.ncs.middleware.network.ConnectionObserver
+import com.wdkl.ncs.middleware.network.ConnectionQuality
+import com.wdkl.ncs.middleware.utils.ThreadFromUtils
+import com.wdkl.ncs.middleware.utils.getJsonString
 import io.reactivex.disposables.Disposable
 import javax.inject.Inject
 
@@ -28,7 +27,9 @@ class MainActivityPresenter @Inject constructor(): RxPresenter<MainActivityContr
     lateinit var deviceApi: DeviceApi
 
     override fun bindDagger() {
-      DaggerPresenterComponent.builder().frameWorkComponent(DaggerFrameWorkComponent.builder().apiProviders(ApiProviders()).build()).build().inject(this)
+      DaggerPresenterComponent.builder().frameWorkComponent(DaggerFrameWorkComponent.builder().apiProviders(
+          ApiProviders()
+      ).build()).build().inject(this)
     }
 
     override fun getTcpServerInfo() {

+ 2 - 2
app/src/main/java/com/wdkl/ncs/entraceguard/tcp/TcpClientHandler.java

@@ -6,8 +6,8 @@ import android.util.Log;
 import com.wdkl.ncs.entraceguard.tcp.channel.DeviceChannel;
 import com.wdkl.ncs.entraceguard.tcp.channel.DeviceUtil;
 import com.wdkl.ncs.entraceguard.tcp.dto.TcpModel;
-import com.wdkl.ncs.framework.common.Constants;
-import com.wdkl.ncs.framework.utils.MessageEvent;
+import com.wdkl.ncs.middleware.common.Constants;
+import com.wdkl.ncs.middleware.utils.MessageEvent;
 
 import org.greenrobot.eventbus.EventBus;
 

+ 2 - 3
app/src/main/java/com/wdkl/ncs/entraceguard/tcp/channel/DeviceChannel.java

@@ -6,9 +6,8 @@ import com.google.gson.Gson;
 import com.wdkl.ncs.entraceguard.model.vo.InteractionVO;
 import com.wdkl.ncs.entraceguard.tcp.dto.TcpModel;
 import com.wdkl.ncs.entraceguard.tcp.enums.TcpAction;
-import com.wdkl.ncs.entraceguard.tcp.enums.TcpType;
-import com.wdkl.ncs.framework.common.Constants;
-import com.wdkl.ncs.framework.utils.MessageEvent;
+import com.wdkl.ncs.middleware.common.Constants;
+import com.wdkl.ncs.middleware.utils.MessageEvent;
 
 
 import org.greenrobot.eventbus.EventBus;

+ 169 - 0
app/src/main/java/com/wdkl/ncs/entraceguard/utils/AudioRouteUtils.kt

@@ -0,0 +1,169 @@
+package com.wdkl.ncs.entraceguard.utils
+
+import org.linphone.core.AudioDevice
+import org.linphone.core.Call
+import org.linphone.core.Core
+import org.linphone.core.tools.Log
+
+class AudioRouteUtils {
+    companion object {
+        private fun applyAudioRouteChange(
+            core: Core,
+            call: Call?,
+            types: List<AudioDevice.Type>,
+            output: Boolean = true
+        ) {
+            val currentCall = if (core.callsNb > 0) {
+                call ?: core.currentCall ?: core.calls[0]
+            } else {
+                Log.w("[Audio Route Helper] No call found, setting audio route on Core")
+                null
+            }
+            val conference = core.conference
+            val capability = if (output)
+                AudioDevice.Capabilities.CapabilityPlay
+            else
+                AudioDevice.Capabilities.CapabilityRecord
+            val preferredDriver = if (output) {
+                core.defaultOutputAudioDevice?.driverName
+            } else {
+                core.defaultInputAudioDevice?.driverName
+            }
+
+            val extendedAudioDevices = core.extendedAudioDevices
+            Log.i("[Audio Route Helper] Looking for an ${if (output) "output" else "input"} audio device with capability [$capability], driver name [$preferredDriver] and type [$types] in extended audio devices list (size ${extendedAudioDevices.size})")
+            val foundAudioDevice = extendedAudioDevices.find {
+                it.driverName == preferredDriver && types.contains(it.type) && it.hasCapability(capability)
+            }
+            val audioDevice = if (foundAudioDevice == null) {
+                Log.w("[Audio Route Helper] Failed to find an audio device with capability [$capability], driver name [$preferredDriver] and type [$types]")
+                extendedAudioDevices.find {
+                    types.contains(it.type) && it.hasCapability(capability)
+                }
+            } else {
+                foundAudioDevice
+            }
+
+            if (audioDevice == null) {
+                Log.e("[Audio Route Helper] Couldn't find audio device with capability [$capability] and type [$types]")
+                for (device in extendedAudioDevices) {
+                    // TODO: switch to debug?
+                    Log.i("[Audio Route Helper] Extended audio device: [${device.deviceName} (${device.driverName}) ${device.type} / ${device.capabilities}]")
+                }
+                return
+            }
+            if (conference != null && conference.isIn) {
+                Log.i("[Audio Route Helper] Found [${audioDevice.type}] ${if (output) "playback" else "recorder"} audio device [${audioDevice.deviceName} (${audioDevice.driverName})], routing conference audio to it")
+                if (output) conference.outputAudioDevice = audioDevice
+                else conference.inputAudioDevice = audioDevice
+            } else if (currentCall != null) {
+                Log.i("[Audio Route Helper] Found [${audioDevice.type}] ${if (output) "playback" else "recorder"} audio device [${audioDevice.deviceName} (${audioDevice.driverName})], routing call audio to it")
+                if (output) currentCall.outputAudioDevice = audioDevice
+                else currentCall.inputAudioDevice = audioDevice
+            } else {
+                Log.i("[Audio Route Helper] Found [${audioDevice.type}] ${if (output) "playback" else "recorder"} audio device [${audioDevice.deviceName} (${audioDevice.driverName})], changing core default audio device")
+                if (output) core.outputAudioDevice = audioDevice
+                else core.inputAudioDevice = audioDevice
+            }
+        }
+
+        private fun changeCaptureDeviceToMatchAudioRoute(core: Core, call: Call?, types: List<AudioDevice.Type>) {
+            when (types.first()) {
+                AudioDevice.Type.Bluetooth -> {
+                    if (isBluetoothAudioRecorderAvailable(core)) {
+                        Log.i("[Audio Route Helper] Bluetooth device is able to record audio, also change input audio device")
+                        applyAudioRouteChange(core, call, arrayListOf(AudioDevice.Type.Bluetooth), false)
+                    }
+                }
+                AudioDevice.Type.Headset, AudioDevice.Type.Headphones -> {
+                    if (isHeadsetAudioRecorderAvailable(core)) {
+                        Log.i("[Audio Route Helper] Headphones/Headset device is able to record audio, also change input audio device")
+                        applyAudioRouteChange(core, call, (arrayListOf(AudioDevice.Type.Headphones, AudioDevice.Type.Headset)), false)
+                    }
+                }
+                AudioDevice.Type.Earpiece, AudioDevice.Type.Speaker -> {
+                    Log.i("[Audio Route Helper] Audio route requested to Earpiece or Speaker, setting input to Microphone")
+                    applyAudioRouteChange(core, call, (arrayListOf(AudioDevice.Type.Microphone)), false)
+                }
+                else -> {
+                    Log.w("[Audio Route Helper] Unexpected audio device type: ${types.first()}")
+                }
+            }
+        }
+
+        private fun routeAudioTo(
+            core: Core,
+            call: Call?,
+            types: List<AudioDevice.Type>,
+            skipTelecom: Boolean = false
+        ) {
+            val currentCall = call ?: core.currentCall ?: core.calls.firstOrNull()
+
+                if (currentCall != null) {
+                    Log.i("[Audio Route Helper] Telecom Helper & matching connection found, dispatching audio route change through it")
+                    // We will be called here again by NativeCallWrapper.onCallAudioStateChanged()
+                    // but this time with skipTelecom = true
+                    //if (!Compatibility.changeAudioRouteForTelecomManager(connection, route)) {
+                        Log.w("[Audio Route Helper] Connection is already using this route internally, make the change!")
+                        applyAudioRouteChange(core, currentCall, types)
+                        changeCaptureDeviceToMatchAudioRoute(core, currentCall, types)
+                    //}
+                }
+
+        }
+
+        fun routeAudioToEarpiece(core: Core, call: Call? = null, skipTelecom: Boolean = false) {
+            routeAudioTo(core, call, arrayListOf(AudioDevice.Type.Earpiece), skipTelecom)
+        }
+
+        fun routeAudioToSpeaker(core: Core, call: Call? = null, skipTelecom: Boolean = false) {
+            routeAudioTo(core, call, arrayListOf(AudioDevice.Type.Speaker), skipTelecom)
+        }
+
+        fun routeAudioToBluetooth(core: Core, call: Call? = null, skipTelecom: Boolean = false) {
+            routeAudioTo(core, call, arrayListOf(AudioDevice.Type.Bluetooth), skipTelecom)
+        }
+
+        fun routeAudioToHeadset(core: Core, call: Call? = null, skipTelecom: Boolean = false) {
+            routeAudioTo(core, call, arrayListOf(AudioDevice.Type.Headphones, AudioDevice.Type.Headset), skipTelecom)
+        }
+
+
+
+        fun isBluetoothAudioRouteAvailable(core: Core): Boolean {
+            for (audioDevice in core.audioDevices) {
+                if (audioDevice.type == AudioDevice.Type.Bluetooth &&
+                    audioDevice.hasCapability(AudioDevice.Capabilities.CapabilityPlay)
+                ) {
+                    Log.i("[Audio Route Helper] Found bluetooth audio device [${audioDevice.deviceName} (${audioDevice.driverName})]")
+                    return true
+                }
+            }
+            return false
+        }
+
+        private fun isBluetoothAudioRecorderAvailable(core: Core): Boolean {
+            for (audioDevice in core.audioDevices) {
+                if (audioDevice.type == AudioDevice.Type.Bluetooth &&
+                    audioDevice.hasCapability(AudioDevice.Capabilities.CapabilityRecord)
+                ) {
+                    Log.i("[Audio Route Helper] Found bluetooth audio recorder [${audioDevice.deviceName} (${audioDevice.driverName})]")
+                    return true
+                }
+            }
+            return false
+        }
+
+        private fun isHeadsetAudioRecorderAvailable(core: Core): Boolean {
+            for (audioDevice in core.audioDevices) {
+                if ((audioDevice.type == AudioDevice.Type.Headset || audioDevice.type == AudioDevice.Type.Headphones) &&
+                    audioDevice.hasCapability(AudioDevice.Capabilities.CapabilityRecord)
+                ) {
+                    Log.i("[Audio Route Helper] Found headset/headphones audio recorder [${audioDevice.deviceName} (${audioDevice.driverName})]")
+                    return true
+                }
+            }
+            return false
+        }
+    }
+}

+ 1 - 1
app/src/main/java/com/wdkl/ncs/entraceguard/utils/LocaleMangerUtils.java

@@ -9,7 +9,7 @@ import android.util.Log;
 
 import androidx.annotation.RequiresApi;
 
-import com.wdkl.ncs.framework.base.BaseApplication;
+import com.wdkl.ncs.middleware.base.BaseApplication;
 
 import java.util.Locale;
 

+ 31 - 0
app/src/main/java/com/wdkl/ncs/entraceguard/utils/SettingConfig.java

@@ -0,0 +1,31 @@
+package com.wdkl.ncs.entraceguard.utils;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+public class SettingConfig {
+
+
+    private static final String SP_NAME = "SP_FUNCTION";
+
+    //是否使用sip通话
+    private static final String KEY_SP_SIP_ENABLE = "KEY_SP_SIP_ENABLE";
+
+
+    public static boolean getSipEnabled(Context context) {
+        return getSP(context).getBoolean(KEY_SP_SIP_ENABLE, false);
+    }
+
+    public static void setSipEnable(Context context, boolean enable) {
+        getEditor(context).putBoolean(KEY_SP_SIP_ENABLE, enable).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();
+    }
+
+}

BIN
app/src/main/res/drawable/ic_hangup_normal.png


BIN
app/src/main/res/drawable/ic_hangup_press.png


+ 5 - 0
app/src/main/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>

+ 55 - 18
app/src/main/res/layout/activity_main.xml

@@ -1,32 +1,69 @@
 <?xml version="1.0" encoding="utf-8"?>
 <layout>
 
-    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
-        android:orientation="vertical"
         android:layout_height="match_parent">
 
-        <FrameLayout
-            android:id="@+id/surface_view"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"/>
-
-        <FrameLayout
-            android:id="@+id/counter_down_wrap"
+        <RelativeLayout
+            android:id="@+id/rl_main_title"
             android:layout_width="match_parent"
-            android:background="#2A9798"
-            android:layout_height="50dp">
+            android:layout_height="wrap_content"
+            android:padding="10dp"
+            android:background="#2A9798">
+            <TextView
+                android:id="@+id/tv_voice_type"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="20dp"
+                android:layout_centerVertical="true"
+                android:textColor="@color/white"
+                android:textSize="16sp"
+                android:textStyle="bold"/>
             <TextView
                 android:id="@+id/counter_down"
-                android:layout_width="match_parent"
-                android:layout_height="50dp"
-                android:text="等待响应倒计时:"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_centerHorizontal="true"
                 android:gravity="center"
                 android:textColor="@color/white"
                 android:textSize="22sp"
-                android:textStyle="bold"
-                />
-        </FrameLayout>
+                android:textStyle="bold" />
+        </RelativeLayout>
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_below="@id/rl_main_title">
+            <FrameLayout
+                android:id="@+id/surface_view"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:visibility="gone"/>
+
+            <TextureView
+                android:id="@+id/sip_video_surface"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:visibility="gone"/>
+
+
+            <ImageView
+                android:id="@+id/call_hangup"
+                android:layout_width="100dp"
+                android:layout_height="100dp"
+                android:layout_alignParentBottom="true"
+                android:layout_marginBottom="60dp"
+                android:layout_centerHorizontal="true"
+                android:src="@drawable/selector_call_hangup"
+                android:visibility="gone"/>
+
+        </RelativeLayout>
+
+        <FrameLayout
+            android:id="@+id/tips_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"/>
 
-    </FrameLayout>
+    </RelativeLayout>
 </layout>

+ 196 - 44
app/src/main/res/layout/view_tips_layout.xml

@@ -1,56 +1,208 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="#2A9798"
-    android:layout_gravity="center"
-    android:gravity="center"
-    android:orientation="vertical">
+    android:background="#2A9798">
 
-    <ImageView
-        android:id="@+id/tips_image"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:src="@drawable/allow_in" />
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:gravity="center"
+        android:orientation="vertical">
+        <ImageView
+            android:id="@+id/tips_image"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
 
         <TextView
             android:id="@+id/tips_message"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:textSize="40sp"
+            android:layout_marginTop="20dp"
             android:textColor="@color/white"
-            android:textStyle="bold"
-            android:layout_marginTop="20dp" />
-
-    <Button
-        android:id="@+id/btn_server_config"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="80dp"
-        android:padding="20dp"
-        android:text="@string/server_config"
-        android:textSize="40sp"
-        android:visibility="gone"/>
-
-    <Button
-        android:id="@+id/btn_exit"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="40dp"
-        android:padding="20dp"
-        android:text="@string/str_exit"
-        android:textSize="40sp"
-        android:visibility="gone"/>
-
-    <TextView
-        android:id="@+id/tv_version"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="20dp"
-        android:textColor="@color/white"
-        android:textSize="30sp"
-        android:text="V--"
-        android:visibility="gone"/>
-</LinearLayout>
+            android:textSize="40sp"
+            android:textStyle="bold" />
+    </LinearLayout>
+
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <!--密码框-->
+        <LinearLayout
+            android:id="@+id/ll_password_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="center"
+            android:padding="20dp"
+            android:orientation="vertical"
+            android:visibility="gone">
+
+            <TextView
+                android:id="@+id/tv_password_view"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:textSize="24sp"
+                android:hint="@string/input_password" />
+
+            <GridView
+                android:id="@+id/grid_password"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:verticalSpacing="5dp"
+                android:horizontalSpacing="5dp"
+                android:numColumns="3"/>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="20dp"
+                android:orientation="horizontal">
+                <TextView
+                    android:id="@+id/bn_delete"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:padding="4dp"
+                    android:gravity="center_horizontal"
+                    android:text="@string/str_delete"
+                    android:textSize="32sp"
+                    android:textColor="@color/white"/>
+
+                <TextView
+                    android:id="@+id/bn_cancel"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:padding="4dp"
+                    android:gravity="center_horizontal"
+                    android:text="@string/str_cancel"
+                    android:textSize="32sp"
+                    android:textColor="@color/white"/>
+
+                <TextView
+                    android:id="@+id/bn_confirm"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:padding="4dp"
+                    android:gravity="center_horizontal"
+                    android:text="@string/str_confirm"
+                    android:textSize="32sp"
+                    android:textColor="@color/white"/>
+            </LinearLayout>
+        </LinearLayout>
+
+        <RelativeLayout
+            android:id="@+id/rl_config"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="center"
+            android:padding="20dp"
+            android:visibility="gone">
+
+            <LinearLayout
+                android:id="@+id/ll_sip_config"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_centerHorizontal="true">
+                <TextView
+                    android:id="@+id/tv_sip_title"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/setting_sip_enable"
+                    android:textSize="40sp" />
+
+                <RadioGroup
+                    android:id="@+id/group_sip"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_toRightOf="@id/tv_sip_title"
+                    android:layout_marginLeft="10dp"
+                    android:orientation="horizontal">
+
+                    <RadioButton
+                        android:id="@+id/radio_sip_on"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="@string/str_yes"
+                        android:textSize="40sp" />
+
+                    <RadioButton
+                        android:id="@+id/radio_sip_off"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginLeft="10dp"
+                        android:text="@string/str_no"
+                        android:textSize="40sp" />
+                </RadioGroup>
+            </LinearLayout>
+
+            <!--服务器ip配置-->
+            <LinearLayout
+                android:id="@+id/ll_url_config"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_below="@id/ll_sip_config"
+                android:layout_marginTop="40dp">
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:gravity="center"
+                    android:text="Server IP: "
+                    android:textSize="40sp" />
+
+                <EditText
+                    android:id="@+id/edit_url"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="4dp"
+                    android:digits="1234567890."
+                    android:inputType="number"
+                    android:textSize="40sp" />
+            </LinearLayout>
+
+            <Button
+                android:id="@+id/btn_save"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="40dp"
+                android:layout_below="@id/ll_url_config"
+                android:layout_centerHorizontal="true"
+                android:padding="20dp"
+                android:text="@string/str_save"
+                android:textSize="40sp" />
+
+            <Button
+                android:id="@+id/btn_exit"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="40dp"
+                android:layout_below="@id/btn_save"
+                android:layout_centerHorizontal="true"
+                android:padding="20dp"
+                android:text="@string/str_exit"
+                android:textSize="40sp" />
+
+            <TextView
+                android:id="@+id/tv_version"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="20dp"
+                android:layout_below="@id/btn_exit"
+                android:layout_centerHorizontal="true"
+                android:text="V--"
+                android:textColor="@color/white"
+                android:textSize="30sp" />
+
+        </RelativeLayout>
+
+    </RelativeLayout>
+</FrameLayout>
 

+ 20 - 0
app/src/main/res/raw/linphonerc_default

@@ -0,0 +1,20 @@
+[sip]
+contact="Linphone Android" <sip:allen@8.129.220.143>
+use_info=0
+use_ipv6=1
+keepalive_period=30000
+sip_port=-1
+sip_tcp_port=-1
+sip_tls_port=-1
+media_encryption=none
+
+[video]
+size=vga
+
+[app]
+tunnel=disabled
+push_notification=1
+
+[misc]
+max_calls=10
+history_max_size=100

+ 34 - 0
app/src/main/res/raw/linphonerc_factory

@@ -0,0 +1,34 @@
+
+#
+#This file shall not contain path referencing package name, in order to be portable when app is renamed.
+#Paths to resources must be set from LinphoneManager, after creating LinphoneCore.
+[net]
+mtu=1300
+#Because dynamic bitrate adaption can increase bitrate, we must allow "no limit"
+download_bw=0
+upload_bw=0
+force_ice_disablement=0
+
+[sip]
+guess_hostname=1
+register_only_when_network_is_up=1
+auto_net_state_mon=1
+auto_answer_replacing_calls=1
+ping_with_options=0
+use_cpim=1
+
+[video]
+displaytype=MSAndroidTextureDisplay
+
+[misc]
+enable_basic_to_client_group_chat_room_migration=0
+enable_simple_group_chat_message_state=0
+aggregate_imdn=1
+notify_each_friend_individually_when_presence_received=0
+
+[app]
+activation_code_length=4
+prefer_basic_chat_room=1
+
+[assistant]
+xmlrpc_url=https://subscribe.linphone.org:444/wizard.php

+ 14 - 15
build.gradle

@@ -4,7 +4,7 @@ buildscript {
     /**
      * Kotlin统一版本
      */
-    ext.kotlin_version = '1.3.10'
+    ext.kotlin_version = '1.3.21'
 
     /**
      * Aop编制版本
@@ -13,7 +13,7 @@ buildscript {
     /**
      * SDK最小支持版本
      */
-    ext.min_sdk_version = 22
+    ext.min_sdk_version = 23
 
     /**
      * SDK目标支持版本
@@ -23,7 +23,7 @@ buildscript {
     /**
      * SDK编译版本
      */
-    ext.build_tools_version = "26.0.2"
+    ext.build_tools_version = "28.0.3"
 
     /**
      * 支持库版本
@@ -44,27 +44,26 @@ buildscript {
         /**
          * 依赖仓储
          */
-        maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' }
-        maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
-        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
+        maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
+        maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter'}
+        maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
         maven { url 'https://jitpack.io' }
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle'
-        classpath 'com.android.tools.build:gradle:3.5.4'
+
         repositories {
             /**
              * 依赖仓储
              */
-            maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' }
-            maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
-            maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
+            maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
+            maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter'}
+            maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
             maven { url 'https://jitpack.io' }
         }
         /**
          * Gradle插件
          */
-        classpath 'com.android.tools.build:gradle'
+        classpath 'com.android.tools.build:gradle:3.5.0'
 
         /**
          * Kawo组件化插件
@@ -90,9 +89,9 @@ buildscript {
 
 allprojects {
     repositories {
-        maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' }
-        maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
-        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
+        maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
+        maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter'}
+        maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
         maven { url 'https://jitpack.io' }
         maven { url 'https://dl.bintray.com/geamtear/maven' }
 

+ 0 - 9
framework/src/main/AndroidManifest.xml

@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.wdkl.ncs.framework">
-
-    <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_NUMBERS" />
-    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
-</manifest>

+ 0 - 11
framework/src/main/java/com/wdkl/ncs/framework/di/FrameWorkComponent.kt

@@ -1,11 +0,0 @@
-package com.wdkl.ncs.framework.di
-
-import android.bluetooth.BluetoothClass
-import com.wdkl.ncs.framework.api.DeviceApi
-import dagger.Component
-
-@Component(modules = arrayOf(ApiProviders::class))
-interface FrameWorkComponent {
-
-    fun provideDeviceApi():DeviceApi
-}

+ 0 - 26
framework/src/main/java/com/wdkl/ncs/framework/utils/MessageEvent.kt

@@ -1,26 +0,0 @@
-package com.wdkl.ncs.framework.utils
-
-class MessageEvent(var tcpModel: Any,var tag: Int) {
-
-    private var message: Any? = null
-    private var tagInit: Int =0
-
-    fun getMessage(): Any? {
-        return tcpModel
-    }
-
-    fun setMessage(tcpModel: Any?) {
-        this.message = tcpModel
-    }
-
-    fun getType(): Int {
-        return tagInit
-    }
-
-    fun setType(tag: Int) {
-        this.tagInit = tag
-    }
-
-
-
-}

+ 2 - 1
gradle/wrapper/gradle-wrapper.properties

@@ -1,6 +1,7 @@
 #Sat Nov 05 15:33:16 CST 2022
 distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-bin.zip
+#distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-bin.zip
+distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-5.5.1-bin.zip
 distributionPath=wrapper/dists
 zipStorePath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME

+ 1 - 1
janus/build.gradle

@@ -36,7 +36,7 @@ dependencies {
 
     implementation 'org.webrtc:google-webrtc:1.0.32006'
     implementation 'com.squareup.okhttp3:okhttp:3.8.0'
-    implementation project(path: ':framework')
+    implementation project(path: ':middleware')
 //    implementation 'com.squareup.okhttp3:okhttp:3.8.0'
     //api 'org.greenrobot:eventbus:3.0.0'
 //    compile project(':common')

+ 8 - 1
janus/src/main/java/com/wdkl/ncs/janus/rtc/WebRTCEngine.java

@@ -100,6 +100,7 @@ public class WebRTCEngine {
     // 是否使用录屏
     private boolean screencaptureEnabled = false;
     private boolean isSwitch = false; // 是否正在切换摄像头
+    private AudioDeviceModule audioDeviceModule;
 
     private ScheduledExecutorService executor;
     private static final WebRTCEngine instance = new WebRTCEngine();
@@ -220,7 +221,7 @@ public class WebRTCEngine {
         }
 
         // 构造Factory
-        AudioDeviceModule audioDeviceModule = JavaAudioDeviceModule.builder(mContext).createAudioDeviceModule();
+        audioDeviceModule = JavaAudioDeviceModule.builder(mContext).createAudioDeviceModule();
         PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();
         return PeerConnectionFactory.builder()
                 .setOptions(options)
@@ -469,6 +470,12 @@ public class WebRTCEngine {
         return false;
     }
 
+    public void setVolumeMute(boolean on) {
+        if (audioDeviceModule != null) {
+            audioDeviceModule.setSpeakerMute(on);
+        }
+    }
+
     /**
      * 结束本地预览
      */

+ 2 - 2
janus/src/main/java/com/wdkl/ncs/janus/util/Constant.java

@@ -1,8 +1,8 @@
 package com.wdkl.ncs.janus.util;
 
 
-import com.wdkl.ncs.framework.beans.ServerInfo;
-import com.wdkl.ncs.framework.utils.ServerInfoUtil;
+import com.wdkl.ncs.middleware.beans.ServerInfo;
+import com.wdkl.ncs.middleware.utils.ServerInfoUtil;
 
 public class Constant {
 

framework/.gitignore → middleware/.gitignore


+ 4 - 0
framework/build.gradle

@@ -30,6 +30,10 @@ android {
         sourceCompatibility JavaVersion.VERSION_1_8
         targetCompatibility JavaVersion.VERSION_1_8
     }
+
+    sourceSets {
+        main.java.srcDirs += 'src/main/code'
+    }
 }
 
 dependencies {

framework/consumer-rules.pro → middleware/consumer-rules.pro


framework/proguard-rules.pro → middleware/proguard-rules.pro


framework/src/androidTest/java/com/wdkl/ncs/framework/ExampleInstrumentedTest.java → middleware/src/androidTest/java/com/wdkl/ncs/framework/ExampleInstrumentedTest.java


+ 2 - 0
middleware/src/main/AndroidManifest.xml

@@ -0,0 +1,2 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.wdkl.ncs.android.middleware"/>

+ 3 - 3
framework/src/main/java/com/wdkl/ncs/framework/api/ApiManager.kt

@@ -1,7 +1,7 @@
-package com.wdkl.ncs.framework.api
+package com.wdkl.ncs.middleware.api
 
 import android.annotation.SuppressLint
-import com.wdkl.ncs.framework.base.BaseApplication
+import com.wdkl.ncs.middleware.base.BaseApplication
 
 /**
  * @author  LDD
@@ -35,7 +35,7 @@ object ApiManager {
          * @Type  BaseApi
          * @Note  基础API
          */
-        val DEVICE_API :DeviceApi by lazy { apiFactory.createService(DeviceApi::class.java, urlManager.device_url)}
+        val DEVICE_API : DeviceApi by lazy { apiFactory.createService(DeviceApi::class.java, urlManager.device_url)}
 
 
 }

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/api/DeviceApi.kt

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.api
+package com.wdkl.ncs.middleware.api
 
 import io.reactivex.Observable
 import okhttp3.ResponseBody

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/api/NetFactory.kt

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.api
+package com.wdkl.ncs.middleware.api
 
 import android.content.Context
 import android.util.Log

+ 5 - 5
framework/src/main/java/com/wdkl/ncs/framework/api/UrlManager.kt

@@ -1,7 +1,7 @@
-package com.wdkl.ncs.framework.api
+package com.wdkl.ncs.middleware.api
 
-import com.wdkl.ncs.framework.base.BaseApplication
-import com.wdkl.ncs.framework.utils.CommonUtils
+import com.wdkl.ncs.middleware.base.BaseApplication
+import com.wdkl.ncs.middleware.utils.CommonUtils
 
 
 /**
@@ -33,7 +33,7 @@ interface UrlManager {
          * @Date   2018/8/21 下午4:47
          * @Note   构架Url控制器
          */
-        fun build() : UrlManager{
+        fun build() : UrlManager {
           return  ProUrlManager()
         }
 
@@ -48,7 +48,7 @@ interface UrlManager {
  * @From   com.wdkl.ncs.android.middleware.api
  * @Note   生产模式Url控制器
  */
-private class ProUrlManager : UrlManager{
+private class ProUrlManager : UrlManager {
 
     val url: String = CommonUtils.getUrl(BaseApplication.appContext)
     val port: String = CommonUtils.getUrlPort(BaseApplication.appContext)

+ 3 - 2
framework/src/main/java/com/wdkl/ncs/framework/base/BaseActivity.kt

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.base
+package com.wdkl.ncs.middleware.base
 
 import android.content.Context
 import android.content.Intent
@@ -21,7 +21,8 @@ import javax.inject.Inject
  * @From   com.wdkl.ncs.android.lib.base
  * @Note   Activity基类
  */
-abstract class BaseActivity<PresenterType : BaseContract.BasePresenter, DataBindingType : ViewDataBinding> : AppCompatActivity(), BaseControl {
+abstract class BaseActivity<PresenterType : BaseContract.BasePresenter, DataBindingType : ViewDataBinding> : AppCompatActivity(),
+    BaseControl {
 
 
     protected var activity:AppCompatActivity?=null

+ 1 - 3
framework/src/main/java/com/wdkl/ncs/framework/base/BaseApplication.kt

@@ -1,9 +1,7 @@
-package com.wdkl.ncs.framework.base
+package com.wdkl.ncs.middleware.base
 
 import android.annotation.SuppressLint
 import android.app.Application
-import android.content.Context
-import android.content.Intent
 import androidx.multidex.MultiDexApplication
 
 

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/base/BaseContract.kt

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.base
+package com.wdkl.ncs.middleware.base
 
 /**
  * @author  LDD

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/base/BaseControl.kt

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.base
+package com.wdkl.ncs.middleware.base
 
 /**
  * @author LDD

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/base/DisposableManager.kt

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.base
+package com.wdkl.ncs.middleware.base
 
 import io.reactivex.disposables.CompositeDisposable
 import io.reactivex.disposables.Disposable

+ 1 - 3
framework/src/main/java/com/wdkl/ncs/framework/base/RxPresenter.kt

@@ -1,8 +1,6 @@
-package com.wdkl.ncs.framework.base
+package com.wdkl.ncs.middleware.base
 
 import android.util.Log
-import io.reactivex.disposables.CompositeDisposable
-import io.reactivex.disposables.Disposable
 
 /**
  * @author  LDD

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/beans/ServerInfo.java

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.beans;
+package com.wdkl.ncs.middleware.beans;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.databind.PropertyNamingStrategy;

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/common/Constants.kt

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.common
+package com.wdkl.ncs.middleware.common
 
 class Constants {
     companion object{

+ 3 - 3
framework/src/main/java/com/wdkl/ncs/framework/di/ApiProviders.kt

@@ -1,7 +1,7 @@
-package com.wdkl.ncs.framework.di
+package com.wdkl.ncs.middleware.di
 
-import com.wdkl.ncs.framework.api.ApiManager
-import com.wdkl.ncs.framework.api.DeviceApi
+import com.wdkl.ncs.middleware.api.ApiManager
+import com.wdkl.ncs.middleware.api.DeviceApi
 import dagger.Module
 import dagger.Provides
 

+ 11 - 0
middleware/src/main/code/com/wdkl/ncs/middleware/di/FrameWorkComponent.kt

@@ -0,0 +1,11 @@
+package com.wdkl.ncs.middleware.di
+
+import com.wdkl.ncs.middleware.api.DeviceApi
+import com.wdkl.ncs.middleware.di.ApiProviders
+import dagger.Component
+
+@Component(modules = arrayOf(ApiProviders::class))
+interface FrameWorkComponent {
+
+    fun provideDeviceApi(): DeviceApi
+}

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/exception/ExceptionHandle.java

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.exception;
+package com.wdkl.ncs.middleware.exception;
 
 import android.util.Log;
 

+ 2 - 7
framework/src/main/java/com/wdkl/ncs/framework/helper/NetHelper.java

@@ -1,8 +1,7 @@
-package com.wdkl.ncs.framework.helper;
+package com.wdkl.ncs.middleware.helper;
 
 import android.Manifest;
 import android.annotation.SuppressLint;
-import android.bluetooth.BluetoothAdapter;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
@@ -15,9 +14,7 @@ import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 
 
-import com.wdkl.ncs.framework.base.BaseApplication;
-
-import org.greenrobot.eventbus.EventBus;
+import com.wdkl.ncs.middleware.base.BaseApplication;
 
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -31,8 +28,6 @@ import java.util.Collections;
 import java.util.Enumeration;
 import java.util.List;
 import java.util.Timer;
-import java.util.TimerTask;
-
 
 
 public class NetHelper {

+ 2 - 2
framework/src/main/java/com/wdkl/ncs/framework/helper/RingPlayHelper.java

@@ -1,9 +1,9 @@
-package com.wdkl.ncs.framework.helper;
+package com.wdkl.ncs.middleware.helper;
 
 import android.content.Context;
 import android.media.AudioManager;
 
-import com.wdkl.ncs.framework.utils.AsyncPlayer;
+import com.wdkl.ncs.middleware.utils.AsyncPlayer;
 
 
 public class RingPlayHelper {

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/network/ConnectionClassManager.java

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.network;
+package com.wdkl.ncs.middleware.network;
 
 import java.util.ArrayList;
 import java.util.concurrent.atomic.AtomicReference;

+ 6 - 6
framework/src/main/java/com/wdkl/ncs/framework/network/ConnectionObserver.kt

@@ -1,12 +1,12 @@
-package com.wdkl.ncs.framework.network
+package com.wdkl.ncs.middleware.network
 
 import android.content.Context
 import android.net.ConnectivityManager
-import com.wdkl.ncs.framework.base.BaseApplication
-import com.wdkl.ncs.framework.exception.ExceptionHandle
-import com.wdkl.ncs.framework.utils.VoiNetTool
-import com.wdkl.ncs.framework.utils.getJsonString
-import com.wdkl.ncs.framework.utils.then
+import com.wdkl.ncs.middleware.base.BaseApplication
+import com.wdkl.ncs.middleware.exception.ExceptionHandle
+import com.wdkl.ncs.middleware.utils.VoiNetTool
+import com.wdkl.ncs.middleware.utils.getJsonString
+import com.wdkl.ncs.middleware.utils.then
 import io.reactivex.Observer
 import io.reactivex.disposables.Disposable
 import org.json.JSONObject

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/network/ConnectionQuality.kt

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.network
+package com.wdkl.ncs.middleware.network
 
 
 

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/network/ConnectionQualityMonitor.kt

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.network
+package com.wdkl.ncs.middleware.network
 
 
 /**

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/network/DeviceBandwidthSampler.java

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.network;
+package com.wdkl.ncs.middleware.network;
 
 import android.net.TrafficStats;
 import android.os.Handler;

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/network/ExponentialGeometricAverage.java

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.network;
+package com.wdkl.ncs.middleware.network;
 
 /**
  * Moving average calculation for ConnectionClass.

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/utils/AsyncPlayer.java

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.utils;
+package com.wdkl.ncs.middleware.utils;
 
 import android.content.Context;
 import android.media.AudioDeviceInfo;

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/utils/CommonUtils.java

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.utils;
+package com.wdkl.ncs.middleware.utils;
 
 import android.content.Context;
 import android.content.SharedPreferences;

+ 3 - 3
framework/src/main/java/com/wdkl/ncs/framework/utils/ExtendMethods.kt

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.utils
+package com.wdkl.ncs.middleware.utils
 
 /**
  * @author  LDD
@@ -16,8 +16,8 @@ import android.view.animation.Animation
 import android.widget.Toast
 import androidx.core.content.ContextCompat
 import androidx.databinding.ObservableField
-import com.wdkl.ncs.framework.base.BaseApplication
-import com.wdkl.ncs.framework.base.DisposableManager
+import com.wdkl.ncs.middleware.base.BaseApplication
+import com.wdkl.ncs.middleware.base.DisposableManager
 import io.reactivex.disposables.Disposable
 import okhttp3.ResponseBody
 import org.json.JSONArray

+ 33 - 0
middleware/src/main/code/com/wdkl/ncs/middleware/utils/MessageEvent.kt

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

+ 2 - 2
framework/src/main/java/com/wdkl/ncs/framework/utils/ServerInfoUtil.java

@@ -1,11 +1,11 @@
-package com.wdkl.ncs.framework.utils;
+package com.wdkl.ncs.middleware.utils;
 
 import android.os.Environment;
 import android.util.Log;
 
 
 import com.alibaba.fastjson.JSON;
-import com.wdkl.ncs.framework.beans.ServerInfo;
+import com.wdkl.ncs.middleware.beans.ServerInfo;
 
 import java.io.File;
 import java.io.FileInputStream;

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/utils/SystemTool.java

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.utils;
+package com.wdkl.ncs.middleware.utils;
 
 import android.Manifest;
 import android.content.Context;

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/utils/ThreadFromUtils.java

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.utils;
+package com.wdkl.ncs.middleware.utils;
 
 import org.reactivestreams.Publisher;
 

+ 1 - 2
framework/src/main/java/com/wdkl/ncs/framework/utils/Util.kt

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.utils
+package com.wdkl.ncs.middleware.utils
 
 import android.annotation.SuppressLint
 import android.app.KeyguardManager
@@ -7,7 +7,6 @@ import android.content.Context.KEYGUARD_SERVICE
 import android.os.Build
 import android.os.PowerManager
 import android.telephony.TelephonyManager
-import android.util.Log
 import com.google.common.base.Strings
 import java.lang.Exception
 

+ 1 - 1
framework/src/main/java/com/wdkl/ncs/framework/utils/VoiNetTool.java

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.framework.utils;
+package com.wdkl.ncs.middleware.utils;
 
 import android.content.Context;
 import android.net.ConnectivityManager;

framework/src/test/java/com/wdkl/ncs/framework/ExampleUnitTest.java → middleware/src/test/java/com/wdkl/ncs/framework/ExampleUnitTest.java


BIN
release/ncs_entraceguard_V1.1.0_10_black_IP172.28.100.100.apk


+ 2 - 0
resource/src/main/res/values-es/strings.xml

@@ -22,4 +22,6 @@
     <string name="str_loading">Carga</string>
     <string name="str_yes">Sí</string>
     <string name="str_no">No</string>
+
+    <string name="setting_sip_enable">Enable SIP:</string>
 </resources>

+ 2 - 0
resource/src/main/res/values-ru/strings.xml

@@ -22,4 +22,6 @@
     <string name="str_loading">Загрузка</string>
     <string name="str_yes">Да</string>
     <string name="str_no">Нет</string>
+
+    <string name="setting_sip_enable">Enable SIP:</string>
 </resources>

+ 2 - 0
resource/src/main/res/values-zh/strings.xml

@@ -22,4 +22,6 @@
     <string name="str_loading">正在加载</string>
     <string name="str_yes">是</string>
     <string name="str_no">否</string>
+
+    <string name="setting_sip_enable">启用SIP:</string>
 </resources>

+ 2 - 0
resource/src/main/res/values/strings.xml

@@ -22,4 +22,6 @@
     <string name="str_loading">Loading</string>
     <string name="str_yes">Yes</string>
     <string name="str_no">No</string>
+
+    <string name="setting_sip_enable">Enable SIP:</string>
 </resources>

+ 2 - 2
settings.gradle

@@ -1,3 +1,3 @@
-include ':app',':framework',':janus','resource'
+include ':app', ':middleware',':janus','resource'
 //:webrtc',':rtc-chat',':libwebrtc'
-rootProject.name = "entraceguard"
+//rootProject.name = "entraceguard"