|
@@ -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()
|
|
|
+ }
|
|
|
}
|